@Override public boolean pause() { if (updateRequest.isComplete()) { return false; } try { Thread.sleep(500); } catch (final InterruptedException ie) { Thread.currentThread().interrupt(); return false; } return !updateRequest.isComplete(); } };
private void performUpdateVariableRegistryStep(final String groupId, final VariableRegistryUpdateRequest request, final VariableRegistryUpdateStep step, final String stepDescription, final Runnable action) { if (request.isComplete()) { logger.info("In updating Variable Registry for Process Group with ID {}" + ", skipping the following step because the request has completed already: {}", groupId, stepDescription); return; } try { logger.info("In order to update Variable Registry for Process Group with ID {}, {}", groupId, stepDescription); action.run(); step.setComplete(true); } catch (final Exception e) { logger.error("Failed to update variable registry for Process Group with ID {}", groupId, e); step.setComplete(true); step.setFailureReason(e.getMessage()); request.setComplete(true); request.setFailureReason("Failed to update Variable Registry because failed while performing step: " + stepDescription); } request.setLastUpdated(new Date()); }
@Override public String getVariableValue(final VariableDescriptor descriptor) { if (descriptor == null) { return null; } final String value = getVariableMap().get(descriptor); if (value != null) { return value; } return parent.getVariableValue(descriptor); } }
public VariableRegistryUpdateRequestDTO createVariableRegistryUpdateRequestDto(final VariableRegistryUpdateRequest request) { final VariableRegistryUpdateRequestDTO dto = new VariableRegistryUpdateRequestDTO(); dto.setComplete(request.isComplete()); dto.setFailureReason(request.getFailureReason()); dto.setLastUpdated(request.getLastUpdated()); dto.setProcessGroupId(request.getProcessGroupId()); dto.setRequestId(request.getRequestId()); dto.setSubmissionTime(request.getSubmissionTime()); final List<VariableRegistryUpdateStepDTO> updateSteps = new ArrayList<>(); updateSteps.add(createVariableRegistryUpdateStepDto(request.getIdentifyRelevantComponentsStep())); updateSteps.add(createVariableRegistryUpdateStepDto(request.getStopProcessorsStep())); updateSteps.add(createVariableRegistryUpdateStepDto(request.getDisableServicesStep())); updateSteps.add(createVariableRegistryUpdateStepDto(request.getApplyUpdatesStep())); updateSteps.add(createVariableRegistryUpdateStepDto(request.getEnableServicesStep())); updateSteps.add(createVariableRegistryUpdateStepDto(request.getStartProcessorsStep())); dto.setUpdateSteps(updateSteps); dto.setAffectedComponents(new HashSet<>(request.getAffectedComponents().values())); return dto; }
performUpdateVariableRegistryStep(groupId, updateRequest, updateRequest.getStopProcessorsStep(), "Stopping Processors", () -> stopProcessors(updateRequest, groupId, processorRevisionMap, pause)); performUpdateVariableRegistryStep(groupId, updateRequest, updateRequest.getDisableServicesStep(), "Disabling Controller Services", () -> disableControllerServices(updateRequest, groupId, serviceRevisionMap, pause)); performUpdateVariableRegistryStep(groupId, updateRequest, updateRequest.getApplyUpdatesStep(), "Applying updates to Variable Registry", () -> { final VariableRegistryEntity entity = serviceFacade.updateVariableRegistry(requestRevision, requestEntity.getVariableRegistry()); updateRequest.setProcessGroupRevision(entity.getProcessGroupRevision()); }); performUpdateVariableRegistryStep(groupId, updateRequest, updateRequest.getEnableServicesStep(), "Re-enabling Controller Services", () -> enableControllerServices(updateRequest, groupId, updatedServiceRevisionMap, pause)); performUpdateVariableRegistryStep(groupId, updateRequest, updateRequest.getStartProcessorsStep(), "Restarting Processors", () -> startProcessors(updateRequest, groupId, updatedProcessorRevisionMap, pause)); updateRequest.setComplete(true); updateRequest.setLastUpdated(new Date()); } catch (final Exception e) { logger.error("Failed to update Variable Registry for Proces Group with ID " + groupId, e); updateRequest.setComplete(true); updateRequest.setFailureReason("An unexpected error has occurred: " + e); } finally {
updateRequest.setLastUpdated(new Date()); updateRequest.getApplyUpdatesStep().setComplete(true); updateRequest.setProcessGroupRevision(entity.getProcessGroupRevision()); } else { final String message = getResponseEntity(clusterResponse, String.class); updateRequest.getApplyUpdatesStep().setFailureReason("Failed to apply updates to the Variable Registry: " + message); updateRequest.setComplete(true); updateRequest.setFailureReason("Failed to apply updates to the Variable Registry: " + message);
updateStep.setFailureReason("Failed while " + updateStep.getDescription()); updateStep.setComplete(true); updateRequest.setFailureReason("Failed while " + updateStep.getDescription()); return; updateRequest.setLastUpdated(new Date()); final boolean serviceTransitioned = waitForControllerServiceStatus(originalUri, groupId, affectedServiceIds, desiredState, updateRequest, pause); updateStep.setComplete(true); updateStep.setFailureReason("Failed while " + updateStep.getDescription()); updateRequest.setComplete(true); updateRequest.setFailureReason("Failed while " + updateStep.getDescription());
scheduleProcessors(groupId, originalUri, updateRequest, pause, affectedProcessors, ScheduledState.STOPPED, updateRequest.getStopProcessorsStep()); } else { logger.info("In order to update Variable Registry for Process Group with ID {}, no Processors are affected.", groupId); updateRequest.getStopProcessorsStep().setComplete(true); activateControllerServices(groupId, originalUri, updateRequest, pause, affectedServices, ControllerServiceState.DISABLED, updateRequest.getDisableServicesStep()); } else { logger.info("In order to update Variable Registry for Process Group with ID {}, no Controller Services are affected.", groupId); updateRequest.getDisableServicesStep().setComplete(true); activateControllerServices(groupId, originalUri, updateRequest, pause, affectedServices, ControllerServiceState.ENABLED, updateRequest.getEnableServicesStep()); } else { logger.info("In order to update Variable Registry for Process Group with ID {}, no Controller Services are affected.", groupId); updateRequest.getEnableServicesStep().setComplete(true); scheduleProcessors(groupId, originalUri, updateRequest, pause, affectedProcessors, ScheduledState.RUNNING, updateRequest.getStartProcessorsStep()); } else { logger.info("In order to update Variable Registry for Process Group with ID {}, no Processors are affected.", groupId); updateRequest.getStartProcessorsStep().setComplete(true);
private VariableRegistryUpdateRequest createVariableRegistryUpdateRequest(final String groupId, final Set<AffectedComponentEntity> affectedComponents, final NiFiUser user) { final VariableRegistryUpdateRequest updateRequest = new VariableRegistryUpdateRequest(UUID.randomUUID().toString(), groupId, affectedComponents, user); // before adding to the request map, purge any old requests. Must do this by creating a List of ID's // and then removing those ID's one-at-a-time in order to avoid ConcurrentModificationException. final Date oneMinuteAgo = new Date(System.currentTimeMillis() - VARIABLE_REGISTRY_UPDATE_REQUEST_EXPIRATION); final List<String> completedRequestIds = varRegistryUpdateRequests.entrySet().stream() .filter(entry -> entry.getValue().isComplete()) .filter(entry -> entry.getValue().getLastUpdated().before(oneMinuteAgo)) .map(Map.Entry::getKey) .collect(Collectors.toList()); completedRequestIds.stream().forEach(id -> varRegistryUpdateRequests.remove(id)); final int requestCount = varRegistryUpdateRequests.size(); if (requestCount > MAX_VARIABLE_REGISTRY_UPDATE_REQUESTS) { throw new IllegalStateException("There are already " + requestCount + " update requests for variable registries. " + "Cannot issue any more requests until the older ones are deleted or expire"); } this.varRegistryUpdateRequests.put(updateRequest.getRequestId(), updateRequest); return updateRequest; }
updateRequest.getIdentifyRelevantComponentsStep().setComplete(true); final Pause pause = createPause(updateRequest); responseEntity.setProcessGroupRevision(updateRequest.getProcessGroupRevision()); responseEntity.getRequest().setUri(generateResourceUri("process-groups", groupId, "variable-registry", "update-requests", updateRequest.getRequestId()));
public VariableRegistryUpdateStepDTO createVariableRegistryUpdateStepDto(final VariableRegistryUpdateStep step) { final VariableRegistryUpdateStepDTO dto = new VariableRegistryUpdateStepDTO(); dto.setComplete(step.isComplete()); dto.setDescription(step.getDescription()); dto.setFailureReason(step.getFailureReason()); return dto; }
private ProcessorNode createProcessorNode(final LoggableComponent<Processor> processor, final boolean creationSuccessful) { final ComponentVariableRegistry componentVarRegistry = new StandardComponentVariableRegistry(this.variableRegistry); final ValidationContextFactory validationContextFactory = new StandardValidationContextFactory(serviceProvider, componentVarRegistry); final ProcessorNode procNode; if (creationSuccessful) { procNode = new StandardProcessorNode(processor, identifier, validationContextFactory, processScheduler, serviceProvider, componentVarRegistry, reloadComponent, extensionManager, validationTrigger); } else { final String simpleClassName = type.contains(".") ? StringUtils.substringAfterLast(type, ".") : type; final String componentType = "(Missing) " + simpleClassName; procNode = new StandardProcessorNode(processor, identifier, validationContextFactory, processScheduler, serviceProvider, componentType, type, componentVarRegistry, reloadComponent, extensionManager, validationTrigger, true); } applyDefaultSettings(procNode); return procNode; }
private Set<String> getUpdatedVariables(final Map<String, String> newVariableValues) { final Set<String> updatedVariableNames = new HashSet<>(); final MutableVariableRegistry registry = getVariableRegistry(); for (final Map.Entry<String, String> entry : newVariableValues.entrySet()) { final String varName = entry.getKey(); final String newValue = entry.getValue(); final String curValue = registry.getVariableValue(varName); if (!Objects.equals(newValue, curValue)) { updatedVariableNames.add(varName); } } return updatedVariableNames; }
@Override public void setVariables(final Map<String, String> variables) { writeLock.lock(); try { verifyCanUpdateVariables(variables); if (variables == null) { return; } final Map<VariableDescriptor, String> variableMap = new HashMap<>(); variables.entrySet() // cannot use Collectors.toMap because value may be null .forEach(entry -> variableMap.put(new VariableDescriptor(entry.getKey()), entry.getValue())); variableRegistry.setVariables(variableMap); } finally { writeLock.unlock(); } }
public ProcessGroup createProcessGroup(final String id) { final MutableVariableRegistry mutableVariableRegistry = new MutableVariableRegistry(flowController.getVariableRegistry()); final ProcessGroup group = new StandardProcessGroup(requireNonNull(id), flowController.getControllerServiceProvider(), processScheduler, nifiProperties, flowController.getEncryptor(), flowController, mutableVariableRegistry); allProcessGroups.put(group.getIdentifier(), group); return group; }
/** * Updates the affected controller services in the specified updateRequest with the serviceEntities. * * @param serviceEntities service entities * @param updateRequest update request */ private void updateAffectedControllerServices(final Set<ControllerServiceEntity> serviceEntities, final VariableRegistryUpdateRequest updateRequest) { // update the affected components serviceEntities.stream() .filter(entity -> updateRequest.getAffectedComponents().containsKey(entity.getId())) .forEach(entity -> { final AffectedComponentEntity affectedComponentEntity = updateRequest.getAffectedComponents().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()); } } }); }
@Override public VariableDescriptor getVariableKey(final String name) { if (name == null) { return null; } final VariableDescriptor spec = new VariableDescriptor(name); for (final Map.Entry<VariableDescriptor, String> entry : getVariableMap().entrySet()) { if (entry.getKey().equals(spec)) { return entry.getKey(); } } return null; }
private ControllerServiceNode createGhostControllerServiceNode() { final String simpleClassName = type.contains(".") ? StringUtils.substringAfterLast(type, ".") : type; final String componentType = "(Missing) " + simpleClassName; final GhostControllerService ghostService = new GhostControllerService(identifier, type); final LoggableComponent<ControllerService> proxiedLoggableComponent = new LoggableComponent<>(ghostService, bundleCoordinate, null); final ControllerServiceInvocationHandler invocationHandler = new StandardControllerServiceInvocationHandler(extensionManager, ghostService); final ComponentVariableRegistry componentVarRegistry = new StandardComponentVariableRegistry(this.variableRegistry); final ValidationContextFactory validationContextFactory = new StandardValidationContextFactory(serviceProvider, variableRegistry); final ControllerServiceNode serviceNode = new StandardControllerServiceNode(proxiedLoggableComponent, proxiedLoggableComponent, invocationHandler, identifier, validationContextFactory, serviceProvider, componentType, type, componentVarRegistry, reloadComponent, extensionManager, validationTrigger, true); return serviceNode; }
@Override public String getVariableValue(final String name) { if (name == null) { return null; } final VariableDescriptor descriptor = new VariableDescriptor(name); final String value = getVariableMap().get(descriptor); if (value != null) { return value; } return parent.getVariableValue(descriptor); }
private ReportingTaskNode createReportingTaskNode(final LoggableComponent<ReportingTask> reportingTask, final boolean creationSuccessful) { final ComponentVariableRegistry componentVarRegistry = new StandardComponentVariableRegistry(this.variableRegistry); final ValidationContextFactory validationContextFactory = new StandardValidationContextFactory(serviceProvider, componentVarRegistry); final ReportingTaskNode taskNode; if (creationSuccessful) { taskNode = new StandardReportingTaskNode(reportingTask, identifier, flowController, processScheduler, validationContextFactory, componentVarRegistry, reloadComponent, extensionManager, validationTrigger); taskNode.setName(taskNode.getReportingTask().getClass().getSimpleName()); } else { final String simpleClassName = type.contains(".") ? StringUtils.substringAfterLast(type, ".") : type; final String componentType = "(Missing) " + simpleClassName; taskNode = new StandardReportingTaskNode(reportingTask, identifier, flowController, processScheduler, validationContextFactory, componentType, type, componentVarRegistry, reloadComponent, extensionManager, validationTrigger, true); taskNode.setName(componentType); } return taskNode; }