Search in sources :

Example 41 with NodeResponse

use of org.apache.nifi.cluster.manager.NodeResponse in project nifi by apache.

the class TestThreadPoolRequestReplicator method testResponseRemovedWhenCompletedAndFetched.

/**
 * If we replicate a request, whenever we obtain the merged response from
 * the AsyncClusterResponse object, the response should no longer be
 * available and should be cleared from internal state. This test is to
 * verify that this behavior occurs.
 */
@Test
public void testResponseRemovedWhenCompletedAndFetched() {
    withReplicator(replicator -> {
        final Set<NodeIdentifier> nodeIds = new HashSet<>();
        nodeIds.add(new NodeIdentifier("1", "localhost", 8000, "localhost", 8001, "localhost", 8002, 8003, false));
        final URI uri = new URI("http://localhost:8080/processors/1");
        final Entity entity = new ProcessorEntity();
        // set the user
        final Authentication authentication = new NiFiAuthenticationToken(new NiFiUserDetails(StandardNiFiUser.ANONYMOUS));
        SecurityContextHolder.getContext().setAuthentication(authentication);
        final AsyncClusterResponse response = replicator.replicate(nodeIds, HttpMethod.GET, uri, entity, new HashMap<>(), true, true);
        // We should get back the same response object
        assertTrue(response == replicator.getClusterResponse(response.getRequestIdentifier()));
        assertEquals(HttpMethod.GET, response.getMethod());
        assertEquals(nodeIds, response.getNodesInvolved());
        assertTrue(response == replicator.getClusterResponse(response.getRequestIdentifier()));
        final NodeResponse nodeResponse = response.awaitMergedResponse(3, TimeUnit.SECONDS);
        assertEquals(8000, nodeResponse.getNodeId().getApiPort());
        assertEquals(Response.Status.OK.getStatusCode(), nodeResponse.getStatus());
        assertNull(replicator.getClusterResponse(response.getRequestIdentifier()));
    });
}
Also used : ProcessorEntity(org.apache.nifi.web.api.entity.ProcessorEntity) Entity(org.apache.nifi.web.api.entity.Entity) Authentication(org.springframework.security.core.Authentication) NodeIdentifier(org.apache.nifi.cluster.protocol.NodeIdentifier) NodeResponse(org.apache.nifi.cluster.manager.NodeResponse) ProcessorEntity(org.apache.nifi.web.api.entity.ProcessorEntity) URI(java.net.URI) NiFiUserDetails(org.apache.nifi.authorization.user.NiFiUserDetails) HashSet(java.util.HashSet) NiFiAuthenticationToken(org.apache.nifi.web.security.token.NiFiAuthenticationToken) Test(org.junit.Test)

Example 42 with NodeResponse

use of org.apache.nifi.cluster.manager.NodeResponse in project nifi by apache.

the class TestThreadPoolRequestReplicator method testLongWaitForResponse.

