Skip to Content
Technical Articles
Author's profile photo Fatih Pense

Faster Groovy Development for SAP CPI without Installing an IDE

The Need for Speed

Groovy scripting is an integral part of the CPI. It is a perfect glue script in Java environments and it has integration history.

There are a few annoyances to using it:

  • The only way to check for syntax errors is to deploy the integration.
  • The only way to check logic and functionality is to deploy the integration and ensure the message processing in the flow by triggering it via an adapter like HTTP or SFTP

It takes a lot of time to validate your script even for small changes.

I tried Eclipse and the experience was not perfect. Intellij IDEA seemed to be the way to go. I prepared myself to install another IDE to my computer on top of different versions of Eclipse that I had to maintain. I was going to learn every button and best practice to tell my consultant colleagues.

Then one night, I couldn’t sleep. Whether I turn to left or right in the bed I was seeing some Groovy script telling me to “run”. Why don’t I build a solution that will make my life and the lives of my fellow SAP integration consultants in the world easier? I had to try even that made me skip sleep a few nights more.

The Quick & Easy Solution

Just use your browser, paste your input, paste your Groovy script, and run. That is all.

You can bookmark the “CPI Test Mode” page.
https://groovyide.com/cpi

Conclusion

For the power user and complicated projects with library dependencies, IntelliJ IDEA may be a better solution now. But even for them, there comes a time to write a one-off script on a different computer and test it fast.

It is free and It will be free, so it can become a useful everyday app in your toolbelt like Postman or SoapUI for SAP CPI development.

