use of org.apache.nifi.web.api.dto.ControllerServiceReferencingComponentDTO in project kylo by Teradata.
the class AbstractNiFiControllerServicesRestClient method updateServiceAndReferencingComponents.
/**
* Updates a controller service
* This will first disable the service, stop all referencing components, enable the service, reset the state of the components back to their prior state
*
* @param controllerService the service to update with the updated properties
* @return the updates service
*/
@Override
public ControllerServiceDTO updateServiceAndReferencingComponents(ControllerServiceDTO controllerService) {
String id = controllerService.getId();
// Get all references to this controller service. this will include processors, other controller services, and reporting tasks
Optional<ControllerServiceReferencingComponentsEntity> references = getReferences(id);
// state of the processors prior to update
Map<String, String> previousProcessorState = null;
// revisions for the processor references
Map<String, RevisionDTO> processorRevisions = null;
// revisions for the controller service references
Map<String, RevisionDTO> controllerServiceRevisions = null;
// a map of component id to reference entity. this will include all referencing processors, controller services, and reporting tasks
Map<String, ControllerServiceReferencingComponentEntity> referencingComponentEntityMap = null;
// Stop all processor references and also disable any other controller service references
if (references.isPresent()) {
// build the reference state and revision maps prior to making this update
referencingComponentEntityMap = getReferencingComponents(references.get().getControllerServiceReferencingComponents());
previousProcessorState = referencingComponentEntityMap.values().stream().filter(e -> e.getComponent().getReferenceType().equalsIgnoreCase("PROCESSOR")).map(c -> c.getComponent()).collect(Collectors.toMap(ControllerServiceReferencingComponentDTO::getId, ControllerServiceReferencingComponentDTO::getState));
processorRevisions = referencingComponentEntityMap.values().stream().filter(e -> e.getComponent().getReferenceType().equalsIgnoreCase("PROCESSOR")).collect(Collectors.toMap(ControllerServiceReferencingComponentEntity::getId, ControllerServiceReferencingComponentEntity::getRevision));
controllerServiceRevisions = referencingComponentEntityMap.values().stream().filter(e -> e.getComponent().getReferenceType().equalsIgnoreCase("ControllerService")).collect(Collectors.toMap(ControllerServiceReferencingComponentEntity::getId, ControllerServiceReferencingComponentEntity::getRevision));
// Stop the referencing processors and ensure they are in the stopped state
if (!processorRevisions.isEmpty()) {
String state = NifiProcessUtil.PROCESS_STATE.STOPPED.name();
log.info("Stopping all component references to controller service {} ", controllerService.getName());
UpdateControllerServiceReferenceRequestEntity stopComponentsRequest = new UpdateControllerServiceReferenceRequestEntity();
stopComponentsRequest.setState(state);
stopComponentsRequest.setId(controllerService.getId());
stopComponentsRequest.setReferencingComponentRevisions(processorRevisions);
updateReferences(id, stopComponentsRequest);
boolean updatedReferences = ensureComponentsAreOfState(id, "Processor", state, 5, 500, TimeUnit.MILLISECONDS);
if (!updatedReferences) {
// error unable to change the state of the references. ... error
throw new NifiClientRuntimeException("Unable to stop processor references to this controller service " + controllerService.getName() + " before making the update");
}
}
// disable any controller service references
if (!controllerServiceRevisions.isEmpty()) {
UpdateControllerServiceReferenceRequestEntity stopComponentsRequest = new UpdateControllerServiceReferenceRequestEntity();
stopComponentsRequest.setState("DISABLED");
stopComponentsRequest.setId(controllerService.getId());
stopComponentsRequest.setReferencingComponentRevisions(controllerServiceRevisions);
updateReferences(id, stopComponentsRequest);
boolean updatedReferences = ensureComponentsAreOfState(id, "ControllerService", "DISABLED", 5, 500, TimeUnit.MILLISECONDS);
if (!updatedReferences) {
// error unable to change the state of the references. ... error
throw new NifiClientRuntimeException("Unable to disable other controller service references to this controller service " + controllerService.getName() + " before making the update");
}
}
}
// mark this controller service as disabled
log.info("Disabling the controller service {} ", controllerService.getName());
// update the service and mark it disabled. this will throw a RuntimeException if it is not successful
ControllerServiceDTO updatedService = updateStateByIdWithRetries(controllerService.getId(), "DISABLED", 5, 500, TimeUnit.MILLISECONDS);
// Perform the update to this controller service
log.info("Updating the controller service {} ", controllerService.getName());
updatedService = update(controllerService);
// Enable the service
updateStateById(controllerService.getId(), NiFiControllerServicesRestClient.State.ENABLED);
// Enable any controller service references
if (!controllerServiceRevisions.isEmpty()) {
log.info("Enabling other controller services referencing this controller service {} ", controllerService.getName());
UpdateControllerServiceReferenceRequestEntity enableReferenceServicesRequest = new UpdateControllerServiceReferenceRequestEntity();
enableReferenceServicesRequest.setId(controllerService.getId());
enableReferenceServicesRequest.setState(NiFiControllerServicesRestClient.State.ENABLED.name());
enableReferenceServicesRequest.setReferencingComponentRevisions(controllerServiceRevisions);
updateReferences(id, enableReferenceServicesRequest);
boolean updatedReferences = ensureComponentsAreOfState(id, "ControllerService", NiFiControllerServicesRestClient.State.ENABLED.name(), 5, 500, TimeUnit.MILLISECONDS);
if (!updatedReferences) {
// error unable to change the state of the references. ... error
throw new NifiClientRuntimeException("The controller service " + controllerService.getName() + " was updated, but it was unable to enable other controller service references to this controller service. Please visit NiFi to reconcile and fix any controller service issues. " + controllerService.getName());
}
}
if (references.isPresent() && previousProcessorState != null) {
// reset the processor state
Map<String, RevisionDTO> finalComponentRevisions = processorRevisions;
// if all referencing processors of of the same state we can call the quick rest endpoint to update all of them
Set<String> distinctStates = previousProcessorState.values().stream().collect(Collectors.toSet());
if (distinctStates.size() > 0) {
if (distinctStates.size() == 1) {
String state = new ArrayList<>(distinctStates).get(0);
if (!NifiProcessUtil.PROCESS_STATE.STOPPED.name().equals(state)) {
UpdateControllerServiceReferenceRequestEntity startComponentsRequest = new UpdateControllerServiceReferenceRequestEntity();
startComponentsRequest.setState(state);
startComponentsRequest.setReferencingComponentRevisions(finalComponentRevisions);
startComponentsRequest.setId(controllerService.getId());
updateReferences(id, startComponentsRequest);
log.info("Updating all component references to be {} for controller service {} ", state, controllerService.getName());
boolean updatedReferences = ensureComponentsAreOfState(id, "Processor", state, 5, 500, TimeUnit.MILLISECONDS);
if (!updatedReferences) {
// error unable to change the state of the references. ... error
throw new NifiClientRuntimeException("The controller service {} was updated, but it was unable to update the state of the processors as " + state + ". Please visit NiFi to reconcile and fix any controller service issues. " + controllerService.getName());
}
log.info("Successfully updated controller service {}", controllerService.getName());
}
} else {
log.info("The controller service component references ({} total) had mixed states prior to updating {}. Going through each processor/component and setting its state back to what it was prior to the update.", previousProcessorState.size(), distinctStates);
// update references back to previous states
List<ProcessorEntity> updatedProcessors = references.get().getControllerServiceReferencingComponents().stream().filter(c -> c.getComponent().getReferenceType().equalsIgnoreCase("PROCESSOR")).filter(c -> !c.getComponent().getState().equals(NifiProcessUtil.PROCESS_STATE.STOPPED.name())).map(referencingComponentEntity -> referencingComponentEntity.getComponent()).map(c -> {
ProcessorEntity entity = new ProcessorEntity();
entity.setRevision(finalComponentRevisions.get(c.getId()));
entity.setId(c.getId());
ProcessorDTO processorDTO = new ProcessorDTO();
processorDTO.setId(c.getId());
processorDTO.setState(c.getState());
entity.setComponent(processorDTO);
return entity;
}).collect(Collectors.toList());
updatedProcessors.stream().forEach(p -> getClient().processors().update(p));
log.info("Successfully updated controller service {} and updated {} components back to their prior state ", controllerService.getName(), previousProcessorState.size());
}
}
}
return updatedService;
}
use of org.apache.nifi.web.api.dto.ControllerServiceReferencingComponentDTO in project nifi by apache.
the class ControllerServiceEntityMerger method mergeControllerServiceReferences.
public static void mergeControllerServiceReferences(final Set<ControllerServiceReferencingComponentEntity> referencingComponents, final Map<NodeIdentifier, Set<ControllerServiceReferencingComponentEntity>> referencingComponentMap) {
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<ControllerServiceReferencingComponentEntity>> nodeEntry : referencingComponentMap.entrySet()) {
final Set<ControllerServiceReferencingComponentEntity> nodeReferencingComponents = nodeEntry.getValue();
// go through all the nodes referencing components
if (nodeReferencingComponents != null) {
for (final ControllerServiceReferencingComponentEntity nodeReferencingComponentEntity : nodeReferencingComponents) {
final ControllerServiceReferencingComponentDTO nodeReferencingComponent = nodeReferencingComponentEntity.getComponent();
if (nodeReferencingComponentEntity.getPermissions().getCanRead()) {
// handle active thread counts
if (nodeReferencingComponent.getActiveThreadCount() != null && nodeReferencingComponent.getActiveThreadCount() > 0) {
final Integer current = activeThreadCounts.get(nodeReferencingComponent.getId());
if (current == null) {
activeThreadCounts.put(nodeReferencingComponent.getId(), nodeReferencingComponent.getActiveThreadCount());
} else {
activeThreadCounts.put(nodeReferencingComponent.getId(), nodeReferencingComponent.getActiveThreadCount() + current);
}
}
// handle controller service state
final String state = states.get(nodeReferencingComponent.getId());
if (state == null) {
if (ControllerServiceState.DISABLING.name().equals(nodeReferencingComponent.getState())) {
states.put(nodeReferencingComponent.getId(), ControllerServiceState.DISABLING.name());
} else if (ControllerServiceState.ENABLING.name().equals(nodeReferencingComponent.getState())) {
states.put(nodeReferencingComponent.getId(), ControllerServiceState.ENABLING.name());
}
}
}
// handle read permissions
final PermissionsDTO mergedPermissions = canReads.get(nodeReferencingComponentEntity.getId());
final PermissionsDTO permissions = nodeReferencingComponentEntity.getPermissions();
if (permissions != null) {
if (mergedPermissions == null) {
canReads.put(nodeReferencingComponentEntity.getId(), permissions);
} else {
PermissionsDtoMerger.mergePermissions(mergedPermissions, permissions);
}
}
}
}
}
// go through each referencing components
if (referencingComponents != null) {
for (final ControllerServiceReferencingComponentEntity referencingComponent : referencingComponents) {
final PermissionsDTO permissions = canReads.get(referencingComponent.getId());
if (permissions != null && permissions.getCanRead() != null && permissions.getCanRead()) {
final Integer activeThreadCount = activeThreadCounts.get(referencingComponent.getId());
if (activeThreadCount != null) {
referencingComponent.getComponent().setActiveThreadCount(activeThreadCount);
}
final String state = states.get(referencingComponent.getId());
if (state != null) {
referencingComponent.getComponent().setState(state);
}
final Map<NodeIdentifier, ControllerServiceReferencingComponentEntity> nodeEntities = new HashMap<>();
referencingComponentMap.entrySet().forEach(entry -> {
final NodeIdentifier nodeIdentifier = entry.getKey();
final Set<ControllerServiceReferencingComponentEntity> nodeControllerServiceReferencingComponents = entry.getValue();
nodeControllerServiceReferencingComponents.forEach(nodeControllerServiceReferencingComponent -> {
if (referencingComponent.getId() != null && referencingComponent.getId().equals(nodeControllerServiceReferencingComponent.getId())) {
nodeEntities.put(nodeIdentifier, nodeControllerServiceReferencingComponent);
}
});
});
mergeControllerServiceReferencingComponent(referencingComponent, nodeEntities);
} else {
referencingComponent.setPermissions(permissions);
referencingComponent.setComponent(null);
}
}
}
}
use of org.apache.nifi.web.api.dto.ControllerServiceReferencingComponentDTO in project nifi by apache.
the class StandardNiFiServiceFacade method createControllerServiceReferencingComponentsEntity.
/**
* Creates entities for components referencing a ControllerServcie using the specified revisions.
*
* @param reference ControllerServiceReference
* @param revisions The revisions
* @param visited Which services we've already considered (in case of cycle)
* @return The entity
*/
private ControllerServiceReferencingComponentsEntity createControllerServiceReferencingComponentsEntity(final ControllerServiceReference reference, final Map<String, Revision> revisions, final Set<ControllerServiceNode> visited) {
final String modifier = NiFiUserUtils.getNiFiUserIdentity();
final Set<ConfiguredComponent> referencingComponents = reference.getReferencingComponents();
final Set<ControllerServiceReferencingComponentEntity> componentEntities = new HashSet<>();
for (final ConfiguredComponent refComponent : referencingComponents) {
PermissionsDTO permissions = null;
if (refComponent instanceof Authorizable) {
permissions = dtoFactory.createPermissionsDto(refComponent);
}
final Revision revision = revisions.get(refComponent.getIdentifier());
final FlowModification flowMod = new FlowModification(revision, modifier);
final RevisionDTO revisionDto = dtoFactory.createRevisionDTO(flowMod);
final ControllerServiceReferencingComponentDTO dto = dtoFactory.createControllerServiceReferencingComponentDTO(refComponent);
if (refComponent instanceof ControllerServiceNode) {
final ControllerServiceNode node = (ControllerServiceNode) refComponent;
// indicate if we've hit a cycle
dto.setReferenceCycle(visited.contains(node));
// mark node as visited before building the reference cycle
visited.add(node);
// if we haven't encountered this service before include it's referencing components
if (!dto.getReferenceCycle()) {
final ControllerServiceReference refReferences = node.getReferences();
final Map<String, Revision> referencingRevisions = new HashMap<>(revisions);
for (final ConfiguredComponent component : refReferences.getReferencingComponents()) {
referencingRevisions.putIfAbsent(component.getIdentifier(), revisionManager.getRevision(component.getIdentifier()));
}
final ControllerServiceReferencingComponentsEntity references = createControllerServiceReferencingComponentsEntity(refReferences, referencingRevisions, visited);
dto.setReferencingComponents(references.getControllerServiceReferencingComponents());
}
}
componentEntities.add(entityFactory.createControllerServiceReferencingComponentEntity(dto, revisionDto, permissions));
}
final ControllerServiceReferencingComponentsEntity entity = new ControllerServiceReferencingComponentsEntity();
entity.setControllerServiceReferencingComponents(componentEntities);
return entity;
}
Aggregations