use of org.apache.nifi.processor.SimpleProcessLogger in project nifi by apache.
the class FlowController method reload.
@Override
public void reload(final ControllerServiceNode existingNode, final String newType, final BundleCoordinate bundleCoordinate, final Set<URL> additionalUrls) throws ControllerServiceInstantiationException {
if (existingNode == null) {
throw new IllegalStateException("Existing ControllerServiceNode cannot be null");
}
final String id = existingNode.getIdentifier();
// ghost components will have a null logger
if (existingNode.getLogger() != null) {
existingNode.getLogger().debug("Reloading component {} to type {} from bundle {}", new Object[] { id, newType, bundleCoordinate });
}
// createControllerService will create a new instance class loader for the same id so
// save the instance class loader to use it for calling OnRemoved on the existing service
final ClassLoader existingInstanceClassLoader = ExtensionManager.getInstanceClassLoader(id);
// create a new node with firstTimeAdded as true so lifecycle methods get called
// attempt the creation to make sure it works before firing the OnRemoved methods below
final ControllerServiceNode newNode = controllerServiceProvider.createControllerService(newType, id, bundleCoordinate, additionalUrls, true);
// call OnRemoved for the existing service using the previous instance class loader
try (final NarCloseable x = NarCloseable.withComponentNarLoader(existingInstanceClassLoader)) {
final ConfigurationContext configurationContext = new StandardConfigurationContext(existingNode, controllerServiceProvider, null, variableRegistry);
ReflectionUtils.quietlyInvokeMethodsWithAnnotation(OnRemoved.class, existingNode.getControllerServiceImplementation(), configurationContext);
} finally {
ExtensionManager.closeURLClassLoader(id, existingInstanceClassLoader);
}
// take the invocation handler that was created for new proxy and is set to look at the new node,
// and set it to look at the existing node
final ControllerServiceInvocationHandler invocationHandler = newNode.getInvocationHandler();
invocationHandler.setServiceNode(existingNode);
// create LoggableComponents for the proxy and implementation
final ComponentLog componentLogger = new SimpleProcessLogger(id, newNode.getControllerServiceImplementation());
final TerminationAwareLogger terminationAwareLogger = new TerminationAwareLogger(componentLogger);
LogRepositoryFactory.getRepository(id).setLogger(terminationAwareLogger);
final LoggableComponent<ControllerService> loggableProxy = new LoggableComponent<>(newNode.getProxiedControllerService(), bundleCoordinate, terminationAwareLogger);
final LoggableComponent<ControllerService> loggableImplementation = new LoggableComponent<>(newNode.getControllerServiceImplementation(), bundleCoordinate, terminationAwareLogger);
// set the new impl, proxy, and invocation handler into the existing node
existingNode.setControllerServiceAndProxy(loggableImplementation, loggableProxy, invocationHandler);
existingNode.setExtensionMissing(newNode.isExtensionMissing());
// need to refresh the properties in case we are changing from ghost component to real component
existingNode.refreshProperties();
}
use of org.apache.nifi.processor.SimpleProcessLogger in project nifi by apache.
the class FlowController method instantiateReportingTask.
private LoggableComponent<ReportingTask> instantiateReportingTask(final String type, final String id, final BundleCoordinate bundleCoordinate, final Set<URL> additionalUrls) throws ReportingTaskInstantiationException {
final ClassLoader ctxClassLoader = Thread.currentThread().getContextClassLoader();
try {
final Bundle reportingTaskBundle = ExtensionManager.getBundle(bundleCoordinate);
if (reportingTaskBundle == null) {
throw new IllegalStateException("Unable to find bundle for coordinate " + bundleCoordinate.getCoordinate());
}
final ClassLoader detectedClassLoader = ExtensionManager.createInstanceClassLoader(type, id, reportingTaskBundle, additionalUrls);
final Class<?> rawClass = Class.forName(type, false, detectedClassLoader);
Thread.currentThread().setContextClassLoader(detectedClassLoader);
final Class<? extends ReportingTask> reportingTaskClass = rawClass.asSubclass(ReportingTask.class);
final Object reportingTaskObj = reportingTaskClass.newInstance();
final ReportingTask reportingTask = reportingTaskClass.cast(reportingTaskObj);
final ComponentLog componentLog = new SimpleProcessLogger(id, reportingTask);
final TerminationAwareLogger terminationAwareLogger = new TerminationAwareLogger(componentLog);
return new LoggableComponent<>(reportingTask, bundleCoordinate, terminationAwareLogger);
} catch (final Exception e) {
throw new ReportingTaskInstantiationException(type, e);
} finally {
if (ctxClassLoader != null) {
Thread.currentThread().setContextClassLoader(ctxClassLoader);
}
}
}
use of org.apache.nifi.processor.SimpleProcessLogger in project nifi by apache.
the class FlowController method instantiateProcessor.
private LoggableComponent<Processor> instantiateProcessor(final String type, final String identifier, final BundleCoordinate bundleCoordinate, final Set<URL> additionalUrls) throws ProcessorInstantiationException {
final Bundle processorBundle = ExtensionManager.getBundle(bundleCoordinate);
if (processorBundle == null) {
throw new ProcessorInstantiationException("Unable to find bundle for coordinate " + bundleCoordinate.getCoordinate());
}
final ClassLoader ctxClassLoader = Thread.currentThread().getContextClassLoader();
try {
final ClassLoader detectedClassLoaderForInstance = ExtensionManager.createInstanceClassLoader(type, identifier, processorBundle, additionalUrls);
final Class<?> rawClass = Class.forName(type, true, detectedClassLoaderForInstance);
Thread.currentThread().setContextClassLoader(detectedClassLoaderForInstance);
final Class<? extends Processor> processorClass = rawClass.asSubclass(Processor.class);
final Processor processor = processorClass.newInstance();
final ComponentLog componentLogger = new SimpleProcessLogger(identifier, processor);
final TerminationAwareLogger terminationAwareLogger = new TerminationAwareLogger(componentLogger);
final ProcessorInitializationContext ctx = new StandardProcessorInitializationContext(identifier, terminationAwareLogger, this, this, nifiProperties);
processor.initialize(ctx);
LogRepositoryFactory.getRepository(identifier).setLogger(terminationAwareLogger);
return new LoggableComponent<>(processor, bundleCoordinate, terminationAwareLogger);
} catch (final Throwable t) {
throw new ProcessorInstantiationException(type, t);
} finally {
if (ctxClassLoader != null) {
Thread.currentThread().setContextClassLoader(ctxClassLoader);
}
}
}
use of org.apache.nifi.processor.SimpleProcessLogger in project nifi by apache.
the class FlowController method reload.
@Override
public void reload(final ReportingTaskNode existingNode, final String newType, final BundleCoordinate bundleCoordinate, final Set<URL> additionalUrls) throws ReportingTaskInstantiationException {
if (existingNode == null) {
throw new IllegalStateException("Existing ReportingTaskNode cannot be null");
}
final String id = existingNode.getReportingTask().getIdentifier();
// ghost components will have a null logger
if (existingNode.getLogger() != null) {
existingNode.getLogger().debug("Reloading component {} to type {} from bundle {}", new Object[] { id, newType, bundleCoordinate });
}
// createReportingTask will create a new instance class loader for the same id so
// save the instance class loader to use it for calling OnRemoved on the existing processor
final ClassLoader existingInstanceClassLoader = ExtensionManager.getInstanceClassLoader(id);
// set firstTimeAdded to true so lifecycle annotations get fired, but don't register this node
// attempt the creation to make sure it works before firing the OnRemoved methods below
final ReportingTaskNode newNode = createReportingTask(newType, id, bundleCoordinate, additionalUrls, true, false);
// call OnRemoved for the existing reporting task using the previous instance class loader
try (final NarCloseable x = NarCloseable.withComponentNarLoader(existingInstanceClassLoader)) {
ReflectionUtils.quietlyInvokeMethodsWithAnnotation(OnRemoved.class, existingNode.getReportingTask(), existingNode.getConfigurationContext());
} finally {
ExtensionManager.closeURLClassLoader(id, existingInstanceClassLoader);
}
// set the new reporting task into the existing node
final ComponentLog componentLogger = new SimpleProcessLogger(id, existingNode.getReportingTask());
final TerminationAwareLogger terminationAwareLogger = new TerminationAwareLogger(componentLogger);
LogRepositoryFactory.getRepository(id).setLogger(terminationAwareLogger);
final LoggableComponent<ReportingTask> newReportingTask = new LoggableComponent<>(newNode.getReportingTask(), newNode.getBundleCoordinate(), terminationAwareLogger);
existingNode.setReportingTask(newReportingTask);
existingNode.setExtensionMissing(newNode.isExtensionMissing());
// need to refresh the properties in case we are changing from ghost component to real component
existingNode.refreshProperties();
}
use of org.apache.nifi.processor.SimpleProcessLogger in project nifi by apache.
the class StandardProcessScheduler method schedule.
@Override
public void schedule(final ReportingTaskNode taskNode) {
final LifecycleState lifecycleState = getLifecycleState(requireNonNull(taskNode), true);
if (lifecycleState.isScheduled()) {
return;
}
final int activeThreadCount = lifecycleState.getActiveThreadCount();
if (activeThreadCount > 0) {
throw new IllegalStateException("Reporting Task " + taskNode.getName() + " cannot be started because it has " + activeThreadCount + " threads still running");
}
if (!taskNode.isValid()) {
throw new IllegalStateException("Reporting Task " + taskNode.getName() + " is not in a valid state for the following reasons: " + taskNode.getValidationErrors());
}
final SchedulingAgent agent = getSchedulingAgent(taskNode.getSchedulingStrategy());
lifecycleState.setScheduled(true);
final Runnable startReportingTaskRunnable = new Runnable() {
@Override
public void run() {
final long lastStopTime = lifecycleState.getLastStopTime();
final ReportingTask reportingTask = taskNode.getReportingTask();
// Continually attempt to start the Reporting Task, and if we fail sleep for a bit each time.
while (true) {
try {
synchronized (lifecycleState) {
// bail; another thread will be responsible for invoking the @OnScheduled methods.
if (!lifecycleState.isScheduled() || lifecycleState.getLastStopTime() != lastStopTime) {
return;
}
try (final NarCloseable x = NarCloseable.withComponentNarLoader(reportingTask.getClass(), reportingTask.getIdentifier())) {
ReflectionUtils.invokeMethodsWithAnnotation(OnScheduled.class, reportingTask, taskNode.getConfigurationContext());
}
agent.schedule(taskNode, lifecycleState);
return;
}
} catch (final Exception e) {
final Throwable cause = e instanceof InvocationTargetException ? e.getCause() : e;
final ComponentLog componentLog = new SimpleProcessLogger(reportingTask.getIdentifier(), reportingTask);
componentLog.error("Failed to invoke @OnEnabled method due to {}", cause);
LOG.error("Failed to invoke the On-Scheduled Lifecycle methods of {} due to {}; administratively yielding this " + "ReportingTask and will attempt to schedule it again after {}", new Object[] { reportingTask, e.toString(), administrativeYieldDuration }, e);
ReflectionUtils.quietlyInvokeMethodsWithAnnotation(OnUnscheduled.class, reportingTask, taskNode.getConfigurationContext());
ReflectionUtils.quietlyInvokeMethodsWithAnnotation(OnStopped.class, reportingTask, taskNode.getConfigurationContext());
try {
Thread.sleep(administrativeYieldMillis);
} catch (final InterruptedException ie) {
}
}
}
}
};
componentLifeCycleThreadPool.execute(startReportingTaskRunnable);
taskNode.setScheduledState(ScheduledState.RUNNING);
}
Aggregations