/ Development  

Unleash the hidden potential of the 'ReST Gateway Connector'; Your gateway to next-level data integration

Hi there AppWorks fans,

Welcome to a new installment of AppWorks tips.

I get questions from all over the world, but this time a question definitely opened my eyes again! When you think you saw it all there is always something new to explore. It took me a while before it landed on the correct spot, but it will help you all on building nice solutions. Why did it take a while? Well, I’m aware of several “Gateway” options on the platform.
The first one the ‘AppWorks Gateway’; It’s a separate product you need to install and supports the use of the entity ‘Mobile’ building block. Secondly, I’m aware of the ‘Web Gateway’ monitor of the AppWorks platform itself. This ‘ReST Gateway’ is now the third “Gateway” to get in touch with. Let’s explore it and share the knowledge in this blog…


Let get right into it…

My first question for this post would be, what problem is this connector solving. Well, I have 2 answers:

From a comrade in crime

1
2
3
4
Let's say if we have a bpm exposed as a Webservice and needs to be called from 
outside Appworks like Postman...the request and response are all in SOAP;
With this we can get response in JSON and calls can be like REST...
so, we don't have to send post requests to get any data.

From the PDF manual of the connector

1
2
3
4
5
6
7
8
The REST Gateway can be used to expose AppWorks Platform SOAP based web services 
as RESTful URIs with one of the HTTP method types (GET, PUT, POST, and DELETE).
When the REST Gateway receives a RESTful request from a client, it reads the
resource information of the request in XMLStore and converts the RESTful request
into an equivalent SOAP request and passes the control to AppWorks Platform.
After it is processed, AppWorks Platform sends the SOAP response back to the
REST Gateway, which converts the SOAP response back to the REST styled response
using the resource information.

Ohwwww…Now we’re getting somewhere! Everywhere I talk about AppWorks there is always that discussion on SOAP (with XML) is old where ReST (with JSON) is new, but that discussion will now be busted…
See if we can find this connector in the woods of OpenText software packages; I thought this connector was once available from this URL, but it’s gone!? Or I totally miss something here. Lucky for you, I found the download location from the good old support portal behind this URL!

I just downloaded three files:

  1. REST Gateway User Guilde.pdf
  2. REST Gateway 3.0.1.cap; There is also a 2.0.0 version, but that’s for the early days of the platform!
  3. REST_Gateway_TomEE_conifg.tar; Yes, the typo is indeed correct; Or not…It depends how you see it.

