org.jclouds.gogrid.compute.strategy.GoGridComputeServiceAdapter.java Source code

Java tutorial

Introduction

Here is the source code for org.jclouds.gogrid.compute.strategy.GoGridComputeServiceAdapter.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF 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.gogrid.compute.strategy;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.util.Predicates2.retry;

import java.security.SecureRandom;
import java.util.Set;

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

import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.gogrid.GoGridClient;
import org.jclouds.gogrid.compute.suppliers.GoGridHardwareSupplier;
import org.jclouds.gogrid.domain.Ip;
import org.jclouds.gogrid.domain.IpType;
import org.jclouds.gogrid.domain.Option;
import org.jclouds.gogrid.domain.PowerCommand;
import org.jclouds.gogrid.domain.Server;
import org.jclouds.gogrid.domain.ServerImage;
import org.jclouds.gogrid.options.GetIpListOptions;
import org.jclouds.gogrid.predicates.ServerLatestJobCompleted;
import org.jclouds.logging.Logger;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Throwables;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.primitives.Longs;

/**
 * defines the connection between the {@link GoGridClient} implementation and the jclouds
 * {@link ComputeService}
 * 
 */
@Singleton
public class GoGridComputeServiceAdapter implements ComputeServiceAdapter<Server, Hardware, ServerImage, Option> {

    @Resource
    protected Logger logger = Logger.NULL;

    private final GoGridClient client;
    private final Function<Hardware, String> sizeToRam;
    private final Predicate<Server> serverLatestJobCompleted;
    private final Predicate<Server> serverLatestJobCompletedShort;

    @Inject
    protected GoGridComputeServiceAdapter(GoGridClient client, Function<Hardware, String> sizeToRam,
            Timeouts timeouts) {
        this.client = checkNotNull(client, "client");
        this.sizeToRam = checkNotNull(sizeToRam, "sizeToRam");
        this.serverLatestJobCompleted = retry(new ServerLatestJobCompleted(client.getJobServices()),
                timeouts.nodeRunning * 9l / 10l);
        this.serverLatestJobCompletedShort = retry(new ServerLatestJobCompleted(client.getJobServices()),
                timeouts.nodeRunning * 1l / 10l);
    }

    @Override
    public NodeAndInitialCredentials<Server> createNodeWithGroupEncodedIntoName(String group, String name,
            Template template) {
        Server addedServer = null;
        boolean notStarted = true;
        int numOfRetries = 20;
        GetIpListOptions unassignedIps = new GetIpListOptions().onlyUnassigned()
                .inDatacenter(template.getLocation().getId()).onlyWithType(IpType.PUBLIC);
        // lock-free consumption of a shared resource: IP address pool
        while (notStarted) { // TODO: replace with Predicate-based thread
            // collision avoidance for simplicity
            Set<Ip> availableIps = client.getIpServices().getIpList(unassignedIps);
            if (availableIps.isEmpty())
                throw new RuntimeException("No IPs available on this identity.");
            int ipIndex = new SecureRandom().nextInt(availableIps.size());
            Ip availableIp = Iterables.get(availableIps, ipIndex);
            try {
                addedServer = addServer(name, template, availableIp);
                notStarted = false;
            } catch (Exception e) {
                if (--numOfRetries == 0)
                    Throwables.propagate(e);
                notStarted = true;
            }
        }
        if (template.getOptions().shouldBlockUntilRunning()) {
            serverLatestJobCompleted.apply(addedServer);
            client.getServerServices().power(addedServer.getName(), PowerCommand.START);
            serverLatestJobCompletedShort.apply(addedServer);
            addedServer = Iterables
                    .getOnlyElement(client.getServerServices().getServersByName(addedServer.getName()));
        }
        LoginCredentials credentials = LoginCredentials
                .fromCredentials(client.getServerServices().getServerCredentialsList().get(addedServer.getName()));
        return new NodeAndInitialCredentials<Server>(addedServer, addedServer.getId() + "", credentials);
    }

    private Server addServer(String name, Template template, Ip availableIp) {
        Server addedServer = client.getServerServices().addServer(name,
                checkNotNull(template.getImage().getProviderId()), sizeToRam.apply(template.getHardware()),
                availableIp.getIp());
        return addedServer;
    }

    @Override
    public Iterable<Hardware> listHardwareProfiles() {
        return GoGridHardwareSupplier.H_ALL;

    }

    @Override
    public Iterable<ServerImage> listImages() {
        return client.getImageServices().getImageList();
    }

    @Override
    public Iterable<Server> listNodes() {
        return client.getServerServices().getServerList();
    }

    @Override
    public Iterable<Server> listNodesByIds(final Iterable<String> ids) {
        Set<Long> idsAsLongs = FluentIterable.from(ids).transform(toLong()).toSet();

        return client.getServerServices().getServersById(Longs.toArray(idsAsLongs));
    }

    @Override
    public Iterable<Option> listLocations() {
        return client.getServerServices().getDatacenters();
    }

    @Override
    public Server getNode(String id) {
        return Iterables.getOnlyElement(
                client.getServerServices().getServersById(Long.valueOf(checkNotNull(id, "id"))), null);
    }

    @Override
    public ServerImage getImage(String id) {
        return Iterables.getOnlyElement(
                client.getImageServices().getImagesById(Long.valueOf(checkNotNull(id, "id"))), null);
    }

    @Override
    public void destroyNode(String id) {
        client.getServerServices().deleteById(Long.valueOf(id));
    }

    @Override
    public void rebootNode(String id) {
        executeCommandOnServer(PowerCommand.RESTART, id);
        Server server = Iterables.getOnlyElement(client.getServerServices().getServersById(Long.valueOf(id)));
        client.getServerServices().power(server.getName(), PowerCommand.START);
        serverLatestJobCompletedShort.apply(server);
    }

    private boolean executeCommandOnServer(PowerCommand command, String id) {
        Server server = Iterables.getOnlyElement(client.getServerServices().getServersById(Long.valueOf(id)));
        client.getServerServices().power(server.getName(), command);
        return serverLatestJobCompleted.apply(server);
    }

    @Override
    public void resumeNode(String id) {
        executeCommandOnServer(PowerCommand.START, id);
    }

    @Override
    public void suspendNode(String id) {
        executeCommandOnServer(PowerCommand.STOP, id);
    }

    private Function<String, Long> toLong() {
        return new Function<String, Long>() {

            @Override
            public Long apply(String id) {
                return Long.valueOf(checkNotNull(id, "id"));
            }
        };
    }
}