Search in sources :

Example 1 with RequestExpiredException

use of org.apache.nifi.remote.exception.RequestExpiredException 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 RequestExpiredException

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

the class StandardRootGroupPort method transferFlowFiles.

@Override
public int transferFlowFiles(final Peer peer, final ServerProtocol serverProtocol) throws NotAuthorizedException, BadRequestException, RequestExpiredException {
    if (getConnectableType() != ConnectableType.OUTPUT_PORT) {
        throw new IllegalStateException("Cannot send FlowFiles because this port is not an Output Port");
    }
    if (!this.isRunning()) {
        throw new IllegalStateException("Port not running");
    }
    try {
        final FlowFileRequest request = new FlowFileRequest(peer, serverProtocol);
        if (!this.requestQueue.offer(request)) {
            throw new RequestExpiredException();
        }
        // Trigger this port to run
        scheduler.registerEvent(this);
        // Get a response from the response queue but don't wait forever if the port is stopped
        ProcessingResult result = null;
        // before the request expires
        while (!request.isBeingServiced()) {
            if (request.isExpired()) {
                // Remove expired request, so that it won't block new request to be offered.
                this.requestQueue.remove(request);
                throw new SocketTimeoutException("Read timed out");
            } else {
                try {
                    Thread.sleep(100L);
                } catch (final InterruptedException e) {
                }
            }
        }
        // we've started to service the request. Now just wait until it's finished
        result = request.getResponseQueue().take();
        final Exception problem = result.getProblem();
        if (problem == null) {
            return result.getFileCount();
        } else {
            throw problem;
        }
    } catch (final NotAuthorizedException | BadRequestException | RequestExpiredException e) {
        throw e;
    } catch (final ProtocolException e) {
        throw new BadRequestException(e);
    } catch (final Exception e) {
        throw new ProcessException(e);
    }
}
Also used : ProtocolException(org.apache.nifi.remote.exception.ProtocolException) ProcessException(org.apache.nifi.processor.exception.ProcessException) SocketTimeoutException(java.net.SocketTimeoutException) BadRequestException(org.apache.nifi.remote.exception.BadRequestException) RequestExpiredException(org.apache.nifi.remote.exception.RequestExpiredException) NotAuthorizedException(org.apache.nifi.remote.exception.NotAuthorizedException) BadRequestException(org.apache.nifi.remote.exception.BadRequestException) ProtocolException(org.apache.nifi.remote.exception.ProtocolException) TransmissionDisabledException(org.apache.nifi.remote.exception.TransmissionDisabledException) NotAuthorizedException(org.apache.nifi.remote.exception.NotAuthorizedException) ProcessException(org.apache.nifi.processor.exception.ProcessException) SocketTimeoutException(java.net.SocketTimeoutException) IOException(java.io.IOException) RequestExpiredException(org.apache.nifi.remote.exception.RequestExpiredException)

Example 3 with RequestExpiredException

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

the class StandardRootGroupPort method receiveFlowFiles.

@Override
public int receiveFlowFiles(final Peer peer, final ServerProtocol serverProtocol) throws NotAuthorizedException, BadRequestException, RequestExpiredException {
    if (getConnectableType() != ConnectableType.INPUT_PORT) {
        throw new IllegalStateException("Cannot receive FlowFiles because this port is not an Input Port");
    }
    if (!this.isRunning()) {
        throw new IllegalStateException("Port not running");
    }
    try {
        final FlowFileRequest request = new FlowFileRequest(peer, serverProtocol);
        if (!this.requestQueue.offer(request)) {
            throw new RequestExpiredException();
        }
        // Trigger this port to run.
        scheduler.registerEvent(this);
        // Get a response from the response queue but don't wait forever if the port is stopped
        ProcessingResult result = null;
        // before the request expires
        while (!request.isBeingServiced()) {
            if (request.isExpired()) {
                // Remove expired request, so that it won't block new request to be offered.
                this.requestQueue.remove(request);
                throw new SocketTimeoutException("Read timed out");
            } else {
                try {
                    Thread.sleep(100L);
                } catch (final InterruptedException e) {
                }
            }
        }
        // we've started to service the request. Now just wait until it's finished
        result = request.getResponseQueue().take();
        final Exception problem = result.getProblem();
        if (problem == null) {
            return result.getFileCount();
        } else {
            throw problem;
        }
    } catch (final NotAuthorizedException | BadRequestException | RequestExpiredException e) {
        throw e;
    } catch (final ProtocolException e) {
        throw new BadRequestException(e);
    } catch (final Exception e) {
        throw new ProcessException(e);
    }
}
Also used : ProtocolException(org.apache.nifi.remote.exception.ProtocolException) ProcessException(org.apache.nifi.processor.exception.ProcessException) SocketTimeoutException(java.net.SocketTimeoutException) BadRequestException(org.apache.nifi.remote.exception.BadRequestException) RequestExpiredException(org.apache.nifi.remote.exception.RequestExpiredException) NotAuthorizedException(org.apache.nifi.remote.exception.NotAuthorizedException) BadRequestException(org.apache.nifi.remote.exception.BadRequestException) ProtocolException(org.apache.nifi.remote.exception.ProtocolException) TransmissionDisabledException(org.apache.nifi.remote.exception.TransmissionDisabledException) NotAuthorizedException(org.apache.nifi.remote.exception.NotAuthorizedException) ProcessException(org.apache.nifi.processor.exception.ProcessException) SocketTimeoutException(java.net.SocketTimeoutException) IOException(java.io.IOException) RequestExpiredException(org.apache.nifi.remote.exception.RequestExpiredException)

