You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@netbeans.apache.org by "jhorvath (via GitHub)" <gi...@apache.org> on 2024/07/02 20:07:19 UTC
[PR] Improving multistep infrastructure, command for uploading cloud assets to config map [netbeans]
jhorvath opened a new pull request, #7540:
URL: https://github.com/apache/netbeans/pull/7540
Multistep inputs are now more modular, with specific steps reusable by multiple commands. Implemented a command to upload the content of Cloud Assets to a ConfigMap artifact.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists
Re: [PR] Improving multistep infrastructure, command for uploading cloud assets to config map [netbeans]
Posted by "sdedic (via GitHub)" <gi...@apache.org>.
sdedic commented on code in PR #7540:
URL: https://github.com/apache/netbeans/pull/7540#discussion_r1670556332
##########
enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/assets/Steps.java:
##########
@@ -92,16 +60,20 @@ public static synchronized Steps getDefault() {
return instance;
}
- public CompletableFuture<Object> executeMultistep(Step firstStep, Lookup lookup) {
+ public CompletableFuture<Values> executeMultistep(AbstractStep firstStep, Lookup lookup) {
DialogDisplayer dd = DialogDisplayer.getDefault();
CompletableFuture future = new CompletableFuture();
RP.post(() -> {
- Multistep multistep = new Multistep(firstStep, lookup);
- NotifyDescriptor.ComposedInput ci = new NotifyDescriptor.ComposedInput(Bundle.AddSuggestedItem(), 3, multistep.createInput());
- if (DialogDescriptor.OK_OPTION == dd.notify(ci)) {
- future.complete(multistep.getResult());
- } else {
- future.cancel(true);
+ try {
+ Multistep multistep = new Multistep(firstStep, lookup);
+ NotifyDescriptor.ComposedInput ci = new NotifyDescriptor.ComposedInput(Bundle.AddSuggestedItem(), 3, multistep.createInput());
+ if (DialogDescriptor.OK_OPTION == dd.notify(ci)) {
Review Comment:
I'd use `dd.notifyFuture(ci).handle()` or `.then*` so that RP (throughput 1) is not blocked.
##########
enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/actions/ConfigMapCommand.java:
##########
@@ -0,0 +1,385 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.cloud.oracle.actions;
+
+import com.oracle.bmc.devops.DevopsClient;
+import com.oracle.bmc.devops.model.DeployArtifactSource;
+import com.oracle.bmc.devops.model.DeployArtifactSummary;
+import com.oracle.bmc.devops.model.InlineDeployArtifactSource;
+import com.oracle.bmc.devops.model.UpdateDeployArtifactDetails;
+import com.oracle.bmc.devops.requests.GetDeployArtifactRequest;
+import com.oracle.bmc.devops.requests.ListDeployArtifactsRequest;
+import com.oracle.bmc.devops.requests.UpdateDeployArtifactRequest;
+import com.oracle.bmc.devops.responses.GetDeployArtifactResponse;
+import com.oracle.bmc.devops.responses.ListDeployArtifactsResponse;
+import com.oracle.bmc.model.BmcException;
+import com.oracle.bmc.vault.VaultsClient;
+import com.oracle.bmc.vault.model.Base64SecretContentDetails;
+import com.oracle.bmc.vault.model.CreateSecretDetails;
+import com.oracle.bmc.vault.model.SecretContentDetails;
+import com.oracle.bmc.vault.model.SecretReuseRule;
+import com.oracle.bmc.vault.model.UpdateSecretDetails;
+import com.oracle.bmc.vault.requests.CreateSecretRequest;
+import com.oracle.bmc.vault.requests.ListSecretsRequest;
+import com.oracle.bmc.vault.requests.UpdateSecretRequest;
+import com.oracle.bmc.vault.responses.ListSecretsResponse;
+import com.oracle.bmc.vault.responses.UpdateSecretResponse;
+import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import org.netbeans.modules.cloud.oracle.steps.DevopsStep;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+import org.netbeans.api.db.explorer.ConnectionManager;
+import org.netbeans.api.db.explorer.DatabaseConnection;
+import org.netbeans.api.progress.ProgressHandle;
+import org.netbeans.api.project.Project;
+import org.netbeans.modules.cloud.oracle.OCIManager;
+import static org.netbeans.modules.cloud.oracle.OCIManager.getDefault;
+import org.netbeans.modules.cloud.oracle.assets.CloudAssets;
+import org.netbeans.modules.cloud.oracle.assets.DependencyUtils;
+import org.netbeans.modules.cloud.oracle.assets.PropertiesGenerator;
+import org.netbeans.modules.cloud.oracle.assets.Steps;
+import org.netbeans.modules.cloud.oracle.database.DatabaseItem;
+import org.netbeans.modules.cloud.oracle.devops.DevopsProjectItem;
+import org.netbeans.modules.cloud.oracle.steps.DatasourceNameStep;
+import org.netbeans.modules.cloud.oracle.steps.KeyStep;
+import org.netbeans.modules.cloud.oracle.steps.OverwriteStep;
+import org.netbeans.modules.cloud.oracle.steps.PasswordStep;
+import org.netbeans.modules.cloud.oracle.steps.ProjectStep;
+import org.netbeans.modules.cloud.oracle.items.OCIItem;
+import org.netbeans.modules.cloud.oracle.steps.CompartmentStep;
+import org.netbeans.modules.cloud.oracle.steps.TenancyStep;
+import org.netbeans.modules.cloud.oracle.vault.KeyItem;
+import org.netbeans.modules.cloud.oracle.vault.VaultItem;
+import org.netbeans.spi.lsp.CommandProvider;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.util.Lookup;
+import org.openide.util.NbBundle;
+import org.openide.util.lookup.Lookups;
+import org.openide.util.lookup.ServiceProvider;
+
+/**
+ * Command that updates a ConfigMap with the current properties generated from the contents of {@link CloudAssets}.
+ *
+ * @author Jan Horvath
+ */
+@NbBundle.Messages({
+ "SuggestVault=For better security when using Autonomous Database, be sure to also add OCI Vault.",
+ "UpdatingConfigMap=Updating Config Map",
+ "CMUpdated=ConfigMap in \"{0}\" project was updated"
+})
+@ServiceProvider(service = CommandProvider.class)
+public class ConfigMapCommand implements CommandProvider {
+
+ private static final Logger LOG = Logger.getLogger(ConfigMapCommand.class.getName());
+
+ private static final String COMMAND_UPLOAD_TO_CONFIGMAP = "nbls.cloud.assets.configmap.upload"; //NOI18N
+
+ private static final Set COMMANDS = new HashSet<>(Arrays.asList(
+ COMMAND_UPLOAD_TO_CONFIGMAP
+ ));
+
+ @Override
+ public Set<String> getCommands() {
+ return Collections.unmodifiableSet(COMMANDS);
+ }
+
+ @Override
+ public CompletableFuture<Object> runCommand(String command, List<Object> arguments) {
+ Steps.NextStepProvider.Builder nsProviderBuilder = Steps.NextStepProvider.builder();
+ CompletableFuture future = new CompletableFuture();
+
+ nsProviderBuilder.stepForClass(TenancyStep.class, (s) -> new CompartmentStep())
+ .stepForClass(CompartmentStep.class, (s) -> new DevopsStep())
+ .stepForClass(DevopsStep.class, (s) -> new ProjectStep());
+
+ Collection<OCIItem> items = CloudAssets.getDefault().getAssignedItems();
+ AtomicReference<VaultItem> vaultRef = new AtomicReference<>();
+ AtomicReference<DatabaseItem> dbRef = new AtomicReference<>();
+ for (OCIItem item : items) {
+ if (item instanceof VaultItem) {
+ vaultRef.set((VaultItem) item);
+ nsProviderBuilder.stepForClass(OverwriteStep.class, (s) -> new KeyStep(vaultRef.get()));
+ } else if (item instanceof DatabaseItem) {
+ dbRef.set((DatabaseItem) item);
+ DatabaseConnection conn = null;
+ DatabaseConnection[] connections = ConnectionManager.getDefault().getConnections();
+ for (int i = 0; i < connections.length; i++) {
+ if (item.getKey().getValue().equals(
+ connections[i].getConnectionProperties().get("OCID"))) { //NOI18N
+ conn = connections[i];
+ break;
+ }
+ }
+ String user, password;
+ if (conn != null) {
+ user = conn.getUser();
+ password = conn.getPassword();
+ } else {
+ user = null;
+ password = null;
+ }
+ nsProviderBuilder.stepForClass(ProjectStep.class, (s) -> new PasswordStep(user, password))
+ .stepForClass(PasswordStep.class, (s) -> new DatasourceNameStep())
+ .stepForClass(DatasourceNameStep.class, (s) -> new OverwriteStep());
+ }
+ }
+
+ if (vaultRef.get() == null && dbRef.get() != null) {
+ NotifyDescriptor.Message msg = new NotifyDescriptor.Message(Bundle.SuggestVault(), NotifyDescriptor.INFORMATION_MESSAGE);
+ DialogDisplayer.getDefault().notifyLater(msg);
+ }
+
+ Lookup lookup = Lookups.fixed(nsProviderBuilder.build());
+ Steps.getDefault()
+ .executeMultistep(new TenancyStep(), lookup)
+ .thenAccept(values -> {
+ Project project = values.getValueForStep(ProjectStep.class);
+ KeyItem key = values.getValueForStep(KeyStep.class);
+ DevopsProjectItem devopsProject = values.getValueForStep(DevopsStep.class);
+ String datasourceName = values.getValueForStep(DatasourceNameStep.class);
+
+ if (dbRef.get() != null) {
+ CloudAssets.getDefault().setReferenceName(dbRef.get(), datasourceName);
+ }
+
+ ProgressHandle h = ProgressHandle.createHandle(Bundle.UpdatingConfigMap());
+ try {
+ PropertiesGenerator propGen = new PropertiesGenerator(false);
+ if (vaultRef.get() != null) {
+ updateVault(h, key, vaultRef.get(), propGen, project);
+ }
+ updateConfigMap(h, devopsProject, propGen, command);
+ NotifyDescriptor.Message msg = new NotifyDescriptor.Message(Bundle.CMUpdated(devopsProject.getName()), NotifyDescriptor.INFORMATION_MESSAGE);
+ DialogDisplayer.getDefault().notify(msg);
Review Comment:
I recommend to use `notifyLater` here, since we do not need to wait on the dialog to complete. `notify` might block the LSP message thread.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists
Re: [PR] Improving multistep infrastructure, command for uploading cloud assets to config map [netbeans]
Posted by "jhorvath (via GitHub)" <gi...@apache.org>.
jhorvath merged PR #7540:
URL: https://github.com/apache/netbeans/pull/7540
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists
Re: [PR] Improving multistep infrastructure, command for uploading cloud assets to config map [netbeans]
Posted by "jhorvath (via GitHub)" <gi...@apache.org>.
jhorvath commented on code in PR #7540:
URL: https://github.com/apache/netbeans/pull/7540#discussion_r1669813578
##########
enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/steps/TenancyStep.java:
##########
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.cloud.oracle.steps;
+
+import com.oracle.bmc.identity.model.Tenancy;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicReference;
+import org.netbeans.api.progress.ProgressHandle;
+import org.netbeans.modules.cloud.oracle.OCIManager;
+import org.netbeans.modules.cloud.oracle.OCIProfile;
+import org.netbeans.modules.cloud.oracle.assets.AbstractStep;
+import org.netbeans.modules.cloud.oracle.items.TenancyItem;
+import org.openide.NotifyDescriptor;
+import org.openide.util.NbBundle;
+
+/**
+ *
+ * @author Jan Horvath
+ */
+@NbBundle.Messages({
+ "SelectProfile=Select OCI Profile",
+ "SelectProfile_Description={0} (region: {1})",
+ "NoProfile=There is not any OCI profile in the config",
+ "CollectingProfiles_Text=Loading OCI Profiles",
+ "SelectKey=Select Key"
+})
+public final class TenancyStep extends AbstractStep<TenancyItem> {
+
+ private List<OCIProfile> profiles = new LinkedList<>();
+ private final AtomicReference<TenancyItem> selected = new AtomicReference<>();
+
+ @Override
+ public NotifyDescriptor createInput() {
+ if (onlyOneChoice()) {
+ throw new IllegalStateException("No data to create input"); // NOI18N
+ }
+ String title = Bundle.SelectProfile();
+ List<NotifyDescriptor.QuickPick.Item> items = new ArrayList<>(profiles.size());
+ for (OCIProfile p : profiles) {
+ Tenancy t = p.getTenancyData();
+ if (t != null) {
+ items.add(new NotifyDescriptor.QuickPick.Item(p.getId(), Bundle.SelectProfile_Description(t.getName(), t.getHomeRegionKey())));
+ }
+ }
+ if (profiles.stream().filter(p -> p.getTenancy().isPresent()).count() == 0) {
+ title = Bundle.NoProfile();
+ }
+ return new NotifyDescriptor.QuickPick(title, title, items, false);
+ }
+
+ @Override
+ public void prepare(ProgressHandle h) {
+ h.progress(Bundle.CollectingProfiles_Text());
+ profiles = OCIManager.getDefault().getConnectedProfiles();
+ }
+
+ @Override
+ public void setValue(String value) {
+ for (OCIProfile profile : profiles) {
+ if (profile.getId().equals(value)) {
+ profile.getTenancy().ifPresent(t -> this.selected.set(t));
Review Comment:
The plain assignment is used wherever it is possible to make it final.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists
Re: [PR] Improving multistep infrastructure, command for uploading cloud assets to config map [netbeans]
Posted by "sdedic (via GitHub)" <gi...@apache.org>.
sdedic commented on code in PR #7540:
URL: https://github.com/apache/netbeans/pull/7540#discussion_r1668498198
##########
enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/actions/AddADBAction.java:
##########
@@ -75,14 +75,16 @@
@NbBundle.Messages({
"AddADB=Add Oracle Autonomous DB",
"SelectProfile=Select OCI Profile",
- "# {0} - tenancy name",
- "# {1} - region id",
- "SelectProfile_Description={0} (region: {1})",
"SelectCompartment=Select Compartment",
"SelectDatabase=Select Database",
"NoDatabase=No Database available in this Compartment",
"EnterUsername=Enter Username",
- "EnterPassword=Enter Password"
+ "EnterPassword=Enter Password",
+ "MSG_CollectingProfiles=Searching for OCI Profiles",
+ "MSG_CollectingProfiles_Text=Loading OCI Profiles",
+ "MSG_CollectingItems=Loading OCI contents",
+ "MSG_CollectingItems_Text=Listing compartments and databases",
+ "SelectProfile_Description={0} (region: {1})"
Review Comment:
Nitpick: parameter defs missing.
##########
enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/actions/DownloadWalletDialog.java:
##########
@@ -92,7 +92,7 @@ static Optional<WalletInfo> showDialog(OCIItem db) {
String dbUser = dlgPanel.dbUserField.getText();
char[] dbPasswd = dlgPanel.dbPasswordField.getPassword();
NbPreferences.forModule(DownloadWalletAction.class).put(LAST_USED_DIR, path); //NOI18N
- return Optional.of(new WalletInfo(path, generatePassword(), dbUser, dbPasswd, db.getKey().getValue(), db.getCompartmentId()));
+ return Optional.of(new WalletInfo(path, generatePassword(), dbUser, dbPasswd, (DatabaseItem) db));
Review Comment:
why `db` is typed just as `OCIItem` and not `DatabaseItem` ?
##########
enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/assets/Steps.java:
##########
@@ -177,16 +147,31 @@ public NextStepProvider build() {
}
}
}
-
+
+ /**
+ * Provides values for steps in the multi step dialog.
+ *
+ */
+ public interface Values {
+
+ /**
+ * Returns a value for a given {@link Step}.
+ * @param step
+ * @return
+ */
+ public Object getValueForStep(Class<? extends Step> step);
Review Comment:
If this is declared as
```
public <X> X getValueForStep(Class<? extends Step<X>> step);
```
then `Steps` clients do not need to do typecasts when extracting the data, if the individual Step classes are properly typed. Isn't it too screwed use of generics @jlahoda ?
##########
enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/assets/AbstractStep.java:
##########
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.cloud.oracle.assets;
+
+import org.netbeans.api.progress.ProgressHandle;
+import org.openide.util.Lookup;
+import org.openide.util.NbBundle;
+
+/**
+ *
+ * @author Jan Horvath
+ */
+@NbBundle.Messages({
+ "LoadingItems=Loading items for the next step"
+})
+public abstract class AbstractStep<U> implements Step<U> {
Review Comment:
I would suggest to merge `AbstractStep` with `Step` to one abstract inheritable class. Then `Steps` implementation (`MultiStep`) can directly send `Steps.Values` to this abstract class using package-private methods.
##########
enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/assets/AbstractStep.java:
##########
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.cloud.oracle.assets;
+
+import org.netbeans.api.progress.ProgressHandle;
+import org.openide.util.Lookup;
+import org.openide.util.NbBundle;
+
+/**
+ *
+ * @author Jan Horvath
+ */
+@NbBundle.Messages({
+ "LoadingItems=Loading items for the next step"
+})
+public abstract class AbstractStep<U> implements Step<U> {
+ private Lookup lookup;
+ protected Steps.Values values;
+
+
+ @Override
+ public final Step prepare(Lookup lookup) {
+ this.lookup = lookup;
+ values = lookup.lookup(Steps.Values.class);
+ ProgressHandle h = ProgressHandle.createHandle(Bundle.LoadingItems());
+ h.start();
+ try {
+ prepare(h);
+ } finally {
+ h.finish();
+ }
+ return this;
+ }
+
+ public void prepare(ProgressHandle handle) {
+ }
+
+ @Override
+ public Step getNext() {
+ Steps.NextStepProvider nsProvider = lookup.lookup(Steps.NextStepProvider.class);
+ if (nsProvider != null) {
+ Step ns = nsProvider.nextStepFor(this);
Review Comment:
I'd move this logic into `Multistep` and just return `null` at `AbstractStep` level to indicate the provider should be used. Either the returned `Step` instance returned from `getNext()` or the provider-returned `Step` instance would be then `prepare()`d by Steps.
This is motivated by "hidden SPI" between `Multistep` and `AbstractStep` through Lookup, we should either make it explicit or hide entirely from Step implementors.
##########
enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/steps/CompartmentStep.java:
##########
@@ -0,0 +1,174 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.cloud.oracle.steps;
+
+import com.oracle.bmc.identity.Identity;
+import com.oracle.bmc.identity.IdentityClient;
+import com.oracle.bmc.identity.model.Compartment;
+import com.oracle.bmc.identity.requests.ListCompartmentsRequest;
+import com.oracle.bmc.identity.responses.ListCompartmentsResponse;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+import org.netbeans.api.progress.ProgressHandle;
+import org.netbeans.modules.cloud.oracle.OCIManager;
+import org.netbeans.modules.cloud.oracle.OCISessionInitiator;
+import org.netbeans.modules.cloud.oracle.assets.AbstractStep;
+import static org.netbeans.modules.cloud.oracle.assets.Steps.createQuickPick;
+import org.netbeans.modules.cloud.oracle.compartment.CompartmentItem;
+import org.netbeans.modules.cloud.oracle.items.OCID;
+import org.netbeans.modules.cloud.oracle.items.OCIItem;
+import org.netbeans.modules.cloud.oracle.items.TenancyItem;
+import org.openide.NotifyDescriptor;
+import org.openide.util.NbBundle;
+
+/**
+ *
+ * @author Jan Horvath
+ */
+@NbBundle.Messages({
+ "NoCompartment=There are no compartments in the Tenancy",
+ "CollectingItems_Text=Listing compartments and databases",
+ "SelectCompartment=Select Compartment",})
+public final class CompartmentStep extends AbstractStep<CompartmentItem> {
+
+ private Map<String, OCIItem> compartments = null;
+ private CompartmentItem selected;
+
+ @Override
+ public void prepare(ProgressHandle h) {
+ h.progress(Bundle.CollectingItems_Text());
+ TenancyItem tenancy = (TenancyItem) values.getValueForStep(TenancyStep.class);
+ compartments = getFlatCompartment(tenancy);
+ }
+
+ @Override
+ public NotifyDescriptor createInput() {
+ if (onlyOneChoice()) {
+ throw new IllegalStateException("Input shouldn't be displayed for one choice"); // NOI18N
+ }
+ if (compartments.isEmpty()) {
+ return createQuickPick(compartments, Bundle.NoCompartment());
+ }
+ return createQuickPick(compartments, Bundle.SelectCompartment());
+ }
+
+ @Override
+ public void setValue(String selected) {
+ this.selected = (CompartmentItem) compartments.get(selected);
+ }
+
+ @Override
+ public CompartmentItem getValue() {
+ if (onlyOneChoice()) {
+ return (CompartmentItem) compartments.values().iterator().next();
+ }
+ return selected;
+ }
+
+ @Override
+ public boolean onlyOneChoice() {
+ return compartments.size() == 1;
+ }
+
+ /**
+ * Retrieve all compartments from a tenancy.
+ *
+ * @param tenancy
+ * @return
+ */
+ static private Map<String, OCIItem> getFlatCompartment(TenancyItem tenancy) {
+ Map<OCID, FlatCompartmentItem> compartments = new HashMap<>();
+ OCISessionInitiator session = OCIManager.getDefault().getActiveSession();
+ Identity identityClient = session.newClient(IdentityClient.class);
+ String nextPageToken = null;
+
+ do {
+ ListCompartmentsResponse response
+ = identityClient.listCompartments(
+ ListCompartmentsRequest.builder()
+ .compartmentId(tenancy.getKey().getValue())
+ .compartmentIdInSubtree(true)
+ .lifecycleState(Compartment.LifecycleState.Active)
+ .accessLevel(ListCompartmentsRequest.AccessLevel.Accessible)
+ .limit(1000)
+ .page(nextPageToken)
+ .build());
+ for (Compartment comp : response.getItems()) {
+ FlatCompartmentItem ci = new FlatCompartmentItem(comp) {
+ @Override
+ FlatCompartmentItem getItem(OCID compId) {
+ return compartments.get(compId);
+ }
+ };
+ compartments.put(ci.getKey(), ci);
+ }
+ nextPageToken = response.getOpcNextPage();
+ } while (nextPageToken != null);
+ Map<String, OCIItem> pickItems = computeFlatNames(compartments);
+ pickItems.put(tenancy.getName() + " (root)", tenancy); // NOI18N
Review Comment:
I18N
##########
enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/assets/AbstractStep.java:
##########
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.cloud.oracle.assets;
+
+import org.netbeans.api.progress.ProgressHandle;
+import org.openide.util.Lookup;
+import org.openide.util.NbBundle;
+
+/**
+ *
+ * @author Jan Horvath
+ */
+@NbBundle.Messages({
+ "LoadingItems=Loading items for the next step"
+})
+public abstract class AbstractStep<U> implements Step<U> {
+ private Lookup lookup;
+ protected Steps.Values values;
+
+
+ @Override
+ public final Step prepare(Lookup lookup) {
+ this.lookup = lookup;
+ values = lookup.lookup(Steps.Values.class);
+ ProgressHandle h = ProgressHandle.createHandle(Bundle.LoadingItems());
Review Comment:
This progresshandle wrapper around `prepare()` could better fit into `Multistep` wizard driver.
##########
enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/steps/DatasourceNameStep.java:
##########
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.cloud.oracle.steps;
+
+import org.netbeans.api.progress.ProgressHandle;
+import org.netbeans.modules.cloud.oracle.assets.AbstractStep;
+import org.openide.NotifyDescriptor;
+import org.openide.util.NbBundle;
+
+/**
+ *
+ * @author Jan Horvath
+ */
+@NbBundle.Messages({
+ "DatasourceName=Datasource Name",
+})
+public class DatasourceNameStep extends AbstractStep<String> {
+ private String selected;
+
+ public DatasourceNameStep() {
+ }
+
+ @Override
+ public void prepare(ProgressHandle h) {
+ }
+
+ @Override
+ public NotifyDescriptor createInput() {
+ return new NotifyDescriptor.InputLine("DEFAULT", Bundle.DatasourceName()); //NOI18N
Review Comment:
Q: what if the user returns to this step: the previously entered value will be lost (not offered in the input line) ?
##########
enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/items/OCIItem.java:
##########
@@ -27,11 +27,12 @@
*
* @author Jan Horvath
*/
-public abstract class OCIItem {
+public abstract class OCIItem implements NamedReference {
final OCID id;
final String name;
final String compartmentId;
String description;
+ private String referenceName = "DEFAULT";
Review Comment:
Q: each `OCI item` becomes a valid `NamedReference` (regadless of OCI item type ?)
##########
enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/steps/TenancyStep.java:
##########
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.cloud.oracle.steps;
+
+import com.oracle.bmc.identity.model.Tenancy;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicReference;
+import org.netbeans.api.progress.ProgressHandle;
+import org.netbeans.modules.cloud.oracle.OCIManager;
+import org.netbeans.modules.cloud.oracle.OCIProfile;
+import org.netbeans.modules.cloud.oracle.assets.AbstractStep;
+import org.netbeans.modules.cloud.oracle.items.TenancyItem;
+import org.openide.NotifyDescriptor;
+import org.openide.util.NbBundle;
+
+/**
+ *
+ * @author Jan Horvath
+ */
+@NbBundle.Messages({
+ "SelectProfile=Select OCI Profile",
+ "SelectProfile_Description={0} (region: {1})",
+ "NoProfile=There is not any OCI profile in the config",
+ "CollectingProfiles_Text=Loading OCI Profiles",
+ "SelectKey=Select Key"
+})
+public final class TenancyStep extends AbstractStep<TenancyItem> {
+
+ private List<OCIProfile> profiles = new LinkedList<>();
+ private final AtomicReference<TenancyItem> selected = new AtomicReference<>();
+
+ @Override
+ public NotifyDescriptor createInput() {
+ if (onlyOneChoice()) {
+ throw new IllegalStateException("No data to create input"); // NOI18N
+ }
+ String title = Bundle.SelectProfile();
+ List<NotifyDescriptor.QuickPick.Item> items = new ArrayList<>(profiles.size());
+ for (OCIProfile p : profiles) {
+ Tenancy t = p.getTenancyData();
+ if (t != null) {
+ items.add(new NotifyDescriptor.QuickPick.Item(p.getId(), Bundle.SelectProfile_Description(t.getName(), t.getHomeRegionKey())));
+ }
+ }
+ if (profiles.stream().filter(p -> p.getTenancy().isPresent()).count() == 0) {
+ title = Bundle.NoProfile();
+ }
+ return new NotifyDescriptor.QuickPick(title, title, items, false);
+ }
+
+ @Override
+ public void prepare(ProgressHandle h) {
+ h.progress(Bundle.CollectingProfiles_Text());
+ profiles = OCIManager.getDefault().getConnectedProfiles();
+ }
+
+ @Override
+ public void setValue(String value) {
+ for (OCIProfile profile : profiles) {
+ if (profile.getId().equals(value)) {
+ profile.getTenancy().ifPresent(t -> this.selected.set(t));
Review Comment:
AtomicRef is used here, but in all other Step implementations, just a plain assignment is used ?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists
Re: [PR] Improving multistep infrastructure, command for uploading cloud assets to config map [netbeans]
Posted by "mbien (via GitHub)" <gi...@apache.org>.
mbien commented on PR #7540:
URL: https://github.com/apache/netbeans/pull/7540#issuecomment-2217283233
don't forget to set the milestones on PRs
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists