Java Code Examples for org.apache.nifi.util.StringUtils#isEmpty()

The following examples show how to use org.apache.nifi.util.StringUtils#isEmpty() . These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source Project: nifi   File: FilePath.java    License: Apache License 2.0 6 votes vote down vote up
@Override
public DataSetRefs analyze(AnalysisContext context, ProvenanceEventRecord event) {
    final Referenceable ref = new Referenceable(TYPE);
    final URI uri = parseUri(event.getTransitUri());
    final String namespace;
    try {
        // use hostname in uri if available for remote path.
        final String uriHost = uri.getHost();
        final String hostname = StringUtils.isEmpty(uriHost) ? InetAddress.getLocalHost().getHostName() : uriHost;
        namespace = context.getNamespaceResolver().fromHostNames(hostname);
    } catch (UnknownHostException e) {
        logger.warn("Failed to get localhost name due to " + e, e);
        return null;
    }

    final String path = uri.getPath();
    ref.set(ATTR_NAME, path);
    ref.set(ATTR_PATH, path);
    ref.set(ATTR_QUALIFIED_NAME, toQualifiedName(namespace, path));

    return singleDataSetRef(event.getComponentId(), event.getEventType(), ref);
}
 
Example 2
Source Project: nifi   File: BaseTlsManager.java    License: Apache License 2.0 6 votes vote down vote up
private String getKeyPassword() {
    if (keyStore.getType().equalsIgnoreCase(KeystoreType.PKCS12.toString())) {
        tlsConfig.setKeyPassword(null);
        return null;
    } else {
        String result = tlsConfig.getKeyPassword();
        if (StringUtils.isEmpty(result)) {
            if (differentKeyAndKeyStorePassword) {
                result = passwordUtil.generatePassword();
            } else {
                result = getKeyStorePassword();
            }
            tlsConfig.setKeyPassword(result);
        }
        return result;
    }
}
 
Example 3
/**
 * Determines the effective ClassLoader for the instance of the given type.
 *
 * @param classType the type of class to lookup the ClassLoader for
 * @param instanceIdentifier the identifier of the specific instance of the classType to look up the ClassLoader for
 * @return the ClassLoader for the given instance of the given type, or null if the type is not a detected extension type
 */
public static ClassLoader getClassLoader(final String classType, final String instanceIdentifier) {
    if (StringUtils.isEmpty(classType) || StringUtils.isEmpty(instanceIdentifier)) {
        throw new IllegalArgumentException("Class Type and Instance Identifier must be provided");
    }

    // Check if we already have a ClassLoader for this instance
    ClassLoader instanceClassLoader = instanceClassloaderLookup.get(instanceIdentifier);

    // If we don't then we'll create a new ClassLoader for this instance and add it to the map for future lookups
    if (instanceClassLoader == null) {
        final ClassLoader registeredClassLoader = getClassLoader(classType);
        if (registeredClassLoader == null) {
            return null;
        }

        // If the class is annotated with @RequiresInstanceClassLoading and the registered ClassLoader is a URLClassLoader
        // then make a new InstanceClassLoader that is a full copy of the NAR Class Loader, otherwise create an empty
        // InstanceClassLoader that has the NAR ClassLoader as a parent
        if (requiresInstanceClassLoading.contains(classType) && (registeredClassLoader instanceof URLClassLoader)) {
            final URLClassLoader registeredUrlClassLoader = (URLClassLoader) registeredClassLoader;
            instanceClassLoader = new InstanceClassLoader(instanceIdentifier, classType, registeredUrlClassLoader.getURLs(), registeredUrlClassLoader.getParent());
        } else {
            instanceClassLoader = new InstanceClassLoader(instanceIdentifier, classType, new URL[0], registeredClassLoader);
        }

        instanceClassloaderLookup.put(instanceIdentifier, instanceClassLoader);
    }

    return instanceClassLoader;
}
 
