Friday, 20 July 2018

Simple RTE observation - enhancement request

I've blogged a lot about RTE, because I think it's pretty cool.

There is one thing that I do not like...  The fact that it's a challenge to get more than one transaction server running.

Remember that your configuration of subscribers is half the battle - you can configure multiple subscribers and have them separated by name and environment - nicely.

Only subscribe to certain messages for certain environments and wow - everything looks nice from P90701A.

The main problem is that the RTE server polls the F90710 that is defined in the OCMs that you put in the transaction server config.

So, it's poll that table with a very simple SQL

SELECT MIN(ETEVNTSEQ) FROM SY910.F90710 WHERE (ETEVNTST = 3);

The same thing, said another way.

The transaction server does not check subscriber information, this is important.  When defining a subscriber and then a connection and events and active environments, remember that this is not going to completely define where messages will end up...  What do you mean?  I hear you ask.

It's not just triggers from the JDE kernels on the enterprise server that initiate the consumption of RTE, the txn server itself polls the F90710 using the statement above.


The following sequence of screens shows this slight calamity
My subscriber, defined for port 136 only

my subscriptions defined for port 136

My environments saying only PY910 messages

my RTE server in DV with the message!  Boo hoo!

It might be a simplistic point of view, but the transaction server could compare environments that are subscribed to and not grab the messages.  The transaction server could also look at F90706 etc to see if it was the machine that was referenced in the subscriber configuration and once again ignore the messages if this was the case.

Any of the two changes to the code would allow multiple transaction servers using a single set of configuration, much better!




Wednesday, 18 July 2018

advanced orchestration lessons

I’ve had a little help on this one, but I wanted to explain some frustrations / limitations in the current edition of the orchestration studio.

My requirements were simple (I thought).

I wanted to scroll through a complex result set, for each row build a string and eventually send that string to a web service.

My web service took a single payload of a parent | child data sequence.

Simple – yeah?  NO!!

image

My initial thoughts were to create the data request and then a groovy connector to concatenate the strings, but this does not work – as the variables only have scope for each iteration of the result set – i.e. I cannot concatenate and get the results after the entire resultset is complete… arrgghh

I started to get fancy and thought that I could use a connector, but this did not work either.

I started creating edit lines, and begin docs – thinking that I was clever, but this did not work either because of the above variable scope and iteration.

So.

I phoned a friend and Trev gave me a tip of manipulating the output of an orchestration.

I then proceeded to have something like:

image


This is simple.

I recommend that if you are going to use this method, you need to get the output of the data request from your orchestration client before you write code, as you will need to understand the output JSON document format.

image

See that I’ve not done and Add’s to the data, left is standard.

Looks something like:

{
   "ServiceRequest1" : {
     "ds_V4209C" : {
       "output" : [ {
         "groupBy" : {
           "F4209.RPER" : 58026
         },
         "F4301.OTOT_SUM" : 756389.52,
         "F4209.DOCO_COUNT_DISTINCT" : 9
       }, {
         "groupBy" : {
           "F4209.RPER" : 8444
         },
         "F4301.OTOT_SUM" : 228918.32,
         "F4209.DOCO_COUNT_DISTINCT" : 9
       }, {
         "groupBy" : {
           "F4209.RPER" : 58018
         },
         "F4301.OTOT_SUM" : 216092.0,
         "F4209.DOCO_COUNT_DISTINCT" : 7
       }, {
         "groupBy" : {
           "F4209.RPER" : 123238
         },
         "F4301.OTOT_SUM" : 113000.0,
         "F4209.DOCO_COUNT_DISTINCT" : 1
       }, {
         "groupBy" : {
           "F4209.RPER" : 7500
         },
         "F4301.OTOT_SUM" : 24893.75,
         "F4209.DOCO_COUNT_DISTINCT" : 3
       }, {
         "groupBy" : {
           "F4209.RPER" : 6002
         },
         "F4301.OTOT_SUM" : 20000.0,
         "F4209.DOCO_COUNT_DISTINCT" : 1
       }, {
         "groupBy" : {
           "F4209.RPER" : 6001
         },
         "F4301.OTOT_SUM" : 2287.29,
         "F4209.DOCO_COUNT_DISTINCT" : 2
       }, {
         "groupBy" : {
           "F4209.RPER" : 533095
         },
         "F4301.OTOT_SUM" : 1327.5,
         "F4209.DOCO_COUNT_DISTINCT" : 7
       }, {
         "groupBy" : {
           "F4209.RPER" : 7504
         },
         "F4301.OTOT_SUM" : 1000.0,
         "F4209.DOCO_COUNT_DISTINCT" : 1
       }, {
         "groupBy" : {
           "F4209.RPER" : 43393
         },
         "F4301.OTOT_SUM" : 593.75,
         "F4209.DOCO_COUNT_DISTINCT" : 1
       }, {
         "groupBy" : {
           "F4209.RPER" : 533093
         },
         "F4301.OTOT_SUM" : 70.0,
         "F4209.DOCO_COUNT_DISTINCT" : 3
       }, {
         "groupBy" : {
           "F4209.RPER" : 70012
         },
         "F4301.OTOT_SUM" : 25.0,
         "F4209.DOCO_COUNT_DISTINCT" : 1
       } ]
     }
   }

With this, I can formulate the code below.  Note the hierarchy of the output and the use of the iterator.


import groovy.json.JsonSlurper;
import groovy.json.JsonBuilder;
import com.oracle.e1.common.OrchestrationAttributes;
String main(OrchestrationAttributes orchAttr, String input)
{
   def jsonIn = new JsonSlurper().parseText(input);
   // modify jsonIn
    
   String bigString = "";
   orchAttr.writeWarn("TEsting");
   items = jsonIn.ServiceRequest1.ds_V4209C.output.iterator();
   while (items.hasNext()) {
     item = items.next();
     bigString += item.get("F4301.OTOT_SUM") + "|"
   }
   jsonIn.put("concat",bigString);
  
   orchAttr.writeWarn(bigString);
   
   def jsonOut = new JsonBuilder(jsonIn).toString();
  
   return jsonOut;
}

When I run this now, I have an additional parameter at the bottom:

  "concat" : "756389.52|228918.32|216092.00|113000.00|24893.75|20000.00|2287.29|1327.50|1000.00|593.75|70.00|25.00|"

Nice variable name!

So, now I need to create a SR that is a connector type that is going to put this output variable “concat” into my other SR that does an external post to my web service!  Easy.

my orchestration looks like this:

image

My connector SR looks like this:

image

Note that the concat variable is defined in the output of the connector SR

So When I call my orchestration that calls the SR that calls an orchestration…

image

I get the output that I want.  The concatenation of the resultset in a string that I can send to my web service, that is great…  A long journey though!

Extending JDE to generative AI