org.jclouds.deltacloud.compute.strategy.DeltacloudComputeServiceAdapter.java Source code

Java tutorial

Introduction

Here is the source code for org.jclouds.deltacloud.compute.strategy.DeltacloudComputeServiceAdapter.java

Source

/**
 *
 * Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
 *
 * ====================================================================
 * Licensed 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.deltacloud.compute.strategy;

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

import java.net.URI;
import java.util.Map;
import java.util.concurrent.TimeUnit;

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.deltacloud.DeltacloudClient;
import org.jclouds.deltacloud.domain.HardwareProfile;
import org.jclouds.deltacloud.domain.Instance;
import org.jclouds.deltacloud.domain.PasswordAuthentication;
import org.jclouds.deltacloud.domain.Realm;
import org.jclouds.deltacloud.domain.Transition;
import org.jclouds.deltacloud.domain.TransitionOnAction;
import org.jclouds.deltacloud.domain.Instance.State;
import org.jclouds.deltacloud.options.CreateInstanceOptions;
import org.jclouds.deltacloud.predicates.InstanceFinished;
import org.jclouds.deltacloud.predicates.InstanceRunning;
import org.jclouds.domain.Credentials;
import org.jclouds.http.HttpRequest;
import org.jclouds.logging.Logger;
import org.jclouds.predicates.RetryablePredicate;

import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Multimap;

/**
 * defines the connection between the {@link DeltacloudClient} implementation and the jclouds
 * {@link ComputeService}
 * 
 */
@Singleton
public class DeltacloudComputeServiceAdapter
        implements ComputeServiceAdapter<Instance, HardwareProfile, org.jclouds.deltacloud.domain.Image, Realm> {
    @Resource
    @Named(ComputeServiceConstants.COMPUTE_LOGGER)
    protected Logger logger = Logger.NULL;

    private final org.jclouds.deltacloud.DeltacloudClient client;
    private final ImmutableMap<State, Predicate<Instance>> stateChanges;

    @Inject
    public DeltacloudComputeServiceAdapter(DeltacloudClient client) {
        this.client = checkNotNull(client, "client");
        // TODO: parameterize
        stateChanges = ImmutableMap.<Instance.State, Predicate<Instance>>of(//
                Instance.State.RUNNING,
                new RetryablePredicate<Instance>(new InstanceRunning(client), 600, 1, TimeUnit.SECONDS), //
                Instance.State.FINISH,
                new RetryablePredicate<Instance>(new InstanceFinished(client), 30, 1, TimeUnit.SECONDS)//
        );
    }

    @Override
    public Instance createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name,
            Template template, Map<String, Credentials> credentialStore) {
        Instance instance = client.createInstance(template.getImage().getProviderId(), CreateInstanceOptions.Builder
                .named(name).hardwareProfile(template.getHardware().getId()).realm(template.getLocation().getId()));
        if (instance.getAuthentication() != null
                && instance.getAuthentication() instanceof PasswordAuthentication) {
            Credentials creds = PasswordAuthentication.class.cast(instance.getAuthentication())
                    .getLoginCredentials();
            // store the credentials so that later functions can use them
            credentialStore.put(instance.getHref().toASCIIString(), creds);
        }
        return instance;
    }

    @Override
    public Iterable<HardwareProfile> listHardwareProfiles() {
        return client.listHardwareProfiles();
    }

    @Override
    public Iterable<org.jclouds.deltacloud.domain.Image> listImages() {
        return client.listImages();
    }

    @Override
    public Iterable<Instance> listNodes() {
        return client.listInstances();
    }

    @Override
    public Iterable<Realm> listLocations() {
        return client.listRealms();
    }

    @Override
    public org.jclouds.deltacloud.domain.Instance getNode(String id) {
        return client.getInstance(URI.create(checkNotNull(id, "id")));
    }

    @Override
    public void destroyNode(String id) {
        Instance instance = getNode(id);
        for (Transition transition : findChainTo(Instance.State.FINISH, instance.getState(),
                client.getInstanceStates())) {
            instance = getNode(id);
            if (instance == null)
                break;
            if (transition instanceof TransitionOnAction) {
                client.performAction(
                        instance.getActions().get(TransitionOnAction.class.cast(transition).getAction()));
            }
            Predicate<Instance> stateTester = stateChanges.get(transition.getTo());
            if (stateTester != null)
                stateTester.apply(instance);
            else
                logger.debug(String.format("no state tester for: %s", transition));
        }
    }

    Iterable<Transition> findChainTo(Instance.State desired, Instance.State currentState,
            Multimap<Instance.State, ? extends Transition> states) {
        for (Transition transition : states.get(currentState)) {
            if (currentState.ordinal() >= transition.getTo().ordinal())
                continue;
            if (transition.getTo() == desired)
                return ImmutableSet.<Transition>of(transition);
            Iterable<Transition> transitions = findChainTo(desired, transition.getTo(), states);
            if (Iterables.size(transitions) > 0)
                return Iterables.concat(ImmutableSet.of(transition), transitions);
        }
        return ImmutableSet.<Transition>of();
    }

    @Override
    public void rebootNode(String id) {
        HttpRequest rebootUri = getNode(id).getActions().get(Instance.Action.REBOOT);
        if (rebootUri != null) {
            client.performAction(rebootUri);
        } else {
            throw new UnsupportedOperationException();
        }
    }

    @Override
    public void resumeNode(String id) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void suspendNode(String id) {
        throw new UnsupportedOperationException();
    }
}