Telescopic controller services in test framework...

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Telescopic controller services in test framework...

Russell Bateman-2
I've written a controller service that depends on another controller
service. One of the properties in the first service builds itself using
.identifiesControllerService( Service2.class ), but no
.allowableValues()because it was unclear what to put.

In my test code, I'm struggling as to how to reflect this relationship.

    TestRunner runner = TestRunners.newTestRunner( SomeProcessor.class );
    Service1 service1 = new Service1();
    Service2 service2 = new Service2();

    runner.addControllerService( "foo",  service1 );
    runner.setProperty( service1, ..., "" );              // typical
    setProperty() call
    *runner.setProperty( service1, ..., service2 );  // this won't
    compile; it's not an allowable value*

    runner.enableControllerService( service1 );
    runner.assertValid( service1 );
    etc.

How is this really done?

Thanks.
Reply | Threaded
Open this post in threaded view
|

Re: Telescopic controller services in test framework...

Matt Burgess-2
I believe NIFI-1121 [1] covers the ability for properties to depend on
each other, it is still an open issue.  I think the workaround is to
override onPropertyModified(), and rebuild the dependent property
based on the change in value(s). The user will have to hit the Apply
button on the dialog after selecting the controller service, then when
the config dialog is re-opened, the dependent property would be
populated with the corresponding values.  See the code for
RouteOnAttribute [2] as an example, it updates the Relationships but I
think you could use it to update the properties as well. I'm not sure
if you'd get a re-entrant (or extra) call to onPropertyModified if you
change a PropertyDescriptor, so beware of that as a possibility.


Regards,
Matt

[1] https://issues.apache.org/jira/browse/NIFI-1121
[2] https://github.com/apache/nifi/blob/master/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/RouteOnAttribute.java#L149

On Mon, May 15, 2017 at 3:31 PM, Russell Bateman <[hidden email]> wrote:

> I've written a controller service that depends on another controller
> service. One of the properties in the first service builds itself using
> .identifiesControllerService( Service2.class ), but no
> .allowableValues()because it was unclear what to put.
>
> In my test code, I'm struggling as to how to reflect this relationship.
>
>    TestRunner runner = TestRunners.newTestRunner( SomeProcessor.class );
>    Service1 service1 = new Service1();
>    Service2 service2 = new Service2();
>
>    runner.addControllerService( "foo",  service1 );
>    runner.setProperty( service1, ..., "" );              // typical
>    setProperty() call
>    *runner.setProperty( service1, ..., service2 );  // this won't
>    compile; it's not an allowable value*
>
>    runner.enableControllerService( service1 );
>    runner.assertValid( service1 );
>    etc.
>
> How is this really done?
>
> Thanks.
Reply | Threaded
Open this post in threaded view
|

Re: Telescopic controller services in test framework...

Matt Burgess-2
I forgot, InvokeScriptedProcessor has an example of "dynamically"
adding properties, the code is a bit weird but the idea is represented
there: https://github.com/apache/nifi/blob/master/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/InvokeScriptedProcessor.java#L131

On Mon, May 15, 2017 at 3:39 PM, Matt Burgess <[hidden email]> wrote:

> I believe NIFI-1121 [1] covers the ability for properties to depend on
> each other, it is still an open issue.  I think the workaround is to
> override onPropertyModified(), and rebuild the dependent property
> based on the change in value(s). The user will have to hit the Apply
> button on the dialog after selecting the controller service, then when
> the config dialog is re-opened, the dependent property would be
> populated with the corresponding values.  See the code for
> RouteOnAttribute [2] as an example, it updates the Relationships but I
> think you could use it to update the properties as well. I'm not sure
> if you'd get a re-entrant (or extra) call to onPropertyModified if you
> change a PropertyDescriptor, so beware of that as a possibility.
>
>
> Regards,
> Matt
>
> [1] https://issues.apache.org/jira/browse/NIFI-1121
> [2] https://github.com/apache/nifi/blob/master/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/RouteOnAttribute.java#L149
>
> On Mon, May 15, 2017 at 3:31 PM, Russell Bateman <[hidden email]> wrote:
>> I've written a controller service that depends on another controller
>> service. One of the properties in the first service builds itself using
>> .identifiesControllerService( Service2.class ), but no
>> .allowableValues()because it was unclear what to put.
>>
>> In my test code, I'm struggling as to how to reflect this relationship.
>>
>>    TestRunner runner = TestRunners.newTestRunner( SomeProcessor.class );
>>    Service1 service1 = new Service1();
>>    Service2 service2 = new Service2();
>>
>>    runner.addControllerService( "foo",  service1 );
>>    runner.setProperty( service1, ..., "" );              // typical
>>    setProperty() call
>>    *runner.setProperty( service1, ..., service2 );  // this won't
>>    compile; it's not an allowable value*
>>
>>    runner.enableControllerService( service1 );
>>    runner.assertValid( service1 );
>>    etc.
>>
>> How is this really done?
>>
>> Thanks.
Reply | Threaded
Open this post in threaded view
|

Re: Telescopic controller services in test framework...

Mark Payne
In reply to this post by Russell Bateman-2
Russ,

When you call setProperty, it's expecting a String value, so you don't want to set the value of
the property to `service2` but rather you'd set the property to the identifier for service2. For example:

runner.addControllerService( "service-id2", service2 );  // add service2 with an identifier of "service-id2"
runner.addControllerService( "foo", service1 );

runner.setProperty( service1, SERVICE_PROPERTY_DESCRIPTOR, "service-id2" ); // set property so that service1 has ID of service 2
runner.enableControllerService( service2 ); // enable service2 so that it can be used by service1
runner.enableControllerService( service1 ); // enable service1

Does that help?

Thanks
-Mark


> On May 15, 2017, at 3:31 PM, Russell Bateman <[hidden email]> wrote:
>
> I've written a controller service that depends on another controller service. One of the properties in the first service builds itself using .identifiesControllerService( Service2.class ), but no .allowableValues()because it was unclear what to put.
>
> In my test code, I'm struggling as to how to reflect this relationship.
>
>   TestRunner runner = TestRunners.newTestRunner( SomeProcessor.class );
>   Service1 service1 = new Service1();
>   Service2 service2 = new Service2();
>
>   runner.addControllerService( "foo",  service1 );
>   runner.setProperty( service1, ..., "" );              // typical
>   setProperty() call
>   *runner.setProperty( service1, ..., service2 );  // this won't
>   compile; it's not an allowable value*
>
>   runner.enableControllerService( service1 );
>   runner.assertValid( service1 );
>   etc.
>
> How is this really done?
>
> Thanks.