Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
engswee
Active Contributor

[Update 11 Mar 2022]


This post was written more than 4 years ago. Technology moves at the light of speed, and as such, some of what is described here is out of date, but I don't have the time to adjust it continuously to be always in sync with the latest. If you are interested in developing and testing your Groovy scripts, I'd suggest you check my E-Bite on this topic instead which is more current and should provide you a more comprehensive approach to get started. https://blogs.sap.com/2020/06/15/learn-to-develop-groovy-scripts-for-sap-cpi-with-our-new-sap-press-...


 

It all started with a basic (yet very important) question:-

Do you test your Groovy scripts?

Or more accurately, How do you test your Groovy scripts?

Because
if(!software.isTestable()) {
software = null;
}

 

WebUI, SchmebUI


If we leave it to chance, life with SAP Cloud Platform Integration would be colorless like this:-



How do you even work with such an editor in this day and age... let alone test anything on it??

Well, on occasions like this, pardon me, but I would rather take chance into my own hands, and have a bit more color in my life (code completion and on-the-fly syntax check, anyone?):-



 

Ok, Eclipse is Groovier, but how do we test?


Well, before vadim.klimov took matters into his own hands, we would have had to rely on creating our own versions of Cloud Integration's libraries using techniques like Reflecting on the Message class by 7a519509aed84a2c9e6f627841825b5a.

But fortunately for all of us, Vadim bravely trailblazed the way forward with Dark Side of Groovy Scripting: Behind the Scenes of Cloud Integration Runtime.

Before you even continue, you will really need to read thoroughly the above blog, as that is both prerequisite and key.

You will also need the below:-

