use of org.apache.nifi.nar.NarCloseable in project nifi by apache.
the class FlowController method removeReportingTask.
@Override
public void removeReportingTask(final ReportingTaskNode reportingTaskNode) {
final ReportingTaskNode existing = reportingTasks.get(reportingTaskNode.getIdentifier());
if (existing == null || existing != reportingTaskNode) {
throw new IllegalStateException("Reporting Task " + reportingTaskNode + " does not exist in this Flow");
}
reportingTaskNode.verifyCanDelete();
try (final NarCloseable x = NarCloseable.withComponentNarLoader(reportingTaskNode.getReportingTask().getClass(), reportingTaskNode.getReportingTask().getIdentifier())) {
ReflectionUtils.quietlyInvokeMethodsWithAnnotation(OnRemoved.class, reportingTaskNode.getReportingTask(), reportingTaskNode.getConfigurationContext());
}
for (final Map.Entry<PropertyDescriptor, String> entry : reportingTaskNode.getProperties().entrySet()) {
final PropertyDescriptor descriptor = entry.getKey();
if (descriptor.getControllerServiceDefinition() != null) {
final String value = entry.getValue() == null ? descriptor.getDefaultValue() : entry.getValue();
if (value != null) {
final ControllerServiceNode serviceNode = controllerServiceProvider.getControllerServiceNode(value);
if (serviceNode != null) {
serviceNode.removeReference(reportingTaskNode);
}
}
}
}
reportingTasks.remove(reportingTaskNode.getIdentifier());
ExtensionManager.removeInstanceClassLoader(reportingTaskNode.getIdentifier());
}
use of org.apache.nifi.nar.NarCloseable in project nifi by apache.
the class FlowController method createReportingTask.
public ReportingTaskNode createReportingTask(final String type, final String id, final BundleCoordinate bundleCoordinate, final Set<URL> additionalUrls, final boolean firstTimeAdded, final boolean register) throws ReportingTaskInstantiationException {
if (type == null || id == null || bundleCoordinate == null) {
throw new NullPointerException();
}
LoggableComponent<ReportingTask> task = null;
boolean creationSuccessful = true;
try {
task = instantiateReportingTask(type, id, bundleCoordinate, additionalUrls);
} catch (final Exception e) {
LOG.error("Could not create Reporting Task of type " + type + " for ID " + id + "; creating \"Ghost\" implementation", e);
final GhostReportingTask ghostTask = new GhostReportingTask();
ghostTask.setIdentifier(id);
ghostTask.setCanonicalClassName(type);
task = new LoggableComponent<>(ghostTask, bundleCoordinate, null);
creationSuccessful = false;
}
final ComponentVariableRegistry componentVarRegistry = new StandardComponentVariableRegistry(this.variableRegistry);
final ValidationContextFactory validationContextFactory = new StandardValidationContextFactory(controllerServiceProvider, componentVarRegistry);
final ReportingTaskNode taskNode;
if (creationSuccessful) {
taskNode = new StandardReportingTaskNode(task, id, this, processScheduler, validationContextFactory, componentVarRegistry, this);
} else {
final String simpleClassName = type.contains(".") ? StringUtils.substringAfterLast(type, ".") : type;
final String componentType = "(Missing) " + simpleClassName;
taskNode = new StandardReportingTaskNode(task, id, this, processScheduler, validationContextFactory, componentType, type, componentVarRegistry, this, true);
}
taskNode.setName(taskNode.getReportingTask().getClass().getSimpleName());
if (firstTimeAdded) {
final ReportingInitializationContext config = new StandardReportingInitializationContext(id, taskNode.getName(), SchedulingStrategy.TIMER_DRIVEN, "1 min", taskNode.getLogger(), this, nifiProperties, this);
try {
taskNode.getReportingTask().initialize(config);
} catch (final InitializationException ie) {
throw new ReportingTaskInstantiationException("Failed to initialize reporting task of type " + type, ie);
}
try (final NarCloseable x = NarCloseable.withComponentNarLoader(taskNode.getReportingTask().getClass(), taskNode.getReportingTask().getIdentifier())) {
ReflectionUtils.invokeMethodsWithAnnotation(OnAdded.class, taskNode.getReportingTask());
ReflectionUtils.quietlyInvokeMethodsWithAnnotation(OnConfigurationRestored.class, taskNode.getReportingTask());
} catch (final Exception e) {
throw new ComponentLifeCycleException("Failed to invoke On-Added Lifecycle methods of " + taskNode.getReportingTask(), e);
}
}
if (register) {
reportingTasks.put(id, taskNode);
// Register log observer to provide bulletins when reporting task logs anything at WARN level or above
final LogRepository logRepository = LogRepositoryFactory.getRepository(id);
logRepository.addObserver(StandardProcessorNode.BULLETIN_OBSERVER_ID, LogLevel.WARN, new ReportingTaskLogObserver(getBulletinRepository(), taskNode));
}
return taskNode;
}
use of org.apache.nifi.nar.NarCloseable in project nifi by apache.
the class FlowController method shutdown.
/**
* Triggers the controller to begin shutdown, stopping all processors and
* terminating the scheduling engine. After calling this method, the
* {@link #isTerminated()} method will indicate whether or not the shutdown
* has finished.
*
* @param kill if <code>true</code>, attempts to stop all active threads,
* but makes no guarantee that this will happen
*
* @throws IllegalStateException if the controller is already stopped or
* currently in the processor of stopping
*/
public void shutdown(final boolean kill) {
this.shutdown = true;
stopAllProcessors();
readLock.lock();
try {
if (isTerminated() || timerDrivenEngineRef.get().isTerminating()) {
throw new IllegalStateException("Controller already stopped or still stopping...");
}
if (leaderElectionManager != null) {
leaderElectionManager.stop();
}
if (heartbeatMonitor != null) {
heartbeatMonitor.stop();
}
if (kill) {
this.timerDrivenEngineRef.get().shutdownNow();
this.eventDrivenEngineRef.get().shutdownNow();
LOG.info("Initiated immediate shutdown of flow controller...");
} else {
this.timerDrivenEngineRef.get().shutdown();
this.eventDrivenEngineRef.get().shutdown();
LOG.info("Initiated graceful shutdown of flow controller...waiting up to " + gracefulShutdownSeconds + " seconds");
}
clusterTaskExecutor.shutdownNow();
if (zooKeeperStateServer != null) {
zooKeeperStateServer.shutdown();
}
// Trigger any processors' methods marked with @OnShutdown to be called
getRootGroup().shutdown();
stateManagerProvider.shutdown();
// invoke any methods annotated with @OnShutdown on Controller Services
for (final ControllerServiceNode serviceNode : getAllControllerServices()) {
try (final NarCloseable narCloseable = NarCloseable.withComponentNarLoader(serviceNode.getControllerServiceImplementation().getClass(), serviceNode.getIdentifier())) {
final ConfigurationContext configContext = new StandardConfigurationContext(serviceNode, controllerServiceProvider, null, variableRegistry);
ReflectionUtils.quietlyInvokeMethodsWithAnnotation(OnShutdown.class, serviceNode.getControllerServiceImplementation(), configContext);
}
}
// invoke any methods annotated with @OnShutdown on Reporting Tasks
for (final ReportingTaskNode taskNode : getAllReportingTasks()) {
final ConfigurationContext configContext = taskNode.getConfigurationContext();
try (final NarCloseable narCloseable = NarCloseable.withComponentNarLoader(taskNode.getReportingTask().getClass(), taskNode.getIdentifier())) {
ReflectionUtils.quietlyInvokeMethodsWithAnnotation(OnShutdown.class, taskNode.getReportingTask(), configContext);
}
}
try {
this.timerDrivenEngineRef.get().awaitTermination(gracefulShutdownSeconds / 2, TimeUnit.SECONDS);
this.eventDrivenEngineRef.get().awaitTermination(gracefulShutdownSeconds / 2, TimeUnit.SECONDS);
} catch (final InterruptedException ie) {
LOG.info("Interrupted while waiting for controller termination.");
}
try {
flowFileRepository.close();
} catch (final Throwable t) {
LOG.warn("Unable to shut down FlowFileRepository due to {}", new Object[] { t });
}
if (this.timerDrivenEngineRef.get().isTerminated() && eventDrivenEngineRef.get().isTerminated()) {
LOG.info("Controller has been terminated successfully.");
} else {
LOG.warn("Controller hasn't terminated properly. There exists an uninterruptable thread that " + "will take an indeterminate amount of time to stop. Might need to kill the program manually.");
}
for (final RemoteSiteListener listener : externalSiteListeners) {
listener.stop();
}
if (processScheduler != null) {
processScheduler.shutdown();
}
if (contentRepository != null) {
contentRepository.shutdown();
}
if (provenanceRepository != null) {
try {
provenanceRepository.close();
} catch (final IOException ioe) {
LOG.warn("There was a problem shutting down the Provenance Repository: " + ioe.toString());
if (LOG.isDebugEnabled()) {
LOG.warn("", ioe);
}
}
}
} finally {
readLock.unlock();
}
}
use of org.apache.nifi.nar.NarCloseable in project nifi by apache.
the class AbstractConfiguredComponent method getProperties.
@Override
public Map<PropertyDescriptor, String> getProperties() {
try (final NarCloseable narCloseable = NarCloseable.withComponentNarLoader(getComponent().getClass(), getComponent().getIdentifier())) {
final List<PropertyDescriptor> supported = getComponent().getPropertyDescriptors();
if (supported == null || supported.isEmpty()) {
return Collections.unmodifiableMap(properties);
} else {
final Map<PropertyDescriptor, String> props = new LinkedHashMap<>();
for (final PropertyDescriptor descriptor : supported) {
props.put(descriptor, null);
}
props.putAll(properties);
return props;
}
}
}
use of org.apache.nifi.nar.NarCloseable in project nifi by apache.
the class AbstractConfiguredComponent method setProperties.
@Override
public void setProperties(final Map<String, String> properties, final boolean allowRemovalOfRequiredProperties) {
if (properties == null) {
return;
}
lock.lock();
try {
verifyModifiable();
try (final NarCloseable narCloseable = NarCloseable.withComponentNarLoader(getComponent().getClass(), id)) {
boolean classpathChanged = false;
for (final Map.Entry<String, String> entry : properties.entrySet()) {
// determine if any of the property changes require resetting the InstanceClassLoader
final PropertyDescriptor descriptor = getComponent().getPropertyDescriptor(entry.getKey());
if (descriptor.isDynamicClasspathModifier()) {
classpathChanged = true;
}
if (entry.getKey() != null && entry.getValue() == null) {
removeProperty(entry.getKey(), allowRemovalOfRequiredProperties);
} else if (entry.getKey() != null) {
setProperty(entry.getKey(), CharacterFilterUtils.filterInvalidXmlCharacters(entry.getValue()));
}
}
// if at least one property with dynamicallyModifiesClasspath(true) was set, then reload the component with the new urls
if (classpathChanged) {
logger.info("Updating classpath for " + this.componentType + " with the ID " + this.getIdentifier());
final Set<URL> additionalUrls = getAdditionalClasspathResources(getComponent().getPropertyDescriptors());
try {
reload(additionalUrls);
} catch (Exception e) {
getLogger().error("Error reloading component with id " + id + ": " + e.getMessage(), e);
}
}
}
} finally {
lock.unlock();
}
}
Aggregations