You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@taverna.apache.org by Nadeesh Dilanga <na...@gmail.com> on 2016/06/25 06:11:23 UTC

Issue in reusing ActivityInvoker#invokeAsyncActivity for unit tests

Hi,
I am trying to reuse the ActivityInvoker#invokeAsyncActivity  to my
activity plugin unit test. And my code is as follows where I am passing
String inputs to inspect an image. But the ActivityInvoker not passing same
inouts to my DockerActivity.
Ex: In ActivityInvoker > referenceService.register(getNameForObject)
returns  "t2:error//testNS?test0/0" after converting my input
"hello-world". I debug the code, it identifies my input as a
ExternalReferenceSPI and that seems to be what converting my value to
"t2:error//testNS?test0/0"".

Any idea why ? If this is not good to reuse for my case, shall I directly
invoke the activity class ?

DockerActivity activity = new DockerActivity(containerConfiguration);
      activity.configure(activityConfiguration);

Map<String,Object> inputs = new HashMap<String,Object>();
      inputs.put(DockerActivity.ACTION, DockerActivity.INSPECT);
      inputs.put(DockerActivity.IN_IMAGE_NAME, IMAGE_NAME);

Map<String, Class<?>> expectedOutputs = new HashMap<String, Class<?>>();
expectedOutputs.put("response_body", T2Reference.class);

Map<String,Object> outputs =
ActivityInvoker.invokeAsyncActivity(activity, inputs,
expectedOutputs);
      System.out.println(outputs.size());

Re: Issue in reusing ActivityInvoker#invokeAsyncActivity for unit tests

Posted by Alan Williams <al...@googlemail.com>.
On 30-Jun-16 04:19, Nadeesh Dilanga wrote:
> Hi,
> All variables are Strings. After a series of troubleshoot sessions, was
> able to figure out the issue I was facing.
> I had to do following;
>
>  referenceService.renderIdentifier(inputs.get(KEY), String.class, context);
>
> instead of just inputs.get(KEY).getLocalPart(). where inputs is a
> Map<String, T2Reference>. Now I could use the ActivityInvoker ;-).
>
> One other problem facing(I am doing my testings in my Java Project and
> running the tests through a Main method). But when removed and try to add
> them to JUnit and run through mvn install in runtime it again fails with
> that jackson method not found error. Working on finding that out. There
> should be some other module or transient sub module that packs old jackson.

> Will send a new pull request from a new feature branch with that fixed soon.

Brilliant! Well done.

Alan



Re: Issue in reusing ActivityInvoker#invokeAsyncActivity for unit tests

Posted by Nadeesh Dilanga <na...@gmail.com>.
Hi,
All variables are Strings. After a series of troubleshoot sessions, was
able to figure out the issue I was facing.
I had to do following;

 referenceService.renderIdentifier(inputs.get(KEY), String.class, context);

instead of just inputs.get(KEY).getLocalPart(). where inputs is a
Map<String, T2Reference>. Now I could use the ActivityInvoker ;-).

One other problem facing(I am doing my testings in my Java Project and
running the tests through a Main method). But when removed and try to add
them to JUnit and run through mvn install in runtime it again fails with
that jackson method not found error. Working on finding that out. There
should be some other module or transient sub module that packs old jackson.

Will send a new pull request from a new feature branch with that fixed soon.




On Tue, Jun 28, 2016 at 9:46 AM, Stian Soiland-Reyes <st...@apache.org>
wrote:

