All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jclouds.vcloud.compute.strategy.VCloudComputeServiceAdapter Maven / Gradle / Ivy

/**
 * Licensed to jclouds, Inc. (jclouds) under one or more
 * contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  jclouds licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.jclouds.vcloud.compute.strategy;

import static com.google.common.base.Preconditions.checkNotNull;

import java.net.URI;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;

import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.domain.Location;
import org.jclouds.logging.Logger;
import org.jclouds.ovf.Envelope;
import org.jclouds.vcloud.TaskInErrorStateException;
import org.jclouds.vcloud.TaskStillRunningException;
import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.VCloudMediaType;
import org.jclouds.vcloud.compute.suppliers.OrgAndVDCToLocationSupplier;
import org.jclouds.vcloud.domain.Org;
import org.jclouds.vcloud.domain.ReferenceType;
import org.jclouds.vcloud.domain.Status;
import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.VApp;
import org.jclouds.vcloud.domain.VAppTemplate;
import org.jclouds.vcloud.suppliers.VAppTemplatesSupplier;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.ImmutableSet.Builder;

/**
 * defines the connection between the {@link VCloudClient} implementation and the jclouds
 * {@link ComputeService}
 * 
 */
@Singleton
public class VCloudComputeServiceAdapter implements ComputeServiceAdapter {

   @Resource
   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
   protected Logger logger = Logger.NULL;

   protected final VCloudClient client;
   protected final Predicate successTester;
   protected final InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn booter;
   protected final Supplier> nameToOrg;
   protected final Supplier> templates;
   protected final Function templateToEnvelope;
   protected final Supplier> locations;

   @Inject
   protected VCloudComputeServiceAdapter(VCloudClient client, Predicate successTester,
            InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn booter,
            Supplier> nameToOrg, VAppTemplatesSupplier templates,
            Function templateToEnvelope, OrgAndVDCToLocationSupplier locations) {
      this.client = checkNotNull(client, "client");
      this.successTester = checkNotNull(successTester, "successTester");
      this.booter = checkNotNull(booter, "booter");
      this.nameToOrg = checkNotNull(nameToOrg, "nameToOrg");
      this.templates = checkNotNull(templates, "templates");
      this.templateToEnvelope = checkNotNull(templateToEnvelope, "templateToEnvelope");
      this.locations = checkNotNull(locations, "locations");
   }

   @Override
   public NodeAndInitialCredentials createNodeWithGroupEncodedIntoName(String group, String name,
            Template template) {
      return booter.createNodeWithGroupEncodedIntoName(group, name, template);
   }

   @Override
   public Iterable listHardwareProfiles() {
      return supportedTemplates();
   }

   private Iterable supportedTemplates() {
      return Iterables.filter(templates.get(), new Predicate() {

         @Override
         public boolean apply(VAppTemplate from) {
            try {
               templateToEnvelope.apply(from);
            } catch (IllegalArgumentException e){
               logger.warn("Unsupported: "+ e.getMessage());
               return false;
            }
            return true;
         }

      });
   }

   @Override
   public Iterable listImages() {
      return supportedTemplates();
   }

   @Override
   public Iterable listNodes() {
      // TODO: parallel or cache
      Builder nodes = ImmutableSet. builder();
      for (Org org : nameToOrg.get().values()) {
         for (ReferenceType vdc : org.getVDCs().values()) {
            for (ReferenceType resource : client.getVDCClient().getVDC(vdc.getHref()).getResourceEntities().values()) {
               if (resource.getType().equals(VCloudMediaType.VAPP_XML)) {
                  addVAppToSetRetryingIfNotYetPresent(nodes, vdc, resource);
               }
            }
         }
      }
      return nodes.build();
   }

   @VisibleForTesting
   void addVAppToSetRetryingIfNotYetPresent(Builder nodes, ReferenceType vdc, ReferenceType resource) {
      VApp node = null;
      int i = 0;
      while (node == null && i++ < 3) {
         try {
            node = client.getVAppClient().getVApp(resource.getHref());
            nodes.add(node);
         } catch (NullPointerException e) {
            logger.warn("vApp %s not yet present in vdc %s", resource.getName(), vdc.getName());
         }
      }
   }

   @SuppressWarnings("unchecked")
   @Override
   public Iterable listLocations() {
      return (Iterable) locations.get();
   }

   @Override
   public VApp getNode(String in) {
      URI id = URI.create(in);
      return client.getVAppClient().getVApp(id);
   }

   @Override
   public void destroyNode(String id) {
      URI vappId = URI.create(checkNotNull(id, "node.id"));
      VApp vApp = cancelAnyRunningTasks(vappId);
      if (vApp.getStatus() != Status.OFF) {
         logger.debug(">> powering off VApp vApp(%s), current status: %s", vApp.getName(), vApp.getStatus());
         try {
            waitForTask(client.getVAppClient().powerOffVApp(vApp.getHref()));
            vApp = client.getVAppClient().getVApp(vApp.getHref());
            logger.debug("<< %s vApp(%s)", vApp.getStatus(), vApp.getName());
         } catch (IllegalStateException e) {
            logger.warn(e, "<< %s vApp(%s)", vApp.getStatus(), vApp.getName());
         }
         logger.debug(">> undeploying vApp(%s), current status: %s", vApp.getName(), vApp.getStatus());
         try {
            waitForTask(client.getVAppClient().undeployVApp(vApp.getHref()));
            vApp = client.getVAppClient().getVApp(vApp.getHref());
            logger.debug("<< %s vApp(%s)", vApp.getStatus(), vApp.getName());
         } catch (IllegalStateException e) {
            logger.warn(e, "<< %s vApp(%s)", vApp.getStatus(), vApp.getName());
         }
      }
      logger.debug(">> deleting vApp(%s)", vApp.getHref());
      waitForTask(client.getVAppClient().deleteVApp(vApp.getHref()));
      logger.debug("<< deleted vApp(%s)", vApp.getHref());
   }

   VApp waitForPendingTasksToComplete(URI vappId) {
      VApp vApp = client.getVAppClient().getVApp(vappId);
      if (vApp.getTasks().size() == 0)
         return vApp;
      for (Task task : vApp.getTasks())
         waitForTask(task);
      return client.getVAppClient().getVApp(vappId);
   }

   VApp cancelAnyRunningTasks(URI vappId) {
      VApp vApp = client.getVAppClient().getVApp(vappId);
      if (vApp.getTasks().size() == 0)
         return vApp;
      for (Task task : vApp.getTasks()) {
         try {
            client.getTaskClient().cancelTask(task.getHref());
            waitForTask(task);
         } catch (TaskInErrorStateException e) {
         }
      }
      return client.getVAppClient().getVApp(vappId);

   }

   public void waitForTask(Task task) {
      if (!successTester.apply(task.getHref())) 
         throw new TaskStillRunningException(task);
   }

   @Override
   public void rebootNode(String in) {
      URI id = URI.create(checkNotNull(in, "node.id"));
      waitForTask(client.getVAppClient().resetVApp(id));
   }

   @Override
   public void resumeNode(String in) {
      URI id = URI.create(checkNotNull(in, "node.id"));
      waitForTask(client.getVAppClient().powerOnVApp(id));
   }

   @Override
   public void suspendNode(String in) {
      URI id = URI.create(checkNotNull(in, "node.id"));
      waitForTask(client.getVAppClient().powerOffVApp(id));
   }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy