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);
}
}
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());
}
}
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");
}
}
}
}
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());
}
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());
}
Aggregations