@Test(timeout = 15000)
public void testLongWaitForResponse() {
    withReplicator(replicator -> {
        final Set<NodeIdentifier> nodeIds = new HashSet<>();
        final NodeIdentifier nodeId = new NodeIdentifier("1", "localhost", 8000, "localhost", 8001, "localhost", 8002, 8003, false);
        nodeIds.add(nodeId);
        final URI uri = new URI("http://localhost:8080/processors/1");
        final Entity entity = new ProcessorEntity();
        // set the user
        final Authentication authentication = new NiFiAuthenticationToken(new NiFiUserDetails(StandardNiFiUser.ANONYMOUS));
        SecurityContextHolder.getContext().setAuthentication(authentication);
        final AsyncClusterResponse response = replicator.replicate(nodeIds, HttpMethod.GET, uri, entity, new HashMap<>(), true, true);
        // We should get back the same response object
        assertTrue(response == replicator.getClusterResponse(response.getRequestIdentifier()));
        final NodeResponse completedNodeResponse = response.awaitMergedResponse(2, TimeUnit.SECONDS);
        assertNotNull(completedNodeResponse);
        assertNotNull(completedNodeResponse.getThrowable());
        assertEquals(500, completedNodeResponse.getStatus());
        assertTrue(response.isComplete());
        assertNotNull(response.getMergedResponse());
        assertNull(replicator.getClusterResponse(response.getRequestIdentifier()));
    }, Status.OK, 1000, new ProcessingException(new SocketTimeoutException()));
}
Also used : ProcessorEntity(org.apache.nifi.web.api.entity.ProcessorEntity) Entity(org.apache.nifi.web.api.entity.Entity) NodeResponse(org.apache.nifi.cluster.manager.NodeResponse) ProcessorEntity(org.apache.nifi.web.api.entity.ProcessorEntity) URI(java.net.URI) NiFiAuthenticationToken(org.apache.nifi.web.security.token.NiFiAuthenticationToken) SocketTimeoutException(java.net.SocketTimeoutException) Authentication(org.springframework.security.core.Authentication) NodeIdentifier(org.apache.nifi.cluster.protocol.NodeIdentifier) NiFiUserDetails(org.apache.nifi.authorization.user.NiFiUserDetails) HashSet(java.util.HashSet) ProcessingException(javax.ws.rs.ProcessingException) Test(org.junit.Test)

Example 43 with NodeResponse

use of org.apache.nifi.cluster.manager.NodeResponse in project nifi by apache.

the class StandardNiFiContentAccess method getContent.

