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: 
fatihpense
Active Contributor

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.
59 Comments
hasan_celebi
Participant
class HelloFatih {
static void main(String[] args) {
println "He makes life easier...FP"
println "thanks for your valuable sharing"
println "Regards"
print "Hasan"
}
}

 

 

Regards

DG
Active Contributor
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.
Hi Fatih,

Thats really a wonderful tool :).

thanks for sharing.

regards,

Praveen T
dominic4
Active Participant

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

 

 

fatihpense
Active Contributor
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
}
}
r_herrmann
Active Contributor
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!

 
cagreply
Participant
This will save a lot of working hours! Thanks a lot fatih.pense !
dominic4
Active Participant
0 Kudos
Edit: connection to your page would work if you set the correct CORS Header.
aureliengarde
Explorer
when I'm trying to reach  https://groovyide.com/cpi, my company's proxy has detected a potential security risk with this website...
Sriprasadsbhat
Active Contributor
Hello Faith,

This is fantastic tool.Kudos to you.!!

Regards,

Sriprasad Shivaram Bhat
fatihpense
Active Contributor
0 Kudos
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
fatihpense
Active Contributor
0 Kudos
Hi Praveen,

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

Regards,
Fatih
fatihpense
Active Contributor
0 Kudos
Hi Cagri,

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

Regards,
Fatih
fatihpense
Active Contributor
0 Kudos
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
fatihpense
Active Contributor
0 Kudos
Hello Sriprasad!

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

Regards,
Fatih
fatihpense
Active Contributor
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
fatihpense
Active Contributor
0 Kudos
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
MetinD
Participant
Hi,

it is wonderful and will save time for us.

Thanks for sharing.
irijsdijk
Participant
Hi Fatih,

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

Iddo
RajendraPrasadB
Discoverer
Great Job!!
bekirakturk
Explorer
Great Job Fatih!  Thanks for making life easier.
rakeshdamera
Participant

Many thanks Fatih!

Ajit_K_Panda
Product and Topic Expert
Product and Topic Expert
Thank you, Faith, for taking the time to build it. Great work.

 
Hi Fatih,

Great work. Thanks for sharing.
Jitender
Advisor
Advisor
Thanks Fatih,

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

Regards,
Jitender
babicblax
Explorer
A great tool, thanks!

fatihpense
Active Contributor
0 Kudos
Thanks for the feedback Metin. I'm glad it will save time.

Regards,
Fatih
fatihpense
Active Contributor
0 Kudos
Hi Iddo,

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

Thanks for your feedback.

Fatih
fatihpense
Active Contributor
0 Kudos
Thank you for your feedback Rajendra!

Regards,
Fatih
fatihpense
Active Contributor
0 Kudos
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
fatihpense
Active Contributor
0 Kudos
Thank you for your feedback Rakesh!
fatihpense
Active Contributor
0 Kudos
Thank you for your feedback Ajit. I'm glad it is helpful.
fatihpense
Active Contributor
0 Kudos
Thank you for your support, Hasan.

Regards,
Fatih
fatihpense
Active Contributor
0 Kudos
Thank you for the feedback Blazenko! The image made my colleagues' day 🙂

Regards,
Fatih
fatihpense
Active Contributor
0 Kudos
Thanks for the feedback Jitender! I'm glad it is helpful.

Regards,
Fatih
gabriel_alves
Explorer
This is pretty awesome!

Thank you!

 
fatihpense
Active Contributor
0 Kudos
Thanks for the feedback Gabriel!
Michæl
Participant
Great, now all CPI Developers are enabled to easily  "Walk like an Egyptian" <- dance

 

Best regards, mitch
fatihpense
Active Contributor
0 Kudos
Thanks for the feedback, Michael!

Best regards,
Fatih
r_herrmann
Active Contributor
Hi dbeckbauer2 ,

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
dominic4
Active Participant
0 Kudos
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.
r_herrmann
Active Contributor
Hi dbeckbauer2 ,

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}/...


  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}/artif...

    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}/artif...

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


Let me know if I can help you any further.
dominic4
Active Participant
0 Kudos
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 🙂
r_herrmann
Active Contributor

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. ?

SyambabuAllu
Contributor
0 Kudos
Great tool..Thanks for Sharing!

 

Thanks,

Syam
fatihpense
Active Contributor
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.
former_member660697
Discoverer
0 Kudos
Good work
fatihpense
Active Contributor
0 Kudos
Thanks for the feedback Syambabu!

Regards,
Fatih
fatihpense
Active Contributor
0 Kudos
Thanks Mustafa!
former_member540493
Participant
Awesome, great job, thanks for making our job even more funier!
Labels in this area