Example 4
@Override
public void write(OutputStreamFactory outputStreamFactory) throws IOException, GeneralSecurityException {
    super.write(outputStreamFactory);

    String trustStorePassword = tlsClientConfig.getTrustStorePassword();
    boolean trustStorePasswordGenerated = false;
    if (StringUtils.isEmpty(trustStorePassword)) {
        trustStorePassword = getPasswordUtil().generatePassword();
        trustStorePasswordGenerated = true;
    }

    trustStorePassword = TlsHelper.writeKeyStore(trustStore, outputStreamFactory, new File(tlsClientConfig.getTrustStore()), trustStorePassword, trustStorePasswordGenerated);
    tlsClientConfig.setTrustStorePassword(trustStorePassword);

    for (ConfigurationWriter<TlsClientConfig> configurationWriter : configurationWriters) {
        configurationWriter.write(tlsClientConfig, outputStreamFactory);
    }

    if (certificateAuthorityDirectory != null) {
        // Write out all trusted certificates from truststore
        for (String alias : Collections.list(trustStore.aliases())) {
            try {
                KeyStore.Entry trustStoreEntry = trustStore.getEntry(alias, null);
                if (trustStoreEntry instanceof KeyStore.TrustedCertificateEntry) {
                    Certificate trustedCertificate = ((KeyStore.TrustedCertificateEntry) trustStoreEntry).getTrustedCertificate();
                    try (OutputStream outputStream = outputStreamFactory.create(new File(certificateAuthorityDirectory, alias + ".pem"));
                         OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
                         PemWriter pemWriter = new PemWriter(outputStreamWriter)) {
                        pemWriter.writeObject(new JcaMiscPEMGenerator(trustedCertificate));
                    }
                }
            } catch (UnrecoverableEntryException e) {
                // Ignore, not a trusted cert
            }
        }
    }
}
 
Example 5
Source Project: nifi   File: BaseTlsManager.java    License: Apache License 2.0 5 votes vote down vote up
private String getKeyStorePassword() {
    String result = tlsConfig.getKeyStorePassword();
    if (StringUtils.isEmpty(result)) {
        result = passwordUtil.generatePassword();
        keyStorePasswordGenerated = true;
        tlsConfig.setKeyStorePassword(result);
    }
    return result;
}
 
Example 6
Source Project: nifi   File: DeleteGridFS.java    License: Apache License 2.0 5 votes vote down vote up
@Override
public void onTrigger(ProcessContext context, ProcessSession session) throws ProcessException {
    FlowFile input = session.get();
    if (input == null) {
        return;
    }

    final String deleteQuery = getQuery(context, input);
    final String queryAttribute = context.getProperty(QUERY_ATTRIBUTE).isSet()
            ? context.getProperty(QUERY_ATTRIBUTE).evaluateAttributeExpressions(input).getValue()
            : null;
    GridFSBucket bucket = getBucket(input, context);

    try {
        Document query = Document.parse(deleteQuery);
        MongoCursor cursor = bucket.find(query).iterator();
        if (cursor.hasNext()) {
            GridFSFile file = (GridFSFile)cursor.next();
            bucket.delete(file.getObjectId());

            if (!StringUtils.isEmpty(queryAttribute)) {
                input = session.putAttribute(input, queryAttribute, deleteQuery);
            }

            session.transfer(input, REL_SUCCESS);
        } else {
            getLogger().error(String.format("Query %s did not delete anything in %s", deleteQuery, bucket.getBucketName()));
            session.transfer(input, REL_FAILURE);
        }

        cursor.close();
    } catch (Exception ex) {
        getLogger().error(String.format("Error deleting using query: %s", deleteQuery), ex);
        session.transfer(input, REL_FAILURE);
    }
}
 
Example 7
Source Project: nifi   File: ListedEntityTracker.java    License: Apache License 2.0 5 votes vote down vote up
static void validateProperties(ValidationContext context, Collection<ValidationResult> results, Scope scope) {
    validateRequiredProperty(context, results, ListedEntityTracker.TRACKING_STATE_CACHE);
    validateRequiredProperty(context, results, ListedEntityTracker.TRACKING_TIME_WINDOW);

    if (Scope.LOCAL.equals(scope)
        && StringUtils.isEmpty(context.getProperty(NODE_IDENTIFIER).evaluateAttributeExpressions().getValue())) {
        results.add(new ValidationResult.Builder()
                .subject(NODE_IDENTIFIER.getDisplayName())
                .explanation(format("'%s' is required to use local scope with '%s' listing strategy",
                        NODE_IDENTIFIER.getDisplayName(), AbstractListProcessor.BY_ENTITIES.getDisplayName()))
                .build());
    }
}
 
