E9.2 Simple Calculations

Jeff George

Jeff George

Well Known Member
Good morning. I'm using a Data Request to retrieve three aggregated numbers from three fields of a table. I then want to do a calculation on those three fields, e.g. agg field 1 + agg field 2 + agg field 3, etc. Where would I put this in the orchestration so that I can then use it as an input for a Form Request? I can't find a way to do math.
 
Hi Jeff,

You can pass those three values into a Custom Service Request to sum them.

Kevin
 
Hi Jeff, as Kevin said create a custom script component after the data request with inputs to match the outputs of the data request, so in your example you'd have 3 inputs to the script. Then use the scripting language (groovy for example) to transform the input vars into numerics, and then add the numerics. Then set the sum to go to an output variable, and finally map the output variable to the component output for later use in your orchestration.

Lots of words in my explanation, but it will make sense when you get it going! Lots of trial and error the first few times you get into scripting in my experience.
 
Oh boy. Thanks for the replies. I understand, in theory, what you guys are saying. I am just not experienced enough (yet) in Orchestrator to know how to implement it. But if that's the best way to do it then I will figure it out!
 
Good morning. I'm using a Data Request to retrieve three aggregated numbers from three fields of a table. I then want to do a calculation on those three fields, e.g. agg field 1 + agg field 2 + agg field 3, etc. Where would I put this in the orchestration so that I can then use it as an input for a Form Request? I can't find a way to do math.
As I work with Orchestrator I've come to realize that it's almost embarrassingly primitive. Come on Oracle. Generally I do this when it comes to a data request.. Create a work table and a UBE that builds it (using a UKID data item as part of the key). IN a UBE, I've learned to do just about anything I want. I've found that this approach will over come the limitations of the data request and the orchestration is much simpler.
 
As I work with Orchestrator I've come to realize that it's almost embarrassingly primitive. Come on Oracle. Generally I do this when it comes to a data request.. Create a work table and a UBE that builds it (using a UKID data item as part of the key). IN a UBE, I've learned to do just about anything I want. I've found that this approach will over come the limitations of the data request and the orchestration is much simpler.
I have only worked with Orchestrator a little bit so I am very far from being a SME on it and I certainly have some issues with it but from the little that I have seen I think it gives you quite a bit of options and ways to do things so I am not sure I would call it "primitive". You can always build BSFNs to do calculations and other logic or write a web service in some other language/tool and call it (the two methods we have used at our organization) or as others have pointed out it does give you the option to write code in Groovy. I wish it was some other language than Groovy but at least they picked an open standard language and didn't create some proprietary scripting language.

I have not done much with Groovy so maybe I will change my opinion once I have, but personally I think it is best to keep as much business logic and calculations OUT of Orchestrator, put that in BSFNs (you will get reuse from that in other places) or build micro services in some other language and simply use Orchestrator to tie it all together.

This was the approach I used with Business Services. I didn't write a bunch of business logic / calculations in Java, I used Business Services as thin wrappers to BSFNs and it worked well. We have ported some of those Business Services to Orchestrator and by having all the logic in BSFNs it was a very easy port.
 
I have only worked with Orchestrator a little bit so I am very far from being a SME on it and I certainly have some issues with it but from the little that I have seen I think it gives you quite a bit of options and ways to do things so I am not sure I would call it "primitive". You can always build BSFNs to do calculations and other logic or write a web service in some other language/tool and call it (the two methods we have used at our organization) or as others have pointed out it does give you the option to write code in Groovy. I wish it was some other language than Groovy but at least they picked an open standard language and didn't create some proprietary scripting language.

I have not done much with Groovy so maybe I will change my opinion once I have, but personally I think it is best to keep as much business logic and calculations OUT of Orchestrator, put that in BSFNs (you will get reuse from that in other places) or build micro services in some other language and simply use Orchestrator to tie it all together.

This was the approach I used with Business Services. I didn't write a bunch of business logic / calculations in Java, I used Business Services as thin wrappers to BSFNs and it worked well. We have ported some of those Business Services to Orchestrator and by having all the logic in BSFNs it was a very easy port.
The necessity of having to create something else to perform simple math in 2022, that is my definition of "primitive".
 
The necessity of having to create something else to perform simple math in 2022, that is my definition of "primitive".
I think I get what you're saying, but I think that with not too much effort it's possible to start to see the possibilities afforded to us by having Orchestrator implement a widely used scripting language. It's very very very modern in concept and for those of us who have traditionally worked on 10-20 year old software (XE, formscape, even world) and interfaces to have supermodern toys like this with an entire community of developers having contributed to the body of knowledge easily found via google, it's a bit of a dream come true. Using this specific need to do simple math as an excuse to dig a bit into and learn groovy scripting will hopefully open your eyes to the possibilities.

Today I learned how to use groovy and jsonslurper to pull specific json objects out of an orchestrator input, where one of the inputs coming in from an external system is simply of type "object". that json object contains child fields that I couldn't figure out how to get to in the GUI, so resorted to learning and then implementing a very flexible groovy script that calls the jsonslurper library. This is the future! :)
 
