From 5bb44641bf7b40f048e71281885efea68a3fbcbd Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Tue, 21 Jun 2011 21:17:09 +0530 Subject: REST API enhancements --- .../storage/management/client/AbstractClient.java | 103 ++++++++++++--------- .../management/client/GlusterDataModelManager.java | 18 ++-- .../storage/management/client/TasksClient.java | 4 +- .../storage/management/client/VolumesClient.java | 73 ++++++--------- 4 files changed, 94 insertions(+), 104 deletions(-) (limited to 'src/com.gluster.storage.management.client') 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 f38c1a5f..9d9d6c5f 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 @@ -20,11 +20,13 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import com.gluster.storage.management.client.utils.ClientUtil; +import com.gluster.storage.management.core.constants.RESTConstants; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.UniformInterfaceException; import com.sun.jersey.api.client.WebResource; +import com.sun.jersey.api.client.WebResource.Builder; import com.sun.jersey.api.client.config.DefaultClientConfig; import com.sun.jersey.api.representation.Form; import com.sun.jersey.client.urlconnection.HTTPSProperties; @@ -121,8 +123,12 @@ public abstract class AbstractClient { */ @SuppressWarnings({ "unchecked", "rawtypes" }) private Object fetchResource(WebResource res, MultivaluedMap queryParams, Class responseClass) { - return res.queryParams(queryParams).header(HTTP_HEADER_AUTH, authHeader).accept(MediaType.APPLICATION_XML) - .get(responseClass); + try { + return res.path("." + RESTConstants.FORMAT_XML).queryParams(queryParams) + .header(HTTP_HEADER_AUTH, authHeader).accept(MediaType.APPLICATION_XML).get(responseClass); + } catch(UniformInterfaceException e) { + throw new GlusterRuntimeException(e.getResponse().getEntity(String.class)); + } } protected void downloadResource(WebResource res, String filePath) { @@ -212,6 +218,29 @@ public abstract class AbstractClient { return fetchResource(resource.path(subResourceName), queryParams, responseClass); } + private void postRequest(WebResource resource, Form form) { + try { + prepareFormRequestBuilder(resource).post(form); + } catch (UniformInterfaceException e) { + throw new GlusterRuntimeException(e.getResponse().getEntity(String.class)); + } + } + + /** + * Submits given object to the resource and returns the object received as response + * + * @param responseClass + * Class of the object expected as response + * @param requestObject + * the Object to be submitted + * @return Object of given class received as response + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + protected Object postObject(Class responseClass, Object requestObject) { + return resource.type(MediaType.APPLICATION_XML).header(HTTP_HEADER_AUTH, authHeader) + .accept(MediaType.APPLICATION_XML).post(responseClass, requestObject); + } + /** * Submits given Form using POST method to the resource and returns the object received as response * @@ -219,12 +248,7 @@ public abstract class AbstractClient { * Form to be submitted */ protected void postRequest(Form form) { - try { - resource.type(MediaType.APPLICATION_FORM_URLENCODED_TYPE).header(HTTP_HEADER_AUTH, authHeader) - .accept(MediaType.APPLICATION_XML).post(form); - } catch (UniformInterfaceException e) { - throw new GlusterRuntimeException(e.getResponse().getEntity(String.class)); - } + postRequest(resource, form); } /** @@ -236,14 +260,22 @@ public abstract class AbstractClient { * Form to be submitted */ protected void postRequest(String subResourceName, Form form) { + postRequest(resource.path(subResourceName), form); + } + + private void putRequest(WebResource resource, Form form) { try { - resource.path(subResourceName).type(MediaType.APPLICATION_FORM_URLENCODED_TYPE) - .header(HTTP_HEADER_AUTH, authHeader).accept(MediaType.APPLICATION_XML).post(form); + prepareFormRequestBuilder(resource).put(form); } catch (UniformInterfaceException e) { throw new GlusterRuntimeException(e.getResponse().getEntity(String.class)); } } + public Builder prepareFormRequestBuilder(WebResource resource) { + return resource.path("." + RESTConstants.FORMAT_XML).type(MediaType.APPLICATION_FORM_URLENCODED_TYPE) + .header(HTTP_HEADER_AUTH, authHeader).accept(MediaType.APPLICATION_XML); + } + /** * Submits given Form using PUT method to the given sub-resource and returns the object received as response * @@ -253,12 +285,7 @@ public abstract class AbstractClient { * Form to be submitted */ protected void putRequest(String subResourceName, Form form) { - try { - resource.path(subResourceName).type(MediaType.APPLICATION_FORM_URLENCODED_TYPE) - .header(HTTP_HEADER_AUTH, authHeader).accept(MediaType.APPLICATION_XML).put(form); - } catch (UniformInterfaceException e) { - throw new GlusterRuntimeException(e.getResponse().getEntity(String.class)); - } + putRequest(resource.path(subResourceName), form); } /** @@ -268,12 +295,7 @@ public abstract class AbstractClient { * Form to be submitted */ protected void putRequest(Form form) { - try { - resource.type(MediaType.APPLICATION_FORM_URLENCODED_TYPE).header(HTTP_HEADER_AUTH, authHeader) - .accept(MediaType.APPLICATION_XML).put(form); - } catch(UniformInterfaceException e) { - throw new GlusterRuntimeException(e.getResponse().getEntity(String.class)); - } + putRequest(resource, form); } /** @@ -284,38 +306,27 @@ public abstract class AbstractClient { */ protected void putRequest(String subResourceName) { try { - resource.path(subResourceName).type(MediaType.APPLICATION_FORM_URLENCODED_TYPE) - .header(HTTP_HEADER_AUTH, authHeader).accept(MediaType.APPLICATION_XML).put(); + prepareFormRequestBuilder(resource.path(subResourceName)).put(); } catch (UniformInterfaceException e) { throw new GlusterRuntimeException(e.getResponse().getEntity(String.class)); } } - /** - * Submits given object to the resource and returns the object received as response - * - * @param responseClass - * Class of the object expected as response - * @param requestObject - * the Object to be submitted - * @return Object of given class received as response - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected Object postObject(Class responseClass, Object requestObject) { - return resource.type(MediaType.APPLICATION_XML).header(HTTP_HEADER_AUTH, authHeader) - .accept(MediaType.APPLICATION_XML).post(responseClass, requestObject); + private void deleteResource(WebResource resource, MultivaluedMap queryParams) { + try { + resource.path("." + RESTConstants.FORMAT_XML).queryParams(queryParams).header(HTTP_HEADER_AUTH, authHeader) + .delete(); + } catch (UniformInterfaceException e) { + throw new GlusterRuntimeException(e.getResponse().getEntity(String.class)); + } } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected Object deleteResource(Class responseClass, MultivaluedMap queryParams) { - return resource.queryParams(queryParams).header(HTTP_HEADER_AUTH, authHeader).delete(responseClass); + + protected void deleteResource(MultivaluedMap queryParams) { + deleteResource(resource, queryParams); } - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected Object deleteSubResource(String subResourceName, Class responseClass, - MultivaluedMap queryParams) { - return resource.path(subResourceName).queryParams(queryParams).header(HTTP_HEADER_AUTH, authHeader) - .delete(responseClass); + protected void deleteSubResource(String subResourceName, MultivaluedMap queryParams) { + deleteResource(resource.path(subResourceName), queryParams); } protected void deleteSubResource(String subResourceName) { 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 fe8b3048..3a33e4e4 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 @@ -33,6 +33,7 @@ import com.gluster.storage.management.core.model.Event.EVENT_TYPE; import com.gluster.storage.management.core.model.GlusterDataModel; import com.gluster.storage.management.core.model.GlusterServer; import com.gluster.storage.management.core.model.Server; +import com.gluster.storage.management.core.model.Status; import com.gluster.storage.management.core.model.TaskInfo; import com.gluster.storage.management.core.model.Volume; import com.gluster.storage.management.core.model.Volume.TRANSPORT_TYPE; @@ -110,7 +111,9 @@ public class GlusterDataModelManager { private void initializeAutoDiscoveredServers(Cluster cluster) { ServerListResponse discoveredServerListResponse = new DiscoveredServersClient(securityToken) .getDiscoveredServerDetails(); - if (!discoveredServerListResponse.getStatus().isSuccess()) { + Status status = discoveredServerListResponse.getStatus(); + if (!status.isSuccess() && !status.isPartSuccess()) { + // TODO: Find a way to show warning in case of part success throw new GlusterRuntimeException(discoveredServerListResponse.getStatus().getMessage()); } cluster.setAutoDiscoveredServers(discoveredServerListResponse.getData()); @@ -118,20 +121,11 @@ public class GlusterDataModelManager { private void initializeVolumes(Cluster cluster) { VolumesClient volumeClient = new VolumesClient(); - VolumeListResponse response = volumeClient.getAllVolumes(); - if (!response.getStatus().isSuccess()) { - throw new GlusterRuntimeException("Error fetching volume list: [" + response.getStatus() + "]"); - } - cluster.setVolumes(response.getVolumes()); + cluster.setVolumes(volumeClient.getAllVolumes()); } private void initializeVolumeOptionsDefaults() { - VolumeOptionInfoListResponse response = new VolumesClient().getVolumeOptionsDefaults(); - if (!response.getStatus().isSuccess()) { - throw new GlusterRuntimeException("Error fetching volume option defaults: [" - + response.getStatus().getMessage() + "]"); - } - this.volumeOptionsDefaults = response.getOptions(); + this.volumeOptionsDefaults = new VolumesClient().getVolumeOptionsDefaults(); } public void initializeTasks(Cluster cluster) { diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/TasksClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/TasksClient.java index 54ba07e7..b5ee1d1c 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/TasksClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/TasksClient.java @@ -87,10 +87,10 @@ public class TasksClient extends AbstractClient { putRequest(taskId, form); } - public TaskResponse deleteTask(String taskId) { + public void deleteTask(String taskId) { MultivaluedMap queryParams = new MultivaluedMapImpl(); queryParams.add(RESTConstants.FORM_PARAM_OPERATION, RESTConstants.TASK_DELETE); - return (TaskResponse) deleteSubResource(taskId, TaskResponse.class, queryParams); + deleteSubResource(taskId, queryParams); } } 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 24ba119f..9a1eb261 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,7 +31,8 @@ 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.model.VolumeLogMessage; +import com.gluster.storage.management.core.model.VolumeOptionInfo; import com.gluster.storage.management.core.response.LogMessageListResponse; import com.gluster.storage.management.core.response.VolumeListResponse; import com.gluster.storage.management.core.response.VolumeOptionInfoListResponse; @@ -77,6 +78,17 @@ public class VolumesClient extends AbstractClient { public void stopVolume(String volumeName) { performOperation(volumeName, RESTConstants.TASK_STOP); } + + public boolean volumeExists(String volumeName) { + try { + // TODO: instead of fetching full volume name, fetch list of volumes and check if + // it contains our volume name + getVolume(volumeName); + return true; + } catch(Exception e) { + return false; + } + } public void setVolumeOption(String volume, String key, String value) { Form form = new Form(); @@ -89,23 +101,22 @@ public class VolumesClient extends AbstractClient { putRequest(volume + "/" + RESTConstants.RESOURCE_OPTIONS); } - public VolumeListResponse getAllVolumes() { - return (VolumeListResponse) fetchResource(VolumeListResponse.class); + public List getAllVolumes() { + return ((VolumeListResponse) fetchResource(VolumeListResponse.class)).getVolumes(); } - @SuppressWarnings("unchecked") - public GenericResponse getVolume(String volumeName) { - return (GenericResponse)fetchSubResource(volumeName, GenericResponse.class); + public Volume getVolume(String volumeName) { + return (Volume)fetchSubResource(volumeName, Volume.class); } - public Status deleteVolume(Volume volume, boolean deleteOption) { + public void deleteVolume(Volume volume, boolean deleteOption) { MultivaluedMap queryParams = prepareDeleteVolumeQueryParams(deleteOption); - return (Status) deleteSubResource(volume.getName(), Status.class, queryParams); + deleteSubResource(volume.getName(), queryParams); } - public VolumeOptionInfoListResponse getVolumeOptionsDefaults() { + public List getVolumeOptionsDefaults() { return ((VolumeOptionInfoListResponse) fetchSubResource(RESTConstants.RESOURCE_DEFAULT_OPTIONS, - VolumeOptionInfoListResponse.class)); + VolumeOptionInfoListResponse.class)).getOptions(); } public void addBricks(String volumeName, List brickList) { @@ -134,23 +145,23 @@ public class VolumesClient extends AbstractClient { * Number of most recent log messages to be fetched (from each disk) * @return Log Message List response received from the Gluster Management Server. */ - public LogMessageListResponse getLogs(String volumeName, String brickName, String severity, Date fromTimestamp, + public List getLogs(String volumeName, String brickName, String severity, Date fromTimestamp, Date toTimestamp, int messageCount) { MultivaluedMap queryParams = prepareGetLogQueryParams(brickName, severity, fromTimestamp, toTimestamp, messageCount); - return (LogMessageListResponse) fetchSubResource(volumeName + "/" + RESTConstants.RESOURCE_LOGS, - queryParams, LogMessageListResponse.class); + return ((LogMessageListResponse) fetchSubResource(volumeName + "/" + RESTConstants.RESOURCE_LOGS, + queryParams, LogMessageListResponse.class)).getLogMessages(); } public void downloadLogs(String volumeName, String filePath) { downloadSubResource(volumeName + "/" + RESTConstants.RESOURCE_LOGS + "/" + RESTConstants.RESOURCE_DOWNLOAD, filePath); } - public Status removeBricks(String volumeName, List BrickList, boolean deleteOption) { + public void removeBricks(String volumeName, List BrickList, boolean deleteOption) { String bricks = StringUtil.ListToString(GlusterCoreUtil.getQualifiedBrickList(BrickList), ","); MultivaluedMap queryParams = prepareRemoveBrickQueryParams(volumeName, bricks, deleteOption); - return (Status) deleteSubResource(volumeName + "/" + RESTConstants.RESOURCE_BRICKS, Status.class, queryParams); + deleteSubResource(volumeName + "/" + RESTConstants.RESOURCE_BRICKS, queryParams); } private MultivaluedMap prepareRemoveBrickQueryParams(String volumeName, String bricks, @@ -199,41 +210,15 @@ public class VolumesClient extends AbstractClient { form.add(RESTConstants.FORM_PARAM_OPERATION, RESTConstants.TASK_START); form.add(RESTConstants.FORM_PARAM_AUTO_COMMIT, autoCommit); - putRequest( volumeName + "/" + RESTConstants.RESOURCE_BRICKS, form); + putRequest(volumeName + "/" + RESTConstants.RESOURCE_BRICKS, form); } public static void main(String[] args) { UsersClient usersClient = new UsersClient(); if (usersClient.authenticate("gluster", "gluster").isSuccess()) { VolumesClient client = new VolumesClient(usersClient.getSecurityToken()); -// List disks = new ArrayList(); -// Disk diskElement = new Disk(); -// diskElement.setName("sda1"); -// diskElement.setStatus(DISK_STATUS.READY); -// disks.add(diskElement); -// diskElement.setName("sda2"); -// diskElement.setStatus(DISK_STATUS.READY); -// disks.add(diskElement); -// -// Volume vol = new Volume("vol1", null, Volume.VOLUME_TYPE.PLAIN_DISTRIBUTE, Volume.TRANSPORT_TYPE.ETHERNET, -// Volume.VOLUME_STATUS.ONLINE); -// // vol.setDisks(disks); -// System.out.println(client.createVolume(vol)); -// for (VolumeOptionInfo option : client.getVolumeOptionsDefaults()) { -// System.out.println(option.getName() + "-" + option.getDescription() + "-" + option.getDefaultValue()); -// } -// System.out.println(client.getVolume("Volume3").getOptions()); -// System.out.println(client.setVolumeOption("Volume3", "network.frame-timeout", "600").getMessage()); -// List disks = new ArrayList(); -// Disk disk = new Disk(); -// disk.setServerName("server1"); -// disk.setName("sda"); -// disk.setStatus(DISK_STATUS.READY); -// disks.add(disk); -// -// Status status = client.addDisks("Volume3", disks); -// System.out.println(status.getMessage()); - client.downloadLogs("vol1", "/tmp/temp1.tar.gz"); + System.out.println(client.getAllVolumes()); +// client.downloadLogs("vol1", "/tmp/temp1.tar.gz"); } } } -- cgit