Example 8
@Override
protected Collection<ValidationResult> customValidate(ValidationContext validationContext) {
    Set<ValidationResult> results = new HashSet<>();

    // Ensure that if username or password is set, then the other is too
    String userName = validationContext.getProperty(USERNAME).evaluateAttributeExpressions().getValue();
    String password = validationContext.getProperty(PASSWORD).evaluateAttributeExpressions().getValue();
    if (StringUtils.isEmpty(userName) != StringUtils.isEmpty(password)) {
        results.add(new ValidationResult.Builder().valid(false).explanation(
                "If username or password is specified, then the other must be specified as well").build());
    }

    return results;
}
 
Example 9
public void generateCertificateAndGetItSigned(TlsClientConfig tlsClientConfig, String certificateDirectory, String configJson, boolean differentKeyAndKeyStorePassword) throws Exception {
    TlsClientManager tlsClientManager;
    try {
        tlsClientManager = new TlsClientManager(tlsClientConfig);
    } catch (IOException e) {
        logger.error("Unable to open existing keystore, it can be reused by specifiying both " + BaseCertificateAuthorityCommandLine.CONFIG_JSON_ARG + " and " +
                BaseCertificateAuthorityCommandLine.USE_CONFIG_JSON_ARG);
        throw e;
    }
    tlsClientManager.setDifferentKeyAndKeyStorePassword(differentKeyAndKeyStorePassword);

    if (!StringUtils.isEmpty(certificateDirectory)) {
        tlsClientManager.setCertificateAuthorityDirectory(new File(certificateDirectory));
    }

    if (!StringUtils.isEmpty(configJson)) {
        tlsClientManager.addClientConfigurationWriter(new JsonConfigurationWriter<>(new ObjectMapper(), new File(configJson)));
    }

    if (tlsClientManager.getEntry(TlsToolkitStandalone.NIFI_KEY) == null) {
        if (logger.isInfoEnabled()) {
            logger.info("Requesting new certificate from " + tlsClientConfig.getCaHostname() + ":" + tlsClientConfig.getPort());
        }
        KeyPair keyPair = TlsHelper.generateKeyPair(tlsClientConfig.getKeyPairAlgorithm(), tlsClientConfig.getKeySize());

        X509Certificate[] certificates = tlsClientConfig.createCertificateSigningRequestPerformer().perform(keyPair);

        tlsClientManager.addPrivateKeyToKeyStore(keyPair, TlsToolkitStandalone.NIFI_KEY, certificates);
        tlsClientManager.setCertificateEntry(TlsToolkitStandalone.NIFI_CERT, certificates[certificates.length - 1]);
    } else {
        if (logger.isInfoEnabled()) {
            logger.info("Already had entry for " + TlsToolkitStandalone.NIFI_KEY + " not requesting new certificate.");
        }
    }

    tlsClientManager.write(outputStreamFactory);
}
 
Example 10
@Override
protected CommandLine doParse(String[] args) throws CommandLineParseException {
    CommandLine commandLine = super.doParse(args);

    token = commandLine.getOptionValue(TOKEN_ARG);

    boolean useConfigJson = commandLine.hasOption(USE_CONFIG_JSON_ARG);

    configJsonOut = commandLine.getOptionValue(CONFIG_JSON_ARG, DEFAULT_CONFIG_JSON);
    configJsonIn = commandLine.getOptionValue(READ_CONFIG_JSON_ARG);
    if (StringUtils.isEmpty(configJsonIn) && useConfigJson) {
        configJsonIn = configJsonOut;
    }

    if (StringUtils.isEmpty(token) && StringUtils.isEmpty(configJsonIn)) {
        printUsageAndThrow(TOKEN_ARG + " argument must not be empty unless " + USE_CONFIG_JSON_ARG + " or " + READ_CONFIG_JSON_ARG+ " set", ExitCode.ERROR_TOKEN_ARG_EMPTY);
    }

    if (!StringUtils.isEmpty(token)) {
        byte[] tokenBytes = token.getBytes(StandardCharsets.UTF_8);
        if (tokenBytes.length < 16) {
            printUsageAndThrow(TOKEN_ARG + " does not meet minimum size of 16 bytes", ExitCode.ERROR_TOKEN_ARG_TOO_SHORT);
        }
    }

    port = getIntValue(commandLine, PORT_ARG, TlsConfig.DEFAULT_PORT);
    dn = commandLine.getOptionValue(DN_ARG, new TlsConfig().calcDefaultDn(getDnHostname()));
    return commandLine;
}
 