> Now I think it's the conversion of the outputs.. you are asking to
> convert to T2Reference (which mean no converting), but the
> ActivityInvoker does not permit that - and it would not work well as
> you don't have access to the referenceService outside to resolve the
> T2Reference.
>
>
> Instead try:
>
> expectedOutputs.put("response_body", String.class);
>
> and then you should get the output json back as a java.lang.String.
>
>
> Note that the output would be an Error Document if an exception was
> thrown by the Activity - which means you should not need to do this:
>
>                 } catch (Exception e){
>                     String log = "Error occurred while executing
> remote docker commands " + e.getMessage();
>                     LOG.error(log ,e);
>                     responseBodyRef =
> referenceService.register("{\"error\",\"" + log + "\"}", 0, true,
> context);
>                }
>
>
> If there are any checked exception (e.g. IOException) you can instead
> fail close to the error, e.g.:
>
> try {
>    dockerclient.hello();
> } catch (IOException ex) {
>   callback.fail("Can't connect to Docker engine", ex);
>   return;
> }
>
>
>
>
>
> Generally a large try..catch (Exception) is a bad idea as it hides
> error situations you probably should have recovered from earlier in
> the code. More useful error messages also help workflow users, as then
> they won't always need to hunt through that stacktrace.
>
>
> BTW - with Java 8 you no longer need to instantiate the Runnable
> explicitly, you can do this with a lambda:
>
> callback.requestRun( () -> {
>   callback.receiveResult(...);
> });
>
> Perhaps this could be fixed in
>
> https://github.com/apache/incubator-taverna-engine/blob/master/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/main/java/__classPrefix__Activity.java#L87
>
> On 28 June 2016 at 14:18, Stian Soiland-Reyes <st...@apache.org> wrote:
> > What's the type of DockerActivity.INSPECT and IMAGE_NAME? It sounds like
> > something goes wrong in converting either within ActivityInvoker or
> within
> > DockerActivity.
> >
> > String and byte[] should work.
> >
> >
> > On 25 Jun 2016 7:11 a.m., "Nadeesh Dilanga" <na...@gmail.com>
> wrote:
> >>
> >> Hi,
> >> I am trying to reuse the ActivityInvoker#invokeAsyncActivity  to my
> >> activity plugin unit test. And my code is as follows where I am passing
> >> String inputs to inspect an image. But the ActivityInvoker not passing
> >> same
> >> inouts to my DockerActivity.
> >> Ex: In ActivityInvoker > referenceService.register(getNameForObject)
> >> returns  "t2:error//testNS?test0/0" after converting my input
> >> "hello-world". I debug the code, it identifies my input as a
> >> ExternalReferenceSPI and that seems to be what converting my value to
> >> "t2:error//testNS?test0/0"".
> >>
> >> Any idea why ? If this is not good to reuse for my case, shall I
> directly
> >> invoke the activity class ?
> >>
> >> DockerActivity activity = new DockerActivity(containerConfiguration);
> >>       activity.configure(activityConfiguration);
> >>
> >> Map<String,Object> inputs = new HashMap<String,Object>();
> >>       inputs.put(DockerActivity.ACTION, DockerActivity.INSPECT);
> >>       inputs.put(DockerActivity.IN_IMAGE_NAME, IMAGE_NAME);
> >>
> >> Map<String, Class<?>> expectedOutputs = new HashMap<String, Class<?>>();
> >> expectedOutputs.put("response_body", T2Reference.class);
> >>
> >> Map<String,Object> outputs =
> >> ActivityInvoker.invokeAsyncActivity(activity, inputs,
> >> expectedOutputs);
> >>       System.out.println(outputs.size());
>
>
>
> --
> Stian Soiland-Reyes
> Apache Taverna (incubating), Apache Commons
> http://orcid.org/0000-0001-9842-9718
>

Re: Issue in reusing ActivityInvoker#invokeAsyncActivity for unit tests

Posted by Stian Soiland-Reyes <st...@apache.org>.
Now I think it's the conversion of the outputs.. you are asking to
convert to T2Reference (which mean no converting), but the
ActivityInvoker does not permit that - and it would not work well as
you don't have access to the referenceService outside to resolve the
T2Reference.


Instead try:

expectedOutputs.put("response_body", String.class);

and then you should get the output json back as a java.lang.String.


Note that the output would be an Error Document if an exception was
thrown by the Activity - which means you should not need to do this:

                } catch (Exception e){
                    String log = "Error occurred while executing
remote docker commands " + e.getMessage();
                    LOG.error(log ,e);
                    responseBodyRef =
referenceService.register("{\"error\",\"" + log + "\"}", 0, true,
context);
               }


If there are any checked exception (e.g. IOException) you can instead
fail close to the error, e.g.:

try {
   dockerclient.hello();
} catch (IOException ex) {
  callback.fail("Can't connect to Docker engine", ex);
  return;
}





Generally a large try..catch (Exception) is a bad idea as it hides
error situations you probably should have recovered from earlier in
the code. More useful error messages also help workflow users, as then
they won't always need to hunt through that stacktrace.


