Skip to content

Commit

Permalink
Introducing a action/command that allows for the direct switching of …
Browse files Browse the repository at this point in the history
…OCI Regions from within the IDE
  • Loading branch information
jhorvath committed Mar 15, 2024
1 parent 63dc7ee commit e6195f7
Show file tree
Hide file tree
Showing 18 changed files with 540 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@
public class OCINode extends AbstractNode {
private RefreshListener refreshListener;

private final OCIItem item;
final OCIItem item;
private final CloudChildFactory factory;
private final OCISessionInitiator session;
final OCISessionInitiator session;

public OCINode(OCIItem item) {
this(new CloudChildFactory(item), item, OCIManager.getDefault().getActiveSession(), Lookups.fixed(item));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
import com.oracle.bmc.identity.requests.GetTenancyRequest;
import com.oracle.bmc.identity.responses.GetTenancyResponse;
import com.oracle.bmc.model.BmcException;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Method;
Expand All @@ -46,13 +48,16 @@
import java.util.Optional;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.prefs.Preferences;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import static org.netbeans.modules.cloud.oracle.OCIManager.PROP_ACTIVE_PROFILE;
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.util.Lookup;
import org.openide.util.NbBundle;
import org.openide.util.NbPreferences;
import org.openide.util.lookup.Lookups;

/**
Expand All @@ -65,6 +70,10 @@ public final class OCIProfile implements OCISessionInitiator {
* ID of the default profile.
*/
public static final String DEFAULT_ID = "DEFAULT"; // NOI18N
/**
* name of preference for active region
*/
static final String PROP_ACTIVE_REGION_CODE = "activeRegionCode";
/**
* Profile ID.
*/
Expand All @@ -81,6 +90,8 @@ public final class OCIProfile implements OCISessionInitiator {
private IOException initError;
private Tenancy tenancyOpt;
private static final Logger LOG = Logger.getLogger(OCIProfile.class.getName());
private Region region;


OCIProfile(Path configPath, String id) {
this(configPath, id, true);
Expand Down Expand Up @@ -115,6 +126,13 @@ private void init() {
String stringPath = configPath.toAbsolutePath().toString();
ConfigFileReader.ConfigFile configFile = id == null ? ConfigFileReader.parse(stringPath) : ConfigFileReader.parse(stringPath, id);
configProvider = new ConfigFileAuthenticationDetailsProvider(configFile);
Preferences prefs = NbPreferences.forModule(OCIProfile.class);
String regionCode = prefs.get(PROP_ACTIVE_REGION_CODE + "/" + id, null);
if (regionCode == null) {
region = configProvider.getRegion();
} else {
region = Region.valueOf(regionCode);
}
fileStamp = stamp;
} catch (IOException ex) {
LOG.log(Level.INFO, "init()", ex);
Expand All @@ -136,6 +154,17 @@ public String getId() {
public boolean isValid() {
return configProvider != null && fileStamp == configPath.toFile().lastModified(); // avoid IOE
}

public void setRegionCode(String regionCode) {
setRegion(Region.valueOf(regionCode));
}

public void setRegion(Region region) {
Preferences prefs = NbPreferences.forModule(OCIProfile.class);
prefs.put(PROP_ACTIVE_REGION_CODE + "/" + id, region.getRegionCode());
listeners.firePropertyChange(PROP_ACTIVE_REGION_CODE, this.region, region);
this.region = region;
}

@Override
public BasicAuthenticationDetailsProvider getAuthenticationProvider() {
Expand All @@ -144,7 +173,7 @@ public BasicAuthenticationDetailsProvider getAuthenticationProvider() {

@Override
public Region getRegion() {
return configProvider.getRegion();
return region;
}

@Override
Expand Down Expand Up @@ -212,7 +241,7 @@ public <T> T newClient(Class<T> clientClass) {
try {
T client = clientClass.getConstructor(BasicAuthenticationDetailsProvider.class).newInstance(configProvider);
Method setRegion = clientClass.getMethod("setRegion", Region.class);
setRegion.invoke(client, configProvider.getRegion());
setRegion.invoke(client, getRegion());
return client;
} catch (ReflectiveOperationException ex) {
throw new IllegalArgumentException("Could not initialize client: " + clientClass);
Expand Down Expand Up @@ -298,6 +327,26 @@ public Optional<String> createAutonomousDatabase(String compartmentId, String db
return Optional.empty();
}
}

private PropertyChangeSupport listeners;

public void addPropertyChangeListener(PropertyChangeListener listener) {
synchronized (this) {
if (listeners == null) {
listeners = new PropertyChangeSupport(this);
}
listeners.addPropertyChangeListener(listener);
}
}

public void removePropertyChangeListener(PropertyChangeListener listener) {
synchronized (this) {
if (listeners == null) {
return;
}
listeners.removePropertyChangeListener(listener);
}
}

@Override
public int hashCode() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
*
* @author Jan Horvath
*/
@NbBundle.Messages({
"MSG_BrokenProfile=Broken profile {0}"
})
public class TenancyInstance implements ServerInstanceImplementation, Lookup.Provider {

private final OCIItem tenancy;
Expand All @@ -41,28 +44,15 @@ public TenancyInstance(OCIItem tenancy, OCIProfile profile) {
this.profile = profile;
lkp = tenancy != null ? Lookups.fixed(profile, tenancy) : Lookups.fixed(profile);
}

@NbBundle.Messages({
"# {0} - tenancy ID",
"# {1} - profile ID",
"MSG_TenancyDesc={0} ({1})",
"# {0} - tenancy ID",
"# {1} - profile ID",
"MSG_BrokenTenancy=Unavailable tenancy {0}",
"# {0} - profile ID",
"MSG_BrokenProfile=Broken profile {0}",
})

@Override
public String getDisplayName() {
if (tenancy != null) {
return Bundle.MSG_TenancyDesc(tenancy.getName(), profile.getId());
} else if (profile.getTenantId() != null) {
return Bundle.MSG_BrokenTenancy(profile.getTenantId(), profile.getId());
} else {
return Bundle.MSG_BrokenProfile(profile.getId());
return tenancy.getName();
}
return profile.getId();
}

@Override
public Lookup getLookup() {
return lkp;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,41 @@ public TenancyNode(OCIItem tenancy, String disp, OCISessionInitiator session) {
// home region will be set as a description
setShortDescription(tenancy.getDescription());
OCIManager.getDefault().addPropertyChangeListener(WeakListeners.propertyChange(this, OCIManager.getDefault()));
if (session instanceof OCIProfile) {
((OCIProfile) session).addPropertyChangeListener(this);
}
}

@Override
public void propertyChange(PropertyChangeEvent e) {
if (OCIManager.PROP_ACTIVE_PROFILE.equals(e.getPropertyName())) {
if (OCIManager.PROP_ACTIVE_PROFILE.equals(e.getPropertyName()) ||
OCIProfile.PROP_ACTIVE_REGION_CODE.equals(e.getPropertyName()) ) {
fireDisplayNameChange(null, null);
}
}

@NbBundle.Messages({
"# {0} - tenancy ID",
"# {1} - profile ID",
"MSG_TenancyDesc={0} (profile: {1}, region: {2})",
"# {0} - tenancy ID",
"# {1} - profile ID",
"MSG_BrokenTenancy=Unavailable tenancy {0}",
"# {0} - profile ID",
"MSG_BrokenProfileNode=Broken profile {0}",
})
@Override
public String getDisplayName() {
OCIProfile profile = (OCIProfile) session;
if (item != null) {
return Bundle.MSG_TenancyDesc(item.getName(), profile.getId(), profile.getRegion());
} else if (profile.getTenantId() != null) {
return Bundle.MSG_BrokenTenancy(profile.getTenantId(), profile.getId());
} else {
return Bundle.MSG_BrokenProfileNode(profile.getId());
}
}

@NbBundle.Messages({
"HTML_EmphasizeName=<b>{0}</b>"
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,5 @@ DownloadWalletDialog.dbUserLabel.text=DB Username:
DownloadWalletDialog.dbPasswordLabel.text=DB Password:
DownloadWalletDialog.addDBCheckbox.toolltip=In addition to downloading Wallet, it also adds this database connection to the database manager.
DownloadWalletDialog.addDBCheckbox.text=Add As Database Connection
SetRegionDialog.jLabel1.text=Region:
SetRegionDialog.text=Please choose an Oracle Cloud Region from the list below. Your selected region will be the default for all future requests.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import java.awt.GraphicsEnvironment;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Locale;
import java.util.Optional;
import javax.swing.JFileChooser;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* 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.identity.Identity;
import com.oracle.bmc.identity.IdentityClient;
import com.oracle.bmc.identity.requests.ListRegionsRequest;
import com.oracle.bmc.identity.responses.ListRegionsResponse;
import java.awt.Dialog;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.stream.Collectors;
import org.netbeans.modules.cloud.oracle.OCIManager;
import org.netbeans.modules.cloud.oracle.OCIProfile;
import org.netbeans.modules.cloud.oracle.OCISessionInitiator;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionReferences;
import org.openide.awt.ActionRegistration;
import org.openide.util.NbBundle;

/**
* This action lets user select an Oracle Cloud region. This region will be used for all subsequent requests.
*
* @author Jan Horvath
*/
@ActionID(
category = "Tools",
id = "org.netbeans.modules.cloud.oracle.actions.SetDefaultRegionAction"
)
@ActionRegistration(
displayName = "#SetDefaultRegion",
asynchronous = true
)
@ActionReferences(value = {
@ActionReference(path = "Cloud/Oracle/Tenancy/Actions", position = 250)
})
@NbBundle.Messages({
"SetDefaultRegion=Set OCI Region",
"SelectRegion=Select a Region"
})
public class SetRegionAction implements ActionListener {

private final OCIProfile context;

public SetRegionAction(OCIProfile context) {
this.context = context;
}

@Override
public void actionPerformed(ActionEvent e) {
OCISessionInitiator session = OCIManager.getDefault().getActiveSession();
Identity identityClient = IdentityClient.builder().build(session.getAuthenticationProvider());
ListRegionsRequest request = ListRegionsRequest.builder().build();

ListRegionsResponse response = identityClient.listRegions(request);

List<String> items = response.getItems().stream()
.map(region -> region.getName())
.sorted((r1, r2) -> r1.compareTo(r2))
.collect(Collectors.toList());

if (!GraphicsEnvironment.isHeadless()) {
SetRegionDialog dlgPanel = new SetRegionDialog(items);
DialogDescriptor descriptor = new DialogDescriptor(dlgPanel, Bundle.SelectRegion()); //NOI18N
Dialog dialog = DialogDisplayer.getDefault().createDialog(descriptor);
dialog.setMinimumSize(dlgPanel.getPreferredSize());
dialog.setVisible(true);
if (DialogDescriptor.OK_OPTION == descriptor.getValue()) {
String selectedCode = dlgPanel.getSelectedRegion();
context.setRegionCode(selectedCode);
}
}

}

}

0 comments on commit e6195f7

Please sign in to comment.