Example 11
protected Response sendRequestToElasticsearch(OkHttpClient client, URL url, String username, String password, String verb, RequestBody body) throws IOException {

        final ComponentLog log = getLogger();
        Request.Builder requestBuilder = new Request.Builder()
                .url(url);
        if ("get".equalsIgnoreCase(verb)) {
            requestBuilder = requestBuilder.get();
        } else if ("put".equalsIgnoreCase(verb)) {
            requestBuilder = requestBuilder.put(body);
        } else {
            throw new IllegalArgumentException("Elasticsearch REST API verb not supported by this processor: " + verb);
        }

        if(!StringUtils.isEmpty(username) && !StringUtils.isEmpty(password)) {
            String credential = Credentials.basic(username, password);
            requestBuilder = requestBuilder.header("Authorization", credential);
        }
        Request httpRequest = requestBuilder.build();
        log.debug("Sending Elasticsearch request to {}", new Object[]{url});

        Response responseHttp = client.newCall(httpRequest).execute();

        // store the status code and message
        int statusCode = responseHttp.code();

        if (statusCode == 0) {
            throw new IllegalStateException("Status code unknown, connection hasn't been attempted.");
        }

        log.debug("Received response from Elasticsearch with status code {}", new Object[]{statusCode});

        return responseHttp;
    }
 
Example 12
/**
 * Custom validation for ensuring exactly one of Script File or Script Body is populated
 *
 * @param validationContext provides a mechanism for obtaining externally
 *                          managed values, such as property values and supplies convenience methods
 *                          for operating on those values
 * @return A collection of validation results
 */
public Collection<ValidationResult> customValidate(ValidationContext validationContext) {
    Set<ValidationResult> results = new HashSet<>();

    // Verify that exactly one of "script file" or "script body" is set
    Map<PropertyDescriptor, String> propertyMap = validationContext.getProperties();
    if (StringUtils.isEmpty(propertyMap.get(ScriptingComponentUtils.SCRIPT_FILE)) == StringUtils.isEmpty(propertyMap.get(ScriptingComponentUtils.SCRIPT_BODY))) {
        results.add(new ValidationResult.Builder().valid(false).explanation(
                "Exactly one of Script File or Script Body must be set").build());
    }

    return results;
}
 
Example 13
Source Project: nifi   File: PrometheusMetricsUtil.java    License: Apache License 2.0 5 votes vote down vote up
public static CollectorRegistry createBulletinMetrics(BulletinMetricsRegistry bulletinMetricsRegistry, String instId, String compType, String compId, String pgId, String nodeAddr,
                                                      String cat, String srcName, String srcId, String lvl) {
    final String instanceId = StringUtils.isEmpty(instId) ? DEFAULT_LABEL_STRING : instId;
    final String componentType = StringUtils.isEmpty(compType) ? DEFAULT_LABEL_STRING : compType;
    final String componentId = StringUtils.isEmpty(compId) ? DEFAULT_LABEL_STRING : compId;
    final String sourceId = StringUtils.isEmpty(srcId) ? DEFAULT_LABEL_STRING : srcId;
    final String sourceName = StringUtils.isEmpty(srcName) ? DEFAULT_LABEL_STRING : srcName;
    final String nodeAddress = StringUtils.isEmpty(nodeAddr) ? DEFAULT_LABEL_STRING : nodeAddr;
    final String category = StringUtils.isEmpty(cat) ? DEFAULT_LABEL_STRING : cat;
    final String parentId = StringUtils.isEmpty(pgId) ? DEFAULT_LABEL_STRING : pgId;
    final String level = StringUtils.isEmpty(lvl) ? DEFAULT_LABEL_STRING : lvl;
    bulletinMetricsRegistry.setDataPoint(1, "BULLETIN", instanceId, componentType, componentId, parentId, nodeAddress, category, sourceName, sourceId, level);
    return bulletinMetricsRegistry.getRegistry();
}
 
