com.cloudera.director.aws.ec2.VirtualizationMappings.java Source code

Java tutorial

Introduction

Here is the source code for com.cloudera.director.aws.ec2.VirtualizationMappings.java

Source

// (c) Copyright 2015 Cloudera, Inc.
//
// 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 com.cloudera.director.aws.ec2;

import static com.cloudera.director.aws.ec2.VirtualizationMappings.VirtualizationMappingsConfigProperties.VirtualizationMappingsConfigurationPropertyToken.CUSTOM_MAPPINGS_PATH;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

import com.cloudera.director.aws.common.PropertyResolvers;
import com.cloudera.director.spi.v1.model.ConfigurationProperty;
import com.cloudera.director.spi.v1.model.Configured;
import com.cloudera.director.spi.v1.model.LocalizationContext;
import com.cloudera.director.spi.v1.model.util.ChildLocalizationContext;
import com.cloudera.director.spi.v1.model.util.SimpleConfiguration;
import com.cloudera.director.spi.v1.model.util.SimpleConfigurationPropertyBuilder;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Maps;
import com.google.common.io.Files;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;

import javax.annotation.Nonnull;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.PropertyResolver;

/**
 * Maps a virtualization type to the instance types that support it. EC2 does
 * not provide a means through the API to discover mappings. This class looks up
 * mappings using a built-in list and an override list that the user can easily
 * modify.
 */
public class VirtualizationMappings implements Function<String, List<String>> {

    private static final Logger LOG = LoggerFactory.getLogger(VirtualizationMappings.class);

    private static final Splitter SPLITTER = Splitter.on(',').trimResults();
    private static final Joiner JOINER = Joiner.on(',');

    public static class VirtualizationMappingsConfigProperties {

        /**
         * Virtualization mappings configuration properties.
         */
        // Fully qualifying class name due to compiler bug
        public static enum VirtualizationMappingsConfigurationPropertyToken
                implements com.cloudera.director.spi.v1.model.ConfigurationPropertyToken {

            /**
             * Path for the custom virtualization mappings file. Relative paths are
             * based on the plugin configuration directory.
             */
            CUSTOM_MAPPINGS_PATH(new SimpleConfigurationPropertyBuilder().configKey("customMappingsPath")
                    .name("Custom mappings path")
                    .defaultDescription("The path for the custom virtualization mappings file. Relative "
                            + "paths are based on the plugin configuration directory.")
                    .build());

            /**
             * The configuration property.
             */
            private final ConfigurationProperty configurationProperty;

            /**
             * Creates a configuration property token with the specified parameters.
             *
             * @param configurationProperty the configuration property
             */
            private VirtualizationMappingsConfigurationPropertyToken(ConfigurationProperty configurationProperty) {
                this.configurationProperty = configurationProperty;
            }

            @Override
            public ConfigurationProperty unwrap() {
                return configurationProperty;
            }
        }

        public static final String DEFAULT_CUSTOM_MAPPINGS_PATH = "ec2.virtualizationmappings.properties";

        private final File configurationDirectory;

        private String customMappingsPath = DEFAULT_CUSTOM_MAPPINGS_PATH;

        /**
         * Creates virtualization mappings config properties with the specified parameters.
         *
         * @param configuration            the configuration
         * @param configurationDirectory   the plugin configuration directory
         * @param cloudLocalizationContext the parent cloud localization context
         */
        public VirtualizationMappingsConfigProperties(Configured configuration, File configurationDirectory,
                LocalizationContext cloudLocalizationContext) {
            this.configurationDirectory = configurationDirectory;
            LocalizationContext localizationContext = new ChildLocalizationContext(cloudLocalizationContext,
                    "virtualizationMappings");
            setCustomMappingsPath(configuration.getConfigurationValue(CUSTOM_MAPPINGS_PATH, localizationContext));
        }

        public String getCustomMappingsPath() {
            return customMappingsPath;
        }

        File getCustomMappingsFile() {
            return getCustomMappingsFile(customMappingsPath);
        }

        File getCustomMappingsFile(String customMappingsPath) {
            File customMappingsPathFile = new File(customMappingsPath);
            return customMappingsPathFile.isAbsolute() ? customMappingsPathFile
                    : new File(configurationDirectory, customMappingsPath);
        }

        public void setCustomMappingsPath(String customMappingsPath) {
            if (customMappingsPath != null) {
                LOG.info("Overriding customMappingsPath=%s (default {})", customMappingsPath,
                        DEFAULT_CUSTOM_MAPPINGS_PATH);
                checkArgument(getCustomMappingsFile(customMappingsPath).exists(),
                        "Custom virtualization mappings path " + customMappingsPath + " does not exist");
                this.customMappingsPath = customMappingsPath;
            }
        }
    }

