org.apache.nifi.toolkit.tls.commandLine.BaseCommandLine.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.nifi.toolkit.tls.commandLine.BaseCommandLine.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.apache.nifi.toolkit.tls.commandLine;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.nifi.security.util.KeystoreType;
import org.apache.nifi.toolkit.tls.TlsToolkitMain;
import org.apache.nifi.toolkit.tls.configuration.TlsConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Base class with common CLI parsing functionality as well as arguments shared by multiple entry points
 */
public abstract class BaseCommandLine {
    private static final Logger logger = LoggerFactory.getLogger(BaseCommandLine.class);
    public static final String HELP_ARG = "help";
    public static final String JAVA_HOME = "JAVA_HOME";
    public static final String NIFI_TOOLKIT_HOME = "NIFI_TOOLKIT_HOME";
    public static final String FOOTER = new StringBuilder(System.lineSeparator()).append("Java home: ")
            .append(System.getenv(JAVA_HOME)).append(System.lineSeparator()).append("NiFi Toolkit home: ")
            .append(System.getenv(NIFI_TOOLKIT_HOME)).toString();

    public static final String KEY_SIZE_ARG = "keySize";
    public static final String KEY_ALGORITHM_ARG = "keyAlgorithm";
    public static final String CERTIFICATE_AUTHORITY_HOSTNAME_ARG = "certificateAuthorityHostname";
    public static final String DAYS_ARG = "days";
    public static final String KEY_STORE_TYPE_ARG = "keyStoreType";
    public static final String SIGNING_ALGORITHM_ARG = "signingAlgorithm";
    public static final String DN_ARG = "dn";
    public static final String DIFFERENT_KEY_AND_KEYSTORE_PASSWORDS_ARG = "differentKeyAndKeystorePasswords";

    public static final String KEYSTORE = "keystore.";
    public static final String TRUSTSTORE = "truststore.";

    private final Options options;
    private final String header;
    private int keySize;
    private String keyAlgorithm;
    private String certificateAuthorityHostname;
    private String keyStoreType;
    private int days;
    private String signingAlgorithm;
    private boolean differentPasswordForKeyAndKeystore;

    public BaseCommandLine(String header) {
        this.header = System.lineSeparator() + header + System.lineSeparator() + System.lineSeparator();
        this.options = new Options();
        if (shouldAddDaysArg()) {
            addOptionWithArg("d", DAYS_ARG, "Number of days issued certificate should be valid for.",
                    TlsConfig.DEFAULT_DAYS);
        }
        addOptionWithArg("T", KEY_STORE_TYPE_ARG, "The type of keyStores to generate.", getKeyStoreTypeDefault());
        options.addOption("h", HELP_ARG, false, "Print help and exit.");
        addOptionWithArg("c", CERTIFICATE_AUTHORITY_HOSTNAME_ARG, "Hostname of NiFi Certificate Authority",
                TlsConfig.DEFAULT_HOSTNAME);
        addOptionWithArg("a", KEY_ALGORITHM_ARG, "Algorithm to use for generated keys.",
                TlsConfig.DEFAULT_KEY_PAIR_ALGORITHM);
        addOptionWithArg("k", KEY_SIZE_ARG, "Number of bits for generated keys.", TlsConfig.DEFAULT_KEY_SIZE);
        if (shouldAddSigningAlgorithmArg()) {
            addOptionWithArg("s", SIGNING_ALGORITHM_ARG, "Algorithm to use for signing certificates.",
                    TlsConfig.DEFAULT_SIGNING_ALGORITHM);
        }
        addOptionNoArg("g", DIFFERENT_KEY_AND_KEYSTORE_PASSWORDS_ARG,
                "Use different generated password for the key and the keyStore.");
    }

    protected String getKeyStoreTypeDefault() {
        return TlsConfig.DEFAULT_KEY_STORE_TYPE;
    }

    protected boolean shouldAddSigningAlgorithmArg() {
        return true;
    }

    protected boolean shouldAddDaysArg() {
        return true;
    }

    protected void addOptionWithArg(String arg, String longArg, String description) {
        addOptionWithArg(arg, longArg, description, null);
    }

    protected void addOptionNoArg(String arg, String longArg, String description) {
        options.addOption(arg, longArg, false, description);
    }

    protected void addOptionWithArg(String arg, String longArg, String description, Object defaultVal) {
        String fullDescription = description;
        if (defaultVal != null) {
            fullDescription += " (default: " + defaultVal + ")";
        }
        options.addOption(arg, longArg, true, fullDescription);
    }