Example 14
Source Project: nifi   File: ScriptingComponentHelper.java    License: Apache License 2.0 5 votes vote down vote up
public void setupVariables(ProcessContext context) {
    scriptEngineName = context.getProperty(SCRIPT_ENGINE).getValue();
    scriptPath = context.getProperty(ScriptingComponentUtils.SCRIPT_FILE).evaluateAttributeExpressions().getValue();
    scriptBody = context.getProperty(ScriptingComponentUtils.SCRIPT_BODY).getValue();
    String modulePath = context.getProperty(ScriptingComponentUtils.MODULES).evaluateAttributeExpressions().getValue();
    if (!StringUtils.isEmpty(modulePath)) {
        modules = modulePath.split(",");
    } else {
        modules = new String[0];
    }
}
 
Example 15
public void setupVariables(ConfigurationContext context) {
    scriptEngineName = context.getProperty(SCRIPT_ENGINE).getValue();
    scriptPath = context.getProperty(ScriptingComponentUtils.SCRIPT_FILE).evaluateAttributeExpressions().getValue();
    scriptBody = context.getProperty(ScriptingComponentUtils.SCRIPT_BODY).getValue();
    String modulePath = context.getProperty(ScriptingComponentUtils.MODULES).evaluateAttributeExpressions().getValue();
    if (!StringUtils.isEmpty(modulePath)) {
        modules = modulePath.split(",");
    } else {
        modules = new String[0];
    }
}
 
Example 16
Source Project: nifi   File: TlsClientConfig.java    License: Apache License 2.0 5 votes vote down vote up
@Override
public void initDefaults() {
    super.initDefaults();
    if (StringUtils.isEmpty(trustStoreType)) {
        trustStoreType = DEFAULT_KEY_STORE_TYPE;
    }
}
 
Example 17
public boolean hasCsr() {
    return !StringUtils.isEmpty(csr);
}
 
Example 18
Source Project: nifi   File: JettyWebSocketClient.java    License: Apache License 2.0 4 votes vote down vote up
@OnEnabled
@Override
public void startClient(final ConfigurationContext context) throws Exception{

    final SSLContextService sslService = context.getProperty(SSL_CONTEXT).asControllerService(SSLContextService.class);
    SslContextFactory sslContextFactory = null;
    if (sslService != null) {
        sslContextFactory = createSslFactory(sslService, false, false, null);
    }
    client = new WebSocketClient(sslContextFactory);

    configurePolicy(context, client.getPolicy());
    final String userName = context.getProperty(USER_NAME).evaluateAttributeExpressions().getValue();
    final String userPassword = context.getProperty(USER_PASSWORD).evaluateAttributeExpressions().getValue();
    if (!StringUtils.isEmpty(userName) && !StringUtils.isEmpty(userPassword)) {
        final String charsetName = context.getProperty(AUTH_CHARSET).evaluateAttributeExpressions().getValue();
        if (StringUtils.isEmpty(charsetName)) {
            throw new IllegalArgumentException(AUTH_CHARSET.getDisplayName() + " was not specified.");
        }
        final Charset charset = Charset.forName(charsetName);
        final String base64String = Base64.encodeBase64String((userName + ":" + userPassword).getBytes(charset));
        authorizationHeader = "Basic " + base64String;
    } else {
        authorizationHeader = null;
    }

    client.start();
    activeSessions.clear();

    webSocketUri = new URI(context.getProperty(WS_URI).evaluateAttributeExpressions().getValue());
    connectionTimeoutMillis = context.getProperty(CONNECTION_TIMEOUT).evaluateAttributeExpressions().asTimePeriod(TimeUnit.MILLISECONDS);

    final Long sessionMaintenanceInterval = context.getProperty(SESSION_MAINTENANCE_INTERVAL).evaluateAttributeExpressions().asTimePeriod(TimeUnit.MILLISECONDS);

    sessionMaintenanceScheduler = Executors.newSingleThreadScheduledExecutor();
    sessionMaintenanceScheduler.scheduleAtFixedRate(() -> {
        try {
            maintainSessions();
        } catch (final Exception e) {
            getLogger().warn("Failed to maintain sessions due to {}", new Object[]{e}, e);
        }
    }, sessionMaintenanceInterval, sessionMaintenanceInterval, TimeUnit.MILLISECONDS);
}
 
