org.jclouds.glesys.compute.GleSYSComputeServiceAdapter.java Source code

Java tutorial

Introduction

Here is the source code for org.jclouds.glesys.compute.GleSYSComputeServiceAdapter.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.glesys.compute;

import static com.google.common.base.Charsets.UTF_8;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.contains;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.find;
import static com.google.common.io.BaseEncoding.base16;
import static org.jclouds.compute.util.ComputeServiceUtils.metadataAndTagsAsCommaDelimitedValue;
import static org.jclouds.concurrent.FutureIterables.transformParallel;
import static org.jclouds.util.Predicates2.retry;

import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;

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

import org.jclouds.Constants;
import org.jclouds.collect.Memoized;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.HardwareBuilder;
import org.jclouds.compute.domain.Processor;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.Volume;
import org.jclouds.compute.domain.internal.VolumeImpl;
import org.jclouds.compute.predicates.ImagePredicates;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
import org.jclouds.domain.Location;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.glesys.GleSYSApi;
import org.jclouds.glesys.GleSYSAsyncApi;
import org.jclouds.glesys.compute.options.GleSYSTemplateOptions;
import org.jclouds.glesys.domain.AllowedArgumentsForCreateServer;
import org.jclouds.glesys.domain.OSTemplate;
import org.jclouds.glesys.domain.Server;
import org.jclouds.glesys.domain.ServerDetails;
import org.jclouds.glesys.domain.ServerSpec;
import org.jclouds.glesys.options.CreateServerOptions;
import org.jclouds.glesys.options.DestroyServerOptions;
import org.jclouds.location.predicates.LocationPredicates;
import org.jclouds.logging.Logger;

import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;

/**
 * defines the connection between the {@link GleSYSApi} implementation and
 * the jclouds {@link ComputeService}
 * 
 */
