Skip to main content

Calling and publishing a web service

Header

Level: Advanced

Keywords: external web service, integration

The result: calling and publishing of external web servis in SAMO Application

Metadata placement​

Directory structure
lids-as\business-service
|
└──services
└──services-group-name (optional)
└──services.json
File content - configuration example
{
"public": true,
"securityMethodOwner": "",

"actions" : {
"serviceName": {
"access": [],
"accepts" : {
"contentType" : [],
"strategy" : "",
"method" : ""
},
"steps": [{}]
}
}
}
JavaScript API subset
api
|
└──.http()
└──.prepareExchangeFormData()
└──.prepareExchangeJson()
└──.prepareExchangeSOAP()
└──.prepareExchangeTemplated()
└──.prepareExchangeXML()
|
└──.request()
└──.prepareCreateJSONRequestReader()
└──.prepareCreateSOAPRequestReader()
└──.prepareCreateXMLRequestReader()
|
└──.response()
└──.prepareCreateJSONResponse()
└──.prepareCreateSOAPResponse()
└──.prepareCreateXMLResponse()

How to call a webservice?​

1. Create a standard Business action which will call an external service​

2. Create a JavaScript file for defined action step and prepare script​

Use standard Business Scripting API for communication defined in SAMO Lighthouse.

JavaScript API subset
api
└──.http()
└──.prepareExchangeFormData()
└──.prepareExchangeJson()
└──.prepareExchangeSOAP()
└──.prepareExchangeTemplated()
└──.prepareExchangeXML()
JSON service source code example
function action(context) {
api.logging().prepareLog(context).message(scriptFileName).addValue("START").logDebug();

var request = context.entity
var geoserver = context.variables.geoserver;

if (!geoserver || !geoserver.checkState || !geoserver.checkState.url){
api.exceptions()
.prepareException(context)
.localizedMessage("geoserver.missingVariable")
.addArgument("arg1", "geoserver.checkState.url")
.throwInternalError();
}
var checkStateURL = geoserver.checkState.url;
var extSystemReady = false;

var prepareExchangeJson = api.http().prepareExchangeJson(context).throwExceptionOnError(false).url(checkStateURL);

// add Basic Auth
if (geoserver.checkState.user != null && geoserver.checkState.password != null){
prepareExchangeJson
.prepareAddBasicAuthentication()
.username(geoserver.checkState.user)
.password(geoserver.checkState.password)
.add();
}

var response = prepareExchangeJson.exchange();
var statusCode = response.getStatusCode();

if (statusCode == "200"){
var responseString = response.getResponseBodyAsString();
var responseJSON = JSON.parse(responseString);

api.logging().prepareLog(context)
.message(scriptFileName)
.addVariable("URL", checkStateURL)
.addVariable("statusCode", statusCode)
.addVariable("response", responseJSON)
.logDebug();

if (!(responseJSON.success == true
&&
responseJSON.plotAvailable
&&
responseJSON.plotAvailable.allAvailable == true
))
{
api.exceptions()
.prepareException(context)
.localizedMessage("odb.checkStateNotAvailable")
.locale("de")
.throwInternalError();
}
}
else{
api.exceptions()
.prepareException(context)
.localizedMessage("odb.checkStateError")
.addArgument("arg1", statusCode)
.locale("de")
.throwInternalError();
}

api.logging().prepareLog(context).message(scriptFileName).addValue("END").logDebug();
}

Best practice for storing of external service URL is in the environment file

How to publish a webservice?​

1. Create empty JSON file in services directory​

(see Common - Directory structure)

Directory structure
package-name
|
└──lids-as\business-service
└──services
└──my-group
└──my-services.json

2. Add a structure to your JSON file​

(see Common - Metadata file structure)

  • Set attribute "public" if the service will be public (called without an authorization)
  • Set attribute "securityMethodOwner"
  • Set section "access" modifiers
  • Set section "accepts"
    • to work with XML content contentType has to be set
    • to work with JSON content whole section can be omitted
    • to publish a service as POST, PUT or GET it is necessary to set method. Default is POST
  • Define "actions" and their "steps"
File content - configuration example
{
"public": true,
"securityMethodOwner": "application:APP",

"actions" : {
"soapServiceName": {
"access": ["static", "external"],
"accepts" : {
"contentType" : ["xml"],
"strategy" : "requestApi",
"method" : "POST"
},

"steps": [
{
"type" : "script",
"source" : "{@packageRoot(package-name)}/services/my-group/scripts/my-services/soapServiceFile.js"
}
]
},

"jsonServiceName": {
"access": ["static", "external"],

"steps": [
{
"type" : "script",
"source" : "{@packageRoot(package-name)}/services/my-group/scripts/my-services/jsonServiceFile.js"
}
]
}
}
}

3. Create a JavaScript file for defined step and prepare script​

SOAP service source code
function action(context) {
api.logging().prepareLog(context).message(scriptFileName).addValue("START").logDebug();

// get request
var document = api.request().prepareCreateXMLRequestReader(context).create().getDocument();

// get node value
var nodeValue = document
.getNodeByPathThrowing("Envelope")
.getNodeByPathThrowing("Body")
.getNodeByPathThrowing("nodeA")
.getNodeByPathThrowing("nodeB")
.getValueAsString();
// do something
var today = api.format().dateTime(context).formatString("yyyy-MM-dd HH:mm:ss").timestamp(new Date().getTime()).getFormattedString();

// set SOAP response
var responseBody = {
"name": "RESPONSE",
"children": [
{
"name": "CONTENT",
"children": [
{
"name": "NODE1",
"children": [
{
"name": "NODE2",
"children":[
{ "name": "VALUE1", "value": "Value1" },
{ "name": "VALUE2", "value": nodeValue },
{ "name": "DATE" , "value": today }
]
}
]
}
]
}
]
};

// create SOAP response
var response = api.response().prepareCreateSOAPResponse(context)
.envelopeAttributes(
{
"xmlns:soap":"http://www.w3.org/2003/05/soap-envelope"
}
)
.soapBody(responseBody)
.create();
// send response
return api.result().prepareCreateActionResult(context)
.result(response)
.create();
}

4. Test your service by calling an URL​

  1. Public service
http://[server-name]/lids-as/rest/business/public-service/[tenant]/[service-group]/[service-name]/action/[action-name]
  1. Private service
http://[server-name]/lids-as/rest/business/service/[tenant]/[service-group]/[service-name]/action/[action-name]
  1. Public SOAP service URL example
http://localhost:8080/lids-as/rest/business/public-service/[tenant]/my-group/my-services/action/soapServiceName
http://localhost:8080/lids-as/rest/business/public-service/[tenant]/my-group/my-services/action/jsonServiceName