org.apache.nifi.toolkit.s2s.SiteToSiteCliMain.java Source code

Java tutorial

Introduction

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

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
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.remote.TransferDirection;
import org.apache.nifi.remote.client.KeystoreType;
import org.apache.nifi.remote.client.SiteToSiteClient;
import org.apache.nifi.remote.protocol.SiteToSiteTransportProtocol;
import org.apache.nifi.remote.protocol.http.HttpProxy;
import org.apache.nifi.util.FormatUtils;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

public class SiteToSiteCliMain {
    public static final String URL_OPTION = "url";
    public static final String URL_OPTION_DEFAULT = "http://localhost:8080/nifi";
    public static final String DIRECTION_OPTION = "direction";
    public static final String DIRECTION_OPTION_DEFAULT = TransferDirection.SEND.toString();
    public static final String PORT_NAME_OPTION = "portName";
    public static final String PORT_IDENTIFIER_OPTION = "portIdentifier";
    public static final String TIMEOUT_OPTION = "timeout";
    public static final String PENALIZATION_OPTION = "penalization";
    public static final String KEYSTORE_OPTION = "keyStore";
    public static final String KEY_STORE_TYPE_OPTION = "keyStoreType";
    public static final String KEY_STORE_PASSWORD_OPTION = "keyStorePassword";
    public static final String TRUST_STORE_OPTION = "trustStore";
    public static final String TRUST_STORE_TYPE_OPTION = "trustStoreType";
    public static final String TRUST_STORE_PASSWORD_OPTION = "trustStorePassword";
    public static final String PEER_PERSISTENCE_FILE_OPTION = "peerPersistenceFile";
    public static final String COMPRESSION_OPTION = "compression";
    public static final String TRANSPORT_PROTOCOL_OPTION = "transportProtocol";
    public static final String TRANSPORT_PROTOCOL_OPTION_DEFAULT = SiteToSiteTransportProtocol.RAW.toString();
    public static final String BATCH_COUNT_OPTION = "batchCount";
    public static final String BATCH_SIZE_OPTION = "batchSize";
    public static final String BATCH_DURATION_OPTION = "batchDuration";
    public static final String HELP_OPTION = "help";
    public static final String PROXY_HOST_OPTION = "proxyHost";
    public static final String PROXY_PORT_OPTION = "proxyPort";
    public static final String PROXY_USERNAME_OPTION = "proxyUsername";
    public static final String PROXY_PASSWORD_OPTION = "proxyPassword";
    public static final String PROXY_PORT_OPTION_DEFAULT = "80";
    public static final String KEYSTORE_TYPE_OPTION_DEFAULT = KeystoreType.JKS.toString();
    public static final String NEED_CLIENT_AUTH_OPTION = "needClientAuth";

