com.joyent.manta.config.TestConfigContext.java Source code

Java tutorial

Introduction

Here is the source code for com.joyent.manta.config.TestConfigContext.java

Source

/*
 * Copyright (c) 2015-2017, Joyent, Inc. All rights reserved.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
package com.joyent.manta.config;

import com.joyent.http.signature.KeyFingerprinter;
import com.joyent.manta.util.UnitTestConstants;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
import org.bouncycastle.openssl.jcajce.JcePEMEncryptorBuilder;

import java.io.IOException;
import java.io.StringWriter;
import java.net.URL;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.util.Properties;

import static com.joyent.manta.util.UnitTestConstants.UNIT_TEST_URL;

/**
 * {@link com.joyent.manta.config.ConfigContext} implementation that loads
 * configuration parameters in an order that makes sense for unit testing
 * and allows for TestNG parameters to be loaded.
 *
 * @author <a href="https://github.com/dekobon">Elijah Zupancic</a>
 */
public class TestConfigContext extends BaseChainedConfigContext {

    public TestConfigContext() {
        super(new StandardConfigContext().setMaximumConnections(DEFAULT_CONFIG.getMaximumConnections())
                .setRetries(DEFAULT_CONFIG.getRetries()).setHttpsProtocols(DEFAULT_CONFIG.getHttpsProtocols())
                .setHttpsCipherSuites(DEFAULT_CONFIG.getHttpsCipherSuites()).setMantaURL(UNIT_TEST_URL)
                .setMantaUser("username").setMantaKeyId(UnitTestConstants.FINGERPRINT)
                .setPrivateKeyContent(UnitTestConstants.PRIVATE_KEY));
    }

    /**
     * Populate configuration from defaults, environment variables, system
     * properties and an addition context passed in.
     *
     * @param context                additional context to layer on top
     * @param properties             properties to load into context
     * @param includeEnvironmentVars flag indicated if we include the environment into the context
     */
    public TestConfigContext(ConfigContext context, Properties properties, boolean includeEnvironmentVars) {
        super();

        // load defaults
        overwriteWithContext(DEFAULT_CONFIG);
        // now load in an additional context
        overwriteWithContext(context);
        // overwrite with system properties
        overwriteWithContext(new MapConfigContext(properties));

        if (includeEnvironmentVars) {
            overwriteWithContext(new EnvVarConfigContext());
        }
    }

    /**
     * Populate configuration from defaults, environment variables, system
     * properties and an addition context passed in.
     *
     * @param context    additional context to layer on top
     * @param properties properties to load into context
     */
    public TestConfigContext(ConfigContext context, Properties properties) {
        this(context, properties, true);
    }

    /**
     * Populate configuration from defaults, environment variables, system
     * properties and an addition context passed in.
     *
     * @param context additional context to layer on top
     */
    public TestConfigContext(ConfigContext context) {
        this(context, System.getProperties());
    }

    public TestConfigContext(String mantaUrl, String mantaUser, String mantaKeyPath, String mantaKeyId,
            Integer mantaTimeout) {
        this(buildTestContext(mantaUrl, mantaUser, mantaKeyPath, mantaKeyId, mantaTimeout, 6));
    }

    static ConfigContext buildTestContext(String mantaUrl, String mantaUser, String mantaKeyPath, String mantaKeyId,
            Integer mantaTimeout, Integer retries) {
        URL privateKeyUrl = mantaKeyPath == null ? null
                : Thread.currentThread().getContextClassLoader().getResource(mantaKeyPath);

        BaseChainedConfigContext testConfig = new StandardConfigContext().setMantaURL(mantaUrl)
                .setMantaUser(mantaUser).setMantaKeyId(mantaKeyId).setTimeout(mantaTimeout).setRetries(retries);

        if (privateKeyUrl != null) {
            testConfig.setMantaKeyPath(privateKeyUrl.getFile());
        } else {
            testConfig.setMantaKeyPath(mantaKeyPath);
        }

        return testConfig;
    }

    public static ImmutablePair<KeyPair, BaseChainedConfigContext> generateKeyPairBackedConfig() {
        return generateKeyPairBackedConfig(null);
    }

    /**
     * Some test cases need a direct reference to a KeyPair along with it's associated config. Manually calling
     * KeyPairFactory with a half-baked config can get cumbersome, so let's build a ConfigContext which has
     * everything ready and supplies the relevant KeyPair.
     *
     * @return the generated keypair and a config which uses a serialized version of that keypair
     */
    public static ImmutablePair<KeyPair, BaseChainedConfigContext> generateKeyPairBackedConfig(
            final String passphrase) {
        final KeyPair keyPair;
        try {
            keyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
        } catch (final NoSuchAlgorithmException impossible) {
            throw new Error(impossible); // "RSA" is always provided
        }

        final Object keySerializer;
        if (passphrase != null) {
            try {
                keySerializer = new JcaMiscPEMGenerator(keyPair.getPrivate(),
                        new JcePEMEncryptorBuilder("AES-128-CBC").build(passphrase.toCharArray()));
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } else {
            keySerializer = keyPair.getPrivate();
        }

        final String keyContent;
        try (final StringWriter content = new StringWriter();
                final JcaPEMWriter writer = new JcaPEMWriter(content)) {
            writer.writeObject(keySerializer);
            writer.flush();
            keyContent = content.toString();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        final BaseChainedConfigContext config = new ChainedConfigContext(DEFAULT_CONFIG)
                // we need to unset the key path in case one exists at ~/.ssh/id_rsa
                // see the static initializer in DefaultsConfigContext
                .setMantaKeyPath(null).setPrivateKeyContent(keyContent)
                .setMantaKeyId(KeyFingerprinter.md5Fingerprint(keyPair));

        if (passphrase != null) {
            config.setPassword(passphrase);
        }

        return new ImmutablePair<>(keyPair, config);
    }
}