    public static class VirtualizationMappingsConfig {

        public static final String BUILT_IN_LOCATION = "classpath:/com/cloudera/director/aws/ec2/virtualizationmappings.properties";

        protected VirtualizationMappingsConfigProperties virtualizationMappingsConfigProperties;

        public PropertyResolver virtualizationMappingsResolver() {
            try {
                return PropertyResolvers.newMultiResourcePropertyResolver(BUILT_IN_LOCATION,
                        "file:" + virtualizationMappingsConfigProperties.getCustomMappingsFile().getAbsolutePath());
            } catch (IOException e) {
                throw new IllegalArgumentException("Could not load custom virtualization mappings", e);
            }
        }

        /**
         * Creates an virtualization mappings config with the specified parameters.
         *
         * @param virtualizationMappingsConfigProperties the config properties
         */
        public VirtualizationMappingsConfig(
                VirtualizationMappingsConfigProperties virtualizationMappingsConfigProperties) {
            this.virtualizationMappingsConfigProperties = virtualizationMappingsConfigProperties;
        }
    }

    VirtualizationMappingsConfigProperties virtualizationMappingsConfigProperties;

    PropertyResolver virtualizationMappingsResolver;

    /**
     * Creates virtualization mappings with the specified parameters.
     *
     * @param configuration               the configuration
     * @param configurationDirectory      the plugin configuration directory
     * @param localizationContext         the localization context
     */
    public VirtualizationMappings(Configured configuration, File configurationDirectory,
            LocalizationContext localizationContext) {
        this(new VirtualizationMappingsConfigProperties(configuration, configurationDirectory,
                localizationContext));
    }

    /**
     * Creates virtualization mappings with the specified parameters.
     *
     * @param virtualizationMappingsConfigProperties the config properties
     */
    public VirtualizationMappings(VirtualizationMappingsConfigProperties virtualizationMappingsConfigProperties) {
        this(virtualizationMappingsConfigProperties,
                new VirtualizationMappingsConfig(virtualizationMappingsConfigProperties)
                        .virtualizationMappingsResolver());
    }

    /**
     * Creates virtualization mappings with the specified parameters.
     *
     * @param virtualizationMappingsConfigProperties the config properties
     * @param virtualizationMappingsResolver         the virtualization mappings resolver
     */
    private VirtualizationMappings(VirtualizationMappingsConfigProperties virtualizationMappingsConfigProperties,
            PropertyResolver virtualizationMappingsResolver) {
        this.virtualizationMappingsConfigProperties = virtualizationMappingsConfigProperties;
        this.virtualizationMappingsResolver = virtualizationMappingsResolver;
    }

    /**
     * Gets the instance types that support the given virtualization type.
     *
     * @param virtualizationType virtualization type
     * @return list of instance types
     * @throws IllegalArgumentException if the virtualization type is unknown
     */
    @Nonnull
    public List<String> apply(String virtualizationType) {
        checkNotNull(virtualizationType, "virtualizationType is null");
        String instanceTypeList = virtualizationMappingsResolver.getProperty(virtualizationType);
        if (instanceTypeList == null) {
            throw new IllegalArgumentException("Unknown virtualization type " + virtualizationType);
        }
        return SPLITTER.splitToList(instanceTypeList);
    }

    /**
     * Gets a test instance of this class that uses only the given mapping.
     *
     * @param instanceTypes       map of virtualization types to instance types
     * @param localizationContext the localization context
     * @return new mapping object
     */
    public static VirtualizationMappings getTestInstance(final Map<String, List<String>> instanceTypes,
            LocalizationContext localizationContext) {
        Map<String, String> propertyMap = Maps.transformValues(instanceTypes, new Function<List<String>, String>() {
            @Override
            public String apply(@Nonnull List<String> input) {
                return JOINER.join(input);
            }
        });
        PropertyResolver virtualizationMappingsResolver = PropertyResolvers.newMapPropertyResolver(propertyMap);
        File tempDir = Files.createTempDir();
        tempDir.deleteOnExit();
        VirtualizationMappingsConfigProperties virtualizationMappingsConfigProperties = new VirtualizationMappingsConfigProperties(
                new SimpleConfiguration(), tempDir, localizationContext);
        return new VirtualizationMappings(virtualizationMappingsConfigProperties, virtualizationMappingsResolver);
    }
}