Example 4 with RequestExpiredException

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

the class StandardRootGroupPort method onTrigger.

private void onTrigger(final ProcessContext context, final ProcessSession session, final FlowFileRequest flowFileRequest) {
    final ServerProtocol protocol = flowFileRequest.getProtocol();
    final BlockingQueue<ProcessingResult> responseQueue = flowFileRequest.getResponseQueue();
    if (flowFileRequest.isExpired()) {
        final String message = String.format("%s Cannot service request from %s because the request has timed out", this, flowFileRequest.getPeer());
        logger.warn(message);
        eventReporter.reportEvent(Severity.WARNING, CATEGORY, message);
        responseQueue.add(new ProcessingResult(new RequestExpiredException()));
        return;
    }
    final Peer peer = flowFileRequest.getPeer();
    final CommunicationsSession commsSession = peer.getCommunicationsSession();
    final String sourceDn = commsSession.getUserDn();
    logger.debug("{} Servicing request for {} (DN={})", this, peer, sourceDn);
    final PortAuthorizationResult authorizationResult = checkUserAuthorization(sourceDn);
    if (!authorizationResult.isAuthorized()) {
        final String message = String.format("%s Cannot service request from %s (DN=%s) because peer is not authorized to communicate with this port: %s", this, flowFileRequest.getPeer(), flowFileRequest.getPeer().getCommunicationsSession().getUserDn(), authorizationResult.getExplanation());
        logger.error(message);
        eventReporter.reportEvent(Severity.ERROR, CATEGORY, message);
        responseQueue.add(new ProcessingResult(new NotAuthorizedException(authorizationResult.getExplanation())));
        return;
    }
    final FlowFileCodec codec = protocol.getPreNegotiatedCodec();
    if (codec == null) {
        responseQueue.add(new ProcessingResult(new BadRequestException("None of the supported FlowFile Codecs supplied is compatible with this instance")));
        return;
    }
    final int transferCount;
    try {
        if (getConnectableType() == ConnectableType.INPUT_PORT) {
            transferCount = receiveFlowFiles(context, session, codec, flowFileRequest);
        } else {
            transferCount = transferFlowFiles(context, session, codec, flowFileRequest);
        }
    } catch (final IOException e) {
        session.rollback();
        responseQueue.add(new ProcessingResult(e));
        return;
    } catch (final Exception e) {
        session.rollback();
        responseQueue.add(new ProcessingResult(e));
        return;
    }
    // TODO: Comfirm this. Session.commit here is not required since it has been committed inside receiveFlowFiles/transferFlowFiles.
    // session.commit();
    responseQueue.add(new ProcessingResult(transferCount));
}
Also used : RequestExpiredException(org.apache.nifi.remote.exception.RequestExpiredException) CommunicationsSession(org.apache.nifi.remote.protocol.CommunicationsSession) NotAuthorizedException(org.apache.nifi.remote.exception.NotAuthorizedException) IOException(java.io.IOException) ServerProtocol(org.apache.nifi.remote.protocol.ServerProtocol) FlowFileCodec(org.apache.nifi.remote.codec.FlowFileCodec) BadRequestException(org.apache.nifi.remote.exception.BadRequestException) ProtocolException(org.apache.nifi.remote.exception.ProtocolException) TransmissionDisabledException(org.apache.nifi.remote.exception.TransmissionDisabledException) NotAuthorizedException(org.apache.nifi.remote.exception.NotAuthorizedException) ProcessException(org.apache.nifi.processor.exception.ProcessException) SocketTimeoutException(java.net.SocketTimeoutException) IOException(java.io.IOException) RequestExpiredException(org.apache.nifi.remote.exception.RequestExpiredException) BadRequestException(org.apache.nifi.remote.exception.BadRequestException)

