Search in sources :

Example 1 with CompressionInputStream

use of org.apache.nifi.remote.io.CompressionInputStream in project nifi by apache.

the class TestHttpClient method readIncomingPacket.

private static DataPacket readIncomingPacket(HttpServletRequest req) throws IOException {
    final StandardFlowFileCodec codec = new StandardFlowFileCodec();
    InputStream inputStream = req.getInputStream();
    if (Boolean.valueOf(req.getHeader(HttpHeaders.HANDSHAKE_PROPERTY_USE_COMPRESSION))) {
        inputStream = new CompressionInputStream(inputStream);
    }
    return codec.decode(inputStream);
}
Also used : CompressionInputStream(org.apache.nifi.remote.io.CompressionInputStream) ByteArrayInputStream(org.apache.nifi.stream.io.ByteArrayInputStream) CompressionInputStream(org.apache.nifi.remote.io.CompressionInputStream) InputStream(java.io.InputStream) StandardFlowFileCodec(org.apache.nifi.remote.codec.StandardFlowFileCodec)

Example 2 with CompressionInputStream

use of org.apache.nifi.remote.io.CompressionInputStream in project nifi by apache.

the class TestCompressionInputOutputStreams method testSendingMultipleFilesBackToBackOnSameStream.

@Test
public void testSendingMultipleFilesBackToBackOnSameStream() throws IOException {
    final String str = "The quick brown fox jumps over the lazy dog\r\n\n\n\r";
    final byte[] data = str.getBytes("UTF-8");
    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
    final CompressionOutputStream cos = new CompressionOutputStream(baos, 8192);
    for (int i = 0; i < 512; i++) {
        cos.write(data);
        cos.flush();
    }
    cos.close();
    final CompressionOutputStream cos2 = new CompressionOutputStream(baos, 8192);
    for (int i = 0; i < 512; i++) {
        cos2.write(data);
        cos2.flush();
    }
    cos2.close();
    final byte[] data512;
    final StringBuilder sb = new StringBuilder();
    for (int i = 0; i < 512; i++) {
        sb.append(str);
    }
    data512 = sb.toString().getBytes("UTF-8");
    final byte[] compressedBytes = baos.toByteArray();
    final ByteArrayInputStream bais = new ByteArrayInputStream(compressedBytes);
    final CompressionInputStream cis = new CompressionInputStream(bais);
    final byte[] decompressed = readFully(cis);
    assertTrue(Arrays.equals(data512, decompressed));
    final CompressionInputStream cis2 = new CompressionInputStream(bais);
    final byte[] decompressed2 = readFully(cis2);
    assertTrue(Arrays.equals(data512, decompressed2));
}
Also used : CompressionOutputStream(org.apache.nifi.remote.io.CompressionOutputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) CompressionInputStream(org.apache.nifi.remote.io.CompressionInputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Test(org.junit.Test)

Example 3 with CompressionInputStream

use of org.apache.nifi.remote.io.CompressionInputStream in project nifi by apache.

the class AbstractFlowFileServerProtocol method receiveFlowFiles.

@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());
        if (handshakeProperties.isUseGzip()) {
            // Close CompressionInputStream to free acquired memory, without closing underlying stream.
            checkedInputStream.close();
        }
        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);
}
Also used : FlowFile(org.apache.nifi.flowfile.FlowFile) ProtocolException(org.apache.nifi.remote.exception.ProtocolException) CRC32(java.util.zip.CRC32) CompressionInputStream(org.apache.nifi.remote.io.CompressionInputStream) HashMap(java.util.HashMap) DataInputStream(java.io.DataInputStream) CheckedInputStream(java.util.zip.CheckedInputStream) CompressionInputStream(org.apache.nifi.remote.io.CompressionInputStream) InputStream(java.io.InputStream) DataInputStream(java.io.DataInputStream) StandardDataPacket(org.apache.nifi.remote.util.StandardDataPacket) CheckedInputStream(java.util.zip.CheckedInputStream) StopWatch(org.apache.nifi.util.StopWatch) HashSet(java.util.HashSet)

Example 4 with CompressionInputStream

use of org.apache.nifi.remote.io.CompressionInputStream in project nifi by apache.

the class AbstractTransaction method receive.

