use of org.apache.nifi.controller.service.ControllerServiceInvocationHandler 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();
}
Aggregations