Time to explore the PDF first (#RTFM); In the meantime, I start my VM as there is an installation/deployment section ahead of us…


Installing the connector

After the VM is started, I dive into the system space with my precious sysadmin account. With this account, you can now open the ‘Application Deployer’ artifact. Keep it locked in the ‘Shared’ space, browse to the REST Gateway 3.0.1.cap file and hit the “Upload and Deploy” button. Now you just follow the wizard and ‘Finish’ in the end…No hard task to do on your own spare time! 😁

The PDF talks about unsigned CAP packages and how to avoid it during installation from the ‘Security Administration’ artifact…In case you didn’t disable it already for your DEV environment like I normally do.

I’m always curious what just changed on my VM, so let’s have a basic view:

  • In the ‘Web Service Interface Explorer’ artifact we have some service operations available:
    • generateServiceMappings, generateAndGetTheServiceRESTMapping, generateUniqueHash, and getTransformedJSONResponse
    • We can guess what they will do…It will be something magic!
  • In the ‘User Manager’ artifact we have 2 roles; ReST Developer and an internal role Entity REST API Developer; I guess we need to assign ourselves to that first one!
  • On the server a set of JAR files where /opt/opentext/AppWorksPlatform/defaultInst/com/cordys/web/rest/RESTGateway.jar is the most important; The others are dependencies where json-lib 2.4 is our JSON library!! That’s a library from “Dec 14, 2010”…Right!…Maybe that’s why people don’t mention this connector, and it’s hard to get your hand on it! 🤔
  • Finally, some JavaScript files with xForms I don’t want to dive into; I guess they will expose a new artifact where we configure ReST stuff!? To be more specific; The Generate REST Services and Test REST Services artifacts (when you connect yourself to the correct role)!

Ohw boy…That’s a first view which makes me less enthusiastic, but let’s not throw the towel into the ring!

After this CAP deployment, we require to extract the file REST_Gateway_TomEE_conifg.tar and upload its content to a special location. Let’s hit the gazzz with some Unix Bash statements after that file is uploaded into the home directory of the sysadmin account of my VM:

1
2
3
tar xvf ~/REST_Gateway_TomEE_conifg.tar -C /opt/opentext/AppWorksPlatform/defaultInst/webroot/WEB-INF/lib/
sudo chown tomcat:tomcat /opt/opentext/AppWorksPlatform/defaultInst/webroot/WEB-INF/lib/*
sudo chmod 777 /opt/opentext/AppWorksPlatform/defaultInst/webroot/WEB-INF/lib/*

After this upload we need to edit a special (unknown by me!?) file: vi /opt/opentext/AppWorksPlatform/defaultInst/config/bcp.classpath. At the end of this file add 4 extra jar-file dependencies:

1
/opt/opentext/AppWorksPlatform/defaultInst/com/cordys/web/rest/RESTGateway.jar:/opt/opentext/AppWorksPlatform/defaultInst/com/cordys/web/rest/ext/json-lib.jar:/opt/opentext/AppWorksPlatform/defaultInst/com/cordys/web/rest/ext/commons-lang-2.6.jar:/opt/opentext/AppWorksPlatform/defaultInst/ext/commons-logging.jar

Notes:

  • Beware of the : in Unix; Windows uses ;…Don’t shoot the messenger!
  • Use the commons-lang-2.6.jar and not $CORDYS_HOME/ext/commons-lang3.jar…I thought being smart, but I quickly learned from my own smartness! 😒

Because of all the JAR changes…systemctl restart tomee!

Once back, we now move to our own organization with our developer account. Here we need to assign our awdev account to the ReST Developer role in the ‘User Manager’ artifact. Before the playground is open, we also need a new service container from the ‘System Resource Manager’ artifact. You can use this input for it:

  • Connector type: WS-AppServer
  • Service group name: sg_ws_appserver
  • Select the 2 ‘REST Gateway’ web service interfaces
  • Service name: sc_ws_appserver
  • Make it automatically start
  • Assign it to the OS Process (our TomEE instance!)
  • In the ‘JRE Configuration’ tab, add the same 4 jar-files from the bcp.classpath!
  • We do NOT need a database

When the service container is GREEN, your playground is open…


Our first ReST example

The PDF manual of this connector sets up an FTP circus with connector and FTP server, but why not use the simplest service call with input like this:

1
2
3
4
5
6
7
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP:Body>
<GetBasicUserDetails xmlns="http://schemas.cordys.com/1.0/ldap">
<dn>o=appworks_tips,cn=cordys,cn=defaultInst,o=23.1.com</dn>
</GetBasicUserDetails>
</SOAP:Body>
</SOAP:Envelope>

You can use the ‘Web Service Interface Explorer’ artifact to try it yourself.

Time to generate a ReST Service out of this basic SOAP service…WHAT!?!? Yes, my friend…Open the ‘Generate REST Services’ artifact with this input:

rest_001

On my image I see an error passing by at that first service click:

1
2
3
4
5
superclass access check failed: class nu.xom.JDK15XML1_0Parser
(in unnamed module @0x4b3432a4) cannot access
class com.sun.org.apache.xerces.internal.parsers.SAXParser
(in module java.xml) because module java.xml does not export
com.sun.org.apache.xerces.internal.parsers to unnamed module @0x4b3432a4

After a little research, I found this solution as JVM parameter for my TomEE instance:

1
2
3
4
sudo vi /usr/lib/systemd/system/tomee.service
#Update this line with '--add-exports' and '--illegal-access' parameters: Environment="JAVA_OPTS=-Djava.security.egd=file:///dev/urandom --add-exports java.xml/com.sun.org.apache.xerces.internal.parsers=ALL-UNNAMED --add-exports java.xml/com.sun.org.apache.xerces.internal.util=ALL-UNNAMED --illegal-access=permit"
systemctl daemon-reload
systemctl restart tomee

These are my research URLs to eventually solve it:

When done (leave the dn parameter), you can ‘Save’ it (at the bottom), and you get the information message that the resource is generated successfully!? Now what? Well, what about evaluating it with the artifact ‘Test REST Service’!? WHAT!! 😏

If you’re curious where this “resource” is generated? Have a look in the XML store on this location: /Cordys/servicemapping/soaptorest. You can also delete it here and regenerate it!

After opening the test artifact, we can have a first test like this:

rest_002

That’s JSON!!! On a SOAP/XML minded platform…The world upside-down! AMAZING! 🤗

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"@xmlns":"http://schemas.cordys.com/1.0/ldap",
"@xmlns:ns1":"http://schemas.cordys.com/generic/rest/1.0",
"@xmlns:SOAP":"http://schemas.xmlsoap.org/soap/envelope/",
"tuple":{
"old":{
"user":{
"authuserdn":"cn=awdev@awp,cn=authenticated users,cn=cordys,cn=defaultInst,o=23.1.com",
"description":"AppWorks Developer",
"organization":{
"@default":"true",
"dn":"o=appworks_tips,cn=cordys,cn=defaultInst,o=23.1.com",
"description":"AppWorks Tips",
"organizationaluser":{
"dn":"cn=awdev@awp,cn=organizational users,o=appworks_tips,cn=cordys,cn=defaultInst,o=23.1.com"
}
}
}
}
}
}

NOTES:

  • Don’t hit the ‘Invoke’ button like a madman if it’s not working…I saw that my TomEE eventually hang!!
  • I also played with URL encoding for the parameters; This is a great site. Eventually it was not needed, but the “dencoder”-site is still one to remember.
  • Monitor the ReST response via TomEE access log: sudo tail -999f /opt/tomee/apache-tomee-plus-8.0.14/logs/localhost_access_log.{date}.txt
  • Nothing happened on my first time clicking the ‘Invoke’ button! I only saw another error in the ‘catalina.out’: java.lang.ClassNotFoundException: net.sf.json.xml.XMLSerializer. Trying and struggling it finally decided me to #RTFM and solved it via the section ‘Known Issues and troubleshooting’ in de PDF. More specific; Updating my RESTGateway.jar\META-INF\MINIFEST.MF file with this content part Class-Path: ext/json-lib.jar ext/commons-lang-2.6.jar:

rest_003

You can edit a JAR best with 7-Zip…Tip from the PRO!

Well, DONE! right? NOPE…


Answer to a question (Q/A)

A comrade with the same connector interests asked me this interesting question:

1
2
3
Hey Antal, hope you are doing well. We have a soap webservice that we are 
calling from RESTGateway. But we are not sure how to pass the authentication
token from OTDS. Any clue how we can pass the token? Appreciate your help...

Let’s see if we can find a solution…The first thing where I would start for an answer is how on earth can we reach this ReST endpoint from outside the platform!? I though being smart with URLs like this:

  • http://192.168.56.107:8080/home/appworks_tips/getbasicuserdetailsresponse/o=appworks_tips,cn=cordys,cn=defaultInst,o=23.1.com
  • http://192.168.56.107:8080/getbasicuserdetailsresponse/o=appworks_tips,cn=cordys,cn=defaultInst,o=23.1.com
  • http://192.168.56.107:8080/home/getbasicuserdetailsresponse/o=appworks_tips,cn=cordys,cn=defaultInst,o=23.1.com

Eventually (after a check in the Chrome developer console while hitting the ‘Invoke’ button) it’s a URL like this:

1
http://192.168.56.107:8080/cordys/restful/getbasicuserdetailsresponse/o=appworks_tips,cn=cordys,cn=defaultInst,o=23.1.com/com.cordys.web.rest.RESTGateway.wcp?organization=o=appworks_tips,cn=cordys,cn=defaultInst,o=23.1.com

Interesting here is when the input is wrong (like the DN parameter), you get back a RESTFault error in XML format!? 🤣

So, back to the question! That last URL was off course validated with an AppWorks session already in place! Now, let’s add a new incognito tab and directly call the URL!…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
"@xmlns":"http://schemas.cordys.com/1.0/ldap",
"@xmlns:ns1":"http://schemas.cordys.com/generic/rest/1.0",
"@xmlns:SOAP":"http://schemas.xmlsoap.org/soap/envelope/",
"tuple":{
"old":{
"user":{
"authuserdn":"cn=anonymous,cn=authenticated users,cn=cordys,cn=defaultInst,o=23.1.com",
"description":"Authenticated user anonymous",
"organization":{
"dn":"o=appworks_tips,cn=cordys,cn=defaultInst,o=23.1.com",
"description":"AppWorks Tips",
"organizationaluser":{
"dn":"cn=anonymous,cn=organizational users,o=appworks_tips,cn=cordys,cn=defaultInst,o=23.1.com"
}
}
}
}
}
}

So, how to pass a valid (OTDS!) authentication!?!? For this…My friend, we will follow our own Postman post. Why? Well, it’s just a simple HTTP GET request where we can pass a SAML token!

In quick steps from this post:

  • I don’t use Postman, but I use ‘curl’ for Windows…It’s the same, but I always wanted to play with it a little more!
  • This will be our target call: curl -X GET "{our_url}", but needs some authentication (over OTDS).
  • We first do an OTDS API call for retrieving a ticket:
1
curl -X POST "http://192.168.56.107:8181/otdsws/rest/authentication/credentials" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"userName\": \"awdev\", \"password\": \"admin\", \"targetResourceId\": \"682e5f08-9fb9-4517-a350-ff586af2075a\"}"
  • The SwaggerUI for this request is accessible via http://192.168.56.107:8181/otdsws/api/index.html
  • The result is an OTDS-ticket starting with *VER2*!
  • That resourceID is available in OTDS (http://192.168.56.107:8181/otds-admin/#resources); Make sure to use the same resourceID which is also connected to your appworks platform! See this post for more details.
  • Next step is to convert the OTDS-ticket to a SAML-token which we use for our further communication to AppWorks:
1
curl -X POST "http://192.168.56.107:8080/home/appworks_tips/com.eibus.web.soap.Gateway.wcp" -H "accept: */*" -H "Content-Type: text/xml" -d "<SOAP:Envelope xmlns:SOAP=\"http://schemas.xmlsoap.org/soap/envelope/\"><SOAP:Header><OTAuthentication xmlns=\"urn:api.ecm.opentext.com\"><AuthenticationToken>{OTDS_ticket}</AuthenticationToken></OTAuthentication></SOAP:Header><SOAP:Body><samlp:Request xmlns:samlp=\"urn:oasis:names:tc:SAML:1.0:protocol\" MajorVersion=\"1\" MinorVersion=\"1\" IssueInstant=\"2018-09-07T16:47:13.359Z\" RequestID=\"a5470c392e-264e-jopl-56ac-4397b1b416d\"><samlp:AuthenticationQuery><saml:Subject xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\"><saml:NameIdentifier Format=\"urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified\"/></saml:Subject></samlp:AuthenticationQuery></samlp:Request></SOAP:Body></SOAP:Envelope>"
  • Don’t forget to update the {OTDS_ticket} part with a valid OTDS-ticket from the previous call
  • The result is a SAML artifact token; found in the AssertionArtifact element!
  • Now we can do a call like this: curl -X GET "{our_url}" -H "SAMLart: {saml_artifact_id}"

rest_004

There you also have the answer to our Q/A section!

Windows wants everything with the correct "‘s; That’s the reason for escaping with \"! In Linux this works much smoother; Don’t ask me why I did not do it on my Linux VM!? Sometimes you have already made your decision. I guess it’s just time for a good weekend rest! 😅


I give it a “DONE” for this post! Long live JSON on our XML minded platform. Have also a read through the PDF-manual as only 80% is covered of the valuable connector; Like how to move a ReST Service into a package and deliver it! I just provided you those first baby steps where it went wrong from my side. I do not understand why OpenText is “Hiding” this connector? It looks pretty valuable from my understanding, and it has a valuable addition to the Typed ReST layer we already have; Especially when it comes to custom services or services extracted from a BPM!…Let’s ask this question once more when I sit together in one of the OpenText sessions. Let’s have a good weekend and I will see you next week for another interesting AppWorks Tips topic!

Don’t forget to subscribe to get updates on the activities happening on this site. Have you noticed the quiz where you find out if you are also “The AppWorks guy”?