@Override
public final DataPacket receive() throws IOException {
    try {
        try {
            if (state != TransactionState.DATA_EXCHANGED && state != TransactionState.TRANSACTION_STARTED) {
                throw new IllegalStateException("Cannot receive data from " + peer + " because Transaction State is " + state);
            }
            if (direction == TransferDirection.SEND) {
                throw new IllegalStateException("Attempting to receive data from " + peer + " but started a SEND Transaction");
            }
            // if we already know there's no data, just return null
            if (!dataAvailable) {
                return null;
            }
            // if we have already received a packet, check if another is available.
            if (transfers > 0) {
                // Determine if Peer will send us data or has no data to send us
                final Response dataAvailableCode = readTransactionResponse();
                switch(dataAvailableCode.getCode()) {
                    case CONTINUE_TRANSACTION:
                        logger.debug("{} {} Indicates Transaction should continue", this, peer);
                        this.dataAvailable = true;
                        break;
                    case FINISH_TRANSACTION:
                        logger.debug("{} {} Indicates Transaction should finish", this, peer);
                        this.dataAvailable = false;
                        break;
                    default:
                        throw new ProtocolException("Got unexpected response from " + peer + " when asking for data: " + dataAvailableCode);
                }
            }
            // if no data available, return null
            if (!dataAvailable) {
                return null;
            }
            logger.debug("{} Receiving data from {}", this, peer);
            final InputStream is = peer.getCommunicationsSession().getInput().getInputStream();
            final InputStream dataIn = compress ? new CompressionInputStream(is) : is;
            final DataPacket packet = codec.decode(new CheckedInputStream(dataIn, crc));
            if (packet == null) {
                this.dataAvailable = false;
            } else {
                transfers++;
                contentBytes += packet.getSize();
            }
            this.state = TransactionState.DATA_EXCHANGED;
            return packet;
        } catch (final IOException ioe) {
            throw new IOException("Failed to receive data from " + peer + " due to " + ioe, ioe);
        }
    } catch (final Exception e) {
        error();
        throw e;
    }
}
Also used : Response(org.apache.nifi.remote.protocol.Response) ProtocolException(org.apache.nifi.remote.exception.ProtocolException) CompressionInputStream(org.apache.nifi.remote.io.CompressionInputStream) CheckedInputStream(java.util.zip.CheckedInputStream) CompressionInputStream(org.apache.nifi.remote.io.CompressionInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) IOException(java.io.IOException) StandardDataPacket(org.apache.nifi.remote.util.StandardDataPacket) DataPacket(org.apache.nifi.remote.protocol.DataPacket) CheckedInputStream(java.util.zip.CheckedInputStream) IOException(java.io.IOException) ProtocolException(org.apache.nifi.remote.exception.ProtocolException)

Example 5 with CompressionInputStream

use of org.apache.nifi.remote.io.CompressionInputStream in project nifi by apache.

the class TestCompressionInputOutputStreams method testDataLargerThanBufferWhileFlushing.

@Test
public void testDataLargerThanBufferWhileFlushing() throws IOException {
    final String str = "The quick brown fox jumps over the lazy dog\r\n\n\n\r";
    final byte[] data = str.getBytes("UTF-8");
    final StringBuilder sb = new StringBuilder();
    final byte[] data1024;
    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
    final CompressionOutputStream cos = new CompressionOutputStream(baos, 8192);
    for (int i = 0; i < 1024; i++) {
        cos.write(data);
        cos.flush();
        sb.append(str);
    }
    cos.close();
    data1024 = sb.toString().getBytes("UTF-8");
    final byte[] compressedBytes = baos.toByteArray();
    final CompressionInputStream cis = new CompressionInputStream(new ByteArrayInputStream(compressedBytes));
    final byte[] decompressed = readFully(cis);
    assertTrue(Arrays.equals(data1024, decompressed));
}
Also used : CompressionOutputStream(org.apache.nifi.remote.io.CompressionOutputStream) CompressionInputStream(org.apache.nifi.remote.io.CompressionInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Test(org.junit.Test)

Aggregations

CompressionInputStream (org.apache.nifi.remote.io.CompressionInputStream)7 ByteArrayInputStream (java.io.ByteArrayInputStream)5 ByteArrayOutputStream (java.io.ByteArrayOutputStream)4 CompressionOutputStream (org.apache.nifi.remote.io.CompressionOutputStream)4 Test (org.junit.Test)4 InputStream (java.io.InputStream)3 CheckedInputStream (java.util.zip.CheckedInputStream)2 ProtocolException (org.apache.nifi.remote.exception.ProtocolException)2 StandardDataPacket (org.apache.nifi.remote.util.StandardDataPacket)2 DataInputStream (java.io.DataInputStream)1 IOException (java.io.IOException)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 CRC32 (java.util.zip.CRC32)1 FlowFile (org.apache.nifi.flowfile.FlowFile)1 StandardFlowFileCodec (org.apache.nifi.remote.codec.StandardFlowFileCodec)1 DataPacket (org.apache.nifi.remote.protocol.DataPacket)1 Response (org.apache.nifi.remote.protocol.Response)1 ByteArrayInputStream (org.apache.nifi.stream.io.ByteArrayInputStream)1 StopWatch (org.apache.nifi.util.StopWatch)1