Example 19
/**
 * Instantiate ElasticSearch Client. This should be called by subclasses' @OnScheduled method to create a client
 * if one does not yet exist. If called when scheduled, closeClient() should be called by the subclasses' @OnStopped
 * method so the client will be destroyed when the processor is stopped.
 *
 * @param context The context for this processor
 * @throws ProcessException if an error occurs while creating an Elasticsearch client
 */
@Override
protected void createElasticsearchClient(ProcessContext context) throws ProcessException {

    ComponentLog log = getLogger();
    if (esClient.get() != null) {
        return;
    }

    log.debug("Creating ElasticSearch Client");
    try {
        final String clusterName = context.getProperty(CLUSTER_NAME).evaluateAttributeExpressions().getValue();
        final String pingTimeout = context.getProperty(PING_TIMEOUT).evaluateAttributeExpressions().getValue();
        final String samplerInterval = context.getProperty(SAMPLER_INTERVAL).evaluateAttributeExpressions().getValue();
        final String username = context.getProperty(USERNAME).evaluateAttributeExpressions().getValue();
        final String password = context.getProperty(PASSWORD).getValue();

        final SSLContextService sslService =
                context.getProperty(PROP_SSL_CONTEXT_SERVICE).asControllerService(SSLContextService.class);

        Settings.Builder settingsBuilder = Settings.builder()
                .put("cluster.name", clusterName)
                .put("client.transport.ping_timeout", pingTimeout)
                .put("client.transport.nodes_sampler_interval", samplerInterval);

        String xPackUrl = context.getProperty(PROP_XPACK_LOCATION).evaluateAttributeExpressions().getValue();
        if (sslService != null) {
            settingsBuilder.put("xpack.security.transport.ssl.enabled", "true");
            if (!StringUtils.isEmpty(sslService.getKeyStoreFile())) {
                settingsBuilder.put("xpack.ssl.keystore.path", sslService.getKeyStoreFile());
            }
            if (!StringUtils.isEmpty(sslService.getKeyStorePassword())) {
                settingsBuilder.put("xpack.ssl.keystore.password", sslService.getKeyStorePassword());
            }
            if (!StringUtils.isEmpty(sslService.getKeyPassword())) {
                settingsBuilder.put("xpack.ssl.keystore.key_password", sslService.getKeyPassword());
            }
            if (!StringUtils.isEmpty(sslService.getTrustStoreFile())) {
                settingsBuilder.put("xpack.ssl.truststore.path", sslService.getTrustStoreFile());
            }
            if (!StringUtils.isEmpty(sslService.getTrustStorePassword())) {
                settingsBuilder.put("xpack.ssl.truststore.password", sslService.getTrustStorePassword());
            }
        }

        // Set username and password for X-Pack
        if (!StringUtils.isEmpty(username)) {
            StringBuffer secureUser = new StringBuffer(username);
            if (!StringUtils.isEmpty(password)) {
                secureUser.append(":");
                secureUser.append(password);
            }
            settingsBuilder.put("xpack.security.user", secureUser);
        }

        final String hosts = context.getProperty(HOSTS).evaluateAttributeExpressions().getValue();
        esHosts = getEsHosts(hosts);
        Client transportClient = getTransportClient(settingsBuilder, xPackUrl, username, password, esHosts, log);
        esClient.set(transportClient);

    } catch (Exception e) {
        log.error("Failed to create Elasticsearch client due to {}", new Object[]{e}, e);
        throw new ProcessException(e);
    }
}
 
