Search in sources :

Example 1 with HandshakeException

use of org.apache.nifi.remote.exception.HandshakeException in project nifi by apache.

the class DataTransferResource method transferFlowFiles.

@GET
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_OCTET_STREAM)
@Path("output-ports/{portId}/transactions/{transactionId}/flow-files")
@ApiOperation(value = "Transfer flow files from the output port", response = StreamingOutput.class, authorizations = { @Authorization(value = "Write - /data-transfer/output-ports/{uuid}") })
@ApiResponses(value = { @ApiResponse(code = 200, message = "There is no flow file to return."), @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), @ApiResponse(code = 401, message = "Client could not be authenticated."), @ApiResponse(code = 403, message = "Client is not authorized to make this request."), @ApiResponse(code = 404, message = "The specified resource could not be found."), @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful."), @ApiResponse(code = 503, message = "NiFi instance is not ready for serving request, or temporarily overloaded. Retrying the same request later may be successful") })
public Response transferFlowFiles(@ApiParam(value = "The output port id.", required = true) @PathParam("portId") String portId, @PathParam("transactionId") String transactionId, @Context HttpServletRequest req, @Context HttpServletResponse res, @Context ServletContext context, InputStream inputStream) {
    // authorize access
    serviceFacade.authorizeAccess(lookup -> {
        authorizeDataTransfer(lookup, ResourceType.OutputPort, portId);
    });
    final ValidateRequestResult validationResult = validateResult(req, portId, transactionId);
    if (validationResult.errResponse != null) {
        return validationResult.errResponse;
    }
    logger.debug("transferFlowFiles request: portId={}", portId);
    // Before opening the real output stream for HTTP response,
    // use this temporary output stream to buffer handshake result.
    final ByteArrayOutputStream tempBos = new ByteArrayOutputStream();
    final Peer peer = constructPeer(req, inputStream, tempBos, portId, transactionId);
    final int transportProtocolVersion = validationResult.transportProtocolVersion;
    try {
        final HttpFlowFileServerProtocol serverProtocol = initiateServerProtocol(req, peer, transportProtocolVersion);
        StreamingOutput flowFileContent = new StreamingOutput() {

            @Override
            public void write(OutputStream outputStream) throws IOException, WebApplicationException {
                HttpOutput output = (HttpOutput) peer.getCommunicationsSession().getOutput();
                output.setOutputStream(outputStream);
                try {
                    int numOfFlowFiles = serverProtocol.getPort().transferFlowFiles(peer, serverProtocol);
                    logger.debug("finished transferring flow files, numOfFlowFiles={}", numOfFlowFiles);
                    if (numOfFlowFiles < 1) {
                        // There was no flow file to transfer. Throw this exception to stop responding with SEE OTHER.
                        throw new WebApplicationException(Response.Status.OK);
                    }
                } catch (NotAuthorizedException | BadRequestException | RequestExpiredException e) {
                    // Handshake is done outside of write() method, so these exception wouldn't be thrown.
                    throw new IOException("Failed to process the request.", e);
                }
            }
        };
        return responseCreator.acceptedResponse(transactionManager, flowFileContent, transportProtocolVersion);
    } catch (HandshakeException e) {
        return responseCreator.handshakeExceptionResponse(e);
    } catch (Exception e) {
        return responseCreator.unexpectedErrorResponse(portId, e);
    }
}
Also used : WebApplicationException(javax.ws.rs.WebApplicationException) Peer(org.apache.nifi.remote.Peer) OutputStream(java.io.OutputStream) ByteArrayOutputStream(org.apache.nifi.stream.io.ByteArrayOutputStream) StandardHttpFlowFileServerProtocol(org.apache.nifi.remote.protocol.http.StandardHttpFlowFileServerProtocol) HttpFlowFileServerProtocol(org.apache.nifi.remote.protocol.http.HttpFlowFileServerProtocol) StreamingOutput(javax.ws.rs.core.StreamingOutput) RequestExpiredException(org.apache.nifi.remote.exception.RequestExpiredException) ByteArrayOutputStream(org.apache.nifi.stream.io.ByteArrayOutputStream) HttpOutput(org.apache.nifi.remote.io.http.HttpOutput) NotAuthorizedException(org.apache.nifi.remote.exception.NotAuthorizedException) IOException(java.io.IOException) BadRequestException(org.apache.nifi.remote.exception.BadRequestException) HandshakeException(org.apache.nifi.remote.exception.HandshakeException) WebApplicationException(javax.ws.rs.WebApplicationException) AccessDeniedException(org.apache.nifi.authorization.AccessDeniedException) NotAuthorizedException(org.apache.nifi.remote.exception.NotAuthorizedException) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) RequestExpiredException(org.apache.nifi.remote.exception.RequestExpiredException) BadRequestException(org.apache.nifi.remote.exception.BadRequestException) HandshakeException(org.apache.nifi.remote.exception.HandshakeException) Path(javax.ws.rs.Path) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Example 2 with HandshakeException

