예제 #1
0
  /**
   * 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");
  }
예제 #2
0
  /**
   * Gets token from Keystone. It is a synchronous operation.
   *
   * @param uri String
   * @return token String
   */
  public String getAuthToken(String uri) {

    String token = "";
    String tenantId = "";
    Gson gson = new Gson();

    AuthTokenRequest w = new AuthTokenRequest();
    w.auth.passwordCredentials.username = endPoint.getCinderRESTuserName();
    w.auth.passwordCredentials.password = endPoint.getCinderRESTPassword();
    w.auth.tenantName = endPoint.getCinderTenantName();
    String json = gson.toJson(w);

    try {
      ClientResponse js_response = client.post(URI.create(uri), json);
      String s = js_response.getEntity(String.class);
      AccessWrapper wrapper = gson.fromJson(s, AccessWrapper.class);
      token = wrapper.access.token.id;
      tenantId = wrapper.access.token.tenant.id;
    } catch (Exception e) {
      _log.error("Exception!! \n Now trying String processing....\n");
      ClientResponse js_response = client.post(URI.create(uri), json);
      String s = js_response.getEntity(String.class);

      token = getTokenId(s);
      tenantId = getTenantId(s);
    } /* catch */

    // Update it in endPoint instance for every fetch/re-fetch
    endPoint.setCinderToken(token);
    getClient().setAuthTokenHeader(token);
    endPoint.setCinderTenantId(tenantId);

    return token;
  }
예제 #3
0
  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");
  }
예제 #4
0
  /**
   * 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;
  }
예제 #5
0
  /**
   * 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;
  }
예제 #6
0
  /**
   * 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;
  }
예제 #7
0
  /**
   * 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;
  }
예제 #8
0
  /**
   * 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;
  }
예제 #9
0
  /**
   * 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;
  }
예제 #10
0
  /**
   * 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");
  }
예제 #11
0
 /**
  * Create Cinder API client
  *
  * @param provider Storage Provider URI
  * @param client Jersey Client
  * @return
  */
 public CinderApi(CinderEndPointInfo endPointInfo, Client client) {
   endPoint = endPointInfo;
   this.client = new CinderRESTClient(client, endPointInfo.getCinderToken());
 }
예제 #12
0
  /**
   * 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;
  }