Example 20
@Override
public int receiveFlowFiles(final Peer peer, final ProcessContext context, final ProcessSession session, final FlowFileCodec codec) throws IOException, ProtocolException {
    if (!handshakeCompleted) {
        throw new IllegalStateException("Handshake has not been completed");
    }
    if (shutdown) {
        throw new IllegalStateException("Protocol is shutdown");
    }

    logger.debug("{} receiving FlowFiles from {}", this, peer);

    final CommunicationsSession commsSession = peer.getCommunicationsSession();
    final DataInputStream dis = new DataInputStream(commsSession.getInput().getInputStream());
    String remoteDn = commsSession.getUserDn();
    if (remoteDn == null) {
        remoteDn = "none";
    }

    final StopWatch stopWatch = new StopWatch(true);
    final CRC32 crc = new CRC32();

    // Peer has data. Otherwise, we would not have been called, because they would not have sent
    // a SEND_FLOWFILES request to use. Just decode the bytes into FlowFiles until peer says he's
    // finished sending data.
    final Set<FlowFile> flowFilesReceived = new HashSet<>();
    long bytesReceived = 0L;
    boolean continueTransaction = true;
    while (continueTransaction) {
        final long startNanos = System.nanoTime();
        final InputStream flowFileInputStream = handshakeProperties.isUseGzip() ? new CompressionInputStream(dis) : dis;
        final CheckedInputStream checkedInputStream = new CheckedInputStream(flowFileInputStream, crc);

        final DataPacket dataPacket = codec.decode(checkedInputStream);
        if (dataPacket == null) {
            logger.debug("{} Received null dataPacket indicating the end of transaction from {}", this, peer);
            break;
        }
        FlowFile flowFile = session.create();
        flowFile = session.importFrom(dataPacket.getData(), flowFile);
        flowFile = session.putAllAttributes(flowFile, dataPacket.getAttributes());

        final long transferNanos = System.nanoTime() - startNanos;
        final long transferMillis = TimeUnit.MILLISECONDS.convert(transferNanos, TimeUnit.NANOSECONDS);
        final String sourceSystemFlowFileUuid = dataPacket.getAttributes().get(CoreAttributes.UUID.key());

        final String host = StringUtils.isEmpty(peer.getHost()) ? "unknown" : peer.getHost();
        final String port = peer.getPort() <= 0 ? "unknown" : String.valueOf(peer.getPort());

        final Map<String,String> attributes = new HashMap<>(4);
        attributes.put(CoreAttributes.UUID.key(), UUID.randomUUID().toString());
        attributes.put(SiteToSiteAttributes.S2S_HOST.key(), host);
        attributes.put(SiteToSiteAttributes.S2S_ADDRESS.key(), host + ":" + port);

        flowFile = session.putAllAttributes(flowFile, attributes);

        final String transitUri = createTransitUri(peer, sourceSystemFlowFileUuid);
        session.getProvenanceReporter().receive(flowFile, transitUri, sourceSystemFlowFileUuid == null
                ? null : "urn:nifi:" + sourceSystemFlowFileUuid, "Remote Host=" + peer.getHost() + ", Remote DN=" + remoteDn, transferMillis);
        session.transfer(flowFile, Relationship.ANONYMOUS);
        flowFilesReceived.add(flowFile);
        bytesReceived += flowFile.getSize();

        final Response transactionResponse = readTransactionResponse(false, commsSession);
        switch (transactionResponse.getCode()) {
            case CONTINUE_TRANSACTION:
                logger.debug("{} Received ContinueTransaction indicator from {}", this, peer);
                break;
            case FINISH_TRANSACTION:
                logger.debug("{} Received FinishTransaction indicator from {}", this, peer);
                continueTransaction = false;
                break;
            case CANCEL_TRANSACTION:
                logger.info("{} Received CancelTransaction indicator from {} with explanation {}", this, peer, transactionResponse.getMessage());
                session.rollback();
                return 0;
            default:
                throw new ProtocolException("Received unexpected response from peer: when expecting Continue Transaction or Finish Transaction, received" + transactionResponse);
        }
    }

    // we received a FINISH_TRANSACTION indicator. Send back a CONFIRM_TRANSACTION message
    // to peer so that we can verify that the connection is still open. This is a two-phase commit,
    // which helps to prevent the chances of data duplication. Without doing this, we may commit the
    // session and then when we send the response back to the peer, the peer may have timed out and may not
    // be listening. As a result, it will re-send the data. By doing this two-phase commit, we narrow the
    // Critical Section involved in this transaction so that rather than the Critical Section being the
    // time window involved in the entire transaction, it is reduced to a simple round-trip conversation.
    logger.debug("{} Sending CONFIRM_TRANSACTION Response Code to {}", this, peer);
    String calculatedCRC = String.valueOf(crc.getValue());
    writeTransactionResponse(false, ResponseCode.CONFIRM_TRANSACTION, commsSession, calculatedCRC);

    FlowFileTransaction transaction = new FlowFileTransaction(session, context, stopWatch, bytesReceived, flowFilesReceived, calculatedCRC);
    return commitReceiveTransaction(peer, transaction);
}