diff options
| author | Shireesh Anjal <shireesh@gluster.com> | 2011-05-25 18:12:48 +0530 |
|---|---|---|
| committer | Shireesh Anjal <shireesh@gluster.com> | 2011-05-30 17:19:56 +0530 |
| commit | 562a55a68407ed0d65de75c9a491188e1292a2c3 (patch) | |
| tree | 20e849d173713e8d5087b2994ad181f0838d8f1e /src | |
| parent | 66eeb6a273b1a60813375a4bf55bcc38e1a3d00a (diff) | |
Design changes - introducing cluster-server mapping on gateway
Diffstat (limited to 'src')
16 files changed, 415 insertions, 98 deletions
diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/AbstractClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/AbstractClient.java index 10064341..fedfacaa 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/AbstractClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/AbstractClient.java @@ -161,7 +161,7 @@ public abstract class AbstractClient { */
@SuppressWarnings({ "unchecked", "rawtypes" })
protected Object postRequest(Class responseClass, Form form) {
- return resource.type(MediaType.APPLICATION_FORM_URLENCODED_TYPE).header("Authorization", authHeader)
+ return resource.type(MediaType.APPLICATION_FORM_URLENCODED_TYPE).header(HTTP_HEADER_AUTH, authHeader)
.accept(MediaType.TEXT_XML).post(responseClass, form);
}
@@ -179,7 +179,7 @@ public abstract class AbstractClient { @SuppressWarnings({ "rawtypes", "unchecked" })
protected Object postRequest(String subResourceName, Class responseClass, Form form) {
return resource.path(subResourceName).type(MediaType.APPLICATION_FORM_URLENCODED_TYPE)
- .header("Authorization", authHeader).accept(MediaType.TEXT_XML).post(responseClass, form);
+ .header(HTTP_HEADER_AUTH, authHeader).accept(MediaType.TEXT_XML).post(responseClass, form);
}
/**
@@ -195,7 +195,21 @@ public abstract class AbstractClient { */
protected Object putRequest(String subResourceName, Class responseClass, Form form) {
return resource.path(subResourceName).type(MediaType.APPLICATION_FORM_URLENCODED_TYPE)
- .header("Authorization", authHeader).accept(MediaType.TEXT_XML).put(responseClass, form);
+ .header(HTTP_HEADER_AUTH, authHeader).accept(MediaType.TEXT_XML).put(responseClass, form);
+ }
+
+ /**
+ * Submits given Form using PUT method to the given sub-resource and returns the object received as response
+ *
+ * @param responseClass
+ * Class of the object expected as response
+ * @param form
+ * Form to be submitted
+ * @return Object of given class received as response
+ */
+ protected Object putRequest(Class responseClass, Form form) {
+ return resource.type(MediaType.APPLICATION_FORM_URLENCODED_TYPE).header(HTTP_HEADER_AUTH, authHeader)
+ .accept(MediaType.TEXT_XML).put(responseClass, form);
}
/**
@@ -209,7 +223,7 @@ public abstract class AbstractClient { */
protected Object putRequest(String subResourceName, Class responseClass) {
return resource.path(subResourceName).type(MediaType.APPLICATION_FORM_URLENCODED_TYPE)
- .header("Authorization", authHeader).accept(MediaType.TEXT_XML).put(responseClass);
+ .header(HTTP_HEADER_AUTH, authHeader).accept(MediaType.TEXT_XML).put(responseClass);
}
/**
diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/ClustersClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/ClustersClient.java index 08c380e0..8eeb96fe 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/ClustersClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/ClustersClient.java @@ -19,6 +19,7 @@ package com.gluster.storage.management.client; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_CLUSTER_NAME; +import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_SERVER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_CLUSTERS; import java.util.List; @@ -58,6 +59,13 @@ public class ClustersClient extends AbstractClient { return (Status)postRequest(Status.class, form); } + public Status registerCluster(String clusterName, String knownServer) { + Form form = new Form(); + form.add(FORM_PARAM_CLUSTER_NAME, clusterName); + form.add(FORM_PARAM_SERVER_NAME, knownServer); + return (Status)putRequest(Status.class, form); + } + public Status deleteCluster(String clusterName) { return (Status)deleteSubResource(clusterName, Status.class); } diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java index 356e1e0d..b01a0ece 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java @@ -137,7 +137,7 @@ public class GlusterDataModelManager { } private void initializeVolumes(Cluster cluster) { - VolumesClient volumeClient = new VolumesClient(securityToken); + VolumesClient volumeClient = new VolumesClient(clusterName); VolumeListResponse response = volumeClient.getAllVolumes(); if (!response.getStatus().isSuccess()) { throw new GlusterRuntimeException("Error fetching volume list: [" + response.getStatus() + "]"); diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/UsersClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/UsersClient.java index 099b64a0..864418a7 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/UsersClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/UsersClient.java @@ -18,6 +18,8 @@ *******************************************************************************/ package com.gluster.storage.management.client; +import javax.ws.rs.core.Response; + import com.gluster.storage.management.core.model.Status; import com.sun.jersey.api.client.UniformInterfaceException; import com.sun.jersey.api.representation.Form; @@ -27,7 +29,6 @@ public class UsersClient extends AbstractClient { private static final String RESOURCE_NAME = "users"; private static final String FORM_PARAM_OLD_PASSWORD = "oldpassword"; private static final String FORM_PARAM_NEW_PASSWORD = "newpassword"; - private static final int HTTP_STATUS_UNAUTHORIZED = 401; private String generateSecurityToken(String user, String password) { return new String(Base64.encode(user + ":" + password)); @@ -48,7 +49,8 @@ public class UsersClient extends AbstractClient { return authStatus; } catch (Exception e) { if (e instanceof UniformInterfaceException - && ((UniformInterfaceException) e).getResponse().getStatus() == HTTP_STATUS_UNAUTHORIZED) { + && ((UniformInterfaceException) e).getResponse().getStatus() == Response.Status.UNAUTHORIZED + .getStatusCode()) { // authentication failed. clear security token. setSecurityToken(null); return new Status(Status.STATUS_CODE_FAILURE, "Invalid user id or password!"); diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java index 96517766..d38a41b3 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java @@ -31,6 +31,7 @@ import com.gluster.storage.management.core.constants.RESTConstants; import com.gluster.storage.management.core.model.Brick; import com.gluster.storage.management.core.model.Status; import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.core.response.GenericResponse; import com.gluster.storage.management.core.response.LogMessageListResponse; import com.gluster.storage.management.core.response.VolumeListResponse; import com.gluster.storage.management.core.response.VolumeOptionInfoListResponse; @@ -88,8 +89,9 @@ public class VolumesClient extends AbstractClient { return (VolumeListResponse) fetchResource(VolumeListResponse.class); } - public Volume getVolume(String volumeName) { - return (Volume) fetchSubResource(volumeName, Volume.class); + @SuppressWarnings("unchecked") + public GenericResponse<Volume> getVolume(String volumeName) { + return (GenericResponse<Volume>)fetchSubResource(volumeName, GenericResponse.class); } public Status deleteVolume(Volume volume, boolean deleteOption) { diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/RESTConstants.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/RESTConstants.java index 80622992..33323021 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/RESTConstants.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/RESTConstants.java @@ -40,6 +40,7 @@ public class RESTConstants { public static final String RESOURCE_SERVERS = "servers"; public static final String FORM_PARAM_CLUSTER_NAME = "clusterName"; + public static final String FORM_PARAM_SERVER_NAME = "serverName"; public static final String FORM_PARAM_DISKS = "disks"; public static final String FORM_PARAM_OPERATION = "operation"; public static final String FORM_PARAM_VALUE_START = "start"; diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/ProcessResult.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/ProcessResult.java index 9d6ddc93..c297a9c4 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/ProcessResult.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/ProcessResult.java @@ -61,4 +61,9 @@ public class ProcessResult { public boolean isSuccess() { return exitValue == SUCCESS; } + + @Override + public String toString() { + return "["+ getExitValue() + "][" + getOutput() + "]"; + } } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/ClusterSelectionDialog.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/ClusterSelectionDialog.java index 7bc6eb58..f001da62 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/ClusterSelectionDialog.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/ClusterSelectionDialog.java @@ -24,8 +24,11 @@ import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.fieldassist.ControlDecoration; import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StackLayout; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.TraverseEvent; import org.eclipse.swt.events.TraverseListener; import org.eclipse.swt.layout.GridData; @@ -36,6 +39,7 @@ import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; import com.gluster.storage.management.gui.IImageKeys; import com.gluster.storage.management.gui.utils.GUIHelper; @@ -44,14 +48,31 @@ import com.gluster.storage.management.gui.utils.GUIHelper; * Cluster selection dialog, which prompts for the cluster name to be managed */ public class ClusterSelectionDialog extends Dialog { + protected enum CLUSTER_MODE { SELECT, CREATE, REGISTER }; + private Combo clusterNameCombo = null; + private Text newClusterNameText = null; + private Text existingClusterNameText = null; + private Text serverNameText = null; private Button okButton; private final GUIHelper guiHelper = GUIHelper.getInstance(); private Composite composite; - private ControlDecoration errorDecoration; + private ControlDecoration newClusterNameErrorDecoration; + private ControlDecoration existingClusterNameErrorDecoration; + private ControlDecoration serverNameErrorDecoration; private List<String> clusters; + private Button selectButton; + private Button createButton; + private Button registerButton; + private Composite clusterSelectionComposite; + private Composite clusterCreationComposite; + private Composite clusterRegisterComposite; + private StackLayout stackLayout; + private String clusterName; + private CLUSTER_MODE clusterMode; + private String serverName; public ClusterSelectionDialog(Shell parentShell, List<String> clusters) { super(parentShell); @@ -79,24 +100,20 @@ public class ClusterSelectionDialog extends Dialog { } private void createClusterNameLabel(Composite composite) { - Label userIdLabel = new Label(composite, SWT.NONE); - userIdLabel.setText("&Cluster to Manage:"); - userIdLabel.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); + Label clusterNameLabel = new Label(composite, SWT.NONE); + clusterNameLabel.setText("Cluster &Name:"); + clusterNameLabel.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); } private void createClusterNameCombo(Composite composite) { - clusterNameCombo = new Combo(composite, SWT.BORDER); + clusterNameCombo = new Combo(composite, SWT.READ_ONLY); clusterNameCombo.setItems(clusters.toArray(new String[0])); clusterNameCombo.select(0); - -// GridData layoutData = new GridData(SWT.FILL, GridData.FILL, true, false); -// layoutData.widthHint = convertWidthInCharsToPixels(32); -// clusterNameCombo.setLayoutData(layoutData); } private void configureDialogLayout(Composite composite) { GridLayout layout = (GridLayout) composite.getLayout(); - layout.numColumns = 2; + layout.numColumns = 3; layout.marginLeft = 20; layout.marginRight = 20; layout.marginTop = 20; @@ -123,13 +140,191 @@ public class ClusterSelectionDialog extends Dialog { composite = (Composite) super.createDialogArea(parent); configureDialogLayout(composite); - createClusterNameLabel(composite); - createClusterNameCombo(composite); - createErrorDecoration(); + createRadioButtons(); + createSubComposites(); return composite; } + private void createSubComposites() { + Composite subComposite = new Composite(composite, SWT.NONE); + GridData data = new GridData(); + data.horizontalSpan = 3; + subComposite.setLayoutData(data); + stackLayout = new StackLayout(); + subComposite.setLayout(stackLayout); + + createClusterSelectionComposite(subComposite, stackLayout); + createClusterCreationComposite(subComposite); + createClusterRegisterComposite(subComposite); + + createRadioButtonListeners(subComposite); + if(clusters.size() > 0) { + selectButton.setSelection(true); + } else { + createButton.setSelection(true); + } + } + + private void createClusterRegisterComposite(Composite composite) { + clusterRegisterComposite = new Composite(composite, SWT.NONE); + GridLayout layout = new GridLayout(2, false); + clusterRegisterComposite.setLayout(layout); + + createClusterNameLabel(clusterRegisterComposite); + existingClusterNameText = createText(clusterRegisterComposite); + existingClusterNameText.setToolTipText("Enter a name for the cluster being registered."); + existingClusterNameErrorDecoration = createErrorDecoration(existingClusterNameText, "Please enter a cluster name!"); + existingClusterNameErrorDecoration.show(); + + createClusterServerLabel(clusterRegisterComposite); + serverNameText = createText(clusterRegisterComposite); + serverNameText.setToolTipText("Enter host name / IP address of one of the servers of the cluster."); + serverNameErrorDecoration = createErrorDecoration(serverNameText, "Please enter a server name!"); + serverNameErrorDecoration.show(); + } + + private void createClusterServerLabel(Composite composite) { + Label serverNameLabel = new Label(composite, SWT.NONE); + serverNameLabel.setText("Server Na&me:"); + serverNameLabel.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); + } + + private void createClusterCreationComposite(Composite subComposite) { + clusterCreationComposite = new Composite(subComposite, SWT.NONE); + GridLayout layout = new GridLayout(2, false); + clusterCreationComposite.setLayout(layout); + + createClusterNameLabel(clusterCreationComposite); + newClusterNameText = createText(clusterCreationComposite); + newClusterNameText.setToolTipText("Enter name of the cluster to be created"); + newClusterNameErrorDecoration = createErrorDecoration(newClusterNameText, "Please enter cluster name!"); + newClusterNameErrorDecoration.show(); + } + + private Text createText(Composite parent) { + Text text = new Text(parent, SWT.NONE); + GridData layoutData = new GridData(SWT.FILL, GridData.FILL, true, false); + int width = convertWidthInCharsToPixels(32); + layoutData.widthHint = width; + layoutData.minimumWidth = width; + text.setLayoutData(layoutData); + + text.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + validate(); + } + }); + + return text; + } + + private void createClusterSelectionComposite(Composite subComposite, StackLayout stackLayout) { + clusterSelectionComposite = new Composite(subComposite, SWT.NONE); + GridLayout layout = new GridLayout(2, false); + clusterSelectionComposite.setLayout(layout); + createClusterNameLabel(clusterSelectionComposite); + createClusterNameCombo(clusterSelectionComposite); + stackLayout.topControl = clusterSelectionComposite; + } + + private void createRadioButtons() { + { + if (clusters.size() > 0) { + selectButton = new Button(composite, SWT.RADIO); + selectButton.setText("&Select"); + } + } + { + createButton = new Button(composite, SWT.RADIO); + createButton.setText("&Create"); + } + { + registerButton = new Button(composite, SWT.RADIO); + registerButton.setText("&Register"); + } + } + + private void validate() { + okButton.setEnabled(false); + + if(selectButton.getSelection()) { + okButton.setEnabled(true); + return; + } + + if(createButton.getSelection()) { + String newClusterName = newClusterNameText.getText().trim(); + if(newClusterName.isEmpty()) { + newClusterNameErrorDecoration.setDescriptionText("Please enter a cluster name!"); + newClusterNameErrorDecoration.show(); + } else if(clusters.contains(newClusterName)) { + newClusterNameErrorDecoration.setDescriptionText("Cluster [" + newClusterName + "] already exists!"); + newClusterNameErrorDecoration.show(); + } else { + okButton.setEnabled(true); + newClusterNameErrorDecoration.hide(); + } + } + + if(registerButton.getSelection()) { + okButton.setEnabled(true); + String clusterName = existingClusterNameText.getText().trim(); + if(existingClusterNameText.getText().trim().isEmpty()) { + existingClusterNameErrorDecoration.setDescriptionText("Please enter a cluster name!"); + existingClusterNameErrorDecoration.show(); + okButton.setEnabled(false); + } else if(clusters.contains(clusterName)) { + existingClusterNameErrorDecoration.setDescriptionText("Cluster [" + clusterName + "] already exists!"); + existingClusterNameErrorDecoration.show(); + okButton.setEnabled(false); + } else { + existingClusterNameErrorDecoration.hide(); + } + + if(serverNameText.getText().trim().isEmpty()) { + serverNameErrorDecoration.show(); + okButton.setEnabled(false); + } else { + serverNameErrorDecoration.hide(); + } + } + } + + private void createRadioButtonListeners(final Composite parent) { + if (clusters.size() > 0) { + selectButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + stackLayout.topControl = clusterSelectionComposite; + clusterNameCombo.select(0); + validate(); + parent.layout(); + clusterNameCombo.setFocus(); + } + }); + } + createButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + stackLayout.topControl = clusterCreationComposite; + validate(); + parent.layout(); + newClusterNameText.setFocus(); + } + }); + registerButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + stackLayout.topControl = clusterRegisterComposite; + validate(); + parent.layout(); + existingClusterNameText.setFocus(); + } + }); + } + @Override protected void createButtonsForButtonBar(Composite parent) { okButton = createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); @@ -138,10 +333,11 @@ public class ClusterSelectionDialog extends Dialog { setupDataBinding(); } - private void createErrorDecoration() { - errorDecoration = guiHelper.createErrorDecoration(clusterNameCombo); - errorDecoration.setDescriptionText("Please select an existing cluster name, or enter a new one!"); + private ControlDecoration createErrorDecoration(Text text, String message) { + ControlDecoration errorDecoration = guiHelper.createErrorDecoration(text); + errorDecoration.setDescriptionText(message); errorDecoration.hide(); + return errorDecoration; } /** @@ -156,10 +352,10 @@ public class ClusterSelectionDialog extends Dialog { public void modifyText(ModifyEvent e) { if(clusterNameCombo.getText().trim().isEmpty()) { okButton.setEnabled(false); - errorDecoration.show(); + newClusterNameErrorDecoration.show(); } else { okButton.setEnabled(true); - errorDecoration.hide(); + newClusterNameErrorDecoration.hide(); } } }); @@ -167,11 +363,29 @@ public class ClusterSelectionDialog extends Dialog { @Override protected void okPressed() { - clusterName = clusterNameCombo.getText(); + if(selectButton.getSelection()) { + clusterMode = CLUSTER_MODE.SELECT; + clusterName = clusterNameCombo.getText(); + } else if(createButton.getSelection()) { + clusterMode = CLUSTER_MODE.CREATE; + clusterName = newClusterNameText.getText().trim(); + } else if(registerButton.getSelection()) { + clusterMode = CLUSTER_MODE.REGISTER; + clusterName = existingClusterNameText.getText().trim(); + serverName = serverNameText.getText().trim(); + } super.okPressed(); } public String getClusterName() { return clusterName; } + + public CLUSTER_MODE getClusterMode() { + return clusterMode; + } + + public String getServerName() { + return serverName; + } } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java index 947a8747..502923ba 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java @@ -51,6 +51,7 @@ import com.gluster.storage.management.core.model.ConnectionDetails; import com.gluster.storage.management.core.model.Status; import com.gluster.storage.management.core.response.StringListResponse; import com.gluster.storage.management.gui.IImageKeys; +import com.gluster.storage.management.gui.dialogs.ClusterSelectionDialog.CLUSTER_MODE; import com.gluster.storage.management.gui.utils.GUIHelper; import com.gluster.storage.management.gui.validators.StringRequiredValidator; @@ -212,13 +213,17 @@ public class LoginDialog extends Dialog { cancelPressed(); return; } + try { + CLUSTER_MODE mode = clusterDialog.getClusterMode(); String clusterName = clusterDialog.getClusterName(); - if(clusterNames.contains(clusterName)) { + switch(mode) { + case SELECT: GlusterDataModelManager.getInstance().initializeModel(usersClient.getSecurityToken(), - clusterName); - } else { - Status status = createCluster(clustersClient, clusterName); + clusterName); + break; + case CREATE: + Status status = clustersClient.createCluster(clusterName); if(!status.isSuccess()) { MessageDialog.openError(getShell(), "Cluster Creation Failed!", status.toString()); setReturnCode(RETURN_CODE_ERROR); @@ -226,6 +231,9 @@ public class LoginDialog extends Dialog { } GlusterDataModelManager.getInstance().initializeModelWithNewCluster(usersClient.getSecurityToken(), clusterName); + break; + case REGISTER: + break; } super.okPressed(); @@ -239,10 +247,6 @@ public class LoginDialog extends Dialog { } } - private Status createCluster(ClustersClient clustersClient, String clusterName) { - return clustersClient.createCluster(clusterName); - } - private List<String> getClusterNames(ClustersClient clustersClient) { StringListResponse clustersResponse = clustersClient.getClusters(); List<String> clusters = new ArrayList<String>(); diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java index efecbf7a..da9d6544 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java @@ -128,7 +128,7 @@ public class ClusterSummaryView extends ViewPart { private void createDiskSpaceSection() { Composite section = guiHelper.createSection(form, toolkit, "Disk Space", null, 3, false); if (cluster.getServers().size() == 0) { - toolkit.createLabel(section, "This section will be populated after at least one server is added to the storage cloud."); + toolkit.createLabel(section, "This section will be populated after at least\none server is added to the storage cloud."); return; } @@ -262,10 +262,10 @@ public class ClusterSummaryView extends ViewPart { private void createCPUUsageSection() { Composite section = guiHelper.createSection(form, toolkit, "CPU Usage (aggregated)", null, 1, false); if (cluster.getServers().size() == 0) { - toolkit.createLabel(section, "This section will be populated after at least one server is added to the storage cloud."); + toolkit.createLabel(section, "This section will be populated after at least\none server is added to the storage cloud."); return; } - toolkit.createLabel(section, "Historical CPU Usage graph aggregated across all servers will be displayed here."); + toolkit.createLabel(section, "Historical CPU Usage graph aggregated across\nall servers will be displayed here."); } private void createNetworkUsageSection() { diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServersSummaryView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServersSummaryView.java index ba9faca4..d80e3879 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServersSummaryView.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServersSummaryView.java @@ -73,6 +73,10 @@ public class GlusterServersSummaryView extends ViewPart { private void createSummarySection() { Composite section = guiHelper.createSection(form, toolkit, "Availability", null, 2, false); + if(servers.getEntities().size() == 0) { + toolkit.createLabel(section, "This section will be populated after at least\none server is added to the storage cloud."); + return; + } Double[] values = new Double[] { Double.valueOf(getServerCountByStatus(servers, SERVER_STATUS.ONLINE)), Double.valueOf(getServerCountByStatus(servers, SERVER_STATUS.OFFLINE)) }; diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumesSummaryView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumesSummaryView.java index 88ca96c5..db2bb71d 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumesSummaryView.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumesSummaryView.java @@ -133,8 +133,11 @@ public class VolumesSummaryView extends ViewPart { private void createSummarySection() { Composite section = guiHelper.createSection(form, toolkit, AVAILABILITY, null, 2, false); - // Cluster cluster = GlusterDataModelManager.getInstance().getModel() - // .getCluster(); + if(volumes.getEntities().size() == 0) { + toolkit.createLabel(section, + "This section will be populated after at least\none volume is created the storage cloud."); + return; + } Double[] values = new Double[] { Double.valueOf(getVolumeCountByStatus(volumes, VOLUME_STATUS.ONLINE)), Double.valueOf(getVolumeCountByStatus(volumes, VOLUME_STATUS.OFFLINE)) }; diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/ClustersResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/ClustersResource.java index f04941cf..18bece88 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/ClustersResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/ClustersResource.java @@ -19,6 +19,7 @@ package com.gluster.storage.management.server.resources; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_CLUSTER_NAME; +import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_SERVER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_CLUSTER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_CLUSTERS; @@ -35,10 +36,14 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; +import com.gluster.storage.management.core.exceptions.ConnectionException; +import com.gluster.storage.management.core.model.GlusterServer; import com.gluster.storage.management.core.model.Status; import com.gluster.storage.management.core.response.StringListResponse; import com.gluster.storage.management.server.data.ClusterInfo; import com.gluster.storage.management.server.data.PersistenceDao; +import com.gluster.storage.management.server.data.ServerInfo; +import com.gluster.storage.management.server.utils.GlusterUtil; import com.sun.jersey.api.core.InjectParam; /** @@ -49,6 +54,12 @@ public class ClustersResource { @InjectParam private PersistenceDao clusterDao; + + @InjectParam + private GlusterServersResource glusterServersResource; + + @InjectParam + private GlusterUtil glusterUtil; public void setClusterDao(PersistenceDao clusterDao) { this.clusterDao = clusterDao; @@ -86,6 +97,30 @@ public class ClustersResource { + "]: [" + e.getMessage() + "]"); } } + + public Status registerCluster(@FormParam(FORM_PARAM_CLUSTER_NAME) String clusterName, + @FormParam(FORM_PARAM_SERVER_NAME) String knownServer) { + EntityTransaction txn = clusterDao.startTransaction(); + ClusterInfo cluster = new ClusterInfo(); + cluster.setName(clusterName); + + GlusterServer server = new GlusterServer(knownServer); + try { + List<GlusterServer> glusterServers = glusterUtil.getGlusterServers(server); + List<ServerInfo> servers = new ArrayList<ServerInfo>(); + for(GlusterServer glusterServer : glusterServers) { + ServerInfo serverInfo = new ServerInfo(); + serverInfo.setName(glusterServer.getName()); + serverInfo.setCluster(cluster); + servers.add(serverInfo); + } + cluster.setServers(servers); + clusterDao.save(cluster); + return Status.STATUS_SUCCESS; + } catch(Exception e) { + return new Status(e); + } + } @SuppressWarnings("unchecked") @Path("{" + PATH_PARAM_CLUSTER_NAME + "}") diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/GlusterServersResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/GlusterServersResource.java index 58f72ffd..d020a35e 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/GlusterServersResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/GlusterServersResource.java @@ -102,7 +102,10 @@ public class GlusterServersResource extends AbstractServersResource { return null; } - private GlusterServerListResponse getServerDetails(String clusterName) { + @GET + @Produces(MediaType.TEXT_XML) + public GlusterServerListResponse getGlusterServers( + @PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName) { GlusterServer onlineServer = getOnlineServer(clusterName); if(onlineServer == null) { return new GlusterServerListResponse(Status.STATUS_SUCCESS, new ArrayList<GlusterServer>()); @@ -146,13 +149,6 @@ public class GlusterServersResource extends AbstractServersResource { } @GET - @Produces(MediaType.TEXT_XML) - public GlusterServerListResponse getGlusterServers( - @PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName) { - return getServerDetails(clusterName); - } - - @GET @Path("{serverName}") @Produces(MediaType.TEXT_XML) public GlusterServerResponse getGlusterServer( diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java index 3857f104..9a5ee0c5 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java @@ -20,9 +20,9 @@ */ package com.gluster.storage.management.server.resources; +import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_BRICKS; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_OPERATION; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_SOURCE; -import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_BRICKS; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_TARGET; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_VALUE_START; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_VALUE_STOP; @@ -71,8 +71,10 @@ import javax.ws.rs.core.StreamingOutput; import com.gluster.storage.management.core.constants.CoreConstants; import com.gluster.storage.management.core.constants.RESTConstants; +import com.gluster.storage.management.core.exceptions.ConnectionException; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.Brick; +import com.gluster.storage.management.core.model.GlusterServer; import com.gluster.storage.management.core.model.LogMessage; import com.gluster.storage.management.core.model.Status; import com.gluster.storage.management.core.model.Volume; @@ -98,14 +100,17 @@ public class VolumesResource { private static final String VOLUME_BRICK_LOG_SCRIPT = "get_volume_brick_log.py"; @InjectParam - private static ServerUtil serverUtil; + private GlusterServersResource glusterServersResource; + + @InjectParam + private ServerUtil serverUtil; @InjectParam - private static GlusterUtil glusterUtil; + private GlusterUtil glusterUtil; - private static final FileUtil fileUtil = new FileUtil(); + private FileUtil fileUtil = new FileUtil(); - private static GlusterCoreUtil glusterCoreUtil = new GlusterCoreUtil(); + private GlusterCoreUtil glusterCoreUtil = new GlusterCoreUtil(); @InjectParam private VolumeOptionsDefaults volumeOptionsDefaults; @@ -113,13 +118,21 @@ public class VolumesResource { @GET @Produces(MediaType.TEXT_XML) public VolumeListResponse getAllVolumes(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName) { + GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); + if(onlineServer == null) { + return new VolumeListResponse(Status.STATUS_SUCCESS, new ArrayList<Volume>()); + } + try { - // TODO: pass cluster name to getAllVolumes - return new VolumeListResponse(Status.STATUS_SUCCESS, glusterUtil.getAllVolumes()); - } catch (Exception e) { - // TODO: log the error - e.printStackTrace(); - return new VolumeListResponse(new Status(Status.STATUS_CODE_FAILURE, e.getMessage()), null); + return new VolumeListResponse(Status.STATUS_SUCCESS, glusterUtil.getAllVolumes(onlineServer.getName())); + } catch(ConnectionException e) { + // online server has gone offline! try with a different one. + onlineServer = glusterServersResource.getNewOnlineServer(clusterName); + if(onlineServer == null) { + return new VolumeListResponse(Status.STATUS_SUCCESS, new ArrayList<Volume>()); + } + + return new VolumeListResponse(Status.STATUS_SUCCESS, glusterUtil.getAllVolumes(onlineServer.getName())); } } @@ -141,13 +154,28 @@ public class VolumesResource { return status; } + @SuppressWarnings("rawtypes") @GET @Path("{" + PATH_PARAM_VOLUME_NAME + "}") @Produces(MediaType.TEXT_XML) - public Volume getVolume(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, + public GenericResponse getVolume(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, @PathParam(PATH_PARAM_VOLUME_NAME) String volumeName) { - // TODO: Pass cluster name to getVolume - return glusterUtil.getVolume(volumeName); + GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); + if(onlineServer == null) { + return new GenericResponse<Volume>(new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]"), null); + } + + try { + return new GenericResponse<Volume>(Status.STATUS_SUCCESS, glusterUtil.getVolume(volumeName, onlineServer.getName())); + } catch(ConnectionException e) { + // online server has gone offline! try with a different one. + onlineServer = glusterServersResource.getNewOnlineServer(clusterName); + if(onlineServer == null) { + return new GenericResponse<Volume>(new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]"), null); + } + + return new GenericResponse<Volume>(Status.STATUS_SUCCESS, glusterUtil.getVolume(volumeName, onlineServer.getName())); + } } @PUT @@ -171,22 +199,32 @@ public class VolumesResource { public Status deleteVolume(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, @QueryParam(QUERY_PARAM_VOLUME_NAME) String volumeName, @QueryParam(QUERY_PARAM_DELETE_OPTION) boolean deleteFlag) { - // TODO: Delete volume on given cluster - Volume volume = glusterUtil.getVolume(volumeName); - Status status = glusterUtil.deleteVolume(volumeName); - - String deleteOption = ""; - if (deleteFlag) { - deleteOption = "-d"; + GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); + if(onlineServer == null) { + return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]"); } + + Volume volume = null; + try { + volume = glusterUtil.getVolume(volumeName, onlineServer.getName()); + } catch(ConnectionException e) { + // online server has gone offline! try with a different one. + onlineServer = glusterServersResource.getNewOnlineServer(clusterName); + if(onlineServer == null) { + return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]"); + } + volume = glusterUtil.getVolume(volumeName, onlineServer.getName()); + } + + Status status = glusterUtil.deleteVolume(volumeName, onlineServer.getName()); if (status.isSuccess()) { List<String> disks = volume.getDisks(); - Status postDeleteStatus = postDelete(volumeName, disks, deleteOption); + Status postDeleteStatus = postDelete(volumeName, disks, deleteFlag); if (!postDeleteStatus.isSuccess()) { status.setCode(Status.STATUS_CODE_PART_SUCCESS); - status.setMessage("Error while post deletion operation: " + postDeleteStatus); + status.setMessage("Error in post-delete operation: " + postDeleteStatus); } } return status; @@ -218,7 +256,7 @@ public class VolumesResource { return status; } - private Status postDelete(String volumeName, List<String> disks, String deleteFlag) { + private Status postDelete(String volumeName, List<String> disks, boolean deleteFlag) { String serverName, diskName, diskInfo[]; Status result; for (int i = 0; i < disks.size(); i++) { @@ -226,7 +264,7 @@ public class VolumesResource { serverName = diskInfo[0]; diskName = diskInfo[1]; result = (Status) serverUtil.executeOnServer(true, serverName, VOLUME_DIRECTORY_CLEANUP_SCRIPT + " " - + diskName + " " + volumeName + " " + deleteFlag, Status.class); + + diskName + " " + volumeName + (deleteFlag ? " -d" : ""), Status.class); if (!result.isSuccess()) { return result; } @@ -384,7 +422,7 @@ public class VolumesResource { @Override public void write(OutputStream output) throws IOException, WebApplicationException { - Volume volume = getVolume(clusterName, volumeName); + Volume volume = (Volume)getVolume(clusterName, volumeName).getData(); try { // TODO: pass clusterName to downloadLogs File archiveFile = new File(downloadLogs(volume)); @@ -435,7 +473,7 @@ public class VolumesResource { try { // TODO: Fetch logs from brick(s) of given cluster only - Volume volume = getVolume(clusterName, volumeName); + Volume volume = (Volume)getVolume(clusterName, volumeName).getData(); if (brickName == null || brickName.isEmpty() || brickName.equals(CoreConstants.ALL)) { logMessages = getLogsForAllBricks(volume, lineCount); } else { diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/GlusterUtil.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/GlusterUtil.java index 64595e5f..7991cfb0 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/GlusterUtil.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/GlusterUtil.java @@ -93,14 +93,6 @@ public class GlusterUtil { return null; } - private GlusterServer getKnownServer(String knownServer) { - GlusterServer server = new GlusterServer(knownServer); - server.setStatus(SERVER_STATUS.ONLINE); //TODO: If pingable - //NOTE: No UUID assumed, it can be fetch while getting server details - return server; - } - - public GlusterServer getGlusterServer(GlusterServer onlineServer, String serverName) { List<GlusterServer> servers = getGlusterServers(onlineServer); for(GlusterServer server : servers) { @@ -278,24 +270,23 @@ public class GlusterUtil { return new Status(processUtil.executeCommand(command)); } - public Status deleteVolume(String volumeName) { - return new Status(processUtil.executeCommand("gluster", "--mode=script", "volume", "delete", volumeName)); + public Status deleteVolume(String volumeName, String knownServer) { + return new Status(sshUtil.executeRemote(knownServer, "gluster --mode=script volume delete " + volumeName)); } - private String getVolumeInfo(String volumeName) { - ProcessResult result = new ProcessUtil().executeCommand("gluster", "volume", "info", volumeName); + private String getVolumeInfo(String volumeName, String knownServer) { + ProcessResult result = sshUtil.executeRemote(knownServer, "gluster volume info " + volumeName); if (!result.isSuccess()) { - throw new GlusterRuntimeException("Command [gluster volume info] failed with error: [" - + result.getExitValue() + "][" + result.getOutput() + "]"); + throw new GlusterRuntimeException("Command [gluster volume info] failed on [" + knownServer + + "] with error: " + result); } return result.getOutput(); } - private String getVolumeInfo() { - ProcessResult result = new ProcessUtil().executeCommand("gluster", "volume", "info"); + private String getVolumeInfo(String knownServer) { + ProcessResult result = sshUtil.executeRemote(knownServer, "gluster volume info "); if (!result.isSuccess()) { - throw new GlusterRuntimeException("Command [gluster volume info] failed with error: [" - + result.getExitValue() + "][" + result.getOutput() + "]"); + throw new GlusterRuntimeException("Command [gluster volume info] failed on [" + knownServer + "] with error: " + result); } return result.getOutput(); } @@ -399,16 +390,16 @@ public class GlusterUtil { return false; } - public Volume getVolume(String volumeName) { - List<Volume> volumes = parseVolumeInfo(getVolumeInfo(volumeName)); + public Volume getVolume(String volumeName, String knownServer) { + List<Volume> volumes = parseVolumeInfo(getVolumeInfo(volumeName, knownServer)); if (volumes.size() > 0) { return volumes.get(0); } return null; } - public List<Volume> getAllVolumes() { - return parseVolumeInfo(getVolumeInfo()); + public List<Volume> getAllVolumes(String knownServer) { + return parseVolumeInfo(getVolumeInfo(knownServer)); } private List<Volume> parseVolumeInfo(String volumeInfoText) { |
