public interface ControllerService extends ConfigurableComponent
This interface provides a mechanism for creating services that are shared
among all Processor
s, ReportingTask
s, and other
ControllerService
s.
ControllerService
s are discovered using Java's
ServiceLoader
mechanism. As a result, all implementations must
follow these rules:
META-INF/services
directory. This file contains a list of
fully-qualified class names of all ControllerService
s in the
jar, one-per-line.
All implementations of this interface must be thread-safe.
A ControllerService is accessible only through its interface. The framework provides access to a ControllerService through two different mechanisms:
PropertyDescriptor
can be created via the
PropertyDescriptor.Builder
after calling the
identifiesControllerService(Class)
method and then the ControllerService is accessed via
PropertyValue.asControllerService(Class)
method.
For example:
public static final PropertyDescriptor MY_PROPERTY = new PropertyDescriptor.Builder()
.name("My Property")
.description("Example Property")
.identifiesControllerService( MyControllerServiceInterface.class )
.build();
...
public void onTrigger(ProcessContext context, ProcessSessionFactory sessionFactory) throws ProcessException {
// Obtain the user-selected controller service
final MyControllerServiceInterface service = context.getProperty(MY_PROPERTY).asControllerService( MyControllerServiceInterface.class );
...
}
ControllerServiceLookup
. This lookup may be obtained, for example,
from the ProcessContext
that is provided to a Processor
's
onTrigger
method.
For example:
public void onTrigger(ProcessContext context, ProcessSessionFactory sessionFactory) throws ProcessException {
final MyControllerServiceInterface service = (MyControllerServiceInterface) context.getControllerServiceLookup().getControllerService("service_identifier");
}
Note in both of the examples above, that the Controller Service was accessed
only by its interface, and this interface extends ControllerService. If we
have an implementation named MyServiceImpl, for example, that implements
MyControllerServiceInterface, we cannot, in either case, attempt to cast the
ControllerService to the desired implementation. Doing so will result in a
ClassCastException
. This is by design and is done for the following
reasons:
Due to the fact that a Controller Service may be referenced from a different NAR than the one in which the implementation lives, it is crucial that both the Controller Service's interface and the code referencing the interface inherit from the same ClassLoader. This is accomplished by ensuring that the NAR that contains the Controller Service interface is the parent (or ancestor) of the NAR that references the Controller Service interface.
Typically, this is done by creating a NAR structure as follows:
+ my-services-api-nar +--- service-X-implementation-nar +--- service-Y-implementation-nar +--- service-Z-implementation-nar +--- processor-A-nar +--- processor-B-nar
In this case, the MyControllerServiceInterface
interface, and any
other Controller Service interfaces, will be defined in the
my-services-api-nar
NAR. Implementations are then encapsulated within
the service-X-implementation-nar
,
service-Y-implementation-nar
, and
service-Z-implementation-nar
NARs. All Controller Services and all
Processors defined in these NARs are able to reference any other Controller
Services whose interfaces are provided in the my-services-api-nar
NAR.
For more information on NARs, see the NiFi Developer Guide.
Modifier and Type | Method and Description |
---|---|
void |
initialize(ControllerServiceInitializationContext context)
Provides the Controller Service with access to objects that may be of use
throughout the life of the service.
|
getIdentifier, getPropertyDescriptor, getPropertyDescriptors, onPropertyModified, validate
void initialize(ControllerServiceInitializationContext context) throws InitializationException
context
- of initializationInitializationException
- if unable to initCopyright © 2022 Apache NiFi Project. All rights reserved.