    /**
     * Prints the usage to System.out
     *
     * @param errorMessage optional error message
     * @param options      the options object to print usage for
     */
    public static void printUsage(String errorMessage, Options options) {
        if (errorMessage != null) {
            System.out.println(errorMessage);
            System.out.println();
            System.out.println();
        }
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET);
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        System.out.println(
                "s2s is a command line tool that can either read a list of DataPackets from stdin to send over site-to-site or write the received DataPackets to stdout");
        System.out.println();
        System.out.println(
                "The s2s cli input/output format is a JSON list of DataPackets.  They can have the following formats:");
        try {
            System.out.println();
            objectMapper.writeValue(System.out, Arrays.asList(
                    new DataPacketDto("hello nifi".getBytes(StandardCharsets.UTF_8)).putAttribute("key", "value")));
            System.out.println();
            System.out.println(
                    "Where data is the base64 encoded value of the FlowFile content (always used for received data) or");
            System.out.println();
            objectMapper.writeValue(System.out,
                    Arrays.asList(new DataPacketDto(new HashMap<>(), new File("EXAMPLE").getAbsolutePath())
                            .putAttribute("key", "value")));
            System.out.println();
            System.out.println("Where dataFile is a file to read the FlowFile content from");
            System.out.println();
            System.out.println();
            System.out.println(
                    "Example usage to send a FlowFile with the contents of \"hey nifi\" to a local unsecured NiFi over http with an input port named input:");
            System.out.print("echo '");
            DataPacketDto dataPacketDto = new DataPacketDto("hey nifi".getBytes(StandardCharsets.UTF_8));
            dataPacketDto.setAttributes(null);
            objectMapper.writeValue(System.out, Arrays.asList(dataPacketDto));
            System.out.println("' | bin/s2s.sh -n input -p http");
            System.out.println();
        } catch (IOException e) {
            e.printStackTrace();
        }
        HelpFormatter helpFormatter = new HelpFormatter();
        helpFormatter.setWidth(160);
        helpFormatter.printHelp("s2s", options);
        System.out.flush();
    }

    /**
     * Parses command line options into a CliParse object
     *
     * @param options an empty options object (so callers can print usage if the parse fails
     * @param args    the string array of arguments
     * @return a CliParse object containing the constructed SiteToSiteClient.Builder and a TransferDirection
     * @throws ParseException if there is an error parsing the command line
     */
    public static CliParse parseCli(Options options, String[] args) throws ParseException {
        options.addOption("u", URL_OPTION, true, "NiFI URL to connect to (default: " + URL_OPTION_DEFAULT + ")");
        options.addOption("d", DIRECTION_OPTION, true, "Direction (valid directions: "
                + Arrays.stream(TransferDirection.values()).map(Object::toString).collect(Collectors.joining(", "))
                + ") (default: " + DIRECTION_OPTION_DEFAULT + ")");
        options.addOption("n", PORT_NAME_OPTION, true, "Port name");
        options.addOption("i", PORT_IDENTIFIER_OPTION, true, "Port id");
        options.addOption(null, TIMEOUT_OPTION, true, "Timeout");
        options.addOption(null, PENALIZATION_OPTION, true, "Penalization period");
        options.addOption(null, KEYSTORE_OPTION, true, "Keystore");
        options.addOption(null, KEY_STORE_TYPE_OPTION, true,
                "Keystore type (default: " + KEYSTORE_TYPE_OPTION_DEFAULT + ")");
        options.addOption(null, KEY_STORE_PASSWORD_OPTION, true, "Keystore password");
        options.addOption(null, TRUST_STORE_OPTION, true, "Truststore");
        options.addOption(null, TRUST_STORE_TYPE_OPTION, true,
                "Truststore type (default: " + KEYSTORE_TYPE_OPTION_DEFAULT + ")");
        options.addOption(null, TRUST_STORE_PASSWORD_OPTION, true, "Truststore password");
        options.addOption(null, NEED_CLIENT_AUTH_OPTION, false, "Need client auth");
        options.addOption("c", COMPRESSION_OPTION, false, "Use compression");
        options.addOption(null, PEER_PERSISTENCE_FILE_OPTION, true,
                "File to write peer information to so it can be recovered on restart");
        options.addOption("p", TRANSPORT_PROTOCOL_OPTION, true,
                "Site to site transport protocol (default: " + TRANSPORT_PROTOCOL_OPTION_DEFAULT + ")");
        options.addOption(null, BATCH_COUNT_OPTION, true, "Number of flow files in a batch");
        options.addOption(null, BATCH_SIZE_OPTION, true, "Size of flow files in a batch");
        options.addOption(null, BATCH_DURATION_OPTION, true, "Duration of a batch");
        options.addOption(null, PROXY_HOST_OPTION, true, "Proxy hostname");
        options.addOption(null, PROXY_PORT_OPTION, true, "Proxy port");
        options.addOption(null, PROXY_USERNAME_OPTION, true, "Proxy username");
        options.addOption(null, PROXY_PASSWORD_OPTION, true, "Proxy password");
        options.addOption("h", HELP_OPTION, false, "Show help message and exit");
        CommandLineParser parser = new DefaultParser();
        CommandLine commandLine;
        commandLine = parser.parse(options, args);
        if (commandLine.hasOption(HELP_OPTION)) {
            printUsage(null, options);
            System.exit(1);
        }
        SiteToSiteClient.Builder builder = new SiteToSiteClient.Builder();
        builder.url(commandLine.getOptionValue(URL_OPTION, URL_OPTION_DEFAULT));
        if (commandLine.hasOption(PORT_NAME_OPTION)) {
            builder.portName(commandLine.getOptionValue(PORT_NAME_OPTION));
        }
        if (commandLine.hasOption(PORT_IDENTIFIER_OPTION)) {
            builder.portIdentifier(commandLine.getOptionValue(PORT_IDENTIFIER_OPTION));
        }
        if (commandLine.hasOption(TIMEOUT_OPTION)) {
            builder.timeout(
                    FormatUtils.getTimeDuration(commandLine.getOptionValue(TIMEOUT_OPTION), TimeUnit.NANOSECONDS),
                    TimeUnit.NANOSECONDS);
        }
        if (commandLine.hasOption(PENALIZATION_OPTION)) {
            builder.nodePenalizationPeriod(FormatUtils.getTimeDuration(
                    commandLine.getOptionValue(PENALIZATION_OPTION), TimeUnit.NANOSECONDS), TimeUnit.NANOSECONDS);
        }
        if (commandLine.hasOption(KEYSTORE_OPTION)) {
            builder.keystoreFilename(commandLine.getOptionValue(KEYSTORE_OPTION));
            builder.keystoreType(KeystoreType.valueOf(
                    commandLine.getOptionValue(KEY_STORE_TYPE_OPTION, KEYSTORE_TYPE_OPTION_DEFAULT).toUpperCase()));

            if (commandLine.hasOption(KEY_STORE_PASSWORD_OPTION)) {
                builder.keystorePass(commandLine.getOptionValue(KEY_STORE_PASSWORD_OPTION));
            } else {
                throw new ParseException("Must specify keystore password");
            }
        }
        if (commandLine.hasOption(TRUST_STORE_OPTION)) {
            builder.truststoreFilename(commandLine.getOptionValue(TRUST_STORE_OPTION));
            builder.truststoreType(KeystoreType.valueOf(commandLine
                    .getOptionValue(TRUST_STORE_TYPE_OPTION, KEYSTORE_TYPE_OPTION_DEFAULT).toUpperCase()));

            if (commandLine.hasOption(TRUST_STORE_PASSWORD_OPTION)) {
                builder.truststorePass(commandLine.getOptionValue(TRUST_STORE_PASSWORD_OPTION));
            } else {
                throw new ParseException("Must specify truststore password");
            }
        }
        if (commandLine.hasOption(COMPRESSION_OPTION)) {
            builder.useCompression(true);
        } else {
            builder.useCompression(false);
        }
        if (commandLine.hasOption(PEER_PERSISTENCE_FILE_OPTION)) {
            builder.peerPersistenceFile(new File(commandLine.getOptionValue(PEER_PERSISTENCE_FILE_OPTION)));
        }
        if (commandLine.hasOption(BATCH_COUNT_OPTION)) {
            builder.requestBatchCount(Integer.parseInt(commandLine.getOptionValue(BATCH_COUNT_OPTION)));
        }
        if (commandLine.hasOption(BATCH_SIZE_OPTION)) {
            builder.requestBatchSize(Long.parseLong(commandLine.getOptionValue(BATCH_SIZE_OPTION)));
        }
        if (commandLine.hasOption(BATCH_DURATION_OPTION)) {
            builder.requestBatchDuration(FormatUtils.getTimeDuration(
                    commandLine.getOptionValue(BATCH_DURATION_OPTION), TimeUnit.NANOSECONDS), TimeUnit.NANOSECONDS);
        }
        if (commandLine.hasOption(PROXY_HOST_OPTION)) {
            builder.httpProxy(new HttpProxy(commandLine.getOptionValue(PROXY_HOST_OPTION),
                    Integer.parseInt(commandLine.getOptionValue(PROXY_PORT_OPTION, PROXY_PORT_OPTION_DEFAULT)),
                    commandLine.getOptionValue(PROXY_USERNAME_OPTION),
                    commandLine.getOptionValue(PROXY_PASSWORD_OPTION)));
        }
        builder.transportProtocol(SiteToSiteTransportProtocol.valueOf(commandLine
                .getOptionValue(TRANSPORT_PROTOCOL_OPTION, TRANSPORT_PROTOCOL_OPTION_DEFAULT).toUpperCase()));
        TransferDirection transferDirection = TransferDirection
                .valueOf(commandLine.getOptionValue(DIRECTION_OPTION, DIRECTION_OPTION_DEFAULT));
        return new CliParse() {
            @Override
            public SiteToSiteClient.Builder getBuilder() {
                return builder;
            }

            @Override
            public TransferDirection getTransferDirection() {
                return transferDirection;
            }
        };
    }

    public static void main(String[] args) {
        // Make IO redirection useful
        PrintStream output = System.out;
        System.setOut(System.err);
        Options options = new Options();
        try {
            CliParse cliParse = parseCli(options, args);
            try (SiteToSiteClient siteToSiteClient = cliParse.getBuilder().build()) {
                if (cliParse.getTransferDirection() == TransferDirection.SEND) {
                    new SiteToSiteSender(siteToSiteClient, System.in).sendFiles();
                } else {
                    new SiteToSiteReceiver(siteToSiteClient, output).receiveFiles();
                }
            }
        } catch (Exception e) {
            printUsage(e.getMessage(), options);
            e.printStackTrace();
        }
    }

    /**
     * Combines a SiteToSiteClient.Builder and TransferDirection into a return value for parseCli
     */
    public interface CliParse {
        SiteToSiteClient.Builder getBuilder();

        TransferDirection getTransferDirection();
    }
}