summaryrefslogtreecommitdiffstats
path: root/src/com.gluster.storage.management.server
diff options
context:
space:
mode:
authorShireesh Anjal <shireesh@gluster.com>2011-06-21 21:17:09 +0530
committerShireesh Anjal <shireesh@gluster.com>2011-06-22 18:33:12 +0530
commit5bb44641bf7b40f048e71281885efea68a3fbcbd (patch)
tree77819aab61ec66e0f7a798c186c2170aeaa11e62 /src/com.gluster.storage.management.server
parent8c5c224a98f194402f1ce413d6d1dd59946e2d52 (diff)
REST API enhancements
Diffstat (limited to 'src/com.gluster.storage.management.server')
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractResource.java40
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/DiscoveredServersResource.java4
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java659
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/GlusterUtil.java119
4 files changed, 558 insertions, 264 deletions
diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractResource.java
index 2fcf3875..d96ea5f5 100644
--- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractResource.java
+++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractResource.java
@@ -19,12 +19,21 @@
package com.gluster.storage.management.server.resources;
import java.net.URI;
+import java.util.ArrayList;
import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.core.StreamingOutput;
import javax.ws.rs.core.UriInfo;
+import com.gluster.storage.management.core.constants.RESTConstants;
+import com.gluster.storage.management.core.exceptions.GlusterRuntimeException;
+import com.gluster.storage.management.core.model.Volume;
+import com.gluster.storage.management.core.response.VolumeListResponse;
+
/**
*
*/
@@ -74,7 +83,7 @@ public class AbstractResource {
* @return the {@link Response} object
*/
protected Response errorResponse(String errMessage) {
- return Response.serverError().entity(errMessage).build();
+ return Response.serverError().type(MediaType.TEXT_HTML).entity(errMessage).build();
}
/**
@@ -86,6 +95,33 @@ public class AbstractResource {
* @return the {@link Response} object
*/
protected Response badRequestResponse(String errMessage) {
- return Response.status(Status.BAD_REQUEST).entity(errMessage).build();
+ return Response.status(Status.BAD_REQUEST).type(MediaType.TEXT_HTML).entity(errMessage).build();
+ }
+
+ /**
+ * Creates an OK response and sets the entity in the response body.
+ *
+ * @param entity
+ * Entity to be set in the response body
+ * @param mediaType
+ * Media type to be set on the response
+ * @return the {@link Response} object
+ */
+ protected Response okResponse(Object entity, String mediaType) {
+ return Response.ok(entity).type(mediaType).build();
+ }
+
+ /**
+ * Creates a streaming output response and sets the given streaming output in the response. Typically used for
+ * "download" requests
+ *
+ * @param entity
+ * Entity to be set in the response body
+ * @param mediaType
+ * Media type to be set on the response
+ * @return the {@link Response} object
+ */
+ protected Response streamingOutputResponse(StreamingOutput output) {
+ return Response.ok(output).type(MediaType.APPLICATION_OCTET_STREAM).build();
}
}
diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/DiscoveredServersResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/DiscoveredServersResource.java
index 740f7cfa..4359b7d5 100644
--- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/DiscoveredServersResource.java
+++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/DiscoveredServersResource.java
@@ -37,12 +37,14 @@ import com.gluster.storage.management.core.model.Status;
import com.gluster.storage.management.core.response.GenericResponse;
import com.gluster.storage.management.core.response.ServerListResponse;
import com.gluster.storage.management.core.response.StringListResponse;
+
+import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_FORMAT;
import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_DISCOVERED_SERVERS;
import com.sun.jersey.spi.resource.Singleton;
@Component
@Singleton
-@Path(RESOURCE_PATH_DISCOVERED_SERVERS)
+@Path(RESOURCE_PATH_DISCOVERED_SERVERS + ".{" + PATH_PARAM_FORMAT + "}")
public class DiscoveredServersResource extends AbstractServersResource {
private List<String> discoveredServerNames = new ArrayList<String>();
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 71dc3579..369ef349 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,13 +20,20 @@
*/
package com.gluster.storage.management.server.resources;
+import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_ACCESS_PROTOCOLS;
+import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_AUTO_COMMIT;
import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_BRICKS;
+import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_CLUSTER_NAME;
import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_OPERATION;
+import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_REPLICA_COUNT;
import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_SOURCE;
+import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_STRIPE_COUNT;
import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_TARGET;
-import static com.gluster.storage.management.core.constants.RESTConstants.TASK_START;
-import static com.gluster.storage.management.core.constants.RESTConstants.TASK_STOP;
-import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_AUTO_COMMIT;
+import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_TRANSPORT_TYPE;
+import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_VOLUME_NAME;
+import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_VOLUME_OPTIONS;
+import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_VOLUME_TYPE;
+import static com.gluster.storage.management.core.constants.RESTConstants.*;
import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_CLUSTER_NAME;
import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_VOLUME_NAME;
import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_BRICKS;
@@ -45,6 +52,8 @@ import static com.gluster.storage.management.core.constants.RESTConstants.RESOUR
import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_OPTIONS;
import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_CLUSTERS;
import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_VOLUMES;
+import static com.gluster.storage.management.core.constants.RESTConstants.TASK_START;
+import static com.gluster.storage.management.core.constants.RESTConstants.TASK_STOP;
import java.io.File;
import java.io.IOException;
@@ -56,7 +65,6 @@ import java.util.Comparator;
import java.util.Date;
import java.util.List;
-import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
@@ -68,6 +76,7 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;
import com.gluster.storage.management.core.constants.CoreConstants;
@@ -77,9 +86,8 @@ 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.Status;
-import com.gluster.storage.management.core.model.Task.TASK_TYPE;
-import com.gluster.storage.management.core.model.TaskInfo;
import com.gluster.storage.management.core.model.Volume;
+import com.gluster.storage.management.core.model.Volume.VOLUME_TYPE;
import com.gluster.storage.management.core.model.VolumeLogMessage;
import com.gluster.storage.management.core.response.GenericResponse;
import com.gluster.storage.management.core.response.LogMessageListResponse;
@@ -93,7 +101,6 @@ import com.gluster.storage.management.core.utils.ProcessUtil;
import com.gluster.storage.management.server.constants.VolumeOptionsDefaults;
import com.gluster.storage.management.server.data.ClusterInfo;
import com.gluster.storage.management.server.services.ClusterService;
-import com.gluster.storage.management.server.tasks.MigrateDiskTask;
import com.gluster.storage.management.server.utils.GlusterUtil;
import com.gluster.storage.management.server.utils.ServerUtil;
import com.sun.jersey.api.core.InjectParam;
@@ -101,7 +108,7 @@ import com.sun.jersey.spi.resource.Singleton;
@Singleton
@Path(RESOURCE_PATH_CLUSTERS + "/{" + PATH_PARAM_CLUSTER_NAME + "}/" + RESOURCE_VOLUMES)
-public class VolumesResource {
+public class VolumesResource extends AbstractResource {
private static final String PREPARE_BRICK_SCRIPT = "create_volume_directory.py";
private static final String VOLUME_DIRECTORY_CLEANUP_SCRIPT = "clear_volume_directory.py";
private static final String VOLUME_BRICK_LOG_SCRIPT = "get_volume_brick_log.py";
@@ -122,101 +129,215 @@ public class VolumesResource {
private VolumeOptionsDefaults volumeOptionsDefaults;
@GET
- @Produces(MediaType.APPLICATION_XML)
- public VolumeListResponse getAllVolumes(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName) {
+ @Produces({MediaType.APPLICATION_XML})
+ public Response getVolumesXML(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName) {
+ return getVolumes(clusterName, MediaType.APPLICATION_XML);
+ }
+
+ @GET
+ @Produces({MediaType.APPLICATION_JSON})
+ public Response getVolumesJSON(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName) {
+ return getVolumes(clusterName, MediaType.APPLICATION_JSON);
+ }
+
+ public Response getVolumes(String clusterName, String mediaType) {
+ if (clusterName == null || clusterName.isEmpty()) {
+ return badRequestResponse("Parameter [" + FORM_PARAM_CLUSTER_NAME + "] is missing in request!");
+ }
+
+ if (clusterService.getCluster(clusterName) == null) {
+ return badRequestResponse("Cluster [" + clusterName + "] not found!");
+ }
+
+ return okResponse(getVolumes(clusterName), mediaType);
+ }
+
+ public VolumeListResponse getVolumes(String clusterName) {
GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName);
if (onlineServer == null) {
- return new VolumeListResponse(Status.STATUS_SUCCESS, new ArrayList<Volume>());
+ return new VolumeListResponse(new ArrayList<Volume>());
}
try {
- return new VolumeListResponse(Status.STATUS_SUCCESS, glusterUtil.getAllVolumes(onlineServer.getName()));
+ return new VolumeListResponse(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(new ArrayList<Volume>());
}
- return new VolumeListResponse(Status.STATUS_SUCCESS, glusterUtil.getAllVolumes(onlineServer.getName()));
+ return new VolumeListResponse(glusterUtil.getAllVolumes(onlineServer.getName()));
}
}
@POST
- @Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
- public Status createVolume(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, Volume volume) {
- List<String> brickDirectories = GlusterCoreUtil.getQualifiedBrickList(volume.getBricks());
+ public Response createVolume(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, @FormParam(FORM_PARAM_VOLUME_NAME) String volumeName,
+ @FormParam(FORM_PARAM_VOLUME_TYPE) String volumeType, @FormParam(FORM_PARAM_TRANSPORT_TYPE) String transportType,
+ @FormParam(FORM_PARAM_REPLICA_COUNT) Integer replicaCount, @FormParam(FORM_PARAM_STRIPE_COUNT) Integer stripeCount,
+ @FormParam(FORM_PARAM_BRICKS) String bricks, @FormParam(FORM_PARAM_ACCESS_PROTOCOLS) String accessProtocols,
+ @FormParam(FORM_PARAM_VOLUME_OPTIONS) String options) {
+ String missingParam = checkMissingParamsForCreateVolume(clusterName, volumeName, volumeType, transportType, replicaCount, stripeCount, bricks, accessProtocols, options);
+ if(missingParam != null) {
+ return badRequestResponse("Parameter [" + missingParam + "] is missing in request!");
+ }
+
+ if (clusterService.getCluster(clusterName) == null) {
+ return badRequestResponse("Cluster [" + clusterName + "] not found!");
+ }
+
+ if (volumeType.equals(VOLUME_TYPE.DISTRIBUTED_MIRROR) && replicaCount <= 0) {
+ return badRequestResponse("Replica count must be a positive integer");
+ }
+
+ if (volumeType.equals(VOLUME_TYPE.DISTRIBUTED_STRIPE) && stripeCount <= 0) {
+ return badRequestResponse("Stripe count must be a positive integer");
+ }
GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName);
if (onlineServer == null) {
- return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]");
+ return errorResponse("No online servers found in cluster [" + clusterName + "]");
}
- Status status = null;
try {
- status = glusterUtil.createVolume(volume, brickDirectories, onlineServer.getName());
+ glusterUtil.createVolume(onlineServer.getName(), volumeName, volumeType, transportType, replicaCount, stripeCount, bricks, accessProtocols, options);
+ return createdResponse(volumeName);
} 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
- + "]");
+ return errorResponse("No online servers found in cluster [" + clusterName + "]");
+ }
+
+ try {
+ glusterUtil.createVolume(onlineServer.getName(), volumeName, volumeType, transportType, replicaCount, stripeCount, bricks, accessProtocols, options);
+ return createdResponse(volumeName);
+ } catch(Exception e1) {
+ return errorResponse(e1.getMessage());
}
- status = glusterUtil.createVolume(volume, brickDirectories, onlineServer.getName());
}
- return status;
}
- @SuppressWarnings("rawtypes")
+ /**
+ * Returns name of the missing parameter if any. If all parameters are present,
+ * @param clusterName
+ * @param volumeName
+ * @param volumeType
+ * @param transportType
+ * @param replicaCount
+ * @param stripeCount
+ * @param bricks
+ * @param accessProtocols
+ * @param options
+ * @return
+ */
+ private String checkMissingParamsForCreateVolume(String clusterName, String volumeName, String volumeType,
+ String transportType, Integer replicaCount, Integer stripeCount, String bricks, String accessProtocols,
+ String options) {
+
+ return (clusterName == null || clusterName.isEmpty()) ? FORM_PARAM_CLUSTER_NAME :
+ (volumeName == null || volumeName.isEmpty()) ? FORM_PARAM_VOLUME_NAME :
+ (volumeType == null || volumeType.isEmpty()) ? FORM_PARAM_VOLUME_TYPE :
+ (transportType == null || transportType.isEmpty()) ? FORM_PARAM_TRANSPORT_TYPE :
+ (replicaCount == null) ? FORM_PARAM_REPLICA_COUNT :
+ (stripeCount == null) ? FORM_PARAM_STRIPE_COUNT :
+ (bricks == null || bricks.isEmpty()) ? FORM_PARAM_BRICKS :
+ (accessProtocols == null || accessProtocols.isEmpty()) ? FORM_PARAM_ACCESS_PROTOCOLS :
+ (options == null || options.isEmpty()) ? FORM_PARAM_VOLUME_OPTIONS :
+ null;
+ }
+
@GET
@Path("{" + PATH_PARAM_VOLUME_NAME + "}")
@Produces(MediaType.APPLICATION_XML)
- public GenericResponse getVolume(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName,
+ public Response getVolumeXML(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName,
@PathParam(PATH_PARAM_VOLUME_NAME) String volumeName) {
+ return getVolume(clusterName, volumeName, MediaType.APPLICATION_XML);
+ }
+
+ @GET
+ @Path("{" + PATH_PARAM_VOLUME_NAME + "}")
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response getVolumeJSON(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName,
+ @PathParam(PATH_PARAM_VOLUME_NAME) String volumeName) {
+ return getVolume(clusterName, volumeName, MediaType.APPLICATION_JSON);
+ }
+
+ private Response getVolume(String clusterName, String volumeName, String mediaType) {
+ Volume volume = null;
+
+ if (clusterName == null || clusterName.isEmpty()) {
+ return badRequestResponse("Parameter [" + FORM_PARAM_CLUSTER_NAME + "] is missing in request!");
+ }
+
+ if (clusterService.getCluster(clusterName) == null) {
+ return badRequestResponse("Cluster [" + clusterName + "] not found!");
+ }
+
+ try {
+ volume = getVolume(clusterName, volumeName);
+ return okResponse(volume, mediaType);
+ } catch(Exception e) {
+ return errorResponse(e.getMessage());
+ }
+ }
+
+ private Volume getVolume(String clusterName, String volumeName) {
+ Volume volume;
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);
+ throw new GlusterRuntimeException("No online servers found in cluster [" + clusterName + "]");
}
try {
- return new GenericResponse<Volume>(Status.STATUS_SUCCESS, glusterUtil.getVolume(volumeName,
- onlineServer.getName()));
+ 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 GenericResponse<Volume>(new Status(Status.STATUS_CODE_FAILURE,
- "No online servers found in cluster [" + clusterName + "]"), null);
+ throw new GlusterRuntimeException("No online servers found in cluster [" + clusterName + "]");
}
- return new GenericResponse<Volume>(Status.STATUS_SUCCESS, glusterUtil.getVolume(volumeName,
- onlineServer.getName()));
+ volume = glusterUtil.getVolume(volumeName, onlineServer.getName());
}
+ return volume;
}
@PUT
@Path("{" + PATH_PARAM_VOLUME_NAME + "}")
- @Produces(MediaType.APPLICATION_XML)
- public Status performOperation(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName,
+ public Response performOperation(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName,
@PathParam(PATH_PARAM_VOLUME_NAME) String volumeName, @FormParam(FORM_PARAM_OPERATION) String operation) {
+ if (clusterName == null || clusterName.isEmpty()) {
+ return badRequestResponse("Parameter [" + FORM_PARAM_CLUSTER_NAME + "] is missing in request!");
+ }
+
+ if (clusterService.getCluster(clusterName) == null) {
+ return badRequestResponse("Cluster [" + clusterName + "] not found!");
+ }
+
GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName);
if (onlineServer == null) {
- return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]");
+ return errorResponse("No online servers found in cluster [" + clusterName + "]");
}
try {
- return performOperation(volumeName, operation, onlineServer);
+ performOperation(volumeName, operation, onlineServer);
} 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
- + "]");
+ return errorResponse("No online servers found in cluster [" + clusterName + "]");
+ }
+
+ try {
+ performOperation(volumeName, operation, onlineServer);
+ } catch(Exception e1) {
+ // TODO: Log the exception
+ return errorResponse(e1.getMessage());
}
- return performOperation(volumeName, operation, onlineServer);
}
+ return noContentResponse();
}
private Status performOperation(String volumeName, String operation, GlusterServer onlineServer) {
@@ -231,79 +352,121 @@ public class VolumesResource {
@DELETE
@Path("{" + PATH_PARAM_VOLUME_NAME + "}")
- @Produces(MediaType.APPLICATION_XML)
- public Status deleteVolume(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName,
+ public Response deleteVolume(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName,
@PathParam(PATH_PARAM_VOLUME_NAME) String volumeName,
@QueryParam(QUERY_PARAM_DELETE_OPTION) boolean deleteFlag) {
- GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName);
- if (onlineServer == null) {
- return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]");
+ if (clusterName == null || clusterName.isEmpty()) {
+ return badRequestResponse("Parameter [" + FORM_PARAM_CLUSTER_NAME + "] is missing in request!");
}
+ if (clusterService.getCluster(clusterName) == null) {
+ return badRequestResponse("Cluster [" + clusterName + "] not found!");
+ }
+
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());
+ volume = getVolume(clusterName, volumeName);
+ } catch (Exception e) {
+ // TODO: Log the exception
+ return errorResponse(e.getMessage());
}
+
List<Brick> bricks = volume.getBricks();
- Status status = glusterUtil.deleteVolume(volumeName, onlineServer.getName());
-
- if (status.isSuccess()) {
- Status postDeleteStatus = postDelete(volumeName, bricks, deleteFlag);
-
- if (!postDeleteStatus.isSuccess()) {
- status.setCode(Status.STATUS_CODE_PART_SUCCESS);
- status.setMessage("Error in post-delete operation: " + postDeleteStatus);
- }
+ Status status = glusterUtil.deleteVolume(volumeName, glusterServersResource.getOnlineServer(clusterName)
+ .getName());
+ if(!status.isSuccess()) {
+ return errorResponse("Couldn't delete volume [" + volumeName + "]. Error: " + status);
}
- return status;
+
+ try {
+ postDelete(volumeName, bricks, deleteFlag);
+ } catch(Exception e) {
+ return errorResponse("Volume [" + volumeName
+ + "] deleted from cluster, however following errors happened: " + CoreConstants.NEWLINE
+ + e.getMessage());
+ }
+
+ return noContentResponse();
}
@DELETE
@Path("{" + QUERY_PARAM_VOLUME_NAME + "}/" + RESOURCE_BRICKS)
- @Produces(MediaType.APPLICATION_XML)
- public Status removeBricks(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName,
+ public Response removeBricks(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName,
@PathParam(QUERY_PARAM_VOLUME_NAME) String volumeName, @QueryParam(QUERY_PARAM_BRICKS) String bricks,
@QueryParam(QUERY_PARAM_DELETE_OPTION) boolean deleteFlag) {
List<String> brickList = Arrays.asList(bricks.split(",")); // Convert from comma separated string (query
// parameter)
+ if (clusterName == null || clusterName.isEmpty()) {
+ return badRequestResponse("Parameter [" + FORM_PARAM_CLUSTER_NAME + "] is missing in request!");
+ }
+
+ if (clusterService.getCluster(clusterName) == null) {
+ return badRequestResponse("Cluster [" + clusterName + "] not found!");
+ }
GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName);
if (onlineServer == null) {
- return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]");
+ return errorResponse("No online servers found in cluster [" + clusterName + "]");
}
- Status status = null;
try {
- status = glusterUtil.removeBricks(volumeName, brickList, onlineServer.getName());
+ removeBricks(clusterName, volumeName, brickList, onlineServer);
+ } catch(Exception e) {
+ return errorResponse(e.getMessage());
+ }
+
+ try {
+ cleanupDirectories(brickList, volumeName, brickList.size(), deleteFlag);
+ } catch(Exception e) {
+ // append cleanup error to prepare brick error
+ return errorResponse(e.getMessage());
+ }
+
+ return noContentResponse();
+ }
+
+ public void removeBricks(String clusterName, String volumeName, List<String> brickList, GlusterServer onlineServer) {
+ try {
+ glusterUtil.removeBricks(volumeName, brickList, 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
- + "]");
+ throw new GlusterRuntimeException("No online servers found in cluster [" + clusterName + "]");
}
- status = glusterUtil.removeBricks(volumeName, brickList, onlineServer.getName());
+ glusterUtil.removeBricks(volumeName, brickList, onlineServer.getName());
}
+ }
- if (status.isSuccess()) {
- Status cleanupStatus = cleanupDirectories(brickList, volumeName, brickList.size(), deleteFlag);
- if (!cleanupStatus.isSuccess()) {
- // append cleanup error to prepare brick error
- status.setMessage(status.getMessage() + CoreConstants.NEWLINE + cleanupStatus.getMessage());
+ @SuppressWarnings("rawtypes")
+ private void cleanupDirectories(List<String> bricks, String volumeName, int maxIndex, boolean deleteFlag) {
+ Status result;
+ String errors = "";
+ for (int i = 0; i < maxIndex; i++) {
+ String[] brickInfo = bricks.get(i).split(":");
+ String serverName = brickInfo[0];
+ String brickDirectory = brickInfo[1];
+
+ String mountPoint = brickDirectory.substring(0, brickDirectory.lastIndexOf("/"));
+ Object response = serverUtil.executeOnServer(true, serverName, VOLUME_DIRECTORY_CLEANUP_SCRIPT + " "
+ + mountPoint + " " + volumeName + " " + (deleteFlag ? "-d" : ""), GenericResponse.class);
+ if (response instanceof GenericResponse) {
+ result = ((GenericResponse) response).getStatus();
+ if (!result.isSuccess()) {
+ errors += "[" + mountPoint + "][" + volumeName + "] => " + result
+ + CoreConstants.NEWLINE;
+ }
+ } else {
+ Status errStatus = (Status) response;
+ errors += "[" + mountPoint + "][" + volumeName + "] => " + errStatus + CoreConstants.NEWLINE;
}
}
- return status;
+ if(!errors.trim().isEmpty()) {
+ throw new GlusterRuntimeException("Volume directory cleanup errors: " + errors.trim());
+ }
}
- private Status postDelete(String volumeName, List<Brick> bricks, boolean deleteFlag) {
+ private void postDelete(String volumeName, List<Brick> bricks, boolean deleteFlag) {
Status result;
for (Brick brick : bricks) {
String brickDirectory = brick.getBrickDirectory();
@@ -312,93 +475,122 @@ public class VolumesResource {
result = (Status) serverUtil.executeOnServer(true, brick.getServerName(), VOLUME_DIRECTORY_CLEANUP_SCRIPT
+ " " + mountPoint + " " + volumeName + (deleteFlag ? " -d" : ""), Status.class);
if (!result.isSuccess()) {
- return result;
+ throw new GlusterRuntimeException("Error in post-delete operation of volume [" + volumeName + "]: "
+ + result);
}
}
- return new Status(Status.STATUS_CODE_SUCCESS, "Post volume delete operation successfully initiated");
}
@POST
@Path("{" + PATH_PARAM_VOLUME_NAME + " }/" + RESOURCE_OPTIONS)
- @Produces(MediaType.APPLICATION_XML)
- public Status setOption(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName,
+ public Response setOption(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName,
@PathParam(PATH_PARAM_VOLUME_NAME) String volumeName,
@FormParam(RESTConstants.FORM_PARAM_OPTION_KEY) String key,
@FormParam(RESTConstants.FORM_PARAM_OPTION_VALUE) String value) {
+ if (clusterName == null || clusterName.isEmpty()) {
+ return badRequestResponse("Parameter [" + FORM_PARAM_CLUSTER_NAME + "] is missing in request!");
+ }
+
+ if(volumeName == null || volumeName.isEmpty()) {
+ return badRequestResponse("Parameter [" + FORM_PARAM_VOLUME_NAME + "] is missing in request!");
+ }
+
+ if(key == null || key.isEmpty()) {
+ return badRequestResponse("Parameter [" + FORM_PARAM_OPTION_KEY + "] is missing in request!");
+ }
+
+ if(value == null || value.isEmpty()) {
+ return badRequestResponse("Parameter [" + FORM_PARAM_OPTION_VALUE + "] is missing in request!");
+ }
+
+ if (clusterService.getCluster(clusterName) == null) {
+ return badRequestResponse("Cluster [" + clusterName + "] not found!");
+ }
+
GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName);
if (onlineServer == null) {
- return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]");
+ return errorResponse("No online servers found in cluster [" + clusterName + "]");
}
-
+
try {
- return glusterUtil.setOption(volumeName, key, value, onlineServer.getName());
+ glusterUtil.setOption(volumeName, key, value, 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
- + "]");
+ return errorResponse("No online servers found in cluster [" + clusterName + "]");
+ }
+
+ try {
+ glusterUtil.setOption(volumeName, key, value, onlineServer.getName());
+ } catch(Exception e1) {
+ return errorResponse(e1.getMessage());
}
- return glusterUtil.setOption(volumeName, key, value, onlineServer.getName());
+ } catch(Exception e) {
+ return errorResponse(e.getMessage());
}
+
+ return noContentResponse();
}
@PUT
@Path("{" + PATH_PARAM_VOLUME_NAME + " }/" + RESOURCE_OPTIONS)
- @Produces(MediaType.APPLICATION_XML)
- public Status resetOptions(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName,
+ public Response resetOptions(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName,
@PathParam(PATH_PARAM_VOLUME_NAME) String volumeName) {
+ if (clusterName == null || clusterName.isEmpty()) {
+ return badRequestResponse("Parameter [" + FORM_PARAM_CLUSTER_NAME + "] is missing in request!");
+ }
+
+ if(volumeName == null || volumeName.isEmpty()) {
+ return badRequestResponse("Parameter [" + FORM_PARAM_VOLUME_NAME + "] is missing in request!");
+ }
+
+ if (clusterService.getCluster(clusterName) == null) {
+ return badRequestResponse("Cluster [" + clusterName + "] not found!");
+ }
+
GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName);
if (onlineServer == null) {
- return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]");
+ return errorResponse("No online servers found in cluster [" + clusterName + "]");
}
try {
- return glusterUtil.resetOptions(volumeName, onlineServer.getName());
+ glusterUtil.resetOptions(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
- + "]");
+ return errorResponse("No online servers found in cluster [" + clusterName + "]");
}
- return glusterUtil.resetOptions(volumeName, onlineServer.getName());
+
+ try {
+ glusterUtil.resetOptions(volumeName, onlineServer.getName());
+ } catch(Exception e1) {
+ return errorResponse(e1.getMessage());
+ }
+ } catch(Exception e) {
+ return errorResponse(e.getMessage());
}
+
+ return noContentResponse();
}
@GET
@Path(RESOURCE_DEFAULT_OPTIONS)
@Produces(MediaType.APPLICATION_XML)
- public VolumeOptionInfoListResponse getDefaultOptions(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName) {
+ public VolumeOptionInfoListResponse getDefaultOptionsXML(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName) {
// TODO: Fetch all volume options with their default values from GlusterFS
// whenever such a CLI command is made available in GlusterFS
return new VolumeOptionInfoListResponse(Status.STATUS_SUCCESS, volumeOptionsDefaults.getDefaults());
}
- @SuppressWarnings("rawtypes")
- private Status cleanupDirectories(List<String> bricks, String volumeName, int maxIndex, boolean deleteFlag) {
- Status result;
- for (int i = 0; i < maxIndex; i++) {
- String[] brickInfo = bricks.get(i).split(":");
- String serverName = brickInfo[0];
- String brickDirectory = brickInfo[1];
-
- String mountPoint = brickDirectory.substring(0, brickDirectory.lastIndexOf("/"));
- Object response = serverUtil.executeOnServer(true, serverName, VOLUME_DIRECTORY_CLEANUP_SCRIPT + " "
- + mountPoint + " " + volumeName + " " + (deleteFlag ? "-d" : ""), GenericResponse.class);
- if (response instanceof GenericResponse) {
- result = ((GenericResponse) response).getStatus();
- if (!result.isSuccess()) {
- // TODO: append error and continue with cleaning up of other directories
- return result;
- }
- } else {
- // TODO: append error and continue with cleaning up of other directories
- // In case of script execution failure, a Status object will be returned.
- return (Status) response;
- }
- }
- return new Status(Status.STATUS_CODE_SUCCESS, "Directories cleaned up successfully!");
+ @GET
+ @Path(RESOURCE_DEFAULT_OPTIONS)
+ @Produces(MediaType.APPLICATION_JSON)
+ public VolumeOptionInfoListResponse getDefaultOptionsJSON(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName) {
+ // TODO: Fetch all volume options with their default values from GlusterFS
+ // whenever such a CLI command is made available in GlusterFS
+ return new VolumeOptionInfoListResponse(Status.STATUS_SUCCESS, volumeOptionsDefaults.getDefaults());
}
private List<VolumeLogMessage> getBrickLogs(Volume volume, Brick brick, Integer lineCount)
@@ -436,34 +628,38 @@ public class VolumesResource {
@GET
@Produces(MediaType.APPLICATION_OCTET_STREAM)
@Path("{" + PATH_PARAM_VOLUME_NAME + "}/" + RESOURCE_LOGS + "/" + RESOURCE_DOWNLOAD)
- public StreamingOutput downloadLogs(@PathParam(PATH_PARAM_CLUSTER_NAME) final String clusterName,
+ public Response downloadLogs(@PathParam(PATH_PARAM_CLUSTER_NAME) final String clusterName,
@PathParam(PATH_PARAM_VOLUME_NAME) final String volumeName) {
- final ClusterInfo cluster = clusterService.getCluster(clusterName);
- if (cluster == null) {
- throw new GlusterRuntimeException("Cluster [" + clusterName + "] doesn't exist!");
+ if (clusterName == null || clusterName.isEmpty()) {
+ return badRequestResponse("Parameter [" + FORM_PARAM_CLUSTER_NAME + "] is missing in request!");
}
-
- final Volume volume = (Volume) getVolume(clusterName, volumeName).getData();
- if (volume == null) {
- throw new GlusterRuntimeException("Volume [" + volumeName + "] doesn't exist in cluster [" + clusterName
- + "]!");
+
+ if (clusterService.getCluster(clusterName) == null) {
+ return badRequestResponse("Cluster [" + clusterName + "] not found!");
}
-
- return new StreamingOutput() {
-
- @Override
- public void write(OutputStream output) throws IOException, WebApplicationException {
- try {
- File archiveFile = new File(downloadLogs(volume));
- output.write(FileUtil.readFileAsByteArray(archiveFile));
- archiveFile.delete();
- } catch (Exception e) {
- // TODO: Log the exception
- e.printStackTrace();
- throw new GlusterRuntimeException("Exception while downloading/archiving volume log files!", e);
+
+ try {
+ final Volume volume = getVolume(clusterName, volumeName);
+ StreamingOutput output = new StreamingOutput() {
+
+ @Override
+ public void write(OutputStream output) throws IOException, WebApplicationException {
+ try {
+ File archiveFile = new File(downloadLogs(volume));
+ output.write(FileUtil.readFileAsByteArray(archiveFile));
+ archiveFile.delete();
+ } catch (Exception e) {
+ // TODO: Log the exception
+ e.printStackTrace();
+ String errMsg = "Exception while downloading/archiving volume log files : " + e.getMessage();
+ output.write(errMsg.getBytes());
+ }
}
- }
- };
+ };
+ return streamingOutputResponse(output);
+ } catch(Exception e) {
+ return errorResponse("Volume [" + volumeName + "] doesn't exist in cluster [" + clusterName + "]!");
+ }
}
private String downloadLogs(Volume volume) {
@@ -498,45 +694,66 @@ public class VolumesResource {
@GET
@Path("{" + PATH_PARAM_VOLUME_NAME + "}/" + RESOURCE_LOGS)
- public LogMessageListResponse getLogs(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName,
+ @Produces(MediaType.APPLICATION_XML)
+ public Response getLogsXML(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName,
@PathParam(PATH_PARAM_VOLUME_NAME) String volumeName, @QueryParam(QUERY_PARAM_BRICK_NAME) String brickName,
@QueryParam(QUERY_PARAM_LOG_SEVERITY) String severity,
@QueryParam(QUERY_PARAM_FROM_TIMESTAMP) String fromTimestamp,
@QueryParam(QUERY_PARAM_TO_TIMESTAMP) String toTimestamp,
@QueryParam(QUERY_PARAM_LINE_COUNT) Integer lineCount, @QueryParam(QUERY_PARAM_DOWNLOAD) Boolean download) {
- List<VolumeLogMessage> logMessages = null;
+ return getLogs(clusterName, volumeName, brickName, severity, fromTimestamp, toTimestamp, lineCount, MediaType.APPLICATION_XML);
+ }
- ClusterInfo cluster = clusterService.getCluster(clusterName);
- if (cluster == null) {
- return new LogMessageListResponse(new Status(Status.STATUS_CODE_FAILURE, "Cluster [" + clusterName
- + "] doesn't exist!"), null);
+ @GET
+ @Path("{" + PATH_PARAM_VOLUME_NAME + "}/" + RESOURCE_LOGS)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response getLogsJSON(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName,
+ @PathParam(PATH_PARAM_VOLUME_NAME) String volumeName, @QueryParam(QUERY_PARAM_BRICK_NAME) String brickName,
+ @QueryParam(QUERY_PARAM_LOG_SEVERITY) String severity,
+ @QueryParam(QUERY_PARAM_FROM_TIMESTAMP) String fromTimestamp,
+ @QueryParam(QUERY_PARAM_TO_TIMESTAMP) String toTimestamp,
+ @QueryParam(QUERY_PARAM_LINE_COUNT) Integer lineCount, @QueryParam(QUERY_PARAM_DOWNLOAD) Boolean download) {
+ return getLogs(clusterName, volumeName, brickName, severity, fromTimestamp, toTimestamp, lineCount, MediaType.APPLICATION_JSON);
+ }
+
+ public Response getLogs(String clusterName, String volumeName, String brickName, String severity,
+ String fromTimestamp, String toTimestamp, Integer lineCount, String mediaType) {
+ if (clusterName == null || clusterName.isEmpty()) {
+ return badRequestResponse("Parameter [" + FORM_PARAM_CLUSTER_NAME + "] is missing in request!");
+ }
+
+ if (volumeName == null || volumeName.isEmpty()) {
+ return badRequestResponse("Parameter [" + FORM_PARAM_VOLUME_NAME + "] is missing in request!");
+ }
+
+ if (clusterService.getCluster(clusterName) == null) {
+ return badRequestResponse("Cluster [" + clusterName + "] not found!");
}
+ List<VolumeLogMessage> logMessages = null;
+ Volume volume = null;
try {
- Volume volume = (Volume) getVolume(clusterName, volumeName).getData();
- if (volume == null) {
- return new LogMessageListResponse(new Status(Status.STATUS_CODE_FAILURE, "Volume [" + volumeName
- + "] doesn't exist in cluster [" + clusterName + "]!"), null);
- }
+ volume = (Volume) getVolume(clusterName, volumeName);
+ } catch(Exception e) {
+ return errorResponse(e.getMessage());
+ }
- if (brickName == null || brickName.isEmpty() || brickName.equals(CoreConstants.ALL)) {
- logMessages = getLogsForAllBricks(volume, lineCount);
- } else {
- // fetch logs for given brick of the volume
- for (Brick brick : volume.getBricks()) {
- if (brick.getQualifiedName().equals(brickName)) {
- logMessages = getBrickLogs(volume, brick, lineCount);
- break;
- }
+ if (brickName == null || brickName.isEmpty() || brickName.equals(CoreConstants.ALL)) {
+ logMessages = getLogsForAllBricks(volume, lineCount);
+ } else {
+ // fetch logs for given brick of the volume
+ for (Brick brick : volume.getBricks()) {
+ if (brick.getQualifiedName().equals(brickName)) {
+ logMessages = getBrickLogs(volume, brick, lineCount);
+ break;
}
}
- } catch (Exception e) {
- return new LogMessageListResponse(new Status(e), null);
}
filterLogsBySeverity(logMessages, severity);
filterLogsByTime(logMessages, fromTimestamp, toTimestamp);
- return new LogMessageListResponse(Status.STATUS_SUCCESS, logMessages);
+
+ return okResponse(new LogMessageListResponse(logMessages), mediaType);
}
private void filterLogsByTime(List<VolumeLogMessage> logMessages, String fromTimestamp, String toTimestamp) {
@@ -600,71 +817,87 @@ public class VolumesResource {
@POST
@Path("{" + QUERY_PARAM_VOLUME_NAME + "}/" + RESOURCE_BRICKS)
- public Status addBricks(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName,
+ public Response addBricks(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName,
@PathParam(QUERY_PARAM_VOLUME_NAME) String volumeName, @FormParam(FORM_PARAM_BRICKS) String bricks) {
+ if (clusterName == null || clusterName.isEmpty()) {
+ return badRequestResponse("Parameter [" + FORM_PARAM_CLUSTER_NAME + "] is missing in request!");
+ }
+
+ if (volumeName == null || volumeName.isEmpty()) {
+ return badRequestResponse("Parameter [" + FORM_PARAM_VOLUME_NAME + "] is missing in request!");
+ }
+
+ if (bricks == null || bricks.isEmpty()) {
+ return badRequestResponse("Parameter [" + FORM_PARAM_BRICKS + "] is missing in request!");
+ }
+
+ if (clusterService.getCluster(clusterName) == null) {
+ return badRequestResponse("Cluster [" + clusterName + "] not found!");
+ }
+
GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName);
if (onlineServer == null) {
- return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]");
+ return errorResponse("No online servers found in cluster [" + clusterName + "]");
}
try {
- return glusterUtil.addBricks(volumeName, Arrays.asList(bricks.split(",")), onlineServer.getName());
+ glusterUtil.addBricks(volumeName, Arrays.asList(bricks.split(",")), 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
- + "]");
+ return errorResponse("No online servers found in cluster [" + clusterName + "]");
}
- return glusterUtil.addBricks(volumeName, Arrays.asList(bricks.split(",")), onlineServer.getName());
- }
- }
-
-// @PUT
-// @Path("{" + QUERY_PARAM_VOLUME_NAME + "}/" + RESOURCE_BRICKS)
-// public Status replaceBrick(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName,
-// @PathParam(QUERY_PARAM_VOLUME_NAME) String volumeName, @FormParam(FORM_PARAM_SOURCE) String diskFrom,
-// @FormParam(FORM_PARAM_TARGET) String diskTo, @FormParam(FORM_PARAM_OPERATION) String operation) {
-// GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName);
-// if (onlineServer == null) {
-// return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]");
-// }
-//
-// try {
-//
-// return glusterUtil.migrateDisk(volumeName, diskFrom, diskTo, "start", 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
-// + "]");
-// }
-// return glusterUtil.migrateDisk(volumeName, diskFrom, diskTo, operation, onlineServer.getName());
-// }
-// }
-
+
+ try {
+ glusterUtil.addBricks(volumeName, Arrays.asList(bricks.split(",")), onlineServer.getName());
+ } catch(Exception e1) {
+ return errorResponse(e1.getMessage());
+ }
+ } catch(Exception e1) {
+ return errorResponse(e1.getMessage());
+ }
+
+ return noContentResponse();
+ }
+
@PUT
@Path("{" + PATH_PARAM_VOLUME_NAME + "}/" + RESOURCE_BRICKS)
- public TaskResponse migrateBrick(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName,
+ public Response migrateBrick(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName,
@PathParam(PATH_PARAM_VOLUME_NAME) String volumeName, @FormParam(FORM_PARAM_SOURCE) String fromBrick,
@FormParam(FORM_PARAM_TARGET) String toBrick, @FormParam(FORM_PARAM_AUTO_COMMIT) Boolean autoCommit) {
- TaskResponse taskResponse = new TaskResponse();
+ if (clusterName == null || clusterName.isEmpty()) {
+ return badRequestResponse("Parameter [" + FORM_PARAM_CLUSTER_NAME + "] is missing in request!");
+ }
+
+ if (volumeName == null || volumeName.isEmpty()) {
+ return badRequestResponse("Parameter [" + FORM_PARAM_VOLUME_NAME + "] is missing in request!");
+ }
+
GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName);
if (onlineServer == null) {
- taskResponse.setData(null);
- taskResponse.setStatus(new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster ["
- + clusterName + "]"));
- return taskResponse;
+ return errorResponse("No online servers found in cluster [" + clusterName + "]");
}
-
+
+ String taskId = null;
try {
- return glusterUtil.migrateBrick(volumeName, fromBrick, toBrick, "start", autoCommit, onlineServer.getName());
+ taskId = glusterUtil.migrateBrickStart(volumeName, fromBrick, toBrick, autoCommit, onlineServer.getName());
} catch (ConnectionException e) {
+ // online server has gone offline! try with a different one.
onlineServer = glusterServersResource.getNewOnlineServer(clusterName);
- return glusterUtil.migrateBrick(volumeName, fromBrick, toBrick, "start", autoCommit, onlineServer.getName());
+
+ try {
+ taskId = glusterUtil.migrateBrickStart(volumeName, fromBrick, toBrick, autoCommit, onlineServer.getName());
+ } catch(Exception e1) {
+ return errorResponse(e1.getMessage());
+ }
+ } catch(Exception e1) {
+ return errorResponse(e1.getMessage());
}
+
+ return noContentResponse(uriInfo.getBaseUri() + "/" + RESTConstants.RESOURCE_PATH_CLUSTERS + "/" + clusterName
+ + "/" + RESOURCE_TASKS + "/" + taskId);
}
public static void main(String[] args) throws ClassNotFoundException {
@@ -690,8 +923,6 @@ public class VolumesResource {
// System.out.println("Code : " + status.getCode());
// System.out.println("Message " + status.getMessage());
- Status status1 = vr.removeBricks("testCluster", "test", "192.168.1.210:sdb", true);
- System.out.println("Code : " + status1.getCode());
- System.out.println("Message " + status1.getMessage());
+ vr.removeBricks("testCluster", "test", "192.168.1.210:sdb", true);
}
}
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 6b4bdb35..3472745e 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
@@ -23,12 +23,14 @@ package com.gluster.storage.management.server.utils;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import java.util.Map.Entry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.gluster.storage.management.core.constants.CoreConstants;
+import com.gluster.storage.management.core.constants.RESTConstants;
import com.gluster.storage.management.core.exceptions.GlusterRuntimeException;
import com.gluster.storage.management.core.model.Brick;
import com.gluster.storage.management.core.model.Brick.BRICK_STATUS;
@@ -43,6 +45,7 @@ import com.gluster.storage.management.core.model.Volume.VOLUME_STATUS;
import com.gluster.storage.management.core.model.Volume.VOLUME_TYPE;
import com.gluster.storage.management.core.model.VolumeOptions;
import com.gluster.storage.management.core.response.TaskResponse;
+import com.gluster.storage.management.core.utils.GlusterCoreUtil;
import com.gluster.storage.management.core.utils.ProcessResult;
import com.gluster.storage.management.server.resources.TasksResource;
import com.gluster.storage.management.server.tasks.MigrateDiskTask;
@@ -68,6 +71,8 @@ public class GlusterUtil {
private static final String VOLUME_LOG_LOCATION_PFX = "log file location:";
private static final String VOLUME_TYPE_DISTRIBUTE = "Distribute";
private static final String VOLUME_TYPE_REPLICATE = "Replicate";
+
+ private static final GlusterCoreUtil glusterCoreUtil = new GlusterCoreUtil();
@Autowired
private SshUtil sshUtil;
@@ -203,41 +208,52 @@ public class GlusterUtil {
return new Status(sshUtil.executeRemote(knownServer, "gluster --mode=script volume stop " + volumeName));
}
- public Status resetOptions(String volumeName, String knownServer) {
- return new Status(sshUtil.executeRemote(knownServer, "gluster volume reset " + volumeName));
+ public void resetOptions(String volumeName, String knownServer) {
+ ProcessResult result = sshUtil.executeRemote(knownServer, "gluster volume reset " + volumeName);
+ if(!result.isSuccess()) {
+ throw new GlusterRuntimeException("Couldn't reset options for volume [" + volumeName + "]! Error: "
+ + result);
+ }
}
- public Status createVolume(Volume volume, List<String> brickDirectories, String knownServer) {
+ public void createVolume(String knownServer, String volumeName, String volumeTypeStr, String transportTypeStr,
+ Integer replicaCount, Integer stripeCount, String bricks, String accessProtocols, String options) {
+
int count = 1; // replica or stripe count
- String volumeType = null;
- VOLUME_TYPE volType = volume.getVolumeType();
+
+ VOLUME_TYPE volType = Volume.getVolumeTypeByStr(volumeTypeStr);
+ String volTypeArg = null;
if (volType == VOLUME_TYPE.DISTRIBUTED_MIRROR) {
- volumeType = "replica";
- count = volume.getReplicaCount();
+ volTypeArg = "replica";
+ count = replicaCount;
} else if (volType == VOLUME_TYPE.DISTRIBUTED_STRIPE) {
- volumeType = "stripe";
- count = volume.getStripeCount();
+ volTypeArg = "stripe";
+ count = stripeCount;
}
- String transportTypeStr = null;
- TRANSPORT_TYPE transportType = volume.getTransportType();
- transportTypeStr = (transportType == TRANSPORT_TYPE.ETHERNET) ? "tcp" : "rdma";
- String command = prepareVolumeCreateCommand(volume, brickDirectories, count, volumeType, transportTypeStr);
+ String transportTypeArg = null;
+ TRANSPORT_TYPE transportType = Volume.getTransportTypeByStr(transportTypeStr);
+ transportTypeArg = (transportType == TRANSPORT_TYPE.ETHERNET) ? "tcp" : "rdma";
+
+ String command = prepareVolumeCreateCommand(volumeName, glusterCoreUtil.extractList(bricks, ","), count,
+ volTypeArg, transportTypeArg);
ProcessResult result = sshUtil.executeRemote(knownServer, command);
if (!result.isSuccess()) {
- return new Status(result);
+ throw new GlusterRuntimeException("Error in creating volume [" + volumeName + "]: " + result);
}
- Status status = createOptions(volume, knownServer);
- if (!status.isSuccess()) { // Return partial success if set volume option failed.
- status.setCode(Status.STATUS_CODE_PART_SUCCESS);
- status.setMessage("Error while setting volume options: " + status);
+
+ try {
+ createOptions(volumeName, glusterCoreUtil.extractMap(options, ",", "="), knownServer);
+ } catch(Exception e) {
+ throw new GlusterRuntimeException(
+ "Volume created successfully, however following errors occurred while setting options: "
+ + CoreConstants.NEWLINE + e.getMessage());
}
- return status;
}
- private String prepareVolumeCreateCommand(Volume volume, List<String> brickDirectories, int count,
+ private String prepareVolumeCreateCommand(String volumeName, List<String> brickDirectories, int count,
String volumeType, String transportTypeStr) {
- StringBuilder command = new StringBuilder("gluster volume create " + volume.getName() + " ");
+ StringBuilder command = new StringBuilder("gluster volume create " + volumeName + " ");
if (volumeType != null) {
command.append(volumeType + " " + count + " ");
}
@@ -248,24 +264,34 @@ public class GlusterUtil {
return command.toString();
}
- public Status createOptions(Volume volume, String knownServer) {
- VolumeOptions options = volume.getOptions();
+ public void createOptions(String volumeName, Map<String, String> options, String knownServer) {
+ String errors = "";
if (options != null) {
for (Entry<String, String> option : options.entrySet()) {
String key = option.getKey();
String value = option.getValue();
- Status status = setOption(volume.getName(), key, value, knownServer);
- if (!status.isSuccess()) {
- return status;
+
+ try {
+ setOption(volumeName, key, value, knownServer);
+ } catch(Exception e) {
+ // append error
+ errors += e.getMessage() + CoreConstants.NEWLINE;
}
}
}
- return Status.STATUS_SUCCESS;
+ if (!errors.trim().isEmpty()) {
+ throw new GlusterRuntimeException("Errors while setting option(s) on volume [" + volumeName + "] : "
+ + errors.trim());
+ }
}
- public Status setOption(String volumeName, String key, String value, String knownServer) {
- return new Status(sshUtil.executeRemote(knownServer, "gluster volume set " + volumeName + " " + key + " "
- + "\"" + value + "\""));
+ public void setOption(String volumeName, String key, String value, String knownServer) {
+ ProcessResult result = sshUtil.executeRemote(knownServer, "gluster volume set " + volumeName + " " + key + " "
+ + "\"" + value + "\"");
+ if (!result.isSuccess()) {
+ throw new GlusterRuntimeException("Volume [" + volumeName + "] set [" + key + "=" + value + "] => "
+ + result);
+ }
}
public Status deleteVolume(String volumeName, String knownServer) {
@@ -275,8 +301,8 @@ public class GlusterUtil {
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 on [" + knownServer
- + "] with error: " + result);
+ throw new GlusterRuntimeException("Command [gluster volume info " + volumeName + "] failed on ["
+ + knownServer + "] with error: " + result);
}
return result.getOutput();
}
@@ -393,11 +419,7 @@ public class GlusterUtil {
}
public Volume getVolume(String volumeName, String knownServer) {
- List<Volume> volumes = parseVolumeInfo(getVolumeInfo(volumeName, knownServer));
- if (volumes.size() > 0) {
- return volumes.get(0);
- }
- return null;
+ return parseVolumeInfo(getVolumeInfo(volumeName, knownServer)).get(0);
}
public List<Volume> getAllVolumes(String knownServer) {
@@ -467,12 +489,17 @@ public class GlusterUtil {
return volumes;
}
- public Status addBricks(String volumeName, List<String> bricks, String knownServer) {
+ public void addBricks(String volumeName, List<String> bricks, String knownServer) {
StringBuilder command = new StringBuilder("gluster volume add-brick " + volumeName);
for (String brickDir : bricks) {
command.append(" " + brickDir);
}
- return new Status(sshUtil.executeRemote(knownServer, command.toString()));
+
+ ProcessResult result = sshUtil.executeRemote(knownServer, command.toString());
+ if(!result.isSuccess()) {
+ throw new GlusterRuntimeException("Error in volume [" + volumeName + "] add-brick [" + bricks + "]: "
+ + result);
+ }
}
public String getLogLocation(String volumeName, String brickName, String knownServer) {
@@ -501,19 +528,18 @@ public class GlusterUtil {
}
- public TaskResponse migrateBrick(String volumeName, String fromBrick, String toBrick, String operation,
- Boolean autoCommit, String knownServer) {
- TaskResponse taskResponse = new TaskResponse();
+ public String migrateBrickStart(String volumeName, String fromBrick, String toBrick, Boolean autoCommit,
+ String knownServer) {
MigrateDiskTask migrateDiskTask = new MigrateDiskTask(TASK_TYPE.BRICK_MIGRATE, volumeName, fromBrick, toBrick);
migrateDiskTask.setOnlineServer(knownServer);
migrateDiskTask.setAutoCommit(autoCommit);
+
TaskInfo taskInfo = migrateDiskTask.start();
if (taskInfo.isSuccess()) {
taskResource.addTask(migrateDiskTask);
}
- taskResponse.setData(taskInfo);
- taskResponse.setStatus(new Status(Status.STATUS_CODE_SUCCESS, ""));
- return taskResponse;
+
+ return taskInfo.getId();
}
public Status removeBricks(String volumeName, List<String> bricks, String knownServer) {
@@ -534,7 +560,6 @@ public class GlusterUtil {
List<String> disks = new ArrayList<String>();
disks.add("server1:sda");
disks.add("server1:sdb");
- Status status = new GlusterUtil().addBricks("Volume3", disks, "localhost");
- System.out.println(status);
+ new GlusterUtil().addBricks("Volume3", disks, "localhost");
}
}