Some of it is point of view and how Oracle is marketing Orchestrator. Orchestrator is marketed as a powerful tool that you can do amazing things with, without needing to do "development" or use a "developer". But if you have to resort to writing BSFNs or Groovy script, you start getting away from that idea quickly.

My view is that it is both powerful and primitive at the same time. The power is in how easy it is to wrap an application into something that can easily be called as a rest service. Anything more complex than that, and invariably I seem to end up needing some Groovy script or BSFN to do something.

Utilizing Groovy as a scripting language within Orchestrator is very powerful. However, the Groovy editor is about as primitive as you can get. It is basically a big text field. No intellisense. No debugger. I'm old and cranky and want all the trappings of a modern IDE built in and I want it now 😋
 
Here's what we novices created to attempt to achieve the goal:

Code:
import com.oracle.e1.common.OrchestrationAttributes;
import java.text.SimpleDateFormat;
HashMap<Integer, Object> main(OrchestrationAttributes orchAttr, HashMap inputMap)

{
  HashMap<Integer, Object> returnMap = new HashMap<Integer, Object>();
   // Create sum

    int numVal1 = (int)inputMap.get("Value1");
    int numVal2 = (int)inputMap.get("Value2");
    int numVal3 = (int)inputMap.get("Value3");
    int Total = (int)numVal1 - (int)numVal2 - (int)numVal3;
    
    returnMap.put("Total",Total);
  return returnMap;
}

Here is the test data:

1659622470941.png

However, when executing the test I am getting the following error:

Exception org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '100' with class 'java.lang.String' to class 'int'

I'm not sure what is causing this. We've tried every combination of int and string that is feasible and we still get the error.
 
I see you modified the default hashmap that begins any orch groovy, I've not had to do that in my not-so-extensive experience. I wonder if that might be causing the issue. Also the quotes around the numbers might not be necessary, as I think it treats everything as a string by default (just a guess based on my experience)

Here's one I came up with after googling this article which includes some really good snippets such as checking the inputs to make sure they're int-able. I have found general success just using the template code to get and set the input and output variables. Hope this is helpful!

In general I have found the most success passing vars into an orchestration, and also between orch components, as strings. Even numbers, dates, amounts, etc. When I need something formatted properly I'll toss it into Groovy, format it using proper functions, and then output from groovy as a string again.

JavaScript:
import com.oracle.e1.common.OrchestrationAttributes;
import java.text.SimpleDateFormat;
HashMap<String, Object> main(OrchestrationAttributes orchAttr, HashMap inputMap)
{
  HashMap<String, Object> returnMap = new HashMap<String, Object>();
 
    Integer numVal1 = (String)inputMap.get("Input1") as Integer;
    Integer numVal2 = (String)inputMap.get("Input2") as Integer;
    Integer numVal3 = (String)inputMap.get("Input3") as Integer;
    Integer subtraction1 = numVal1-numVal2-numVal3;
    returnMap.put("Output1",subtraction1);
  return returnMap;
}

1659623354719.png

Aargh, I typed this up and see it's waiting in moderation. Not sure why I'm getting moderated but here we are :)
 
Last edited:
It looks like you've include the double quotes in your input value which would cause this type of error because it can't convert a non-numeric value to integer. Although the error message itself seems to think it has the 100 and not "100". I'd try the same thing without the double quotes included in your test value.
So, without a good IDE that allows you to debug, step through and see the values of variables at each step, I resort to old-school debugging methods.
Comment out everything and start working on the first line to verify what you are seeing. Add an output that is something like DebugOut. Start breaking down your statements into smaller pieces to review what you are getting back.
If you have access to the AIS log, you can also use orchAttr.writeWarn("something"); to write out intermediary values to the log for review.
 
It looks like you've include the double quotes in your input value which would cause this type of error because it can't convert a non-numeric value to integer. Although the error message itself seems to think it has the 100 and not "100". I'd try the same thing without the double quotes included in your test value.
So, without a good IDE that allows you to debug, step through and see the values of variables at each step, I resort to old-school debugging methods.
Comment out everything and start working on the first line to verify what you are seeing. Add an output that is something like DebugOut. Start breaking down your statements into smaller pieces to review what you are getting back.
If you have access to the AIS log, you can also use orchAttr.writeWarn("something"); to write out intermediary values to the log for review.
That was one of the things we tried, i.e. removing the double quotes in the test value. The same error still happens. I'm not sure how to go about using your proposal, since it's happening with the very first test input value.
 
