Interface ControllerService
- All Superinterfaces:
ConfigurableComponent
- All Known Implementing Classes:
AbstractControllerService
This interface provides a mechanism for creating services that are shared
among all Processor
s, ReportingTask
s, FlowAnalysisRule
s, ParameterProvider
s and other
ControllerService
s.
ControllerService
s are discovered using Java's
ServiceLoader
mechanism. As a result, all implementations must
follow these rules:
- The implementation must implement this interface.
- The implementation must have a file named
org.apache.nifi.controller.ControllerService located within the jar's
META-INF/services
directory. This file contains a list of fully-qualified class names of allControllerService
s in the jar, one-per-line. - The implementation must support a default constructor.
All implementations of this interface must be thread-safe.
Accessing Controller Services
A ControllerService is accessible only through its interface. The framework provides access to a ControllerService through two different mechanisms:
-
A
PropertyDescriptor
can be created via thePropertyDescriptor.Builder
after calling theidentifiesControllerService(Class)
method and then the ControllerService is accessed viaPropertyValue.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 ); ... }
- A Controller Service can be obtained via a
ControllerServiceLookup
. This lookup may be obtained, for example, from theProcessContext
that is provided to aProcessor
'sonTrigger
method.For example:
public void onTrigger(ProcessContext context, ProcessSessionFactory sessionFactory) throws ProcessException { final MyControllerServiceInterface service = (MyControllerServiceInterface) context.getControllerServiceLookup().getControllerService("service_identifier"); }
Defining a Controller Service
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:
- It is a good coding practice to implement such a service as an interface in general.
- A Controller Service can be referenced from different NiFi Archives (NARs). This means that the Controller Service may be defined in one ClassLoader and referenced from another unrelated ClassLoader. In order to account for this, NiFi will change the current thread's ClassLoader as appropriate when entering the Controller Service's code and revert back to the previous ClassLoader after exiting the Controller Service's code.
Controller Services and NARs
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.
-
Method Summary
Modifier and TypeMethodDescriptionvoid
Provides the Controller Service with access to objects that may be of use throughout the life of the service.default boolean
isStateful
(ConfigurationContext context) Indicates whether this controller service, configured with the givenConfigurationContext
, stores state.default void
Allows for the migration of an old property configuration to a new configuration.Methods inherited from interface org.apache.nifi.components.ConfigurableComponent
getIdentifier, getPropertyDescriptor, getPropertyDescriptors, onPropertyModified, validate
-
Method Details
-
initialize
Provides the Controller Service with access to objects that may be of use throughout the life of the service. This method will be called before any properties are set- Parameters:
context
- of initialization- Throws:
InitializationException
- if unable to init
-
isStateful
Indicates whether this controller service, configured with the givenConfigurationContext
, stores state.- Parameters:
context
- provides access to convenience methods for obtaining property values- Returns:
- True if this controller service stores state
-
migrateProperties
Allows for the migration of an old property configuration to a new configuration. This allows the Controller Service to evolve over time, as it allows properties to be renamed, removed, or reconfigured.
This method is called only when a Controller Service is restored from a previous configuration. For example, when NiFi is restarted and the flow is restored from disk, when a previously configured flow is imported (e.g., from a JSON file that was exported or a NiFi Registry), or when a node joins a cluster and inherits a flow that has a new Controller Service. Once called, the method will not be invoked again for this Controller Service until NiFi is restarted.
- Parameters:
config
- the current property configuration
-