This blog is about Integration Gateway (IGW) in SAP Mobile Platform 3.0 (SMP).
I’d like to collect as many tips and FAQs as you may find useful.
It is an unordered collection of issues which might occur when using SAP Mobile Platform 3.0 (SMP) and Integration Gateway (IGW) and how to solve them.
Also tips and sample code should be part of this collection.
Please feel encouraged to add your own tips and sample code to the comment-section below.
➕ ➕ ➕ ➕ ➕ ➕ ➕ ➕ ➕
➕ Please participate !!!
➕ ➕ ➕ ➕ ➕ ➕ ➕ ➕ ➕
Description
When invoking a query of a REST based OData service, the following Error is logged in the SMP log:
java.lang.Exception: Error in StreetSet_REST_Query.groovy: groovy.lang.MissingPropertyException: No such property: LogMessage for class: Script1
Reason
The Groovy script contains an object that cannot be resolved. Probably the import statement is missing, or a dependency is missing
Solution:
Add the import statement, e.g.:
import com.sap.gateway.ip.core.customdev.logging.LogMessage
Description
When invoking a query you get an error message in the browser response:
Internal Error
And in the SMP-log:
java.net.BindException: Cannot assign requested address: connect
Reason
Missing proxy definition in SMP Admin
Solution
Add proxy settings to your SMP server.
This is done at https://<your_server>:8083/Admin/
Go to “Settings”-tab then “System” sub-tab
Description
I had the following strange issue several times.
I installed SMP server, opened Gateway Management Cockpit and created a Destination inside corporate network.
So no proxy definition required.
In the Destination tab, I executed the “Test Connection” and it was successful.
The I created an OData service based on the REST data source.
Assigned the destination and opened the Service and Metadata documents -> fine
Then tried the entityset -> error.
Error message in response body in the browser:
For Input String’’
Error message in the log:
java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:507)
at java.lang.Integer.valueOf(Integer.java:585)
at com.ning.http.util.ProxyUtils.createProxyServerSelector(ProxyUtils.java:157)
at com.ning.http.client.AsyncHttpClientConfig$Builder.build(AsyncHttpClientConfig.java:1151)
at com.sap.gateway.core.ip.camel.component.ahc.IGWAhcProducer.getClientConfig(IGWAhcProducer.jav
Reason
All settings seemed to be correct.
I searched long time for the error in the script – no chance, it didn’t even get invoked.
There didn't seem to be a reason
Solution
At the end, I tried the following:
I entered proxy settings for SMP
Since my data source didn’t require a proxy, I also entered my backend as non-proxy host.
Then restarted SMP server
After that, my service worked fine.
Description
You’re creating a service based on REST data source
Error message in the browser:
class java.lang.Stringnull incompatible with class java.util.HashMapnull
Error message in the SMP-log:
ClassCastException.
Reason
The reason is very common for this part of the scripting.
It is about the string that is returned as “body”.
It needs to have exactly the expected structure.
If it doesn’t, this ClassCastException is thrown
Description
You’re creating a service based on REST data source
When invoking the entity set, you get the usual error, which you probably don’t like so much
Reason
One possible reason is a missing property.
Remember: your OData model must have all properties that are in the REST service
The OData model may have more, but not less properties than the backend REST service
Solution
Adapt the OData model according to the backend REST service
Description
You’re creating a service based on REST data source
When invoking the entity set, you get the error:
while trying to invoke the method com.sap.gateway.core.ip.component.commons.ODataResponseType.ordinal() of a null object loaded from local variable 'responseType'
Reason
Returning Structure in message.setBody is not as expected
Solution
Fix the body string such that it meets the structure that is expected by the Integration Gateway framework
Description
When implementing custom code in Javasccript, the following error is thrown in the SMP-log
Javascript error:
Caused by:
org.mozilla.javascript.EvaluatorException: missing ; before statement (/XlsServiceWithFileAccess/src/main/resources/script/OBDcodes_SCRIPT.js#32)
Reason
Don’t search for any missing ;
It has nothing to do with that.
The reason is that you copied a code snippet from java
e.g.
File file = new File(fileName);
And you forgot to adapt it to
var file = new File(fileName);
Solution
Fix your erroneous code.
Description
My service which contains custom code written in javascript fails and the error in the SMP log is
“An exception occurred”
Reason
The javascript code is erroneous and causes an exception
In my example:
I had created a java.util.map, there was a key (property name) and the value was inserted programmatically.
The value turned out to be a primitive value (int) but it has to be an object (Integer)
Solution
Fix the javascript code
Description
My service which contains custom code written in javascript fails and the error in the SMP log is
javax.script.ScriptException: org.mozilla.javascript.EvaluatorException: missing ) after argument list
Reason:
I forgot the + for concatenation
log.logErrors(LogMessage.TechnicalError, "===> done with test + " hssfSheet);
Solution
Fix the code
log.logErrors(LogMessage.TechnicalError, "===> done with test + " + hssfSheet);
Description
In your browser, you go to the SMP Admin page, e.g. at https://localhost:8083/Admin/
After entering the credentials, you get that red error:
An internal server error occurred. Please contact your administrator
You nearly get crazy entering your credentials and you’re sure that they are correct.
What to do?
Reason
Don't care
Solution
Reload the browser page by pressing F5
Description
After deploying your service to SMP, you’ve changed the OData model and deployed again
During runtime, when invoking your entity set, you get an error in the SMP-log:
“failed to serve request”
Reason
SMP doesn’t know about the new changed metadata
Solution
Invoke the metadata document at <service_name>/$metadata
Then call the entity set again. Now it should work
Description
You have entered the proxy settings in SMP, because you need proxy for your destination.
However, the connection still doesn’t work
Reason
Whatever
Solution
Restart the SMP server
Description
You’ve changed your Eclipse project and deployed, but you don’t see the changes reflected at runtime.
Troubleshooting
- Check on OSGi console if bundle is started
- If you have started the SMP via console then check if the console is not blocked. Just hit enter in the console window
- In Eclipse, open the target folder and check if there are 2 jars. Delete them, then generate&deploy again
Description
The x-csrf-token is not sent
Background
The x-csrf-token is required for modifying requests like POST, PUT, DELETE
You have to first send a GET request to a valid URL, e.g. the EntitySet URL
This GET request should be executed with the header
x-csrf-token: fetch
(Name of the header is “x-csrf-token” and the value of the header is “fetch”)
The response headers contain the header x-csrf-token and the value is the token that we need.
Now copy the value and paste it into the request header, such that you have
x-csrf-token: <value of the token from the response>
Problem
If you proceed as described above and don’t get the token, you might get crazy
Reason
The reason is that the token is always sent only once per session.
Solution
In order to force SMP to send it again, just logout from Gateway Management Cockpit or SMP Admin page and login again
Description
Deployment doesn’t finish.
Reason
You have started the local SMP server via console
Somehow, you’ve clicked into the command shell
The below screenshot displays a tiny white block
This pauses the execution of SMP
Solution
Click into the command shell
Then press enter.
The white box is gone
Description
Clear metadata before restart SMP
Before restarting the SMP server, you should
- shutdown SQLAnywhere via context menu on the task bar icon
- Delete the folder <install>\Server\work
- Delete the folder <install>\Server\configuration\org.eclipse.osgi
- Delete the folder <install>\Server\pickup\.state (only required if you’ve deployed artifacts to the pickup)
Description
When you create a Destination in SMP server, you can execute a “Test Connection”
In case of REST service destination, this “Test Connection” might fail
Reason
The complete URL of the backend REST service has to be split and only the host is entered as Destination.
This part of the URL doesn’t respond with a success status code, therefore the “Test Connection” fails.
Solution
Create an additional dummy-destination which you don’t use for assigning it to a service.
This destination uses the full URL of the REST-service and as such the “Test connection” will be successful
Description
Custom error message in response body
Background
You’re creating a service based on REST data source and in your script you want to throw an error message and you want it to be shown in the response body such that the user of the OData service can understand it.
Solution
The error message is set as body-string to the Message-instance.
However, as we know, the IGW – framework expects that the body is an xml-structure (or json-structure) that matches the OData model.
Therefore, we have to tell the IGW-FWK that there isn't any valid response payload, but instead, an error message has to be displayed.
This is achieved by setting an error-status-code to the “camelhttpresponsecode” header.
In the following example, we’re setting status 400 which is BAD REQUEST
message.setHeader("camelhttpresponsecode", 400);
Note
The camelhttpresponsecode is not the HTTP status code that is responsible for the communication of the OData service that we are creating.
The camelhttpresponsecode is responsible for the communication of the IGW with the backend REST service (or other backend data source)
In general: the camelhttpresponsecode describes the integration part of the whole communication cycle
Description
You’ve set up your Eclipse environment for Groovy scripting as described here
You’re implementing methods like def Message processResponseData(message) {
You’re still not satisfied because you don’t get code completion for the Message object?
Solution
Here’s a little trick:
def Message processResponseData(message) {
message = (Message)message;
Description
Implement getFeed() for Custom Code data source:
You have to return a java.util.List containing entries of type java.util.Map
Example:
function getFeed(message){
importPackage(java.util);
var responseMap = new HashMap();
responseMap.put("MyEntityID", "111");
responseMap.put("Name", "MyName");
var list = new ArrayList();
list.add(responseMap);
message.setBody(list);
return message;
}
And how to get empty feed?
Solution:
You have to return a java.util.List containing nothing.
This won’t cause an error, the response will just contain a feed which is empty
Example:
function getFeed(message){
importPackage(java.util);
message.setBody(new ArrayList());
return message;
}
Description
Implement getEntry() for Custom Code data source:
You have to return a java.util.Map
Example:
function getEntry(message) {
importPackage(java.util);
var responseMap = new HashMap();
responseMap.put("MyEntityID", "111");
responseMap.put("Name", "MyName");
message.setBody(responseMap);
return message;
}
And how to throw a “Not found” error ?
Solution
Set the body as null
Example:
function getEntry(message) {
message.setBody(null);
return message;
}
Note:
Setting an empty Map as body like message.setBody(new HashMap()) doesn't give the desired result, it will cause an exception and the response will be “BAD_REQUEST”
Description
Use logger
Solution
In your custom script, the code snippet is the following:
importPackage (com.sap.gateway.ip.core.customdev.logging);
log.logErrors(LogMessage.TechnicalError, "Hello ;-)");
Description
Access UriInfo
Solution
In your custom script, the code snippet is the following:
var uriInfo = message.getHeader("uriinfo", org.apache.olingo.odata2.api.uri.UriInfo);
var top = uriInfo.getTop();
var intValue = top.intValue();
Description
Access ODataContext object, in order to access info about external call to your OData service
e.g. the headers
Solution
In your custom script, the code snippet is the following:
var value = message.getHeader("odatacontext", org.apache.olingo.odata2.api.processor.ODataContext).getRequestHeader("<MyHeader>");
Description
Access the configured destination
Solution
In your custom script, the code snippet is the following:
var destinationConfiguration = message.getHeaders().get("DestinationConfiguration");
// in case of destinationConfiguration instanceof HttpDestinationConfiguration
var destinationURL = destinationConfiguration.getDestinationUrl();
Description
Access the parameters of a function import
Solution
In your custom script, the code snippet is the following:
importPackage(com.sap.gateway.core.ip.script);
var paramMap = ScriptUtil.getFunctionImportParameters(message);
var value = paramMap.get("<paramName>");
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
31 | |
24 | |
8 | |
7 | |
7 | |
6 | |
6 | |
5 | |
5 | |
4 |