@Singleton
public class GleSYSComputeServiceAdapter
        implements ComputeServiceAdapter<ServerDetails, Hardware, OSTemplate, String> {

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

    private final GleSYSApi api;
    private final GleSYSAsyncApi aapi;
    private final ListeningExecutorService userExecutor;
    private final Timeouts timeouts;
    private final Supplier<Set<? extends Location>> locations;

    @Inject
    public GleSYSComputeServiceAdapter(GleSYSApi api, GleSYSAsyncApi aapi,
            @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, Timeouts timeouts,
            @Memoized Supplier<Set<? extends Location>> locations) {
        this.api = checkNotNull(api, "api");
        this.aapi = checkNotNull(aapi, "aapi");
        this.userExecutor = checkNotNull(userExecutor, "userExecutor");
        this.timeouts = checkNotNull(timeouts, "timeouts");
        this.locations = checkNotNull(locations, "locations");
    }

    @Override
    public NodeAndInitialCredentials<ServerDetails> createNodeWithGroupEncodedIntoName(String group, String name,
            Template template) {
        checkNotNull(template, "template was null");
        checkNotNull(template.getOptions(), "template options was null");
        checkArgument(template.getOptions().getClass().isAssignableFrom(GleSYSTemplateOptions.class),
                "options class %s should have been assignable from GleSYSTemplateOptions",
                template.getOptions().getClass());

        GleSYSTemplateOptions templateOptions = template.getOptions().as(GleSYSTemplateOptions.class);

        CreateServerOptions createServerOptions = new CreateServerOptions();
        createServerOptions.ip(templateOptions.getIp());

        Map<String, String> md = metadataAndTagsAsCommaDelimitedValue(template.getOptions());
        if (md.size() > 0) {
            String description = Joiner.on('\n').withKeyValueSeparator("=").join(md);
            // TODO: get glesys to stop stripping out equals and commas!
            createServerOptions.description(base16().lowerCase().encode(description.getBytes(UTF_8)));
        }
        ServerSpec.Builder<?> builder = ServerSpec.builder();
        builder.datacenter(template.getLocation().getId());
        builder.templateName(template.getImage().getId());
        builder.platform(template.getHardware().getHypervisor());
        builder.memorySizeMB(template.getHardware().getRam());
        builder.diskSizeGB(Math.round(template.getHardware().getVolumes().get(0).getSize()));
        builder.cpuCores((int) template.getHardware().getProcessors().get(0).getCores());
        builder.transferGB(templateOptions.getTransferGB());
        ServerSpec spec = builder.build();

        // use random root password unless one was provided via template options
        String password = templateOptions.hasRootPassword() ? templateOptions.getRootPassword()
                : getRandomPassword();

        logger.debug(">> creating new Server spec(%s) name(%s) options(%s)", spec, name, createServerOptions);
        ServerDetails result = api.getServerApi().createWithHostnameAndRootPassword(spec, name, password,
                createServerOptions);
        logger.trace("<< server(%s)", result.getId());

        return new NodeAndInitialCredentials<ServerDetails>(result, result.getId() + "",
                LoginCredentials.builder().password(password).build());
    }

    /**
     * @return a generated random password string
     */
    private String getRandomPassword() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    @Override
    public Iterable<Hardware> listHardwareProfiles() {
        Set<? extends Location> locationsSet = locations.get();
        ImmutableSet.Builder<Hardware> hardwareToReturn = ImmutableSet.builder();

        // do this loop after dupes are filtered, else OOM
        Set<OSTemplate> images = listImages();

        for (Entry<String, AllowedArgumentsForCreateServer> platformToArgs : api.getServerApi()
                .getAllowedArgumentsForCreateByPlatform().entrySet())
            for (String datacenter : platformToArgs.getValue().getDataCenters())
                for (int diskSizeGB : platformToArgs.getValue().getDiskSizesInGB().getAllowedUnits())
                    for (int cpuCores : platformToArgs.getValue().getCpuCoreOptions().getAllowedUnits())
                        for (int memorySizeMB : platformToArgs.getValue().getMemorySizesInMB().getAllowedUnits()) {
                            ImmutableSet.Builder<String> templatesSupportedBuilder = ImmutableSet.builder();
                            for (OSTemplate template : images) {
                                if (template.getPlatform().equals(platformToArgs.getKey())
                                        && diskSizeGB >= template.getMinDiskSize()
                                        && memorySizeMB >= template.getMinMemSize())
                                    templatesSupportedBuilder.add(template.getName());
                            }
                            ImmutableSet<String> templatesSupported = templatesSupportedBuilder.build();
                            if (templatesSupported.size() > 0)
                                hardwareToReturn.add(new HardwareBuilder().ids(String.format(
                                        "datacenter(%s)platform(%s)cpuCores(%d)memorySizeMB(%d)diskSizeGB(%d)",
                                        datacenter, platformToArgs.getKey(), cpuCores, memorySizeMB, diskSizeGB))
                                        .ram(memorySizeMB)
                                        .processors(ImmutableList.of(new Processor(cpuCores, 1.0)))
                                        .volumes(ImmutableList
                                                .<Volume>of(new VolumeImpl((float) diskSizeGB, true, true)))
                                        .hypervisor(platformToArgs.getKey())
                                        .location(find(locationsSet, LocationPredicates.idEquals(datacenter)))
                                        .supportsImage(ImagePredicates.idIn(templatesSupported)).build());
                        }

        return hardwareToReturn.build();
    }

    @Override
    public Set<OSTemplate> listImages() {
        return api.getServerApi().listTemplates().toSet();
    }

    // cheat until we have a getTemplate command
    @Override
    public OSTemplate getImage(final String id) {
        return find(listImages(), new Predicate<OSTemplate>() {

            @Override
            public boolean apply(OSTemplate input) {
                return input.getName().equals(id);
            }

        }, null);
    }

    @Override
    public Iterable<ServerDetails> listNodes() {
        return transformParallel(api.getServerApi().list(),
                new Function<Server, ListenableFuture<? extends ServerDetails>>() {
                    public ListenableFuture<ServerDetails> apply(Server from) {
                        return aapi.getServerApi().get(from.getId());
                    }
                }, userExecutor, null, logger, "server details");
    }

    @Override
    public Iterable<ServerDetails> listNodesByIds(final Iterable<String> ids) {
        return filter(listNodes(), new Predicate<ServerDetails>() {

            @Override
            public boolean apply(ServerDetails server) {
                return contains(ids, server.getId());
            }
        });
    }

    @Override
    public Set<String> listLocations() {
        return FluentIterable.from(api.getServerApi().getAllowedArgumentsForCreateByPlatform().values())
                .transformAndConcat(new Function<AllowedArgumentsForCreateServer, Set<String>>() {
                    @Override
                    public Set<String> apply(AllowedArgumentsForCreateServer arg0) {
                        return arg0.getDataCenters();
                    }
                }).toSet();
    }

    @Override
    public ServerDetails getNode(String id) {
        return api.getServerApi().get(id);
    }

    @Override
    public void destroyNode(String id) {
        retry(new Predicate<String>() {
            public boolean apply(String arg0) {
                try {
                    api.getServerApi().destroy(arg0, DestroyServerOptions.Builder.discardIp());
                    return true;
                } catch (IllegalStateException e) {
                    return false;
                }
            }
        }, timeouts.nodeTerminated).apply(id);
    }

    @Override
    public void rebootNode(String id) {
        api.getServerApi().reboot(id);
    }

    @Override
    public void resumeNode(String id) {
        api.getServerApi().start(id);
    }

    @Override
    public void suspendNode(String id) {
        api.getServerApi().stop(id);
    }
}