# APIs
The ArdenSuite Server provides three interfaces to enable service-oriented access for arbitrary client applications and to integrate the ArdenSuite into existing environments. The following interfaces are supported:
NOTE
Read our instruction manual How to Call Arden Syntax MLMs on an ArdenSuite Server Using REST and SOAP—SIRS Notification as an Example for a practical guide on how to use REST and SOAP with the ArdenSuite Server. Find more how-to instruction manuals as well as the files to accompany the manuals in our Learning Center.
To illustrate how to call an MLM using web service protocols, we supply you with a working example. In this example, we implemented an MLM that performs a simplified body mass index (BMI) calculation and a subsequent classification based on the calculated BMI. The MLM can be found here. To work with this example, create a new project in the ArdenSuite IDE, copy this MLM into the project, compile it, and deploy the compiled MLM on the ArdenSuite Server.
# REST
The ArdenSuite Server provides a REST application programing interface. The URL to access this interface is:
http://{server}:8080/REST/
To access the REST interfaces, a basic authentication is required.
The following endpoints are available:
http://{server}:8080/REST/CALLMLM
This endpoint is used to execute MLMs. To execute an MLM, the URL parameters mlmName and mlmInstitution are required to identify the MLM. The mlmVersion is optional. If no version is specified, the MLM with the highest version number is used.
Usage: POST
http://{server}:8080/REST/CALLMLM?mlmName=FHIRRead&mlmInstitution=Medexter
or
http://{server}:8080/REST/CALLMLM?mlmName=FHIRRead&mlmInstitution=Medexter&mlmVersion=1.0
Parameters: via REST body
# Call Event
http://{server}:8080/REST/CALLEVENT
This endpoint is used to trigger all MLMs which listen for a given event. These events can be specified inside MLMs. This endpoint also includes the STOPEVENT endpoint functionality. When called, the ArdenSuite Server first checks which MLMs should be executed due to the event and after that it checks if there are MLMs where the event was registered as a stop event—the STOPEVENT endpoint checks for stop events only.
Usage: POST http://{server}:8080/REST/CALLEVENT?event=eventname
Parameters: via REST body
# Stop Event
http://{server}:8080/REST/STOPEVENT
This endpoint is used to execute stop events. If MLMs are written to be executed periodically, there is an option to specify an event as UNTIL parameter. Using this endpoint, MLMs bound to a certain stop event are stopped.
Usage: POST http://{server}:8080/REST/STOPEVENT?event=eventname
Parameters: via REST body
# List Server Protocol
http://{server}:8080/REST/LISTSERVERPROTOCOL
This endpoint returns a list of protocol logs generated by the server.
Usage: GET
Parameters: no parameters
# Details Server Protocol
http://{server}:8080/REST/DETAILSERVERPROTOCOL?protocolID=<protocolID>
This endpoint returns a list of protocol log entries of a given protocol ID
.
Usage: GET
Parameters:
# Get Server Protocol status
http://{server}:8080/REST/GETPROTOCOLSTATUS
This endpoint returns the current protocol session id, if there is an active protocol session.
When there is no active protocol session, No active protocol session
is returned.
Usage: GET
Parameters: no parameters
# Start Server Protocol
http://{server}:8080/REST/STARTSERVERPROTOCOL?TTL=<hours>
This endpoint starts a new protocol session, and returns its id. A previously active protocol session will then be closed.
When TTL
(full hours) is given, it stops automatically after the given time.
When TTL
is not provided, the session runs until the next start / stop protocol call.
Usage: GET
Parameters:
# Stop Server Protocol
http://{server}:8080/REST/STOPSERVERPROTOCOL
This endpoint stops the current protocol session.
When no protocol session is active, No active protocol session
is returned.
Usage: GET
Parameters: no parameters
# Remove Server Protocol
http://{server}:8080/REST/REMOVESERVERPROTOCOL?protocolID=<protocolID>
This endpoint removes a given protocol session.
When the protocol session is not found, <protocolID> not found
is returned.
Usage: GET
Parameters:
# Get the server logs
http://{server}:8080/REST/GETLOGZIPS
This endpoint can (when the user has rest.log permissions) collect and send the logs of the server as zip file.
Usage: GET
Parameters: no parameters
# Create a new user
http://{server}:8080/REST/ADDUSER
This endpoint can (when the user has rest.service permissions and is in the Admin group) create a new user. The user is activated on creation. The restrictions of the normal user-creation (encoding + format of password) are also checked.
Neither name
nor pass
nor passRe
may contain the :
char.
Usage: GET
Parameters:
name
Username of the new user (required)pass
Password of the new user (required)passRe
Reenter the password of the new user (required)group
The group of the new user (required)fName
First name of the new user (optional)lName
Last name of the new user (optional)
# Change current password
http://{server}:8080/REST/CHPASSWD
This endpoint can (when the user has rest.service permissions) change the current password of an authenticated user. The restrictions of the normal user-creation (encoding + format of password) are also checked.
Neither pass
nor passRe
may contain the :
char.
Usage: GET
Parameters:
newPass
The new password of the current userpassRe
Reenter the new password of the current user
All parameters are required.
# How to Use Start and Stop Events
The ArdenSuite Server supports starting and stopping periodic MLM calls via events. To this end, it is possible to specify events inside MLMs like the following and use them inside the evoke slot:
admission_event := event {admission}; // admission
discharge_event := event {discharge}; // discharge
evoke: EVERY 10 seconds FOR 1 day STARTING time of admission_event UNTIL discharge_event;;
To support starting and stopping periodic MLMs for e.g., different patients, the input parameters are taken into account. Otherwise, if a periodic MLM was started for patient 1 and 2 respectively, a discharge event would stop both periodic jobs (MLM calls). However, as the input parameters are taken into account when starting and stopping periodic jobs (MLM calls), we can stop periodic jobs for MLMs which were called with a specific input. E.g., an event call was executed (admission) with the following parameter. In this case, the input could represent patient id 1.
{
"type": "number",
"applicability": 1,
"primaryTime": null,
"value": 1
}
The MLM bound to this event will start as a periodic job and will be executed e.g., every 10 seconds for this input (patient id 1). After that we execute the same event call with a different input (e.g., patient id 2):
{
"type": "number",
"applicability": 1,
"primaryTime": null,
"value": 2
}
If we want to stop the MLM execution for patient 1, we will have to execute a discharge event call using the same input as when the admission event was fired. The ArdenSuite Server will stop all periodic MLM jobs which listen to the discharge event and where the input parameter was:
{
"type": "number",
"applicability": 1,
"primaryTime": null,
"value": 1
}
# Input Parameter Specification
MLMs can get external data in multiple ways: Connectors using READ statements and data input via REST/SOAP body.
To provide the evaluated MLM with an input parameter, data are structured and sent in JSON format as body to the web service methods.
Arden Syntax Value: In Arden Syntax there are several data types available to be used as input parameters: number, string, boolean, time, duration, dayofweek, timeofday, truthvalue, null. In JSON format those are written as follows:
{
"type": "string",
"primaryTime": null,
"applicability": 1,
"value": "text value"
}
Arden Syntax List: An Arden Syntax list includes all other data types, including objects:
{
"type": "list",
"primaryTime": null,
"applicability": 1,
"values": [
{
"type": "string",
"primaryTime": null,
"applicability": 1,
"value": "text value 1"
},
{
"type": "string",
"primaryTime": null,
"applicability": 1,
"value": "text value 2"
}
]
}
Arden Syntax Object: An Arden Syntax object may have several fields of any
other data type. Inside MLMs, these fields are accessed using the .
operator:
{
"type": "object",
"primaryTime": "2016-08-22T09:30:27",
"applicability": 1,
"declaration": "Patient",
"fields":
{
"entry": [{
"key": "PaCO2",
"value": {
"type": "number",
"primaryTime": "2016-08-22T09:30:27",
"applicability": 1,
"value": 34
}
},
{
"key": "heartRate",
"value": {
"type": "number",
"primaryTime": "2016-08-22T09:30:27",
"applicability": 1,
"value": 88
}
},
{
"key": "immatureBand",
"value": {
"type": "number",
"primaryTime": "2016-08-22T09:30:27",
"applicability": 1,
"value": 6
}
}
}]
}
}
# SOAP
In addition to the REST interface, the ArdenSuite Server also provides a SOAP interface described by a Web Service Description Language (WSDL) file.
NOTE
Read our instruction manual How to Call Arden Syntax MLMs on anArdenSuite Server Using REST and SOAP―SIRS Notification as an Example for a practical guide on how to use REST and SOAP with the ArdenSuite Server. Find more how-to instruction manuals as well as the files to accompany the manuals in our Learning Center.
# WSDL
The WSDL file represents a platform-independent technical description of the corresponding web service. For each client application, the file generates the client stub that can access the remote service. The URL to this WSDL file is:
http://{server}:8080/AS_XML_Protocol/AS_XML_Protocol?wsdl
# Implementing a Java SOAP Client
# Generate Stubs from WSDL
First, the appropriate classes that abstract the access to the service
need to be generated, so the programer does not have to worry about the
actual network communication. For this, the wsimport
tool from the JDK
is required:
wsimport -p medexter.arden.server.serviceStubs -keep <WSDLUrl>
The above command creates Java classes in the folder where it was
executed using the command line. These classes may be imported into a
Java project, whereas <WSDLUrl>
contains the URL or path to the
WSDL service description, for example:
http://{server}:8080/AS_XML_Protocol/AS_XML_Protocol?wsdl
# Service Call
Once the Java classes have been integrated into the project, the web service can be called. The following sample code shows the invocation of services in Java, including basic authentication:
public static void main(String[] args) {
String url = "http://localhost:8080/AS_XML_Protocol/AS_XML_Protocol";
String user = "admin";
String password = "s3cret";
String argument = "";
// Get the service and the port
ASXMLProtocol_Service service = new ASXMLProtocol_Service();
ASXMLProtocol port = service.getASXMLProtocolPort();
// Use the BindingProvider's context to set the endpoint
BindingProvider bp = (BindingProvider)port;
/* Optional if you to need to change the endpoint */
bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, url);
/* Optional credentials */
bp.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, user);
bp.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, password);
/* calling the web service method */
String text = port.evaluateXMLRequest(argument);
System.out.println(text);
}
final String argument =
"<usecase>" +
"<callMlm>" +
"<key>" +
"<mlmName>RS_SIRS-Notification1</mlmName>" +
"<institution>Medexter Healthcare, Vienna, Austria</institution>" +
"</key>" +
"<arguments" +
"</arguments>" +
"</callMlm>" +
"</usecase>";
The above client calls the method evaluateXMLRequest
of the
ArdenSuite
Server. The method evaluateXMLRequest
calls the
ArdenSuite
Server to evaluate the given request. The request string (argument
variable) must contain an XML document, corresponding to the
ArdenSuite
Server protocol. The XML schema for those messages is available here. The following operations are
supported:
- callMlm
- callEvent
# CDS Hooks
The ArdenSuite provides a CDS Hooks API that was programed according to CDS Hooks specification version 1.0. The ArdenSuite Server allows to specify a Hook name and Hook prefetch data for each MLM individually via the ArdenSuite MLM management screen. The MLMs where these data slots are set will be taken into account by the CDS Hooks discovery endpoint.
# Add Hook to MLM
To add a Hook, please perform the following steps:
Press the "Manage CDS Hooks" button ( ) in the MLM row on the right. A window will open:
You have 2 options: Either choose an already created Hook from the list on the right by clicking on it, or create a new Hook (see next step). MLMs with the same Hook can have different or no prefetch statements. Therefore, when selecting a Hook from the list, the prefetch field is empty.
Create a new Hook:
- Hook Name: Enter Hook name.
- Hook Prefetch: This is optional and has to be set as JSON string
e.g.,
{ "patient" : { "resourceType" : "Patient", "gender" : "male", "birthDate" : "1925-12-23", "id" : "1288992", "active" : "true" } }
Click
Save
to create the Hook, otherwise clickCancel
.
You can easily spot MLMs with Hooks in the MLM Management
screen,
because their "Manage CDS Hooks" buttons ( ) on the right are in
color.
# Edit Hook
To edit an MLM's existing Hook, perform the following steps:
Press the Manage CDS Hooks button ( ) on the right of the MLM. A window will open:
Edit any of the pre-filled fields or choose a different hook from the list instead.
Click
Save
to save your changes, otherwise clickCancel
.
# Delete Hook
To delete a Hook from an MLM, follow these steps:
- Press the "Manage CDS Hooks" button ( ) on the right of the MLM. A window will open.
- Empty the Fields "Hook Name" and "Hook Prefetch".
- Click
Save
to delete the Hook, otherwise clickCancel
.
MLMs without a Hook are indicated with a grey "Manage CDS Hooks" button ( ) .
# CDS Service
Each MLM used for the CDS Hooks API is considered a CDS service
according to the CDS Hooks specification.
An MLM's name, institution, and version serve as the CDS service ID, e.g., there
is an MLM with the name TestCDSHooks
, the institution Medexter Healthcare
, and version
1.0
for which the hook patient-view
was assigned:
CDS Hooks Discovery Endpoint:
http://:8080/CDSHOOKS/cds-services
{
"services": [
{
"hook": "patient-view",
"description": "TestCDSHooks, Arden Version 2.9, Institution: Medexter Healthcare, Version: 1.0",
"id": "TestCDSHooks?mlmInstitution=Medexter Healthcare&mlmVersion=1.0",
"title": "TestCDSHooks"
}
]
}
According to the CDS Hooks specification, this CDS service is available at the following URL:
http://localhost:8080/CDSHOOKS/cds-services/TestCDSHooks?mlmInstitution=Medexter >Healthcare&mlmVersion=1.0
.
If a CDS service is called (see CDS Hooks specification), the whole request body is transformed into an Arden Syntax object and passed to the MLM as input parameter.
NOTE
Calling a CDS service via the CDS Hooks API, a FHIR server may be passed, which is used to retrieve data (see connector options and priority levels section). This server acts as a default connection.
{
"hookInstance" : "d1577c69-dfbe-44ad-ba6d-3e05e953b2ea",
"hook" : "patient-view",
"context" : {
"var1" : "test",
"var2" : 2,
"patientId" : "bd7cb541-732b-4e39-ab49-ae507aa49326"
},
"prefetch" : {
"patientToGreet" : {
"resourceType" : "Patient",
"gender" : "male",
"birthDate" : "1925-12-23",
"id" : "bd7cb541-732b-4e39-ab49-ae507aa49326",
"active" : "true"
}
}
}
Inside the MLM, this request body can be used like
this:input := Argument; patient_birthdate := input.prefetch.patientToGreet.birthDate;
# Cards
To generate CDS Hooks cards, an object representing the specified cards
hierarchy has to be created by the user inside the MLM. The object field
names have to be chosen according to the CDS Hooks specification and in addition
have to use CDSHOOKS_
as prefix. This is to avoid conflicts between
Arden Syntax reserved names and CDS Hooks reserved names.
cardobj := OBJECT [CDSHOOKS_summary, CDSHOOKS_detail, CDSHOOKS_indicator, CDSHOOKS_source,
CDSHOOKS_suggestions, CDSHOOKS_selectionBehavior, CDSHOOKS_links];
sourceobj := OBJECT [CDSHOOKS_label, CDSHOOKS_url, CDSHOOKS_icon];
suggestionobj := OBJECT [CDSHOOKS_label, CDSHOOKS_uuid, CDSHOOKS_actions];
actionobj := OBJECT [CDSHOOKS_type, CDSHOOKS_description, CDSHOOKS_resource];
linkobj := OBJECT [CDSHOOKS_label, CDSHOOKS_url, CDSHOOKS_type, CDSHOOKS_appContext];
resourceobj := OBJECT [CDSHOOKS_resourceType, CDSHOOKS_id, CDSHOOKS_status, CDSHOOKS_date,
CDSHOOKS_weekDay, CDSHOOKS_duration];
These objects can be used to build a CDS Hooks card response:
card := new cardobj;
context := input.context;
prefetch := input.prefetch;
cDetail := context.var1 || " " || context.var2 || " " || prefetch.patientToGreet.birthDate;
card.CDSHOOKS_summary := "This cards summary";
card.CDSHOOKS_detail := cDetail;
card.CDSHOOKS_indicator := "info";
card.CDSHOOKS_selectionBehavior := "at-most-one";
sourceObj := new sourceobj;
sourceObj.CDSHOOKS_label := "Source Label";
sourceObj.CDSHOOKS_url := "www.google.com";
sourceObj.CDSHOOKS_icon := "www.google.com";
card.CDSHOOKS_source := sourceObj;
resource := new resourceobj;
resource.CDSHOOKS_resourceType := "ProcedureRequest";
resource.CDSHOOKS_id := 1.1;
resource.CDSHOOKS_status := true;
resource.CDSHOOKS_date := 2018-11-28T13:30:00;
resource.CDSHOOKS_weekDay := Monday;
resource.CDSHOOKS_duration := 1 day + 2 hours;
action1 := new actionobj;
action1.CDSHOOKS_type := "create";
action1.CDSHOOKS_description := "Action 1";
action1.CDSHOOKS_resource := resource;
action2 := new actionobj;
action2.CDSHOOKS_type := "update";
action2.CDSHOOKS_description := "Action 2";
action2.CDSHOOKS_resource := resource;
actionList := (action1, action2);
suggestion1 := new suggestionobj;
suggestion1.CDSHOOKS_label := "Suggestion 1";
suggestion1.CDSHOOKS_uuid := "1";
suggestion1.CDSHOOKS_actions := actionList;
suggestion2 := new suggestionobj;
suggestion2.CDSHOOKS_label := "Suggestion 2";
suggestion2.CDSHOOKS_uuid := "2";
suggestion2.CDSHOOKS_actions := actionList;
suggestionList := (suggestion1, suggestion2);
card.CDSHOOKS_suggestions := suggestionList;
link1 := new linkobj;
link1.CDSHOOKS_label := "Link 1";
link1.CDSHOOKS_url := "www.google.com/link1";
link1.CDSHOOKS_type := "absolute";
link1.CDSHOOKS_appContext := "Context";
link2 := new linkobj;
link2.CDSHOOKS_label := "Link 2";
link2.CDSHOOKS_url := "www.google.com/link2";
link2.CDSHOOKS_type := "absolute";
link2.CDSHOOKS_appContext := "Context";
linkList := (link1, link2);
card.CDSHOOKS_links := linkList;
If an MLM like this is called, the JSON response would be as follows:
{
"cards": [
{
"summary": "This cards summary",
"indicator": "info",
"selectionBehavior": "at-most-one",
"suggestions": [
{
"label": "Suggestion 1",
"uuid": "1",
"actions": [
{
"resource": {
"date": "2018-11-28T13:30:00+01:00",
"duration": "1 day 2 hours",
"weekDay": 1,
"id": 1.1,
"resourceType": "ProcedureRequest",
"status": true
},
"description": "Action 1",
"type": "create"
},
{
"resource": {
"date": "2018-11-28T13:30:00+01:00",
"duration": "1 day 2 hours",
"weekDay": 1,
"id": 1.1,
"resourceType": "ProcedureRequest",
"status": true
},
"description": "Action 2",
"type": "update"
}
]
},
{
"label": "Suggestion 2",
"uuid": "2",
"actions": [
{
"resource": {
"date": "2018-11-28T13:30:00+01:00",
"duration": "1 day 2 hours",
"weekDay": 1,
"id": 1.1,
"resourceType": "ProcedureRequest",
"status": true
},
"description": "Action 1",
"type": "create"
},
{
"resource": {
"date": "2018-11-28T13:30:00+01:00",
"duration": "1 day 2 hours",
"weekDay": 1,
"id": 1.1,
"resourceType": "ProcedureRequest",
"status": true
},
"description": "Action 2",
"type": "update"
}
]
}
],
"links": [
{
"appContext": "Context",
"label": "Link 1",
"type": "absolute",
"url": "www.google.com/link1"
},
{
"appContext": "Context",
"label": "Link 2",
"type": "absolute",
"url": "www.google.com/link2"
}
],
"detail": "test 2 1925-12-23T00:00:00",
"source": {
"icon": "www.google.com",
"label": "Source Label",
"url": "www.google.com"
}
}
]
}