BTW - with Java 8 you no longer need to instantiate the Runnable
explicitly, you can do this with a lambda:

callback.requestRun( () -> {
  callback.receiveResult(...);
});

Perhaps this could be fixed in
https://github.com/apache/incubator-taverna-engine/blob/master/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/main/java/__classPrefix__Activity.java#L87

On 28 June 2016 at 14:18, Stian Soiland-Reyes <st...@apache.org> wrote:
> What's the type of DockerActivity.INSPECT and IMAGE_NAME? It sounds like
> something goes wrong in converting either within ActivityInvoker or within
> DockerActivity.
>
> String and byte[] should work.
>
>
> On 25 Jun 2016 7:11 a.m., "Nadeesh Dilanga" <na...@gmail.com> wrote:
>>
>> Hi,
>> I am trying to reuse the ActivityInvoker#invokeAsyncActivity  to my
>> activity plugin unit test. And my code is as follows where I am passing
>> String inputs to inspect an image. But the ActivityInvoker not passing
>> same
>> inouts to my DockerActivity.
>> Ex: In ActivityInvoker > referenceService.register(getNameForObject)
>> returns  "t2:error//testNS?test0/0" after converting my input
>> "hello-world". I debug the code, it identifies my input as a
>> ExternalReferenceSPI and that seems to be what converting my value to
>> "t2:error//testNS?test0/0"".
>>
>> Any idea why ? If this is not good to reuse for my case, shall I directly
>> invoke the activity class ?
>>
>> DockerActivity activity = new DockerActivity(containerConfiguration);
>>       activity.configure(activityConfiguration);
>>
>> Map<String,Object> inputs = new HashMap<String,Object>();
>>       inputs.put(DockerActivity.ACTION, DockerActivity.INSPECT);
>>       inputs.put(DockerActivity.IN_IMAGE_NAME, IMAGE_NAME);
>>
>> Map<String, Class<?>> expectedOutputs = new HashMap<String, Class<?>>();
>> expectedOutputs.put("response_body", T2Reference.class);
>>
>> Map<String,Object> outputs =
>> ActivityInvoker.invokeAsyncActivity(activity, inputs,
>> expectedOutputs);
>>       System.out.println(outputs.size());



-- 
Stian Soiland-Reyes
Apache Taverna (incubating), Apache Commons
http://orcid.org/0000-0001-9842-9718

Re: Issue in reusing ActivityInvoker#invokeAsyncActivity for unit tests

Posted by Stian Soiland-Reyes <st...@apache.org>.
What's the type of DockerActivity.INSPECT and IMAGE_NAME? It sounds like
something goes wrong in converting either within ActivityInvoker or within
DockerActivity.

String and byte[] should work.

On 25 Jun 2016 7:11 a.m., "Nadeesh Dilanga" <na...@gmail.com> wrote:

> Hi,
> I am trying to reuse the ActivityInvoker#invokeAsyncActivity  to my
> activity plugin unit test. And my code is as follows where I am passing
> String inputs to inspect an image. But the ActivityInvoker not passing same
> inouts to my DockerActivity.
> Ex: In ActivityInvoker > referenceService.register(getNameForObject)
> returns  "t2:error//testNS?test0/0" after converting my input
> "hello-world". I debug the code, it identifies my input as a
> ExternalReferenceSPI and that seems to be what converting my value to
> "t2:error//testNS?test0/0"".
>
> Any idea why ? If this is not good to reuse for my case, shall I directly
> invoke the activity class ?
>
> DockerActivity activity = new DockerActivity(containerConfiguration);
>       activity.configure(activityConfiguration);
>
> Map<String,Object> inputs = new HashMap<String,Object>();
>       inputs.put(DockerActivity.ACTION, DockerActivity.INSPECT);
>       inputs.put(DockerActivity.IN_IMAGE_NAME, IMAGE_NAME);
>
> Map<String, Class<?>> expectedOutputs = new HashMap<String, Class<?>>();
> expectedOutputs.put("response_body", T2Reference.class);
>
> Map<String,Object> outputs =
> ActivityInvoker.invokeAsyncActivity(activity, inputs,
> expectedOutputs);
>       System.out.println(outputs.size());
>