Example 5 with RequestExpiredException

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

the class DataTransferResource method receiveFlowFiles.

@POST
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
@Produces(MediaType.TEXT_PLAIN)
@Path("input-ports/{portId}/transactions/{transactionId}/flow-files")
@ApiOperation(value = "Transfer flow files to the input port", response = String.class, authorizations = { @Authorization(value = "Write - /data-transfer/input-ports/{uuid}") })
@ApiResponses(value = { @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 receiveFlowFiles(@ApiParam(value = "The input port id.", required = true) @PathParam("portId") String portId, @PathParam("transactionId") String transactionId, @Context HttpServletRequest req, @Context ServletContext context, InputStream inputStream) {
    // authorize access
    serviceFacade.authorizeAccess(lookup -> {
        authorizeDataTransfer(lookup, ResourceType.InputPort, portId);
    });
    final ValidateRequestResult validationResult = validateResult(req, portId, transactionId);
    if (validationResult.errResponse != null) {
        return validationResult.errResponse;
    }
    logger.debug("receiveFlowFiles request: portId={}", portId);
    final ByteArrayOutputStream out = new ByteArrayOutputStream();
    final Peer peer = constructPeer(req, inputStream, out, portId, transactionId);
    final int transportProtocolVersion = validationResult.transportProtocolVersion;
    try {
        HttpFlowFileServerProtocol serverProtocol = initiateServerProtocol(req, peer, transportProtocolVersion);
        int numOfFlowFiles = serverProtocol.getPort().receiveFlowFiles(peer, serverProtocol);
        logger.debug("finished receiving flow files, numOfFlowFiles={}", numOfFlowFiles);
        if (numOfFlowFiles < 1) {
            return Response.status(Response.Status.BAD_REQUEST).entity("Client should send request when there is data to send. There was no flow file sent.").build();
        }
    } catch (HandshakeException e) {
        return responseCreator.handshakeExceptionResponse(e);
    } catch (NotAuthorizedException e) {
        return responseCreator.unauthorizedResponse(e);
    } catch (BadRequestException | RequestExpiredException e) {
        return responseCreator.badRequestResponse(e);
    } catch (Exception e) {
        return responseCreator.unexpectedErrorResponse(portId, e);
    }
    String serverChecksum = ((HttpServerCommunicationsSession) peer.getCommunicationsSession()).getChecksum();
    return responseCreator.acceptedResponse(transactionManager, serverChecksum, transportProtocolVersion);
}
Also used : HttpServerCommunicationsSession(org.apache.nifi.remote.io.http.HttpServerCommunicationsSession) Peer(org.apache.nifi.remote.Peer) StandardHttpFlowFileServerProtocol(org.apache.nifi.remote.protocol.http.StandardHttpFlowFileServerProtocol) HttpFlowFileServerProtocol(org.apache.nifi.remote.protocol.http.HttpFlowFileServerProtocol) RequestExpiredException(org.apache.nifi.remote.exception.RequestExpiredException) ByteArrayOutputStream(org.apache.nifi.stream.io.ByteArrayOutputStream) NotAuthorizedException(org.apache.nifi.remote.exception.NotAuthorizedException) 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) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Aggregations

IOException (java.io.IOException)5 BadRequestException (org.apache.nifi.remote.exception.BadRequestException)5 NotAuthorizedException (org.apache.nifi.remote.exception.NotAuthorizedException)5 RequestExpiredException (org.apache.nifi.remote.exception.RequestExpiredException)5 SocketTimeoutException (java.net.SocketTimeoutException)3 ProcessException (org.apache.nifi.processor.exception.ProcessException)3 ProtocolException (org.apache.nifi.remote.exception.ProtocolException)3 TransmissionDisabledException (org.apache.nifi.remote.exception.TransmissionDisabledException)3 ApiOperation (io.swagger.annotations.ApiOperation)2 ApiResponses (io.swagger.annotations.ApiResponses)2 UnknownHostException (java.net.UnknownHostException)2 Consumes (javax.ws.rs.Consumes)2 Path (javax.ws.rs.Path)2 Produces (javax.ws.rs.Produces)2 WebApplicationException (javax.ws.rs.WebApplicationException)2 AccessDeniedException (org.apache.nifi.authorization.AccessDeniedException)2 Peer (org.apache.nifi.remote.Peer)2 HandshakeException (org.apache.nifi.remote.exception.HandshakeException)2 HttpFlowFileServerProtocol (org.apache.nifi.remote.protocol.http.HttpFlowFileServerProtocol)2 StandardHttpFlowFileServerProtocol (org.apache.nifi.remote.protocol.http.StandardHttpFlowFileServerProtocol)2