@Override
public DownloadableContent getContent(final ContentRequestContext request) {
    // if clustered, send request to cluster manager
    if (properties.isClustered() && clusterCoordinator != null && clusterCoordinator.isConnected()) {
        // get the URI
        URI dataUri;
        try {
            dataUri = new URI(request.getDataUri());
        } catch (final URISyntaxException use) {
            throw new ClusterRequestException(use);
        }
        // set the request parameters
        final MultivaluedMap<String, String> parameters = new MultivaluedHashMap();
        parameters.add(CLIENT_ID_PARAM, request.getClientId());
        // set the headers
        final Map<String, String> headers = new HashMap<>();
        // ensure we were able to detect the cluster node id
        if (request.getClusterNodeId() == null) {
            throw new IllegalArgumentException("Unable to determine the which node has the content.");
        }
        // get the target node and ensure it exists
        final NodeIdentifier nodeId = clusterCoordinator.getNodeIdentifier(request.getClusterNodeId());
        // replicate the request to the cluster coordinator, indicating the target node
        NodeResponse nodeResponse;
        try {
            headers.put(RequestReplicator.REPLICATION_TARGET_NODE_UUID_HEADER, nodeId.getId());
            final NodeIdentifier coordinatorNode = clusterCoordinator.getElectedActiveCoordinatorNode();
            if (coordinatorNode == null) {
                throw new NoClusterCoordinatorException();
            }
            final Set<NodeIdentifier> coordinatorNodes = Collections.singleton(coordinatorNode);
            nodeResponse = requestReplicator.replicate(coordinatorNodes, HttpMethod.GET, dataUri, parameters, headers, false, true).awaitMergedResponse();
        } catch (InterruptedException e) {
            throw new IllegalClusterStateException("Interrupted while waiting for a response from node");
        }
        final Response clientResponse = nodeResponse.getClientResponse();
        final MultivaluedMap<String, String> responseHeaders = clientResponse.getStringHeaders();
        // ensure an appropriate response
        if (Response.Status.NOT_FOUND.getStatusCode() == clientResponse.getStatusInfo().getStatusCode()) {
            throw new ResourceNotFoundException(clientResponse.readEntity(String.class));
        } else if (Response.Status.FORBIDDEN.getStatusCode() == clientResponse.getStatusInfo().getStatusCode() || Response.Status.UNAUTHORIZED.getStatusCode() == clientResponse.getStatusInfo().getStatusCode()) {
            throw new AccessDeniedException(clientResponse.readEntity(String.class));
        } else if (Response.Status.OK.getStatusCode() != clientResponse.getStatusInfo().getStatusCode()) {
            throw new IllegalStateException(clientResponse.readEntity(String.class));
        }
        // get the file name
        final String contentDisposition = responseHeaders.getFirst("Content-Disposition");
        final String filename = StringUtils.substringBetween(contentDisposition, "filename=\"", "\"");
        // get the content type
        final String contentType = responseHeaders.getFirst("Content-Type");
        // create the downloadable content
        return new DownloadableContent(filename, contentType, nodeResponse.getInputStream());
    } else {
        // example URIs:
        // http://localhost:8080/nifi-api/provenance/events/{id}/content/{input|output}
        // http://localhost:8080/nifi-api/flowfile-queues/{uuid}/flowfiles/{uuid}/content
        // get just the context path for comparison
        final String dataUri = StringUtils.substringAfter(request.getDataUri(), "/nifi-api");
        if (StringUtils.isBlank(dataUri)) {
            throw new IllegalArgumentException("The specified data reference URI is not valid.");
        }
        // flowfile listing content
        final Matcher flowFileMatcher = FLOWFILE_CONTENT_URI_PATTERN.matcher(dataUri);
        if (flowFileMatcher.matches()) {
            final String connectionId = flowFileMatcher.group(1);
            final String flowfileId = flowFileMatcher.group(2);
            return getFlowFileContent(connectionId, flowfileId, dataUri);
        }
        // provenance event content
        final Matcher provenanceMatcher = PROVENANCE_CONTENT_URI_PATTERN.matcher(dataUri);
        if (provenanceMatcher.matches()) {
            try {
                final Long eventId = Long.parseLong(provenanceMatcher.group(1));
                final ContentDirection direction = ContentDirection.valueOf(provenanceMatcher.group(2).toUpperCase());
                return getProvenanceEventContent(eventId, dataUri, direction);
            } catch (final IllegalArgumentException iae) {
                throw new IllegalArgumentException("The specified data reference URI is not valid.");
            }
        }
        // invalid uri
        throw new IllegalArgumentException("The specified data reference URI is not valid.");
    }
}
Also used : AccessDeniedException(org.apache.nifi.authorization.AccessDeniedException) HashMap(java.util.HashMap) MultivaluedHashMap(javax.ws.rs.core.MultivaluedHashMap) Matcher(java.util.regex.Matcher) IllegalClusterStateException(org.apache.nifi.cluster.manager.exception.IllegalClusterStateException) NodeResponse(org.apache.nifi.cluster.manager.NodeResponse) URISyntaxException(java.net.URISyntaxException) URI(java.net.URI) MultivaluedHashMap(javax.ws.rs.core.MultivaluedHashMap) Response(javax.ws.rs.core.Response) NodeResponse(org.apache.nifi.cluster.manager.NodeResponse) NoClusterCoordinatorException(org.apache.nifi.cluster.exception.NoClusterCoordinatorException) ContentDirection(org.apache.nifi.controller.repository.claim.ContentDirection) NodeIdentifier(org.apache.nifi.cluster.protocol.NodeIdentifier)

Example 44 with NodeResponse

use of org.apache.nifi.cluster.manager.NodeResponse in project nifi by apache.

the class StandardHttpResponseMapper method mapResponses.