It's a brute force method where you strip you line down to the simplest it can be so you can see what it does and then build up the pieces again.
Start by commenting everything out except for a line like this:
returnMap.put("Total",inputMap.get("Value1"));
Verify what the value looks like.
Then start adding things in like:
returnMap.put("Total",(int)inputMap.get("Value1"));
And we get the error even on something that simple :(. Now I start googling groovy cast string to int. I find several suggested ways of doing it:
int intNum = stringNum as int
or
int intNum = stringNum.toInteger()
or
int intNum = new Integer(stringNum).intValue()
or
int intNum = Integer.valueOf(stringNum)
or
def intVal = stringVal1 as Integer

Okay - I'm going to pick the first because it seems simplest and try (with no quotes inside the input value):

int numVal1 = inputMap.get("Value1") as int;
returnMap.put("Total",numVal1);

Which works. That's what I mean by breaking it down and brute forcing it.

This intrigued me, so I fiddled around some more. I tried:
int numVal2 = (Integer)inputMap.get("Value2");
which did not give you the error trying to cast, but it didn't return the correct result. (53 instead of 5 :unsure:)
I tried this:
def numVal2 = inputMap.get("Value2") as Integer;
and it did return the correct value

As you can guess, I'm not a java/groovy developer either. So I spend a lot of time working my way through the simple stuff figuring out what works.
 
Utilizing Groovy as a scripting language within Orchestrator is very powerful. However, the Groovy editor is about as primitive as you can get. It is basically a big text field. No intellisense. No debugger. I'm old and cranky and want all the trappings of a modern IDE built in and I want it now 😋

Those are absolutely reasonable requests. I can't code without code completion / Intellisense... I mean I can but it cuts my productivity WAY down. One of the first things I did when I started doing JDE development (all the way back in the Xe days) was figure out how to get code completion/Intellisense to work in VS for BSFNs. And debugging is certainly foundational on the programmer's hierarchy of needs.
 
int numVal1 = inputMap.get("Value1") as int;
returnMap.put("Total",numVal1);

Which works. That's what I mean by breaking it down and brute forcing it.

This is great. It works, and I'm pretty sure I understand the syntax. Thanks for digging into that.

Code:
import com.oracle.e1.common.OrchestrationAttributes;
import java.text.SimpleDateFormat;
HashMap<Integer, Object> main(OrchestrationAttributes orchAttr, HashMap inputMap)

{
  HashMap<Integer, Object> returnMap = new HashMap<Integer, Object>();
   
    int numVal1 = inputMap.get("Value1") as int;
    int numVal2 = inputMap.get("Value2") as int;
    int numVal3 = inputMap.get("Value3") as int;
    int Total = (int)numVal1 - (int)numVal2 - (int)numVal3;
    returnMap.put("Total",Total);
  
  // return sum of values
  return returnMap;
}
 
This is great. It works, and I'm pretty sure I understand the syntax. Thanks for digging into that.

Code:
import com.oracle.e1.common.OrchestrationAttributes;
import java.text.SimpleDateFormat;
HashMap<Integer, Object> main(OrchestrationAttributes orchAttr, HashMap inputMap)

{
  HashMap<Integer, Object> returnMap = new HashMap<Integer, Object>();
  
    int numVal1 = inputMap.get("Value1") as int;
    int numVal2 = inputMap.get("Value2") as int;
    int numVal3 = inputMap.get("Value3") as int;
    int Total = (int)numVal1 - (int)numVal2 - (int)numVal3;
    returnMap.put("Total",Total);
 
  // return sum of values
  return returnMap;
}
Just a comment. numVal1-3 are already int, so you don't need the int prefixed on them in the Total line. This should work:
int Total = numVal1 - numVal2 - numVal3
 
Just a comment. numVal1-3 are already int, so you don't need the int prefixed on them in the Total line. This should work:
int Total = numVal1 - numVal2 - numVal3
Good catch. I was so happy just to get the output correct that I didn't even bother to clean any of the testing up. Poor form on my part.
 
I see you modified the default hashmap that begins any orch groovy, I've not had to do that in my not-so-extensive experience. I wonder if that might be causing the issue. Also the quotes around the numbers might not be necessary, as I think it treats everything as a string by default (just a guess based on my experience)

Here's one I came up with after googling this article which includes some really good snippets such as checking the inputs to make sure they're int-able. I have found general success just using the template code to get and set the input and output variables. Hope this is helpful!

In general I have found the most success passing vars into an orchestration, and also between orch components, as strings. Even numbers, dates, amounts, etc. When I need something formatted properly I'll toss it into Groovy, format it using proper functions, and then output from groovy as a string again.

JavaScript:
import com.oracle.e1.common.OrchestrationAttributes;
import java.text.SimpleDateFormat;
HashMap<String, Object> main(OrchestrationAttributes orchAttr, HashMap inputMap)
{
  HashMap<String, Object> returnMap = new HashMap<String, Object>();
 
    Integer numVal1 = (String)inputMap.get("Input1") as Integer;
    Integer numVal2 = (String)inputMap.get("Input2") as Integer;
    Integer numVal3 = (String)inputMap.get("Input3") as Integer;
    Integer subtraction1 = numVal1-numVal2-numVal3;
    returnMap.put("Output1",subtraction1);
  return returnMap;
}

View attachment 19366

Aargh, I typed this up and see it's waiting in moderation. Not sure why I'm getting moderated but here we are :)
Hi DaveWagoner I know this is an older post but I am trying to achieve a similar concept. I have the groovy code working fine and the results come back correct but when I test in ORCH I made my "Total" var convert to string and I get the following error.

1673451009969.png

1673451132562.png
 
Back
Top