public void createUpdateVcenterClusterOperation(
      boolean createCluster, URI vcenterId, URI vcenterDataCenterId, URI clusterId, String stepId) {
    VcenterApiClient vcenterApiClient = null;
    try {
      WorkflowStepCompleter.stepExecuting(stepId);

      VcenterDataCenter vcenterDataCenter =
          _dbClient.queryObject(VcenterDataCenter.class, vcenterDataCenterId);
      Cluster cluster = _dbClient.queryObject(Cluster.class, clusterId);
      Vcenter vcenter = _dbClient.queryObject(Vcenter.class, vcenterId);

      vcenterApiClient = new VcenterApiClient(_coordinator.getPropertyInfo());
      vcenterApiClient.setup(vcenter.getIpAddress(), vcenter.getUsername(), vcenter.getPassword());
      String vcenterClusterId = null;
      if (createCluster) {
        _log.info("Create cluster with name " + cluster.getLabel());
        vcenterClusterId =
            vcenterApiClient.createCluster(vcenterDataCenter.getLabel(), cluster.getLabel());
      } else {
        // Use MoRef if present but don't stop if we fail to find cluster based off this because
        // we'll fall back and try on name
        String externalId = cluster.getExternalId();
        if (externalId != null && !externalId.trim().equals("")) {
          _log.info("Update cluster with MoRef " + externalId);
          try {
            vcenterClusterId =
                vcenterApiClient.updateCluster(vcenterDataCenter.getLabel(), externalId);
          } catch (VcenterObjectNotFoundException e) {
            _log.info(
                "Ignore VcenterObjectNotFoundException updateCluster when using MoRef... Try name based search next");
          }
        }
        if (vcenterClusterId == null) {
          _log.info("Update cluster with name " + cluster.getLabel());
          vcenterClusterId =
              vcenterApiClient.updateCluster(vcenterDataCenter.getLabel(), cluster.getLabel());
        }
      }
      _log.info(
          "Successfully created or updated cluster " + cluster.getLabel() + " " + vcenterClusterId);

      cluster.setVcenterDataCenter(vcenterDataCenter.getId());
      cluster.setExternalId(vcenterClusterId);
      _dbClient.updateAndReindexObject(cluster);

      WorkflowStepCompleter.stepSucceded(stepId);
    } catch (Exception e) {
      _log.error("createUpdateVcenterClusterOperation exception " + e);
      WorkflowStepCompleter.stepFailed(
          stepId,
          VcenterControllerException.exceptions.clusterException(e.getLocalizedMessage(), e));
    } finally {
      if (vcenterApiClient != null) vcenterApiClient.destroy();
    }
  }
  @Override
  protected void complete(DbClient dbClient, Status status, ServiceCoded coded)
      throws DeviceControllerException {
    if (isNotifyWorkflow()) {
      // If there is a workflow, update the step to complete.
      updateWorkflowStatus(status, coded);
    }

    // if export updates were successful, remove all old initiators and deleted hosts
    if (status.equals(Status.ready)) {
      for (HostStateChange hostChange : changes) {
        for (URI initiatorId : hostChange.getOldInitiators()) {
          Initiator initiator = dbClient.queryObject(Initiator.class, initiatorId);
          dbClient.markForDeletion(initiator);
          _logger.info("Initiator marked for deletion: " + this.getId());
        }
      }

      for (URI hostId : deletedHosts) {
        Host host = dbClient.queryObject(Host.class, hostId);
        // don't delete host if it was provisioned by Vipr
        if (!NullColumnValueGetter.isNullURI(host.getComputeElement())) {
          _logger.info(
              "do not delete provisioned host {} - disassociate it from vcenter", host.getLabel());
          host.setVcenterDataCenter(NullColumnValueGetter.getNullURI());
          dbClient.persistObject(host);
        } else {
          ComputeSystemHelper.doDeactivateHost(dbClient, host);
          _logger.info("Deactivating Host: " + host.getId());
        }
      }

      for (URI clusterId : deletedClusters) {
        Cluster cluster = dbClient.queryObject(Cluster.class, clusterId);
        List<URI> clusterHosts =
            ComputeSystemHelper.getChildrenUris(dbClient, clusterId, Host.class, "cluster");
        // don't delete cluster if all hosts weren't deleted (ex: hosts provisioned by ViPR)
        if (!clusterHosts.isEmpty()) {
          _logger.info(
              "do not delete cluster {} - it still has hosts - disassociate it from vcenter",
              cluster.getLabel());
          cluster.setVcenterDataCenter(NullColumnValueGetter.getNullURI());
          cluster.setExternalId(NullColumnValueGetter.getNullStr());
          dbClient.persistObject(cluster);
        } else {
          ComputeSystemHelper.doDeactivateCluster(dbClient, cluster);
          _logger.info("Deactivating Cluster: " + cluster.getId());
        }
      }
    }
  }