@Override
 public CloudResource build(
     OpenStackContext context,
     AuthenticatedContext auth,
     Network network,
     Security security,
     CloudResource resource)
     throws Exception {
   try {
     OSClient osClient = createOSClient(auth);
     NeutronNetworkView networkView = new NeutronNetworkView(network);
     Router router =
         Builders.router()
             .name(resource.getName())
             .adminStateUp(true)
             .tenantId(context.getStringParameter(OpenStackConstants.TENANT_ID))
             .externalGateway(networkView.getPublicNetId())
             .build();
     router = osClient.networking().router().create(router);
     osClient
         .networking()
         .router()
         .attachInterface(
             router.getId(),
             AttachInterfaceType.SUBNET,
             context.getStringParameter(OpenStackConstants.SUBNET_ID));
     return createPersistedResource(resource, router.getId());
   } catch (OS4JException ex) {
     throw new OpenStackResourceException(
         "Router creation failed", resourceType(), resource.getName(), ex);
   }
 }
  @SuppressWarnings("unchecked")
  @Override
  public List<CloudResourceStatus> launch(
      AuthenticatedContext authenticatedContext,
      CloudStack stack,
      PersistenceNotifier notifier,
      AdjustmentType adjustmentType,
      Long threshold) {
    String stackName = authenticatedContext.getCloudContext().getName();
    boolean existingNetwork = isExistingNetwork(stack);
    boolean assignFloatingIp = assignFloatingIp(stack);
    String existingSubnetCidr = getExistingSubnetCidr(authenticatedContext, stack);
    String heatTemplate =
        heatTemplateBuilder.build(
            stackName,
            stack.getGroups(),
            stack.getSecurity(),
            stack.getImage(),
            existingNetwork,
            existingSubnetCidr != null,
            assignFloatingIp);
    Map<String, String> parameters =
        heatTemplateBuilder.buildParameters(
            authenticatedContext,
            stack.getNetwork(),
            stack.getImage(),
            existingNetwork,
            existingSubnetCidr);

    OSClient client = openStackClient.createOSClient(authenticatedContext);

    Stack heatStack =
        client
            .heat()
            .stacks()
            .create(
                Builders.stack()
                    .name(stackName)
                    .template(heatTemplate)
                    .disableRollback(false)
                    .parameters(parameters)
                    .timeoutMins(OPERATION_TIMEOUT)
                    .build());

    CloudResource cloudResource =
        new CloudResource.Builder().type(ResourceType.HEAT_STACK).name(heatStack.getId()).build();
    try {
      notifier.notifyAllocation(cloudResource, authenticatedContext.getCloudContext());
    } catch (Exception e) {
      // Rollback
      terminate(authenticatedContext, stack, Lists.newArrayList(cloudResource));
    }
    List<CloudResourceStatus> resources =
        check(authenticatedContext, Lists.newArrayList(cloudResource));
    LOGGER.debug("Launched resources: {}", resources);
    return resources;
  }
 @Override
 public CloudInstanceMetaData extractMetadata(OSClient client, Server server, String instanceId) {
   String hypervisor = hypervisorExtractor.getHypervisor(server);
   LOGGER.debug("Address map was empty, trying to extract ips");
   List<? extends Port> ports = client.networking().port().list(getPortListOptions(instanceId));
   String portId = ports.get(0).getId();
   List<? extends NetFloatingIP> floatingIps =
       client.networking().floatingip().list(getFloatingIpListOptions(portId));
   NetFloatingIP ips = floatingIps.get(0);
   LOGGER.info("PrivateIp of instance: {} is {}", server.getName(), ips.getFixedIpAddress());
   LOGGER.info("FloatingIp of instance: {} is {}", server.getName(), ips.getFloatingIpAddress());
   return new CloudInstanceMetaData(
       ips.getFixedIpAddress(), ips.getFloatingIpAddress(), hypervisor);
 }
 @Override
 public CloudResource delete(
     OpenStackContext context, AuthenticatedContext auth, CloudResource resource)
     throws Exception {
   try {
     OSClient osClient = createOSClient(auth);
     String subnetId = context.getStringParameter(OpenStackConstants.SUBNET_ID);
     osClient.networking().router().detachInterface(resource.getReference(), subnetId, null);
     ActionResponse response = osClient.networking().router().delete(resource.getReference());
     return checkDeleteResponse(
         response, resourceType(), auth, resource, "Router deletion failed");
   } catch (OS4JException ex) {
     throw new OpenStackResourceException(
         "Router deletion failed", resourceType(), resource.getName(), ex);
   }
 }
 @Override
 protected boolean checkStatus(
     OpenStackContext context, AuthenticatedContext auth, CloudResource resource) {
   CloudContext cloudContext = auth.getCloudContext();
   OSClient osClient = createOSClient(auth);
   Router osRouter = osClient.networking().router().get(resource.getReference());
   if (osRouter != null && context.isBuild()) {
     State routerStatus = osRouter.getStatus();
     if (State.ERROR == routerStatus) {
       throw new OpenStackResourceException(
           "Router in failed state",
           resource.getType(),
           cloudContext.getStackName(),
           cloudContext.getStackId(),
           resource.getName());
     }
     return routerStatus == State.ACTIVE;
   } else if (osRouter == null && !context.isBuild()) {
     return true;
   }
   return false;
 }
  private List<CloudResourceStatus> updateHeatStack(
      AuthenticatedContext authenticatedContext,
      List<CloudResource> resources,
      String heatTemplate,
      Map<String, String> parameters) {
    CloudResource resource = utils.getHeatResource(resources);
    String stackName = authenticatedContext.getCloudContext().getName();
    String heatStackId = resource.getName();

    OSClient client = openStackClient.createOSClient(authenticatedContext);
    StackUpdate updateRequest =
        Builders.stackUpdate()
            .template(heatTemplate)
            .parameters(parameters)
            .timeoutMins(OPERATION_TIMEOUT)
            .build();
    client.heat().stacks().update(stackName, heatStackId, updateRequest);
    LOGGER.info(
        "Heat stack update request sent with stack name: '{}' for Heat stack: '{}'",
        stackName,
        heatStackId);
    return check(authenticatedContext, resources);
  }
  @Override
  public List<CloudResourceStatus> terminate(
      AuthenticatedContext authenticatedContext,
      CloudStack cloudStack,
      List<CloudResource> resources) {

    for (CloudResource resource : resources) {
      switch (resource.getType()) {
        case HEAT_STACK:
          String heatStackId = resource.getName();
          String stackName = authenticatedContext.getCloudContext().getName();
          LOGGER.info("Terminate stack: {}", stackName);
          OSClient client = openStackClient.createOSClient(authenticatedContext);
          client.heat().stacks().delete(stackName, heatStackId);
          break;
        default:
          throw new CloudConnectorException(
              String.format("Invalid resource type: %s", resource.getType()));
      }
    }

    return check(authenticatedContext, resources);
  }
 @Override
 public List<CloudResource> build(
     OpenStackContext context,
     long privateId,
     AuthenticatedContext auth,
     Group group,
     Image image,
     List<CloudResource> buildableResource)
     throws Exception {
   CloudResource resource = buildableResource.get(0);
   try {
     OSClient osClient = createOSClient(auth);
     List<CloudResource> computeResources = context.getComputeResources(privateId);
     CloudResource instance = getInstance(computeResources);
     String pool = osClient.compute().floatingIps().getPoolNames().get(0);
     FloatingIP unusedIp = osClient.compute().floatingIps().allocateIP(pool);
     ActionResponse response =
         osClient
             .compute()
             .floatingIps()
             .addFloatingIP(
                 instance.getParameter(OpenStackConstants.SERVER, Server.class),
                 unusedIp.getFloatingIpAddress());
     if (!response.isSuccess()) {
       throw new OpenStackResourceException(
           "Add floating-ip to server failed",
           resourceType(),
           resource.getName(),
           auth.getCloudContext().getId(),
           response.getFault());
     }
     return Collections.singletonList(createPersistedResource(resource, unusedIp.getId()));
   } catch (OS4JException ex) {
     throw new OpenStackResourceException(
         "Add floating-ip to server failed", resourceType(), resource.getName(), ex);
   }
 }
  @Override
  public List<CloudResourceStatus> check(
      AuthenticatedContext authenticatedContext, List<CloudResource> resources) {
    List<CloudResourceStatus> result = new ArrayList<>();
    OSClient client = openStackClient.createOSClient(authenticatedContext);

    for (CloudResource resource : resources) {
      switch (resource.getType()) {
        case HEAT_STACK:
          String heatStackId = resource.getName();
          String stackName = authenticatedContext.getCloudContext().getName();
          LOGGER.info("Checking OpenStack Heat stack status of: {}", stackName);
          Stack heatStack = client.heat().stacks().getDetails(stackName, heatStackId);
          CloudResourceStatus heatResourceStatus = utils.heatStatus(resource, heatStack);
          result.add(heatResourceStatus);
          break;
        default:
          throw new CloudConnectorException(
              String.format("Invalid resource type: %s", resource.getType()));
      }
    }

    return result;
  }