use of org.apache.nifi.remote.exception.HandshakeException in project nifi by apache.

the class AbstractFlowFileServerProtocol method validateHandshakeRequest.

protected void validateHandshakeRequest(HandshakeProperties confirmed, final Peer peer, final Map<String, String> properties) throws HandshakeException {
    Boolean useGzip = null;
    for (final Map.Entry<String, String> entry : properties.entrySet()) {
        final String propertyName = entry.getKey();
        final String value = entry.getValue();
        final HandshakeProperty property;
        try {
            property = HandshakeProperty.valueOf(propertyName);
        } catch (final Exception e) {
            throw new HandshakeException(ResponseCode.UNKNOWN_PROPERTY_NAME, "Received unknown property: " + propertyName);
        }
        try {
            switch(property) {
                case GZIP:
                    {
                        useGzip = Boolean.parseBoolean(value);
                        confirmed.setUseGzip(useGzip);
                        break;
                    }
                case REQUEST_EXPIRATION_MILLIS:
                    confirmed.setExpirationMillis(Long.parseLong(value));
                    break;
                case BATCH_COUNT:
                    confirmed.setBatchCount(Integer.parseInt(value));
                    break;
                case BATCH_SIZE:
                    confirmed.setBatchBytes(Long.parseLong(value));
                    break;
                case BATCH_DURATION:
                    confirmed.setBatchDurationNanos(TimeUnit.MILLISECONDS.toNanos(Long.parseLong(value)));
                    break;
                case PORT_IDENTIFIER:
                    {
                        checkPortStatus(peer, value);
                    }
            }
        } catch (final NumberFormatException nfe) {
            throw new HandshakeException(ResponseCode.ILLEGAL_PROPERTY_VALUE, "Received invalid value for property '" + property + "'; invalid value: " + value);
        }
    }
    if (useGzip == null) {
        logger.debug("Responding with ResponseCode MISSING_PROPERTY because GZIP Property missing");
        throw new HandshakeException(ResponseCode.MISSING_PROPERTY, "Missing Property " + HandshakeProperty.GZIP.name());
    }
}
Also used : HashMap(java.util.HashMap) Map(java.util.Map) HandshakeException(org.apache.nifi.remote.exception.HandshakeException) HandshakeException(org.apache.nifi.remote.exception.HandshakeException) IOException(java.io.IOException) ProtocolException(org.apache.nifi.remote.exception.ProtocolException)

Example 3 with HandshakeException

use of org.apache.nifi.remote.exception.HandshakeException in project nifi by apache.

the class AbstractFlowFileServerProtocol method checkPortStatus.

protected void checkPortStatus(final Peer peer, String portId) throws HandshakeException {
    Port receivedPort = rootGroup.getInputPort(portId);
    if (receivedPort == null) {
        receivedPort = rootGroup.getOutputPort(portId);
    }
    if (receivedPort == null) {
        logger.debug("Responding with ResponseCode UNKNOWN_PORT for identifier {}", portId);
        throw new HandshakeException(ResponseCode.UNKNOWN_PORT, "Received unknown port identifier: " + portId);
    }
    if (!(receivedPort instanceof RootGroupPort)) {
        logger.debug("Responding with ResponseCode UNKNOWN_PORT for identifier {}", portId);
        throw new HandshakeException(ResponseCode.UNKNOWN_PORT, "Received port identifier " + portId + ", but this Port is not a RootGroupPort");
    }
    this.port = (RootGroupPort) receivedPort;
    final PortAuthorizationResult portAuthResult = this.port.checkUserAuthorization(peer.getCommunicationsSession().getUserDn());
    if (!portAuthResult.isAuthorized()) {
        logger.debug("Responding with ResponseCode UNAUTHORIZED: ", portAuthResult.getExplanation());
        throw new HandshakeException(ResponseCode.UNAUTHORIZED, portAuthResult.getExplanation());
    }
    if (!receivedPort.isValid()) {
        logger.debug("Responding with ResponseCode PORT_NOT_IN_VALID_STATE for {}", receivedPort);
        throw new HandshakeException(ResponseCode.PORT_NOT_IN_VALID_STATE, "Port is not valid");
    }
    if (!receivedPort.isRunning()) {
        logger.debug("Responding with ResponseCode PORT_NOT_IN_VALID_STATE for {}", receivedPort);
        throw new HandshakeException(ResponseCode.PORT_NOT_IN_VALID_STATE, "Port not running");
    }
    // we we will simply not service the request but the sender will timeout
    if (getVersionNegotiator().getVersion() > 1) {
        for (final Connection connection : port.getConnections()) {
            if (connection.getFlowFileQueue().isFull()) {
                logger.debug("Responding with ResponseCode PORTS_DESTINATION_FULL for {}", port);
                throw new HandshakeException(ResponseCode.PORTS_DESTINATION_FULL, "Received port identifier " + portId + ", but its destination is full");
            }
        }
    }
}
Also used : RootGroupPort(org.apache.nifi.remote.RootGroupPort) Port(org.apache.nifi.connectable.Port) RootGroupPort(org.apache.nifi.remote.RootGroupPort) Connection(org.apache.nifi.connectable.Connection) HandshakeException(org.apache.nifi.remote.exception.HandshakeException) PortAuthorizationResult(org.apache.nifi.remote.PortAuthorizationResult)