Eclipse Neon (What do you mean you don't have it yet?!)

Groovy Eclipse (Eclipse is Groovier with Groovy)

 

Let the testing begin!


All ready now?

Let's first create a Groovy Project.



 

After that, let's play nice and have a decent package for your Groovy scripts. You will need two scripts here:-

  • The Groovy script that will be used in your integration flow

  • The script that will test the above script


For simplicity, I will just copy over the default Groovy script that is generated from Cloud Integration, namely script1.groovy below.



For the other script, I will just create a new Groovy class named GroovyScriptTest.groovy.

 

All good so far? Let's replace the code in the testing class with the following code. It's just a very basic logic to showcase the approach. Essentially what it does is:-

  • Load the script to be tested

  • Initialize the message to be passed into the script

  • Execute the script to be tested

  • Display the results via console


Nothing fancy, but I encourage you to at least try to understand what each part does (there's always Google if you need any help!)
package com.equalize.groovy.testing

import com.sap.gateway.ip.core.customdev.processor.MessageImpl
import com.sap.gateway.ip.core.customdev.util.Message

// Load Groovy Script
GroovyShell shell = new GroovyShell()
def script = shell.parse(new File("src/com/equalize/groovy/testing/script1.groovy"))

// Initialize message with body, header and property
Message msg = new MessageImpl()
msg.setBody(new String("Hello Groovy World"))
msg.setHeader("oldHeader", "MyGroovyHeader")
msg.setProperty("oldProperty", "MyGroovyProperty")

// Execute script
script.processData(msg)

// Display results of script in console
println("Body:\r\n" + msg.getBody())

def displayMaps = { String mapName, Map map ->
println mapName
map.each { key, value -> println( key + " = " + value) }
}
displayMaps("Headers:", msg.getHeaders())
displayMaps("Properties:", msg.getProperties())

 

You will now notice some syntax errors in both scripts, the most noticeable one would be for the following elusive class:-

com.sap.gateway.ip.core.customdev.util.Message

Now this is where the fun really begins. Did you bother to read Vadim's blog? You will need it now. Go hunt for the required JAR file, then add it to the project's build path.

Once you got all the syntax error sorted, try executing the testing script:-

Right Click > Run As > Groovy Script

Oh no! More errors - looks like some other JAR files are required during runtime. So keep doing the below:-

Hunt, Add, Test, Repeat


Finally, when all is in place, you will be rewarded with the below screen in the console output 🙂



 

Voila! Now, this is how you test your Groovy scripts!

 

Update 20 Oct 2017

Interesting observation - if you head over to (https://help.sap.com/viewer/368c481cd6954bdfa5d0435479fd4eaf/Cloud/en-US/062f7a7e5c374e67b568dddc7b7...), there is a recently added section detailing how you can add the JAR file for the Message class into your Groovy project 🙂



Another interesting observation is that it does not tell you where to download the file! 😛

 

Update 5 Jan 2018

Further interesting observation. The online documentation has been updated with details on how to download the JAR file for the above mentioned elusive class, now termed the Script API Methods.



 

Basically, you just have to get it from the SAP Development Tools page



 

The problem with this approach is that it only gives you a real bare bones JAR file.



 

IMHO, if you want to do any serious development/testing work locally in Eclipse, this JAR file is insufficient and not worth the effort.
47 Comments
Former Member
Nice workaround. much needed one. This reminds me stand alone java mapping testing.

I am not yet into HCI . Had a little chance to play with HCI long back.

 

message mapping test is available in HCI. It would be nice if SAP does the same with scripts also. and of course changing the colorless editor too.

 

 
0 Kudos
Hi @engswee.yeoh,

 

It's a great blog and very useful for us to work on groovy scripts in HCI. I see there is a link provided in SAP Help portal (https://help.sap.com/viewer/368c481cd6954bdfa5d0435479fd4eaf/Cloud/en-US/062f7a7e5c374e67b568dddc7b7...) detailing how we can add the JAR file for the Message class into your Groovy project but the link to download the jar is missing.

We are working on Groovy script for our complex logic's which needs to be tested constantly for achieving the results. Can you please share the link to download jar file for com.sap.gateway.ip.core.customdev.util.Message class ? It will be really helpful.

 

 

Thanks,

Rajesh N
engswee
Active Contributor
 

Hi Rajesh

 

You will really need to read the blog properly - as it is really obvious, I won't spoil the fun for you.

 

Regards

Eng Swee
0 Kudos
Hi - Thanks I followed the blog ( https://blogs.sap.com/2017/10/02/dark-side-of-groovy-scripting-behind-the-scenes-of-cloud-integration-runtime/ ) and able to fix it.

 

Thanks,

Rajesh N
Hi@engswee.yeoh

Thanks for your post! It's great that I could do some local test!

I have to ask a similar question with Rajesh's.  The com.sap.gateway.ip.core.customdev.util.Message syntax is fixed by import jar file as you suggested, however, I can find no hints for com.sap.gateway.ip.core.customdev.processor.MessageImpl  Seems this class is not in the cloud.integration.script.apis-1.36.1.jar file. Could you advise a bit?

 

Happy new year~

Rong
Former Member
0 Kudos
Hi Rong,

 

Let me know if you find the solution. I am also facing the same problem.

 

Happy New Year!!

 

Shyamalima
engswee
Active Contributor
Hi rong.wei , shyamalimadas ,

 

Please see the updated section of my blog (at the end). I wouldn't suggest using the JAR file provided by SAP in the Development Tools page. Instead, please follow the steps listed in this blog (in particular Hunt, Add, Test, Repeat) and also the details from Vadim's blog.

 

Regards

Eng Swee
maxi1555
Contributor
0 Kudos
Hi,

It didn't work for me:

 



any idea?.

Kind Regards.

Max.
engswee
Active Contributor
0 Kudos
You are on the right track, but you probably missed out the Repeat step of "Hunt, Add, Test, Repeat" step. Keep going until you get all the necessary JAR files - there are quite a few of them required.
maxi1555
Contributor
0 Kudos
Hi,

It is not very clear where to hunt, I tried to download the JAR for "org.apache.camel.TypeConversionException", but it does not exist in CPI :S  , any idea?.

 

Kind Regards.

Max.
engswee
Active Contributor
0 Kudos
Hunt the same way you got the JAR file for the com.sap.gateway.ip.core.customdev.util.Message class.

If you are not sure where to hunt, how did you get that JAR in the first place?
maxi1555
Contributor
Hi,

I know how to hunt( identify missing class, run the IFlow in CPI to extract the corresponding JAR and import the JAR in my project, test and repeat), but I can't identify the missing class ( I thought it was this "org.apache.camel.TypeConversionException", but I can not download the JAR from CPI, I executed the IFlow for it but it does not return anything), thanks for the replies and your time 😉 .

 

Kind Regards.

Max.
engswee
Active Contributor
0 Kudos
Class org.apache.camel.TypeConversionException is correct, and you should be able to find it in JAR file org.apache.camel.camel-core_2.17.4.sap-09.jar in the current version of the tenant.

 

maxi1555
Contributor
Hi,

Thanks, but I solved it with CPI libraries from SAP PO 😉

 

  1. <DISK>:\usr\sap\<SYSID>\J00\j2ee\cluster\bin\ext\com.sap.aii.igw.esb.core.lib\lib\com.sap.gw.rt-camel.components.custom-development-1.35.6.jar

  2. <DISK>:\usr\sap\<SYSID>\J00\j2ee\cluster\bin\ext\com.sap.aii.igw.esb.core.lib\lib\com.sap.aii.igw.esb.core.lib\lib\com.sap.it.public-api-2.8.0.jar

  3. <DISK>:\usr\sap\<SYSID>\J00\j2ee\cluster\bin\ext\com.sap.aii.igw.esb.core.lib\lib\com.sap.gw.rt-script.engine.api-1.35.6.jar

  4. <DISK>:\usr\sap\<SYSID>\J00\j2ee\cluster\bin\ext\com.sap.aii.igw.camel.core.lib\lib\org.apache.camel-camel-core-2.17.4-sap-05.jar

  5. <DISK>:\usr\sap\<SYSID>\J00\j2ee\cluster\bin\ext\com.sap.tc.Logging\sap.com~tc~logging~java~impl.jar

  6. <DISK>:\usr\sap\<SYSID>\J00\j2ee\cluster\bin\ext\com.sap.aii.igw.commons.api.lib\lib\com.sap.it.commons-com.sap.it.commons.logging.slf4j-1.37.0.jar

  7. <DISK>:\usr\sap\<SYSID>\J00\j2ee\cluster\bin\ext\com.sap.aii.igw.commons.api.lib\lib\com.sap.it.commons-com.sap.it.commons-1.37.0.jar

  8. <DISK>:\usr\sap\<SYSID>\J00\j2ee\cluster\bin\ext\com.sap.aii.igw.slf4j.lib\lib\com.sap.aii.igw.slf4j.lib_api.jar

  9. <DISK>:\usr\sap\<SYSID>\J00\j2ee\cluster\bin\ext\com.sap.aii.igw.slf4j.lib\lib\org.slf4j-jcl-over-slf4j-1.7.5.jar

  10. <DISK>:\usr\sap\<SYSID>\J00\j2ee\cluster\bin\ext\com.sap.aii.igw.slf4j.lib\lib\org.slf4j-slf4j-api-1.7.5.jar




 

Kind Regards.

Max.

 
engswee
Active Contributor
0 Kudos

EXCELLENT! Yes, getting it from PO 7.5 works too!

 

Nice to see you claim your reward, after all the hard work and persistence ?

tomvanrooijen
Participant
0 Kudos
Hi Eng Swee,

 

Thanks for the journey and forcing us to do the work 🙂

I think I have all the external libraries loaded in eclipse, 10 in total, all retrieved from CPI.

Now I get this error:

Caught: groovy.lang.MissingMethodException: No signature of method: org.codehaus.groovy.runtime.InvokerHelper$1.processData() is applicable for argument types: (com.sap.gateway.ip.core.customdev.processor.MessageImpl) values: [com.sap.gateway.ip.core.customdev.processor.MessageImpl@1a72a540]
groovy.lang.MissingMethodException: No signature of method: org.codehaus.groovy.runtime.InvokerHelper$1.processData() is applicable for argument types: (com.sap.gateway.ip.core.customdev.processor.MessageImpl) values: [com.sap.gateway.ip.core.customdev.processor.MessageImpl@1a72a540]
at com.equalize.groovy.testing.GroovyScriptTester.run(GroovyScriptTester.groovy:17)

 

Is there still something I am missing? Below is what I have now

 



Thanks!

Tom
engswee
Active Contributor
0 Kudos
Hi Tom

 

I'm glad you enjoyed learning how to fish!

 

Your libraries look fine, so I don't think there's any missing there. Can you show a screenshot of your project structure as well as the code for GroovyScriptTester.groovy?

 

Regards

Eng Swee
Former Member
0 Kudos
Hi, I have tried pretty much everything, google, blog search and could the package for below import.

It is not part of SAP API JAR.

Any help.

Thanks

com.sap.gateway.ip.core.customdev.processor.MessageImpl
Former Member
0 Kudos
The reason I need this JAR is to be able to create a message for testing. Unfortunately there is no other way to test the script in eclipse unless I am able to create a new message and pass it to the function.

Any help is appreciated.

 

Thanks

Athar
tomvanrooijen
Participant
0 Kudos
Hi Eng Swee,

Sorry for the delay, here are the requested screenshots. I updated my project to java 8, but the error remains the same.

 

Thanks!

Tom

 



tomvanrooijen
Participant
0 Kudos
When I try to run it in the groovy console I get this error:

groovy.lang.MissingMethodException: No signature of method: org.codehaus.groovy.runtime.InvokerHelper$1.processData() is applicable for argument types: (com.sap.gateway.ip.core.customdev.processor.MessageImpl) values: [com.sap.gateway.ip.core.customdev.processor.MessageImpl@47949139]

at com.equalize.groovy.testing.GroovyScriptTester.run(GroovyScriptTester.groovy:17)

 
engswee
Active Contributor
0 Kudos
Can you show me the contents of your script1.groovy?
engswee
Active Contributor
0 Kudos
Forget everything you have tried, and read closely every word of this blog and what it refers to. Then follow it.
justin_santhanam
Active Contributor

engswee.yeoh  – Thanks for this excellent write up (as always 🙂 )!!

engswee
Active Contributor
0 Kudos
Thanks for your comment, Justin. Glad you found this helpful.
DG
Active Contributor
0 Kudos
Hi Eng,

Really enjoyed this post, and thought about automating the approach to create the template based on real values. We have added the functionality to the Figaf IRT tool that allow you to test CPI also. So now you can just select a step and then export the content in your format.

https://figaf.com/generate-test-data-for-your-groovy-scripts-in-cpi/

I have chosen to add a mock class for the message implementation to avoid having to go thru all the libraries as you outline here.

I did though find that instead of using the "Dark Side", you can just have a look into the SCA file for CPI on the PI, here I would imagine that you will find all the relevant jars. It is the one starting with SAPXIIGWAPPL
yatanveersingh
Active Participant
0 Kudos

Hi Eng,

 

I followed the blog and trying to get the required jar. Finally stuck at this error

engswee
Active Contributor
0 Kudos
It has nothing to do with the JAR files - they look fine. You'd need to debug why line 8 of your script is causing the error.

 
yatanveersingh
Active Participant
0 Kudos


 

Working Finally.

 

Thanks.
0 Kudos
Hi, I encountered the same nullPointerException error. Could you tell me how you resolved it?

 

Thanks,

--Dave

 
yatanveersingh
Active Participant
0 Kudos
I was using java.lang.String inside getBody, due to this it was faulting.

check the print screen above.
former_member306668
Participant
0 Kudos
Hi @engswee.yeoh;

Great blog and it was working well for me two weeks ago. Unfortunately I didn't download all the required jar files then. It seems like in one of the recent updates the library structure has changed. Now looking for the jara file for com.sap.gateway.ip.core.customerdev.util.Message returns following

JAR file containing class file" jar:bundle://561.0:0/!/ instead of the actual jar. Do you know of another way to get the jar files?



Thanks

Thomas
engswee
Active Contributor
0 Kudos

Hi Thomas

 

Maybe SAP has “blocked” such usage to access the internals. Another approach would be to manually look for them in the file system using something like https://blogs.sap.com/2019/01/03/exploring-cpis-filesystems-content/

Regards

Eng Swee

former_member306668
Participant
0 Kudos
Hi Eng Swee;

Thanks for the quick reply and your suggestion. I created a similar script based on Vadim's blog
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;

def Message processData(Message message) {

String dirInstanceRootPath = "/usr/sap/ljs/";

StringBuilder builder = new StringBuilder();
File dirInstanceRoot = new File(dirInstanceRootPath);
dirInstanceRoot.eachDirRecurse {
builder << "${it.absolutePath}\n";
try {
File dirPlugins = new File("${it.absolutePath}");
dirPlugins.eachFileMatch(~/.*\.jar/) {
try {
builder << "${it.name}\n";
}
catch (Exception ex) {
builder << "can't find file";
}
};

}
catch (Exception ex)
{}
};

Looks like they are not using the individual jar files anymore 😞

Regards

Thomas
engswee
Active Contributor
0 Kudos
It looks like it's just a different way of packaging the libraries. You still can get to them in a slightly different manner.

 

From the earlier response "jar:bundle://561.0:0/!/", it is located in bundle 561.

 

So you just go to the following location for bundle 561, and extract its JAR file.

/usr/sap/ljs/data/cache/bundle561/version0.0/bundle.jar
former_member306668
Participant
Fantastic thanks again, finally got there
Cristian
Participant
0 Kudos
Hi Thomas,

Once you got the new path for the .jar files /usr/sap/ljs/data/cache/bundle561/version0.0/bundle.jar, how did you get the files?

Thanks,

C.
engswee
Active Contributor
0 Kudos
There are various approaches, like the one displayed in Vadim's blog post mentioned in this post - which I highly recommend you to have a look at, so that you can "learn how to fish".

 

But if you are just interested in "getting the fish", you can use the approach mentioned in the blog post below:-

https://blogs.sap.com/2019/01/03/exploring-cpis-filesystems-content/
former_member187447
Participant
0 Kudos
Hi Eng,

 

I followed Vadim's post and I was able to get the jar location successfully but when I tried the Jar content, I am having issues.

 

To start with I was trying your blog to modify the header values. And I got stuck here with class not found exception for "com.sap.it.api.msg.ExchangePropertyProvider"



 

 

So then I started to dig into the Jar using Vadim's post for retrieving the Jar content using the following iflow and the groovy script



Groovy Script



 

When I try to fetch the base 64 encoding of the JAR by doing a GET query from the POSTMAN this is what I get. "An internal server error occured: java.lang.IllegalArgumentException: URI is not hierarchical" I am struggling to understand what this error means. Please let me know if you have any suggestions?



 

Regards

kalyan.
EderSouza
Advisor
Advisor
0 Kudos
Hi Eng Swee and colleagues,

It seems that the location of the cache folder mentioned above has changed in the Cloud Foundry version of CPI (at least for the Trial version). I could find the bundle folders at:

/opt/karaf/data/cache/bundle...

Regards,

Éder

 
cfewfwdwd
Explorer
0 Kudos
Hi Kaylan,

if you still need some help I'd recommend to replace the line
 File classFile = new File(classFilePath);

with the following line of code:
 File classFile = new File("/usr/sap/ljs/data/cache/bundleXXX/version0.0/bundle.jar");

Just replace bundleXXX with the one, where the class "com.sap.it.api.msg.ExchangePropertyProvider" is contained.

 

 

Regards

Timo
0 Kudos
Hi Rong,

Have you solved you issue? I meet the same situation, no hints for com.sap.gateway.ip.core.customdev.processor.MessageImpl .

 

Best Regards

Jone
anz_sapfico
Explorer
0 Kudos

Dear All

From the time this blog is written, the information provided can now be considered obsolete.

Please follow the below instructions on the SAP Development Tools site, and the library errors will disappear in Eclipse. https://tools.hana.ondemand.com/#cloudintegration

The pre-requisite for all the script libraries to work is to install the additional oxygen plugin.

To download the most recent Eclipse version, as of April 2021 - the most recent available Eclipse version is 2021-03 -link- https://www.eclipse.org/downloads/packages/.

SelectEclipse IDE for Java Developers as the software option to install.

Install and Launch the software.

On the next screen, you will find the help menu, where you will also get the option to install new software. Paste the oxygen URL here as per the SAP Tools Development site.

https://tools.hana.ondemand.com/#cloudintegration

Follow the instructions in the procedure section to finish the installation of the oxygen software.

The next step is to download the generic and the script API from the script API section. Note that these libraries have to be a part of the Groovy project for CPI and hence have to be loaded within the groovy project.

Download both JAR files and follow the below steps.

  1. Create a new groovy project. Select File - Project - Groovy -Input Project Name and add the location of the  folder where you intend to save your groovy scripts
  2. Click on next
  3. In the build path, select libraries and add new external JAR files in the classpath section.

Most CPI Libraries issues will be fixed with the above, including errors that are due to the lack of oxygen software installation.

Regards

0 Kudos

Hello @engswee.yeoh

Thank you for your great blog post (and also Youtube Videos) where you are sharing the possibility to fish the gems from SAP to understand the implementation behind the SAP Standard.

My goal is to debug the groovyScript "processAttributePerIDoc" from the iFlow "Replicate Classification From ERP To SAP Commerce Cloud" which consumes Classification iDocs (CLSMAS, CHRMAS...) and converts them to ClassificationAttributes.

First of all, i fished all the necessary jar files so that I finally can run the groovy script.

The interesting part here was to inject the iDoc in a new Message. I archived this with this code snipped:

import com.sap.gateway.ip.core.customdev.processor.MessageImpl
import com.sap.gateway.ip.core.customdev.util.Message

// Load Groovy Script
GroovyShell shell = new GroovyShell()
def script = shell.parse(new File("src/processAttributePerIDOC.groovy"))
String pathToXML = "farbe.xml";

// Initialize message with body, header and property
Message msgIn = new MessageImpl()
msgIn.setBody(readXMLFileToString(pathToXML))


// Execute script
script.processData(msgIn)

// Display results of script in console
println("Body:\r\n" + msgIn.getBody())

def String readXMLFileToString(String path) {
ClassLoader classLoader = getClass().getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream(path);
return readFromInputStream(inputStream);
}

def String readFromInputStream(InputStream inputStream)
throws IOException {
StringBuilder resultStringBuilder = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))
String line;
while ((line = br.readLine()) != null) {
resultStringBuilder.append(line).append("\n");
}
}
catch (Exception ex) {
// Ignore for now
}
return resultStringBuilder.toString();
}

 

The point is, that when I execute the standard groovy script with "script.processData(msgIn)" I get an InvalidContextException:

(For searchable reasons, add Key Parts of the trace as text:)

[com.sap.it.api.impl.ITApiFactoryRegistry] DEBUG : Incoming api type: com.sap.it.api.mapping.ValueMappingApi
[com.sap.it.api.impl.ITApiFactoryRegistry] DEBUG : ITApi factories is null or empty!!!!!!!!!!!!
[com.sap.it.api.ITApiFactory] ERROR : Unable to retrieve API Factory for the apiType: interface com.sap.it.api.mapping.ValueMappingApi
Caught: com.sap.it.api.exception.InvalidContextException: Exception occurred while trying to retrieve API Factory for the apiType: interface com.sap.it.api.mapping.ValueMappingApi
com.sap.it.api.exception.InvalidContextException: Exception occurred while trying to retrieve API Factory for the apiType: interface com.sap.it.api.mapping.ValueMappingApi

The only line I changed in the SAP standard processAttributePerIDOC.groovy is how to get the body. I moved from

message.getBody(String)

To

message.getBody()

It would be great if you can tell me how to set up the right context/Fill the ITApi factory.

Thanks in advance for your time, and at least for reading this comment 🙂

tschnur_nagarro
Explorer
0 Kudos
Hi,

I followed the approach explained in this blog. Debugging of very simple groovy scripts in Eclipse is working. However it looks like I have some dependency/version issues and can't find a solution so far. As soon as I use certin objects (e.g. XmlSlurper) the parsing of my scripts starts failing. Even this very easy script is failing:


 

The processData methods is not even reached but it looks like the parsing of the file already fails in this line:


with the following error:


 

Can somebody help? I did some research and there were some hints that this might be related to a version missmatch of gradle and the JRE (I am using JRE16). I played around witht JRE Version without success.

 
engswee
Active Contributor
0 Kudos
Hi Tobias, due to the frequent questions popping up on this old post, I have updated it with a note all the way at the top - I suggest that you check that out instead.
MarkTrayford
Explorer
0 Kudos

 

Hi Eng Swee, Thanks for this article, it got me started a few months ago on a 3D tool for debugging groovy scripts developed in the Unity game engine, the 3D element is maybe overkill but it was a fun project. I've taken inspiration from your posts, CPIHelper chrome extension and https://groovyide.com/cpi.

The 3d app acts as a companion app to pull in messages and trace data via APIs and sets the files up for the debugger. I've used Intellij IDEA community edition for the Groovy debugging. 

I've also added support for Value Mapping it will pull together all the value maps via the APIs, and dump them in a file on the debugger tool, which then loads them into the message exchange before calling the script.

I've got it to a point where you just press the debug button on the 3D tool and it will line up all the header/properties and body and the script files for your chosen step. All you then need to do is go to the IDE and run it.

It's a bit messy still and I've got a backlog of hundreds of features but just thought I'd share it here. 

I've added the Valuemap code below,  I had to hack a couple of the standard classes to get it to work, it was a while ago now and I've forgotten exactly how. It might just have been a case of that was the quickest way to make it work so I left it at that. If anyone is interested I'll go back and have a look at it and document what I've done

[edit] I also had to add my own version of the ITAPIFactory, which was because I was having trouble accessing some of the private framework methods that would normally construct the VMStore object. I don't really know enough about the outer classes in the framework so I just botched together something that worked, I'm sure someone would be able to come up with something more elegant.

I also just saw you've written a book about Groovy Debugging, maybe you already covered this, perhaps I should have read that first 🙂

 def void CreateValueMappings() {
// Build the Value Mapping Objects from the stored files
Bundle bundle = new MyBundle();
BundleContext bundleContext = bundle.getBundleContext();
def ValueMappingActivator VMActivator = new ValueMappingActivator();
VMActivator.start(bundleContext);

// ????Maybe I could have just done this in the first place and just used VMStore directly?????
VMStore vmStore = VMStore.getInstance(); // maybe we can load straight into it once it's initiated.
println("Getting Files")

// Get each file that matches a pattern from an agreed directory
// Each file contains one value map
// Load the data from each into the VMStore
// ITApiFactory will then automatically use the value
def folder = "C:/CPIViewer/DataDump/VMAP/";
def dir = new File(folder)
Random random = new Random()
// Random number needed for each uploaded value map file, could just be seq also if neeeded
dir.eachFileMatch(FileType.FILES, ~/.*\.xml?/) {
fname = folder + it.name
println fname
File initialFile = new File(fname);
InputStream targetStream = new FileInputStream(initialFile);
vmStore.loadValueMapping(random.nextInt(999999), targetStream);
}
// This is a dummy version of ITApiFactory, that is defined in this project
// This means we can spoof the API handler otherwise I couldn't see how to use the Protected methods to add/bind a handler
// without recreating more of the OSGi framework
// This way we don't need to adapt any of the users script where it uses value mapping

ITApiFactory factory = new ITApiFactory();
println("=====================================")
}
public class  MyBundle implements  Bundle {

static BundleContext bundleContext = new MyBundleContext();

@Override
BundleContext getBundleContext() {
if (bundleContext == null) bundleContext = new MyBundleContext();
return bundleContext;
}

@Override
URL getEntry(String s) {
//URL url = new URL("file://./ValueMappingFile/downloadedvalmap.xml");
URL url = new URL("file:///C:/CPIViewer/DataDump/VMAP/dummy.valuemap");
return url;
}
import com.sap.it.api.ITApi
import com.sap.it.api.exception.InvalidContextException
import com.sap.it.api.impl.ITApiFactoryRegistry
import com.sap.it.spi.ITApiHandler
import com.sap.xi.mapping.camel.valmap.ValueMappingApiService
import org.slf4j.Logger
import org.slf4j.LoggerFactory


public final class ITApiFactory {
private static final Logger TRACE = LoggerFactory.getLogger(com.sap.it.api.ITApiFactory.class);
// This will start a VMStore object, the static constructor of that will load the mapping
public static ITApi myApiService = new ValueMappingApiService();
// public static ValueMappingApiService myapi = new ValueMappingApiService();
private ITApiFactory() {
}
/** @deprecated */
@Deprecated
public static <T extends ITApi> T getApi(Class<? extends ITApi> apiType, Object context) throws InvalidContextException {
return myApiService;
//return getServiceInternal(apiType, context);
}
public static <T extends ITApi> T getService(Class<? extends ITApi> apiType, Object context) throws InvalidContextException {
return myApiService;
//return getServiceInternal(apiType, context);
}
private static <T extends ITApi> T getServiceInternal(Class<? extends ITApi> apiType, Object context) throws InvalidContextException {
ITApiHandler<? extends ITApi> apiFactory = ITApiFactoryRegistry.getApiHandler(apiType);
if (apiFactory != null) {
TRACE.debug("Successfully retrieved API Factory for the apiType: {}", apiType);
return apiFactory.getApi(context);
} else {
TRACE.error("Unable to retrieve API Factory for the apiType: {}", apiType);
throw new InvalidContextException("Exception occurred while trying to retrieve API Factory for the apiType: " + apiType.toString());
}
}
}
Labels in this area