@Override
public NodeResponse mapResponses(final URI uri, final String httpMethod, final Set<NodeResponse> nodeResponses, final boolean merge) {
    final boolean hasSuccess = hasSuccessfulResponse(nodeResponses);
    if (!hasSuccess) {
        // If we have a response that is a 3xx, 4xx, or 5xx, then we want to choose that.
        // Otherwise, it doesn't matter which one we choose. We do this because if we replicate
        // a mutable request, it's possible that one node will respond with a 409, for instance, while
        // others respond with a 150-Continue. We do not want to pick the 150-Continue; instead, we want
        // the failed response.
        final NodeResponse clientResponse = nodeResponses.stream().filter(p -> p.getStatus() > 299).findAny().orElse(nodeResponses.iterator().next());
        // Drain the response from all nodes except for the 'chosen one'. This ensures that we don't
        // leave data lingering on the socket and ensures that we don't consume the content of the response
        // that we intend to respond with
        drainResponses(nodeResponses, clientResponse);
        return clientResponse;
    }
    // Determine which responses are successful
    final Set<NodeResponse> successResponses = nodeResponses.stream().filter(p -> p.is2xx()).collect(Collectors.toSet());
    final Set<NodeResponse> problematicResponses = nodeResponses.stream().filter(p -> !p.is2xx()).collect(Collectors.toSet());
    final NodeResponse clientResponse;
    if ("GET".equalsIgnoreCase(httpMethod) && problematicResponses.size() > 0) {
        // If there are problematic responses, at least one of the nodes couldn't complete the request
        clientResponse = problematicResponses.stream().filter(p -> p.getStatus() >= 400 && p.getStatus() < 500).findFirst().orElse(problematicResponses.stream().filter(p -> p.getStatus() > 500).findFirst().orElse(problematicResponses.iterator().next()));
        return clientResponse;
    } else {
        // Choose any of the successful responses to be the 'chosen one'.
        clientResponse = successResponses.iterator().next();
    }
    if (merge == false) {
        return clientResponse;
    }
    EndpointResponseMerger merger = getEndpointResponseMerger(uri, httpMethod);
    if (merger == null) {
        return clientResponse;
    }
    final NodeResponse response = merger.merge(uri, httpMethod, successResponses, problematicResponses, clientResponse);
    return response;
}
Also used : FlowConfigurationEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.FlowConfigurationEndpointMerger) ControllerServiceTypesEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.ControllerServiceTypesEndpointMerger) FlowMerger(org.apache.nifi.cluster.coordination.http.endpoints.FlowMerger) CurrentUserEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.CurrentUserEndpointMerger) ComponentStateEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.ComponentStateEndpointMerger) LoggerFactory(org.slf4j.LoggerFactory) RemoteProcessGroupEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.RemoteProcessGroupEndpointMerger) ProcessGroupsEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.ProcessGroupsEndpointMerger) PortEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.PortEndpointMerger) FunnelsEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.FunnelsEndpointMerger) ListFlowFilesEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.ListFlowFilesEndpointMerger) ControllerConfigurationEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.ControllerConfigurationEndpointMerger) DropRequestEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.DropRequestEndpointMerger) GroupStatusEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.GroupStatusEndpointMerger) ControllerServicesEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.ControllerServicesEndpointMerger) ProvenanceEventEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.ProvenanceEventEndpointMerger) RequestReplicator(org.apache.nifi.cluster.coordination.http.replication.RequestReplicator) URI(java.net.URI) ConnectionStatusEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.ConnectionStatusEndpointMerger) ProcessorTypesEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.ProcessorTypesEndpointMerger) NodeResponse(org.apache.nifi.cluster.manager.NodeResponse) UsersEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.UsersEndpointMerger) UserGroupEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.UserGroupEndpointMerger) NullOutputStream(org.apache.nifi.stream.io.NullOutputStream) UserEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.UserEndpointMerger) Set(java.util.Set) StreamingOutput(javax.ws.rs.core.StreamingOutput) RemoteProcessGroupStatusEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.RemoteProcessGroupStatusEndpointMerger) Collectors(java.util.stream.Collectors) ProcessorStatusEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.ProcessorStatusEndpointMerger) List(java.util.List) AccessPolicyEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.AccessPolicyEndpointMerger) FlowSnippetEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.FlowSnippetEndpointMerger) ProcessGroupEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.ProcessGroupEndpointMerger) ReportingTasksEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.ReportingTasksEndpointMerger) ConnectionEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.ConnectionEndpointMerger) OutputPortsEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.OutputPortsEndpointMerger) RemoteProcessGroupsEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.RemoteProcessGroupsEndpointMerger) VariableRegistryEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.VariableRegistryEndpointMerger) CountersEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.CountersEndpointMerger) PrioritizerTypesEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.PrioritizerTypesEndpointMerger) ProvenanceQueryEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.ProvenanceQueryEndpointMerger) SearchUsersEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.SearchUsersEndpointMerger) ControllerEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.ControllerEndpointMerger) UserGroupsEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.UserGroupsEndpointMerger) LabelsEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.LabelsEndpointMerger) ReportingTaskEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.ReportingTaskEndpointMerger) ArrayList(java.util.ArrayList) PortStatusEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.PortStatusEndpointMerger) ConnectionsEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.ConnectionsEndpointMerger) ProcessorDiagnosticsEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.ProcessorDiagnosticsEndpointMerger) ProcessorEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.ProcessorEndpointMerger) Logger(org.slf4j.Logger) ReportingTaskTypesEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.ReportingTaskTypesEndpointMerger) ControllerServiceEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.ControllerServiceEndpointMerger) IOException(java.io.IOException) LabelEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.LabelEndpointMerger) TimeUnit(java.util.concurrent.TimeUnit) ProcessorsEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.ProcessorsEndpointMerger) ControllerBulletinsEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.ControllerBulletinsEndpointMerger) FormatUtils(org.apache.nifi.util.FormatUtils) NiFiProperties(org.apache.nifi.util.NiFiProperties) BulletinBoardEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.BulletinBoardEndpointMerger) InputPortsEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.InputPortsEndpointMerger) ControllerServiceReferenceEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.ControllerServiceReferenceEndpointMerger) SystemDiagnosticsEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.SystemDiagnosticsEndpointMerger) ControllerStatusEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.ControllerStatusEndpointMerger) FunnelEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.FunnelEndpointMerger) TemplatesEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.TemplatesEndpointMerger) StatusHistoryEndpointMerger(org.apache.nifi.cluster.coordination.http.endpoints.StatusHistoryEndpointMerger) NodeResponse(org.apache.nifi.cluster.manager.NodeResponse)

