com.cloudera.director.aws.rds.RDSEncryptionInstanceClasses.java Source code

Java tutorial

Introduction

Here is the source code for com.cloudera.director.aws.rds.RDSEncryptionInstanceClasses.java

Source

// (c) Copyright 2016 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.rds;

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

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.annotations.VisibleForTesting;
import com.google.common.base.Function;
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.Nullable;

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

/**
 * A lookup mechanism for RDS encryption instance classes. This class looks up
 * whether an instance class supports storage encryption using a built-in list
 * and an override list that the user can easily modify.
 */
public class RDSEncryptionInstanceClasses implements Function<String, Boolean> {

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

    /**
     * RDS encryption instance classes configuration properties.
     */
    public static enum ConfigurationPropertyToken
            implements com.cloudera.director.spi.v1.model.ConfigurationPropertyToken {

        /**
         * Path for the custom RDS encryption instance classes file. Relative
         * paths are based on the plugin configuration directory.
         */
        CUSTOM_ENCRYPTION_INSTANCE_CLASSES_PATH(new SimpleConfigurationPropertyBuilder()
                .configKey("customEncryptionInstanceClassesPath").name("Custom encryption instance classes path")
                .defaultDescription("The path for the custom list of RDS encryption instance classes. "
                        + "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 ConfigurationPropertyToken(ConfigurationProperty configurationProperty) {
            this.configurationProperty = configurationProperty;
        }

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

    public static class RDSEncryptionInstanceClassesConfigProperties {

        public static final String DEFAULT_CUSTOM_ENCRYPTION_INSTANCE_CLASSES_PATH = "rds.encryptioninstanceclasses.properties";

        private final File configurationDirectory;

        private String customEncryptionInstanceClassesPath = DEFAULT_CUSTOM_ENCRYPTION_INSTANCE_CLASSES_PATH;

        /**
         * Creates RDS encryption instance classes config properties with the
         * specified parameters.
         *
         * @param configuration            the configuration
         * @param configurationDirectory   the plugin configuration directory
         * @param cloudLocalizationContext the parent cloud localization context
         */
        public RDSEncryptionInstanceClassesConfigProperties(Configured configuration, File configurationDirectory,
                LocalizationContext cloudLocalizationContext) {
            this.configurationDirectory = configurationDirectory;
            LocalizationContext localizationContext = new ChildLocalizationContext(cloudLocalizationContext,
                    "rdsEncryptionInstanceClasses");
            setCustomEncryptionInstanceClassesPath(configuration.getConfigurationValue(
                    ConfigurationPropertyToken.CUSTOM_ENCRYPTION_INSTANCE_CLASSES_PATH, localizationContext));
        }

        @VisibleForTesting
        String getCustomEncryptionInstanceClassesPath() {
            return customEncryptionInstanceClassesPath;
        }

        File getCustomEncryptionInstanceClassesFile() {
            return getCustomEncryptionInstanceClassesFile(customEncryptionInstanceClassesPath);
        }

        private File getCustomEncryptionInstanceClassesFile(String customEncryptionInstanceClassesPath) {
            File customEncryptionInstanceClassesPathFile = new File(customEncryptionInstanceClassesPath);
            return customEncryptionInstanceClassesPathFile.isAbsolute() ? customEncryptionInstanceClassesPathFile
                    : new File(configurationDirectory, customEncryptionInstanceClassesPath);
        }

        public final void setCustomEncryptionInstanceClassesPath(String customEncryptionInstanceClassesPath) {
            if (customEncryptionInstanceClassesPath != null) {
                LOG.info("Overriding customEncryptionInstanceClassesPath={} (default {})",
                        customEncryptionInstanceClassesPath, DEFAULT_CUSTOM_ENCRYPTION_INSTANCE_CLASSES_PATH);
                checkArgument(getCustomEncryptionInstanceClassesFile(customEncryptionInstanceClassesPath).exists(),
                        "Custom RDS encryption instance classes path " + customEncryptionInstanceClassesPath
                                + " does not exist");
                this.customEncryptionInstanceClassesPath = customEncryptionInstanceClassesPath;
            }
        }
    }

    private static final String BUILT_IN_LOCATION = "classpath:/com/cloudera/director/aws/rds/encryptioninstanceclasses.properties";

    private static PropertyResolver getResolver(RDSEncryptionInstanceClassesConfigProperties configProperties) {
        try {
            return PropertyResolvers.newMultiResourcePropertyResolver(BUILT_IN_LOCATION,
                    "file:" + configProperties.getCustomEncryptionInstanceClassesFile().getAbsolutePath());
        } catch (IOException e) {
            throw new IllegalArgumentException("Could not load custom encryption instance classes", e);
        }
    }

    private final RDSEncryptionInstanceClassesConfigProperties rdsEncryptionInstanceClassesConfigProperties;
    private final PropertyResolver rdsEncryptionInstanceClassesResolver;

    /**
     * Creates RDS encryption instance classes with the specified parameters.
     *
     * @param configuration               the configuration
     * @param configurationDirectory      the plugin configuration directory
     * @param localizationContext         the localization context
     */
    public RDSEncryptionInstanceClasses(Configured configuration, File configurationDirectory,
            LocalizationContext localizationContext) {
        this.rdsEncryptionInstanceClassesConfigProperties = new RDSEncryptionInstanceClassesConfigProperties(
                configuration, configurationDirectory, localizationContext);
        rdsEncryptionInstanceClassesResolver = getResolver(this.rdsEncryptionInstanceClassesConfigProperties);
    }

    /**
     * Creates RDS encryption instance classes with the specified parameters.
     *
     * @param rdsEncryptionInstanceClassesConfigProperties the config properties
     * @param rdsEncryptionInstanceClassesResolver         the RDS encryption instance classes resolver
     */
    private RDSEncryptionInstanceClasses(
            RDSEncryptionInstanceClassesConfigProperties rdsEncryptionInstanceClassesConfigProperties,
            PropertyResolver rdsEncryptionInstanceClassesResolver) {
        this.rdsEncryptionInstanceClassesConfigProperties = rdsEncryptionInstanceClassesConfigProperties;
        this.rdsEncryptionInstanceClassesResolver = rdsEncryptionInstanceClassesResolver;
    }

    /**
     * Determines if the given instance class supports storage encryption. A
     * custom definition overrides a built-in definition.
     *
     * @param instanceClass instance class
     * @return true if instance class supports encryption
     */
    @Nullable
    @Override
    public Boolean apply(String instanceClass) {
        return Boolean.valueOf(rdsEncryptionInstanceClassesResolver.getProperty(instanceClass, "false"));
    }

    /**
     * Gets a test instance of this class that uses only the given encryption
     * instance classes.
     *
     * @param encryptionInstanceClasses list of instance classes that support storage encryption
     * @param localizationContext the localization context
     * @return new encryption instance classes object
     */
    public static RDSEncryptionInstanceClasses getTestInstance(final List<String> encryptionInstanceClasses,
            LocalizationContext localizationContext) {
        Map<String, String> encryptionInstanceClassesMap = Maps.newHashMap();
        for (String instanceClass : encryptionInstanceClasses) {
            encryptionInstanceClassesMap.put(instanceClass, "true");
        }
        PropertyResolver resolver = PropertyResolvers.newMapPropertyResolver(encryptionInstanceClassesMap);

        File tempDir = Files.createTempDir();
        tempDir.deleteOnExit();

        RDSEncryptionInstanceClassesConfigProperties configProperties = new RDSEncryptionInstanceClassesConfigProperties(
                new SimpleConfiguration(), tempDir, localizationContext);
        return new RDSEncryptionInstanceClasses(configProperties, resolver);
    }
}