Example 4 with HandshakeException

use of org.apache.nifi.remote.exception.HandshakeException in project nifi by apache.

the class TestHttpFlowFileServerProtocol method testIllegalHandshakeProperty.

@Test
public void testIllegalHandshakeProperty() throws Exception {
    final HttpFlowFileServerProtocol serverProtocol = getDefaultHttpFlowFileServerProtocol();
    final Peer peer = getDefaultPeer();
    ((HttpServerCommunicationsSession) peer.getCommunicationsSession()).getHandshakeParams().clear();
    try {
        serverProtocol.handshake(peer);
        fail();
    } catch (final HandshakeException e) {
        assertEquals(ResponseCode.MISSING_PROPERTY, e.getResponseCode());
    }
    assertFalse(serverProtocol.isHandshakeSuccessful());
}
Also used : Peer(org.apache.nifi.remote.Peer) HandshakeException(org.apache.nifi.remote.exception.HandshakeException) Test(org.junit.Test)

Example 5 with HandshakeException

use of org.apache.nifi.remote.exception.HandshakeException in project nifi by apache.

the class TestHttpFlowFileServerProtocol method testPortNotInValidState.

@Test
public void testPortNotInValidState() throws Exception {
    final HttpFlowFileServerProtocol serverProtocol = getDefaultHttpFlowFileServerProtocol();
    final Peer peer = getDefaultPeer();
    ((HttpServerCommunicationsSession) peer.getCommunicationsSession()).putHandshakeParam(HandshakeProperty.PORT_IDENTIFIER, "port-identifier");
    final ProcessGroup processGroup = mock(ProcessGroup.class);
    final RootGroupPort port = mock(RootGroupPort.class);
    final PortAuthorizationResult authResult = mock(PortAuthorizationResult.class);
    doReturn(true).when(processGroup).isRootGroup();
    doReturn(port).when(processGroup).getOutputPort("port-identifier");
    doReturn(authResult).when(port).checkUserAuthorization(any(String.class));
    doReturn(true).when(authResult).isAuthorized();
    serverProtocol.setRootProcessGroup(processGroup);
    try {
        serverProtocol.handshake(peer);
        fail();
    } catch (final HandshakeException e) {
        assertEquals(ResponseCode.PORT_NOT_IN_VALID_STATE, e.getResponseCode());
    }
    assertFalse(serverProtocol.isHandshakeSuccessful());
}
Also used : HttpServerCommunicationsSession(org.apache.nifi.remote.io.http.HttpServerCommunicationsSession) RootGroupPort(org.apache.nifi.remote.RootGroupPort) Peer(org.apache.nifi.remote.Peer) ProcessGroup(org.apache.nifi.groups.ProcessGroup) PortAuthorizationResult(org.apache.nifi.remote.PortAuthorizationResult) HandshakeException(org.apache.nifi.remote.exception.HandshakeException) Test(org.junit.Test)

Aggregations

HandshakeException (org.apache.nifi.remote.exception.HandshakeException)26 Peer (org.apache.nifi.remote.Peer)13 IOException (java.io.IOException)10 Test (org.junit.Test)10 TransactionResultEntity (org.apache.nifi.web.api.entity.TransactionResultEntity)9 HttpFlowFileServerProtocol (org.apache.nifi.remote.protocol.http.HttpFlowFileServerProtocol)8 HttpServerCommunicationsSession (org.apache.nifi.remote.io.http.HttpServerCommunicationsSession)7 UnknownHostException (java.net.UnknownHostException)6 WebApplicationException (javax.ws.rs.WebApplicationException)6 AccessDeniedException (org.apache.nifi.authorization.AccessDeniedException)6 BadRequestException (org.apache.nifi.remote.exception.BadRequestException)6 NotAuthorizedException (org.apache.nifi.remote.exception.NotAuthorizedException)6 RequestExpiredException (org.apache.nifi.remote.exception.RequestExpiredException)6 ApiOperation (io.swagger.annotations.ApiOperation)5 ApiResponses (io.swagger.annotations.ApiResponses)5 DataInputStream (java.io.DataInputStream)5 DataOutputStream (java.io.DataOutputStream)5 Path (javax.ws.rs.Path)5 Produces (javax.ws.rs.Produces)5 ProtocolException (org.apache.nifi.remote.exception.ProtocolException)5