public void expandVolume(String volumeId, long new_size) { _log.info("CinderApi - expandVolume START"); Gson gson = new Gson(); VolumeExpandRequest request = new VolumeExpandRequest(); request.extend.new_size = new_size; String expandVolumeUri = endPoint.getBaseUri() + String.format( CinderConstants.URI_VOLUME_ACTION, new Object[] {endPoint.getCinderTenantId(), volumeId}); _log.debug("Expanding volume with uri : {}", expandVolumeUri); String json = gson.toJson(request); _log.debug("Expanding volume with body : {}", json); ClientResponse js_response = getClient().postWithHeader(URI.create(expandVolumeUri), json); String s = js_response.getEntity(String.class); _log.debug("Got the response {}", s); _log.debug("Response status {}", String.valueOf(js_response.getStatus())); if (js_response.getStatus() != ClientResponse.Status.ACCEPTED.getStatusCode()) { // This means volume expand request not accepted throw CinderException.exceptions.volumeExpandFailed(s); } _log.info("CinderApi - expandVolume END"); }
/** * Deletes the Snapshot with the given id.( It is asynchronous operation ) * * @param snapshotId */ public void deleteSnapshot(String snapshotId) { _log.info("CinderApi - start deleteSnapshot"); String deleteSnapshotUri = endPoint.getBaseUri() + String.format( CinderConstants.URI_DELETE_SNAPSHOT, new Object[] {endPoint.getCinderTenantId(), snapshotId}); ClientResponse deleteResponse = getClient().delete(URI.create(deleteSnapshotUri)); String s = deleteResponse.getEntity(String.class); _log.debug("Got the response {}", s); if (deleteResponse.getStatus() == ClientResponse.Status.NOT_FOUND.getStatusCode()) { throw CinderException.exceptions.snapshotNotFound(snapshotId); } if (deleteResponse.getStatus() != ClientResponse.Status.ACCEPTED.getStatusCode()) { throw CinderException.exceptions.snapshotDeleteFailed(s); } _log.info("CinderApi - end deleteSnapshot"); }
/** * Attaches specified volume to the specified initiator on the host. It is a synchronous * operation. * * @param volumeId the volume id * @param initiator the initiator * @param host the host * @return the volume attachment response * @throws Exception the exception */ public VolumeAttachResponse attachVolume( String volumeId, String initiator, String[] wwpns, String host) throws Exception { _log.info("CinderApi - start attachVolume"); Gson gson = new Gson(); VolumeAttachRequest volumeAttach = new VolumeAttachRequest(); if (initiator != null) { volumeAttach.initializeConnection.connector.initiator = initiator; } else if (wwpns != null) { volumeAttach.initializeConnection.connector.wwpns = Arrays.copyOf(wwpns, wwpns.length); } volumeAttach.initializeConnection.connector.host = host; String volumeAttachmentUri = endPoint.getBaseUri() + String.format( CinderConstants.URI_VOLUME_ACTION, new Object[] {endPoint.getCinderTenantId(), volumeId}); _log.debug("attaching volume to initiator with uri {}", volumeAttachmentUri); String json = gson.toJson(volumeAttach); _log.info("attaching volume with body {}", json); ClientResponse js_response = getClient().postWithHeader(URI.create(volumeAttachmentUri), json); String s = js_response.getEntity(String.class); _log.debug("Got the response {}", s); VolumeAttachResponse response = null; _log.debug("Response status {}", String.valueOf(js_response.getStatus())); if (js_response.getStatus() == ClientResponse.Status.OK.getStatusCode()) { // This means volume attachment request accepted and being processed (Synch opr) try { response = gson.fromJson(s, VolumeAttachResponse.class); } catch (JsonSyntaxException ex) { /** * Some drivers return 'target_wwn' as a string list but some returns it as string. We * observed in practice that IBM SVC returning string which could be a faulty one. In such a * case, we capture the response string in an Alternate Java object and return the details * in default response object. */ VolumeAttachResponseAlt altResponse = gson.fromJson(s, VolumeAttachResponseAlt.class); response = getResponseInVolumeAttachResponseFormat(altResponse); } } else { throw CinderException.exceptions.volumeAttachFailed(s); } _log.info("CinderApi - end attachVolume"); return response; }
/** * Gets all volume types present in the OpenStack cinder node. It is a synchronous operation. * * @return */ public VolumeTypes getVolumeTypes() { VolumeTypes volTypes = null; String vol_types_uri = endPoint.getBaseUri() + String.format(CinderConstants.URI_LIST_VOLUME_TYPES, endPoint.getCinderTenantId()); ClientResponse js_response = getClient().get(URI.create(vol_types_uri)); String s = js_response.getEntity(String.class); _log.info("Volume types = {}", s); Gson gson = new Gson(); volTypes = gson.fromJson(s, VolumeTypes.class); return volTypes; }
/** * Returns the list of snapshots on the end point * * <p>It is a synchronous operation. * * @return */ public SnapshotListResponse listSnapshots() { _log.info("CinderApi - start listSnapshots"); SnapshotListResponse listRes = null; String listSnapshotsUri = endPoint.getBaseUri() + String.format( CinderConstants.URI_LIST_SNAPSHOTS, new Object[] {endPoint.getCinderTenantId()}); ClientResponse js_response = getClient().get(URI.create(listSnapshotsUri)); _log.debug( "uri {} : Response status {}", listSnapshotsUri, String.valueOf(js_response.getStatus())); if (js_response.getStatus() == ClientResponse.Status.OK.getStatusCode()) { String jsonString = js_response.getEntity(String.class); listRes = new Gson().fromJson(jsonString, SnapshotListResponse.class); } _log.info("CinderApi - end listSnapshots"); return listRes; }
/** * Gets the Snapshot information. It is a synchronous operation. * * @param snapshotId * @return */ public SnapshotCreateResponse showSnapshot(String snapshotId) throws Exception { _log.info("CinderApi - start showSnapshot"); String showSnapshotUri = endPoint.getBaseUri() + String.format( CinderConstants.URI_DELETE_SNAPSHOT, new Object[] {endPoint.getCinderTenantId(), snapshotId}); ClientResponse js_response = getClient().get(URI.create(showSnapshotUri)); String jsonString = js_response.getEntity(String.class); if (js_response.getStatus() == ClientResponse.Status.NOT_FOUND.getStatusCode()) { throw CinderException.exceptions.snapshotNotFound(snapshotId); } SnapshotCreateResponse snapshotDetails = new Gson().fromJson(jsonString, SnapshotCreateResponse.class); _log.info("CinderApi - end showSnapshot"); return snapshotDetails; }
/** * Create Snapshot operation ( It is asynchronous operation ) * * @param volumeName * @param volumeTypeId * @return * @throws Exception */ public String createSnapshot(String volumeId, String snapshotName) throws Exception { _log.info("CinderApi - start createSnapshot"); Gson gson = new Gson(); VolumeShowResponse volumeDetails = showVolume(volumeId); String volumeName = volumeDetails.volume.name; SnapshotCreateRequest request = new SnapshotCreateRequest(); request.snapshot.name = snapshotName; request.snapshot.description = "Snapshot of volume " + volumeName; request.snapshot.volume_id = volumeId; request.snapshot.force = true; String snapshotCreateUri = endPoint.getBaseUri() + String.format(CinderConstants.URI_CREATE_SNAPSHOT, endPoint.getCinderTenantId()); _log.debug("Creating snapshot with uri : {}", snapshotCreateUri); String json = gson.toJson(request); _log.debug("Creating snapshot with body : {}", json); ClientResponse js_response = getClient().postWithHeader(URI.create(snapshotCreateUri), json); String s = js_response.getEntity(String.class); _log.debug("Got the response {}", s); _log.debug("Response status {}", String.valueOf(js_response.getStatus())); String snapshotId = ""; if (js_response.getStatus() == ClientResponse.Status.ACCEPTED.getStatusCode()) { // This means snapshot creation request accepted SnapshotCreateResponse response = gson.fromJson(s, SnapshotCreateResponse.class); snapshotId = response.snapshot.id; } else { throw CinderException.exceptions.snapshotCreationFailed(s); } return snapshotId; }
/** * Gets the volume information. Its a synchronous operation. * * @param volumeId * @return */ public VolumeShowResponse showVolume(String volumeId) throws Exception { _log.info("CinderApi - start showVolume"); String showVolumeUri = endPoint.getBaseUri() + String.format( CinderConstants.URI_DELETE_VOLUME, new Object[] {endPoint.getCinderTenantId(), volumeId}); ClientResponse js_response = getClient().get(URI.create(showVolumeUri)); _log.debug( "uri {} : Response status {}", showVolumeUri, String.valueOf(js_response.getStatus())); if (js_response.getStatus() == ClientResponse.Status.NOT_FOUND.getStatusCode()) { throw CinderException.exceptions.volumeNotFound(volumeId); } String jsonString = js_response.getEntity(String.class); VolumeShowResponse volumeDetails = new Gson().fromJson(jsonString, VolumeShowResponse.class); _log.info("CinderApi - end showVolume"); return volumeDetails; }
/** * Detaches the specified volume from the specified initiator. It is an asynchronous operation. * * @param volumeId the volume id * @param initiator the initiator * @param host the host * @return the volume attachment response * @throws Exception */ public void detachVolume(String volumeId, String initiator, String[] wwpns, String host) throws Exception { _log.info("CinderApi - start detachVolume"); Gson gson = new Gson(); VolumeDetachRequest volumeDetach = new VolumeDetachRequest(); if (initiator != null) { volumeDetach.terminateConnection.connector.initiator = initiator; } else if (wwpns != null) { volumeDetach.terminateConnection.connector.wwpns = Arrays.copyOf(wwpns, wwpns.length); } volumeDetach.terminateConnection.connector.host = host; String volumeDetachmentUri = endPoint.getBaseUri() + String.format( CinderConstants.URI_DETACH_VOLUME, new Object[] {endPoint.getCinderTenantId(), volumeId}); _log.debug("detaching volume from initiator with uri {}", volumeDetachmentUri); String json = gson.toJson(volumeDetach); _log.info("detaching volume with body {}", json); ClientResponse js_response = getClient().postWithHeader(URI.create(volumeDetachmentUri), json); String s = js_response.getEntity(String.class); _log.debug("Got the response {}", s); _log.debug("Response status {}", String.valueOf(js_response.getStatus())); if (js_response.getStatus() != ClientResponse.Status.ACCEPTED.getStatusCode()) { // if volume is not found on cinder, mark it as passed. if (js_response.getStatus() == ClientResponse.Status.NOT_FOUND.getStatusCode()) { _log.info( "Volume {} is not found on Cinder. It could have been deleted manually.", volumeId); } else { throw CinderException.exceptions.volumeDetachFailed(s); } } _log.info("CinderApi - end detachVolume"); }
/** * Create volume operation ( It is asynchronous operation ) * * @param volumeName : Name of the new volume. * @param capacity : Capacity/Size of the volume * @param volumeTypeName : The volume type/storage system on which new volume should be created. * @param sourceVolId : The volume id that needs to be cloned. * @param sourceSnapId : The snapshot id that needs to be cloned. * @return volumeId of the new volume under creation * @throws Exception */ private String createVolume( String volumeName, long capacity, String volumeTypeId, String sourceVolId, String sourceSnapId) throws Exception { _log.info("CinderApi - start createVolume"); Gson gson = new Gson(); VolumeCreateRequest volumeCreate = new VolumeCreateRequest(); volumeCreate.volume.display_name = volumeName; volumeCreate.volume.size = capacity; // Volume type wont be available in cinder if volumeTypeId starts with "DEFAULT" // In that case, no need to pass volume type id in create volume request. if (!volumeTypeId.toUpperCase().startsWith(CinderConstants.DEFAULT)) { volumeCreate.volume.volume_type = volumeTypeId; } // volume clone if (null != sourceVolId) { volumeCreate.volume.source_volid = sourceVolId; } // create volume from snapshot if (null != sourceSnapId) { volumeCreate.volume.snapshot_id = sourceSnapId; } String volumeCreateUri = endPoint.getBaseUri() + String.format(CinderConstants.URI_CREATE_VOLUME, endPoint.getCinderTenantId()); _log.debug("creting volume with uri {}", volumeCreateUri); String json = gson.toJson(volumeCreate); _log.debug("creating volume with body {}", json); ClientResponse js_response = getClient().postWithHeader(URI.create(volumeCreateUri), json); String s = js_response.getEntity(String.class); _log.debug("Got the response {}", s); String newVolumeId = ""; if (js_response.getStatus() == ClientResponse.Status.ACCEPTED.getStatusCode()) { // This means volume creation request accepted VolumeCreateResponse response = gson.fromJson(s, VolumeCreateResponse.class); newVolumeId = response.volume.id; } else { if (null != sourceVolId) { throw CinderException.exceptions.volumeCloneFailed(s); } if (null != sourceSnapId) { throw CinderException.exceptions.createVolumeFromSnapshotFailed(s); } throw CinderException.exceptions.volumeCreationFailed(s); } _log.info("CinderApi - end createVolume"); return newVolumeId; }