Assigned Tags

      58 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Hasan Basri CELEBI
      Hasan Basri CELEBI
      class HelloFatih {
         static void main(String[] args) {
            println "He makes life easier...FP"
            println "thanks for your valuable sharing"
            println "Regards"
            print "Hasan"
         }
      } 

       

       

      Regards

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Hello Hasan,

      Can you run this script as a response?

      import com.sap.gateway.ip.core.customdev.util.Message;
      import java.util.HashMap;
      import groovy.json.JsonSlurper;
      import groovy.util.XmlSlurper;
      
      def Message processData(Message message) {
          
          def myResponseToHasan = "Wow! Awesome way to write a comment!";
          
          myResponseToHasan = gulp(myResponseToHasan)
      	
          def xmlExpressYourself = '''
          <root>
              <expression><thank>Thank you</thank><sayhi>Hello There!</sayhi></expression>
          </root>
          '''
          def root = new XmlSlurper().parseText(xmlExpressYourself)
          myResponseToHasan = myResponseToHasan + "\n" + root.expression.thank
          
          def someWordsInBase64 = "dmVyeSBtdWNo"
          myResponseToHasan = myResponseToHasan + " " + new String(someWordsInBase64.decodeBase64())
          
          def jsonHasan = '{"friends":[{"name": "Hasan Basri", "surname":"Celebi" }, "others" ]}'
          def jsonSlurper = new JsonSlurper()
          def object = jsonSlurper.parseText(jsonHasan)
          def friend = object.friends[0]
          myResponseToHasan = myResponseToHasan + " " + friend.name + " " + friend.surname + "."
          
          def byte[] array = [72, 38, 108, 31, 102, 107, 96, 99, 31]
          myResponseToHasan = myResponseToHasan + "\n" + new String(overAnalyze(array))
          
          def String someString = "796f7520666f756e642069742075736566756c2e"
          myResponseToHasan = myResponseToHasan + new String(someString.decodeHex())
          
          println myResponseToHasan
          message.setBody(myResponseToHasan)
          return message;
          }
      
      def gulp(String str){
      	return str.replaceAll("Wow! ","...")
      }
      
      def overAnalyze(byte[] arr){
          arr.eachWithIndex { 
              value, idx -> arr[idx] = value +1
          }
      }
      Author's profile photo Daniel Graversen
      Daniel Graversen

      Love it. Glad you could not sleep. I hope you can sleep better now.

      It enables you to try out some code easy.

      One idea would be to add the option to upload a trace and parse the input and fill it in. That way it will be easier to run.

       

      Ps. If you get to install an IDE then we provide a git repository and Gradle plugins to deploy the ilfow from the IDE.

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Hi Daniel, thanks for the feedback! Yes, I can sleep in peace now.

      Automatically filling in input can be an interesting use case. I try to keep this as simple as possible, so I will think about that.

      Also, storing code in Git is never a bad move. I will check that.

      Regards,
      Fatih

      Author's profile photo Praveen Tirumareddy
      Praveen Tirumareddy

      Hi Fatih,

      Thats really a wonderful tool :).

      thanks for sharing.

      regards,

      Praveen T

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Hi Praveen,

      Thanks for the comment. I'm glad you find this useful.

      Regards,
      Fatih

      Author's profile photo Dominic Beckbauer
      Dominic Beckbauer

      Hi Fatih,

      what do you think about integrate it to the cpi helper plugin?

      I was thinking for a link that sends the trace data and a general link in the editor that also sends the groovy script to your side.

      I do not think that’s too much work on both sides.

      I can do the cpi helper part.

      For you it would be:

      • Provide the possibility to send a post request to your site so that I can send you headers, properties, payload and script.
      • Add Impressum and data protection section to your side. I would not feel good to provide an integration without being sure that the data does not stay private

      What do you think?

       

      But first I should check if it is possible to send data to foreign pages from chrome plugin. Maybe there is some security mechanism that prevents this.

       

      Best regards

      Dominic

       

       

      Author's profile photo Dominic Beckbauer
      Dominic Beckbauer

      Edit: connection to your page would work if you set the correct CORS Header.

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Hello Dominic,

      Thank you for your comment. I agree that a page clarifies data protection is a very good idea even without any integration. Right now server doesn't persist anything, so I should state that.

      Regarding integration with CPI helper plugin. Changing CORS headers can cause everyone to send requests to the server. It can cause more security problems in the long run.

      I also want to control the user experience. So a better option can be preparing a URL in the plugin and opening the URL in a new tab.

      When I implement this feature, I will share here.

      Regards,
      Fatih

      Author's profile photo Raffael Herrmann
      Raffael Herrmann

      Hi Dominic Beckbauer ,

      I would really love to see this feature in your plugin. From my understanding Fatih's current implementation (see here) doesn't need CORS headers. You could just scrape the ressources together, encode them as base64, build the url and then render a regular link in your plugin with target="_blank". That should be sufficient to let users jump from your plugin to the Fatih's pre-filled IDE. Or did I oversee anything?

      Best regards,
      Raffael

      Author's profile photo Dominic Beckbauer
      Dominic Beckbauer

      I am already working on it 🙂

      The problem is to get the current version of the script. So probably there will be a version but it will not send the script. You still have to copy and paste it.

      Author's profile photo Raffael Herrmann
      Raffael Herrmann

      Hi Dominic Beckbauer ,

      I don't know which point exactly is holding you back from getting the script content, but maybe I can help by describing how I would do it. 🙂

      1. Access the browser's tab location property (current url) which should be something like:
        https://{tenant-id}-tmn.hci.eu1.hana.ondemand.com/itspaces/shell/design/contentpackage/{package-id}/integrationflows/{iflow-id}​
      2. Use regex to extract the package-id:
        contentpackage\/(?<packageId>[^\/]+?)\/integrationflows\/(?<iflowId>[^\/]+?)$
      3. Call (via HTTP GET) the following url while inserting the package-id from step 2:
        https://{tenant-id}-tmn.hci.eu1.hana.ondemand.com/itspaces/odata/1.0/workspace.svc/ContentEntities.ContentPackages('{package-id}')?&$format=json​

        Then extract the field "reg_id" from the object where the field "TechnicalName" equals the {package-id} from the response and save it as variable "package-tech-id". (We need it later.)

      4. Call (via HTTP GET) the following url while inserting the package-id from step 2:
        https://{tenant-id}-tmn.hci.eu1.hana.ondemand.com/itspaces/odata/1.0/workspace.svc/ContentEntities.ContentPackages('{package-id}')/Artifacts?&$format=json​

        Then extract the field "reg_id" from the object where the field "Name" equals the {iflow-id} from the response and save it as variable "iflow-tech-id". (We need it later.)

      5. Get the name of the script file. You have two options. Either scrape the HTML source code of the browser tab (precondition: user has selected script step) or call the following API to get the BPMN model (which contains the script steps). Use package-tech-id and iflow-tech-id from steps 3 and 4 to call the url:
        https://{tenant-id}-tmn.hci.eu1.hana.ondemand.com/itspaces/api/1.0/workspace/{package-tech-id}/artifacts/{iflow-tech-id}/entities/{iflow-tech-id}/iflows/{iflow-id}​

        The get the scriptname (without path) from the response (e.g. "script1.groovy") and store it in a variable like "script-name". (We need it for the last step.)

      6. Call (via HTTP GET) the following api. It will return the scripts, wrapped in a JSON structure. Use the variables we received in the steps before:
        https://{tenant-id}-tmn.hci.eu1.hana.ondemand.com/itspaces/api/1.0/workspace/{package-tech-id}/artifacts/{iflow-tech-id}/entities/{iflow-tech-id}/iflows/{iflow-id}/script//{script-name}​

        (Attention the double slash in front of the script name is a must!)

      Let me know if I can help you any further.

      Author's profile photo Dominic Beckbauer
      Dominic Beckbauer

      I already hate the day when SAP changes the internal APIs 🙂

      Seems like this is a way to go. Do you know if it is always the last version of the script? So when I change sth in the iflow, press safe (or maybe do not press safe), do I get this version or the last version that was safed with a version number?

      Thanks for the hint. That saved a lot of time 🙂

      Author's profile photo Raffael Herrmann
      Raffael Herrmann

      Should be always the latest version, because it is the API which is called when you open the script in the IFlow editor. ?

      And yes, when internal APIs change your plugin may break, but until then it makes life easier. By the way I guess this is true for the complete plugin. If anything in the HTML/CSS structure changes, I guess it would even break the plugin…

      But since you are not selling the tool, I guess nobody will blame you if it breaks. And we have to keep in mind: the tool makes life easier, but life is possible without the tool. So let’s use the tool to be more efficient as long as it is working. If it breaks one day, it’s not mission critical because it’s a helper and not an integral part of the interface’s infrastructure. ?

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      I agree with Raffael, it is a free tool we share provided as-is. We can try our best to be stable but no commitments and no deadlines, only fun 🙂 I encourage everyone to publish free tools if they want to change the experience for good.

      In the end, SAP can also pick and implement good ideas from these tools and I want that to happen. That will be a good outcome for CPI developers. In the meantime, people can enjoy increased effectiveness with these tools. It is a win-win.

      Author's profile photo Raffael Herrmann
      Raffael Herrmann

      Hi Fatih,

      what a great tool! If I had one wish free, I would wish, that you would add a "share"-functionality, so that we could generate a shortlink for the current IDE state and share it with our colleagues. Maybe, if you plan to further develop this tool, you could add this feature on your todo list. 🙂

      Best regards and thanks for contributing this tool to the community!

       

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Hi Raffael,

      Thank you for your support and for providing good ideas!

      Short-link is a feature I thought as well. It has some interesting use cases like:

      • Sharing an input and Groovy code in a question.
      • Preparing challenges for juniors in a company.
      • Sharing very specific solutions for a problem or tutorials.

      Storing the state in DB is a solution to this problem. However, it can complicate the infrastructure. Even for a free product, I want to provide stable service and have peace of mind. Being able to say "nothing is stored in the server" is also nice.

      Another option I'm thinking about implementing is using URL to store data. One drawback is it won't be a short-link! It will be a long link... But it will be a practical one. 🙂

      What are your other two wishes? 😉

      Best regards,
      Fatih

      Author's profile photo Cagri Senol
      Cagri Senol

      This will save a lot of working hours! Thanks a lot Fatih Pense !

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Hi Cagri,

      Thanks for your feedback! Every hour a developer saves makes me happier!

      Regards,
      Fatih

      Author's profile photo Aurélien GARDE
      Aurélien GARDE

      when I'm trying to reach  https://groovyide.com/cpi, my company's proxy has detected a potential security risk with this website...

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Hello Aurélien,

      Thanks for your comment and for letting me know.

      As far as I know, firewall proxies work based on categories. This site is very new so it can cause problems. Unfortunately, I can't think of any workaround.

      It seems to be a problem only the network team can solve. I believe the people in the network team are the best friends of an integration consultant.

      Regards,
      Fatih

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Hello Aurélien,

      Now there is an offline version for Windows 10: https://blogs.sap.com/2020/07/20/groovy-ide-fixes-feedback-form-and-desktop-beta/

      You can download from the store page:  https://www.microsoft.com/en-us/p/groovy-ide/9n7z5k1vrhb3

      Regards,
      Fatih

      Author's profile photo Sriprasad Shivaram Bhat
      Sriprasad Shivaram Bhat

      Hello Faith,

      This is fantastic tool.Kudos to you.!!

      Regards,

      Sriprasad Shivaram Bhat

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Hello Sriprasad!

      Thank you for your kind words. It is really motivating when developers find this useful.

      Regards,
      Fatih

      Author's profile photo Metin Dinler
      Metin Dinler

      Hi,

      it is wonderful and will save time for us.

      Thanks for sharing.

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Thanks for the feedback Metin. I'm glad it will save time.

      Regards,
      Fatih

      Author's profile photo Iddo Rijsdijk
      Iddo Rijsdijk

      Hi Fatih,

      Great work! Thanks a lot for making our lives a bit easier.

      Iddo

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Hi Iddo,

      We always work hard to find good solutions for customers. Sometimes we can solve our own problems? 🙂

      Thanks for your feedback.

      Fatih

      Author's profile photo Rajendra Prasad Boddula
      Rajendra Prasad Boddula

      Great Job!!

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Thank you for your feedback Rajendra!

      Regards,
      Fatih

      Author's profile photo bekir akturk
      bekir akturk

      Great Job Fatih!  Thanks for making life easier.

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Hello Bekir!

      Thank you for your support.
      It has been a long time since we drank soda water to relieve stress after a long day's work.

      Best regards,
      Fatih

      Author's profile photo Rakesh Damera
      Rakesh Damera

      Many thanks Fatih!

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Thank you for your feedback Rakesh!

      Author's profile photo Ajit Kumar Panda
      Ajit Kumar Panda

      Thank you, Faith, for taking the time to build it. Great work.

       

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Thank you for your feedback Ajit. I'm glad it is helpful.

      Author's profile photo Hasan Fatih Eksioglu
      Hasan Fatih Eksioglu

      Hi Fatih,

      Great work. Thanks for sharing.

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Thank you for your support, Hasan.

      Regards,
      Fatih

      Author's profile photo Jitender Singh Chauhan
      Jitender Singh Chauhan

      Thanks Fatih,

      This tool is a great help in testing the scripts and will save lot of development time 🙂

      Regards,
      Jitender

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Thanks for the feedback Jitender! I'm glad it is helpful.

      Regards,
      Fatih

      Author's profile photo Blazenko Babic
      Blazenko Babic

      A great tool, thanks!

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Thank you for the feedback Blazenko! The image made my colleagues' day 🙂

      Regards,
      Fatih

      Author's profile photo Gabriel Alves
      Gabriel Alves

      This is pretty awesome!

      Thank you!

       

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Thanks for the feedback Gabriel!

      Author's profile photo Michael Schliebner
      Michael Schliebner

      Great, now all CPI Developers are enabled to easily  "Walk like an Egyptian" <- dance

       

      Best regards, mitch

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Thanks for the feedback, Michael!

      Best regards,
      Fatih

      Author's profile photo Syambabu Allu
      Syambabu Allu

      Great tool..Thanks for Sharing!

       

      Thanks,

      Syam

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Thanks for the feedback Syambabu!

      Regards,
      Fatih

      Author's profile photo mustafa alp
      mustafa alp

      Good work

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Thanks Mustafa!

      Author's profile photo Youssef El Ouatiq
      Youssef El Ouatiq

      Awesome, great job, thanks for making our job even more funier!

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Thank you for the feedback Youssef!

      Regards,
      Fatih

      Author's profile photo Ashutosh Kumar
      Ashutosh Kumar

      One of the best tools ever. Made my life easy.

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Thanks for the comment Ashutosh. I'm glad it is useful!

      Regards,
      Fatih

      Author's profile photo Christopher Linke
      Christopher Linke

      That's awesome, thank you so much!

      One little thing that I noticed, sometimes the CPI groovy script acts a little different than your tool. Is there an explanation for it (different version etc.)?

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Hello Christopher,

      I'm glad it is useful!

      Yes, the differences can be caused by many reasons, including library&runtime versions. It is a completely different runtime built from scratch to emulate the CPI environment. I'm interested to know the differences. Ideally, it should be bug-for-bug compatible with CPI runtime!

      You can always use the "send feedback" form, or send me the script which runs differently as a message. Then, I will try to analyze and get back with an explanation, or hopefully with a fix.

      Best regards,
      Fatih

      Author's profile photo Senz Evo
      Senz Evo

      Amazing, You just saved my sleepless night too. 🙂

      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Thanks Senz! Great to hear that! When it is useful for a lot of people, it motivates me to keep going and sharing 🙂

      There will be a v2 version that can work with local files. It is in development & it will be free.

      Regards,
      Fatih