Example 45 with NodeResponse

use of org.apache.nifi.cluster.manager.NodeResponse in project nifi by apache.

the class AbstractNodeStatusEndpoint method mergeResponses.

@Override
protected final void mergeResponses(DtoType clientDto, Map<NodeIdentifier, DtoType> dtoMap, Set<NodeResponse> successfulResponses, Set<NodeResponse> problematicResponses) {
    final NodeIdentifier selectedNodeId = dtoMap.entrySet().stream().filter(e -> e.getValue() == clientDto).map(e -> e.getKey()).findFirst().orElse(null);
    if (selectedNodeId == null) {
        throw new IllegalArgumentException("Attempted to merge Status request but could not find the appropriate Node Identifier");
    }
    mergeResponses(clientDto, dtoMap, selectedNodeId);
}
Also used : NodeIdentifier(org.apache.nifi.cluster.protocol.NodeIdentifier) Map(java.util.Map) Set(java.util.Set) Entity(org.apache.nifi.web.api.entity.Entity) NodeResponse(org.apache.nifi.cluster.manager.NodeResponse) NodeIdentifier(org.apache.nifi.cluster.protocol.NodeIdentifier)

Aggregations

NodeResponse (org.apache.nifi.cluster.manager.NodeResponse)64 HashMap (java.util.HashMap)44 NodeIdentifier (org.apache.nifi.cluster.protocol.NodeIdentifier)44 Map (java.util.Map)38 URI (java.net.URI)32 Set (java.util.Set)23 URISyntaxException (java.net.URISyntaxException)17 ProcessorEntity (org.apache.nifi.web.api.entity.ProcessorEntity)16 MultivaluedHashMap (javax.ws.rs.core.MultivaluedHashMap)15 ApiOperation (io.swagger.annotations.ApiOperation)12 ApiResponses (io.swagger.annotations.ApiResponses)12 HashSet (java.util.HashSet)12 Collectors (java.util.stream.Collectors)12 Consumes (javax.ws.rs.Consumes)12 GET (javax.ws.rs.GET)12 Produces (javax.ws.rs.Produces)12 Response (javax.ws.rs.core.Response)12 ArrayList (java.util.ArrayList)11 Pattern (java.util.regex.Pattern)11 Path (javax.ws.rs.Path)11