use of org.apache.nifi.web.api.entity.AffectedComponentEntity in project nifi by apache.
the class ClusterReplicationComponentLifecycle method activateControllerServices.
@Override
public Set<AffectedComponentEntity> activateControllerServices(final URI originalUri, final NiFiUser user, final String groupId, final Set<AffectedComponentEntity> affectedServices, final ControllerServiceState desiredState, final Pause pause) throws LifecycleManagementException {
final Set<String> affectedServiceIds = affectedServices.stream().map(component -> component.getId()).collect(Collectors.toSet());
final Map<String, Revision> serviceRevisionMap = getRevisions(groupId, affectedServiceIds);
final Map<String, RevisionDTO> serviceRevisionDtoMap = serviceRevisionMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> dtoFactory.createRevisionDTO(entry.getValue())));
final ActivateControllerServicesEntity activateServicesEntity = new ActivateControllerServicesEntity();
activateServicesEntity.setComponents(serviceRevisionDtoMap);
activateServicesEntity.setId(groupId);
activateServicesEntity.setState(desiredState.name());
URI controllerServicesUri;
try {
controllerServicesUri = new URI(originalUri.getScheme(), originalUri.getUserInfo(), originalUri.getHost(), originalUri.getPort(), "/nifi-api/flow/process-groups/" + groupId + "/controller-services", null, originalUri.getFragment());
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
final Map<String, String> headers = new HashMap<>();
headers.put("content-type", MediaType.APPLICATION_JSON);
// Determine whether we should replicate only to the cluster coordinator, or if we should replicate directly to the cluster nodes themselves.
try {
final NodeResponse clusterResponse;
if (getReplicationTarget() == ReplicationTarget.CLUSTER_NODES) {
clusterResponse = getRequestReplicator().replicate(user, HttpMethod.PUT, controllerServicesUri, activateServicesEntity, headers).awaitMergedResponse();
} else {
clusterResponse = getRequestReplicator().forwardToCoordinator(getClusterCoordinatorNode(), user, HttpMethod.PUT, controllerServicesUri, activateServicesEntity, headers).awaitMergedResponse();
}
final int disableServicesStatus = clusterResponse.getStatus();
if (disableServicesStatus != Status.OK.getStatusCode()) {
final String explanation = getResponseEntity(clusterResponse, String.class);
throw new LifecycleManagementException("Failed to update Controller Services to a state of " + desiredState + " due to " + explanation);
}
final boolean serviceTransitioned = waitForControllerServiceStatus(user, originalUri, groupId, affectedServiceIds, desiredState, pause);
if (!serviceTransitioned) {
throw new LifecycleManagementException("Failed while waiting for Controller Services to finish transitioning to a state of " + desiredState);
}
} catch (final InterruptedException ie) {
Thread.currentThread().interrupt();
throw new LifecycleManagementException("Interrupted while transitioning Controller Services to a state of " + desiredState);
}
return affectedServices.stream().map(componentEntity -> serviceFacade.getControllerService(componentEntity.getId(), user)).map(dtoFactory::createAffectedComponentEntity).collect(Collectors.toSet());
}
use of org.apache.nifi.web.api.entity.AffectedComponentEntity in project nifi by apache.
the class LocalComponentLifecycle method updateAffectedControllerServices.
/**
* Updates the affected controller services in the specified updateRequest with the serviceEntities.
*
* @param serviceEntities service entities
* @param affectedServices all Controller Services whose state should be equal to the given desired state
*/
private void updateAffectedControllerServices(final Set<ControllerServiceEntity> serviceEntities, final Map<String, AffectedComponentEntity> affectedServices) {
// update the affected components
serviceEntities.stream().filter(entity -> affectedServices.containsKey(entity.getId())).forEach(entity -> {
final AffectedComponentEntity affectedComponentEntity = affectedServices.get(entity.getId());
affectedComponentEntity.setRevision(entity.getRevision());
// only consider update this component if the user had permissions to it
if (Boolean.TRUE.equals(affectedComponentEntity.getPermissions().getCanRead())) {
final AffectedComponentDTO affectedComponent = affectedComponentEntity.getComponent();
affectedComponent.setState(entity.getComponent().getState());
if (Boolean.TRUE.equals(entity.getPermissions().getCanRead())) {
affectedComponent.setValidationErrors(entity.getComponent().getValidationErrors());
}
}
});
}
use of org.apache.nifi.web.api.entity.AffectedComponentEntity in project nifi by apache.
the class AffectedComponentEntityMerger method mergeAffectedComponents.
public void mergeAffectedComponents(final Set<AffectedComponentEntity> affectedComponents, final Map<NodeIdentifier, Set<AffectedComponentEntity>> affectedComponentMap) {
final Map<String, Integer> activeThreadCounts = new HashMap<>();
final Map<String, String> states = new HashMap<>();
final Map<String, PermissionsDTO> canReads = new HashMap<>();
for (final Map.Entry<NodeIdentifier, Set<AffectedComponentEntity>> nodeEntry : affectedComponentMap.entrySet()) {
final Set<AffectedComponentEntity> nodeAffectedComponents = nodeEntry.getValue();
// go through all the nodes referencing components
if (nodeAffectedComponents != null) {
for (final AffectedComponentEntity nodeAffectedComponentEntity : nodeAffectedComponents) {
final AffectedComponentDTO nodeAffectedComponent = nodeAffectedComponentEntity.getComponent();
if (nodeAffectedComponentEntity.getPermissions().getCanRead()) {
// handle active thread counts
if (nodeAffectedComponent.getActiveThreadCount() != null && nodeAffectedComponent.getActiveThreadCount() > 0) {
final Integer current = activeThreadCounts.get(nodeAffectedComponent.getId());
if (current == null) {
activeThreadCounts.put(nodeAffectedComponent.getId(), nodeAffectedComponent.getActiveThreadCount());
} else {
activeThreadCounts.put(nodeAffectedComponent.getId(), nodeAffectedComponent.getActiveThreadCount() + current);
}
}
// handle controller service state
final String state = states.get(nodeAffectedComponent.getId());
if (state == null) {
if (ControllerServiceState.DISABLING.name().equals(nodeAffectedComponent.getState())) {
states.put(nodeAffectedComponent.getId(), ControllerServiceState.DISABLING.name());
} else if (ControllerServiceState.ENABLING.name().equals(nodeAffectedComponent.getState())) {
states.put(nodeAffectedComponent.getId(), ControllerServiceState.ENABLING.name());
}
}
}
// handle read permissions
final PermissionsDTO mergedPermissions = canReads.get(nodeAffectedComponentEntity.getId());
final PermissionsDTO permissions = nodeAffectedComponentEntity.getPermissions();
if (permissions != null) {
if (mergedPermissions == null) {
canReads.put(nodeAffectedComponentEntity.getId(), permissions);
} else {
PermissionsDtoMerger.mergePermissions(mergedPermissions, permissions);
}
}
}
}
}
// go through each affected components
if (affectedComponents != null) {
for (final AffectedComponentEntity affectedComponent : affectedComponents) {
final PermissionsDTO permissions = canReads.get(affectedComponent.getId());
if (permissions != null && permissions.getCanRead() != null && permissions.getCanRead()) {
final Integer activeThreadCount = activeThreadCounts.get(affectedComponent.getId());
if (activeThreadCount != null) {
affectedComponent.getComponent().setActiveThreadCount(activeThreadCount);
}
final String state = states.get(affectedComponent.getId());
if (state != null) {
affectedComponent.getComponent().setState(state);
}
} else {
affectedComponent.setPermissions(permissions);
affectedComponent.setComponent(null);
}
}
}
}
use of org.apache.nifi.web.api.entity.AffectedComponentEntity in project nifi by apache.
the class StandardNiFiServiceFacade method createAffectedComponentEntity.
private AffectedComponentEntity createAffectedComponentEntity(final InstantiatedVersionedComponent instance, final String componentTypeName, final String componentState, final NiFiUser user) {
final AffectedComponentEntity entity = new AffectedComponentEntity();
entity.setRevision(dtoFactory.createRevisionDTO(revisionManager.getRevision(instance.getInstanceId())));
entity.setId(instance.getInstanceId());
final Authorizable authorizable = getAuthorizable(componentTypeName, instance);
final PermissionsDTO permissionsDto = dtoFactory.createPermissionsDto(authorizable, user);
entity.setPermissions(permissionsDto);
final AffectedComponentDTO dto = new AffectedComponentDTO();
dto.setId(instance.getInstanceId());
dto.setReferenceType(componentTypeName);
dto.setProcessGroupId(instance.getInstanceGroupId());
dto.setState(componentState);
entity.setComponent(dto);
return entity;
}
use of org.apache.nifi.web.api.entity.AffectedComponentEntity in project nifi by apache.
the class StandardNiFiServiceFacade method getComponentsAffectedByVersionChange.
@Override
public Set<AffectedComponentEntity> getComponentsAffectedByVersionChange(final String processGroupId, final VersionedFlowSnapshot updatedSnapshot, final NiFiUser user) {
final ProcessGroup group = processGroupDAO.getProcessGroup(processGroupId);
final NiFiRegistryFlowMapper mapper = new NiFiRegistryFlowMapper();
final VersionedProcessGroup localContents = mapper.mapProcessGroup(group, controllerFacade.getControllerServiceProvider(), flowRegistryClient, true);
final ComparableDataFlow localFlow = new StandardComparableDataFlow("Local Flow", localContents);
final ComparableDataFlow proposedFlow = new StandardComparableDataFlow("Versioned Flow", updatedSnapshot.getFlowContents());
final Set<String> ancestorGroupServiceIds = getAncestorGroupServiceIds(group);
final FlowComparator flowComparator = new StandardFlowComparator(localFlow, proposedFlow, ancestorGroupServiceIds, new StaticDifferenceDescriptor());
final FlowComparison comparison = flowComparator.compare();
final Set<AffectedComponentEntity> affectedComponents = comparison.getDifferences().stream().filter(// components that are added are not components that will be affected in the local flow.
difference -> difference.getDifferenceType() != DifferenceType.COMPONENT_ADDED).filter(difference -> difference.getDifferenceType() != DifferenceType.BUNDLE_CHANGED).filter(FlowDifferenceFilters.FILTER_ADDED_REMOVED_REMOTE_PORTS).map(difference -> {
final VersionedComponent localComponent = difference.getComponentA();
final String state;
switch(localComponent.getComponentType()) {
case CONTROLLER_SERVICE:
final String serviceId = ((InstantiatedVersionedControllerService) localComponent).getInstanceId();
state = controllerServiceDAO.getControllerService(serviceId).getState().name();
break;
case PROCESSOR:
final String processorId = ((InstantiatedVersionedProcessor) localComponent).getInstanceId();
state = processorDAO.getProcessor(processorId).getPhysicalScheduledState().name();
break;
case REMOTE_INPUT_PORT:
final InstantiatedVersionedRemoteGroupPort inputPort = (InstantiatedVersionedRemoteGroupPort) localComponent;
state = remoteProcessGroupDAO.getRemoteProcessGroup(inputPort.getInstanceGroupId()).getInputPort(inputPort.getInstanceId()).getScheduledState().name();
break;
case REMOTE_OUTPUT_PORT:
final InstantiatedVersionedRemoteGroupPort outputPort = (InstantiatedVersionedRemoteGroupPort) localComponent;
state = remoteProcessGroupDAO.getRemoteProcessGroup(outputPort.getInstanceGroupId()).getOutputPort(outputPort.getInstanceId()).getScheduledState().name();
break;
default:
state = null;
break;
}
return createAffectedComponentEntity((InstantiatedVersionedComponent) localComponent, localComponent.getComponentType().name(), state, user);
}).collect(Collectors.toCollection(HashSet::new));
for (final FlowDifference difference : comparison.getDifferences()) {
// Ignore these as local differences for now because we can't do anything with it
if (difference.getDifferenceType() == DifferenceType.BUNDLE_CHANGED) {
continue;
}
// Ignore differences for adding remote ports
if (FlowDifferenceFilters.isAddedOrRemovedRemotePort(difference)) {
continue;
}
final VersionedComponent localComponent = difference.getComponentA();
if (localComponent == null) {
continue;
}
// If any Process Group is removed, consider all components below that Process Group as an affected component
if (difference.getDifferenceType() == DifferenceType.COMPONENT_REMOVED && localComponent.getComponentType() == org.apache.nifi.registry.flow.ComponentType.PROCESS_GROUP) {
final String localGroupId = ((InstantiatedVersionedProcessGroup) localComponent).getInstanceId();
final ProcessGroup localGroup = processGroupDAO.getProcessGroup(localGroupId);
localGroup.findAllProcessors().stream().map(comp -> createAffectedComponentEntity(comp, user)).forEach(affectedComponents::add);
localGroup.findAllFunnels().stream().map(comp -> createAffectedComponentEntity(comp, user)).forEach(affectedComponents::add);
localGroup.findAllInputPorts().stream().map(comp -> createAffectedComponentEntity(comp, user)).forEach(affectedComponents::add);
localGroup.findAllOutputPorts().stream().map(comp -> createAffectedComponentEntity(comp, user)).forEach(affectedComponents::add);
localGroup.findAllRemoteProcessGroups().stream().flatMap(rpg -> Stream.concat(rpg.getInputPorts().stream(), rpg.getOutputPorts().stream())).map(comp -> createAffectedComponentEntity(comp, user)).forEach(affectedComponents::add);
localGroup.findAllControllerServices().stream().map(comp -> createAffectedComponentEntity(comp, user)).forEach(affectedComponents::add);
}
if (localComponent.getComponentType() == org.apache.nifi.registry.flow.ComponentType.CONTROLLER_SERVICE) {
final String serviceId = ((InstantiatedVersionedControllerService) localComponent).getInstanceId();
final ControllerServiceNode serviceNode = controllerServiceDAO.getControllerService(serviceId);
final List<ControllerServiceNode> referencingServices = serviceNode.getReferences().findRecursiveReferences(ControllerServiceNode.class);
for (final ControllerServiceNode referencingService : referencingServices) {
affectedComponents.add(createAffectedComponentEntity(referencingService, user));
}
final List<ProcessorNode> referencingProcessors = serviceNode.getReferences().findRecursiveReferences(ProcessorNode.class);
for (final ProcessorNode referencingProcessor : referencingProcessors) {
affectedComponents.add(createAffectedComponentEntity(referencingProcessor, user));
}
}
}
// Create a map of all connectable components by versioned component ID to the connectable component itself
final Map<String, List<Connectable>> connectablesByVersionId = new HashMap<>();
mapToConnectableId(group.findAllFunnels(), connectablesByVersionId);
mapToConnectableId(group.findAllInputPorts(), connectablesByVersionId);
mapToConnectableId(group.findAllOutputPorts(), connectablesByVersionId);
mapToConnectableId(group.findAllProcessors(), connectablesByVersionId);
final List<RemoteGroupPort> remotePorts = new ArrayList<>();
for (final RemoteProcessGroup rpg : group.findAllRemoteProcessGroups()) {
remotePorts.addAll(rpg.getInputPorts());
remotePorts.addAll(rpg.getOutputPorts());
}
mapToConnectableId(remotePorts, connectablesByVersionId);
// and the destination (if it exists in the flow currently).
for (final FlowDifference difference : comparison.getDifferences()) {
VersionedComponent component = difference.getComponentA();
if (component == null) {
component = difference.getComponentB();
}
if (component.getComponentType() != org.apache.nifi.registry.flow.ComponentType.CONNECTION) {
continue;
}
final VersionedConnection connection = (VersionedConnection) component;
final String sourceVersionedId = connection.getSource().getId();
final List<Connectable> sources = connectablesByVersionId.get(sourceVersionedId);
if (sources != null) {
for (final Connectable source : sources) {
affectedComponents.add(createAffectedComponentEntity(source, user));
}
}
final String destinationVersionId = connection.getDestination().getId();
final List<Connectable> destinations = connectablesByVersionId.get(destinationVersionId);
if (destinations != null) {
for (final Connectable destination : destinations) {
affectedComponents.add(createAffectedComponentEntity(destination, user));
}
}
}
return affectedComponents;
}
Aggregations