    public void printUsage(String errorMessage) {
        if (errorMessage != null) {
            System.out.println(errorMessage);
            System.out.println();
        }
        HelpFormatter helpFormatter = new HelpFormatter();
        helpFormatter.setWidth(160);
        helpFormatter.printHelp(TlsToolkitMain.class.getCanonicalName(), header, options, FOOTER, true);
    }

    protected <T> T printUsageAndThrow(String errorMessage, ExitCode exitCode) throws CommandLineParseException {
        printUsage(errorMessage);
        throw new CommandLineParseException(errorMessage, exitCode);
    }

    protected int getIntValue(CommandLine commandLine, String arg, int defaultVal)
            throws CommandLineParseException {
        try {
            return Integer.parseInt(commandLine.getOptionValue(arg, Integer.toString(defaultVal)));
        } catch (NumberFormatException e) {
            return printUsageAndThrow("Expected integer for " + arg + " argument. (" + e.getMessage() + ")",
                    ExitCode.ERROR_PARSING_INT_ARG);
        }
    }

    /**
     * Returns the number of bits used when generating KeyPairs
     *
     * @return the number of bits used when generating KeyPairs
     */
    public int getKeySize() {
        return keySize;
    }

    /**
     * Returns the algorithm used when generating KeyPairs
     *
     * @return the algorithm used when generating KeyPairs
     */
    public String getKeyAlgorithm() {
        return keyAlgorithm;
    }

    /**
     * Returns the CA Hostname
     *
     * @return the CA Hostname
     */
    public String getCertificateAuthorityHostname() {
        return certificateAuthorityHostname;
    }

    /**
     * Returns the type to use for KeyStores
     *
     * @return the type to use for KeyStores
     */
    public String getKeyStoreType() {
        return keyStoreType;
    }

    /**
     * Returns the number of Certificates should be valid for
     *
     * @return the number of Certificates should be valid for
     */
    public int getDays() {
        return days;
    }

    /**
     * Returns the signing algorithm to use for cryptographic operations
     *
     * @return the signing algorithm to use for cryptographic operations
     */
    public String getSigningAlgorithm() {
        return signingAlgorithm;
    }

    /**
     * Returns true if different passwords should be used for KeyStore and individual Key entries
     *
     * @return true if different passwords should be used for KeyStore and individual Key entries
     */
    public boolean differentPasswordForKeyAndKeystore() {
        return differentPasswordForKeyAndKeystore;
    }

    protected CommandLine doParse(String[] args) throws CommandLineParseException {
        CommandLineParser parser = new DefaultParser();
        CommandLine commandLine;
        try {
            commandLine = parser.parse(options, args);
            if (commandLine.hasOption(HELP_ARG)) {
                return printUsageAndThrow(null, ExitCode.HELP);
            }
            certificateAuthorityHostname = commandLine.getOptionValue(CERTIFICATE_AUTHORITY_HOSTNAME_ARG,
                    TlsConfig.DEFAULT_HOSTNAME);
            days = getIntValue(commandLine, DAYS_ARG, TlsConfig.DEFAULT_DAYS);
            keySize = getIntValue(commandLine, KEY_SIZE_ARG, TlsConfig.DEFAULT_KEY_SIZE);
            keyAlgorithm = commandLine.getOptionValue(KEY_ALGORITHM_ARG, TlsConfig.DEFAULT_KEY_PAIR_ALGORITHM);
            keyStoreType = commandLine.getOptionValue(KEY_STORE_TYPE_ARG, getKeyStoreTypeDefault());
            if (KeystoreType.PKCS12.toString().equalsIgnoreCase(keyStoreType)) {
                logger.info("Command line argument --" + KEY_STORE_TYPE_ARG + "=" + keyStoreType
                        + " only applies to keystore, recommended truststore type of " + KeystoreType.JKS.toString()
                        + " unaffected.");
            }
            signingAlgorithm = commandLine.getOptionValue(SIGNING_ALGORITHM_ARG,
                    TlsConfig.DEFAULT_SIGNING_ALGORITHM);
            differentPasswordForKeyAndKeystore = commandLine.hasOption(DIFFERENT_KEY_AND_KEYSTORE_PASSWORDS_ARG);
        } catch (ParseException e) {
            return printUsageAndThrow("Error parsing command line. (" + e.getMessage() + ")",
                    ExitCode.ERROR_PARSING_COMMAND_LINE);
        }
        return commandLine;
    }

    /**
     * Parses the command line arguments
     *
     * @param args the command line arguments
     * @throws CommandLineParseException if the arguments cannot be parsed
     */
    public void parse(String... args) throws CommandLineParseException {
        doParse(args);
    }
}