Synchronous Integration
Invocation of the exchange starts an asynchronous process. In some cases however, this might not be possible and/or desirable from a client perspective. For this purpose, it is possible to invoke an integration in a way that provides a seemingly synchronous/blocking interaction pattern.
Consider the following example 'Service Check' to better understand blocking calls.
Service Check
The rest destination "capitations" to reach out to OHI Value Based Payments application is configured as:
Fields | Configuration | Remarks |
---|---|---|
code |
capitations |
|
credentialKey |
cap_user |
Refer to policies_user configuration in the File Upload example for more details. |
addressKey |
address.key.cap.baseurl |
To setup address key using generic api - /properties the following must be done POST: http(s)://{host:port}/{oig application context}/generic/properties with payload:
|
destinationType |
REST |
|
typeConfig |
path: {path} httpMethod: {httpMethod} |
In this example the provider code, service code, and as of date are supplied as request parameters. Generic API can be used to GET /organizationproviders details. The system reads the dynamic record 'Capitated Services' to check if the given service is capitated or not. If the service is capitated as of the input date, then the exchange must return the response as 'Service is Capitated', otherwise 'Service is Not Capitated'. This use case can be realized by having a CUSTOM step.
Implement the dynamic logic 'Custom Function' as follows:
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
import java.text.SimpleDateFormat
import javax.ws.rs.core.Response;
def q = "code.eq('" +
properties.get("providerCode") + "')"
Response providers = webTarget("capitation")
.path("generic").path("organizationproviders")
.queryParam("q", q)
.request()
.header("Accept", "application/json;expand=all")
.buildGet()
.invoke()
if (providers.status == 200) {
(new JsonSlurper()
.parseText(providers.readEntity(String.class)))
.items.each { item ->
def serviceCode = properties.get("serviceCode")
def qualifier = properties.get("qualifier")
def referenceDate = properties.get("referenceDate")
def capitatedServicesFiltered = item.capitatedServices.find {
it.code == serviceCode && it.qualifier == qualifier && dateBetween(it, referenceDate) == true
}
if (capitatedServicesFiltered != null) {
exchangeStep.addLogEntry("Service is capitated.")
properties.put("result", 'Service is capitated.')
return "Service is capitated"
} else {
exchangeStep.addLogEntry("Service is not capitated.")
properties.put("result", 'Service is not capitated.')
return "Service is not capitated"
}
}
}
def dateBetween(it, referenceDate) {
def pattern = "yyyy-MM-dd"
if (it.endDate == null) {
return referenceDate >= it.startDate
} else {
return referenceDate >= it.startDate && referenceDate <= it.endDate
}
}
return ""
The integration is configured by sending in the following payload to /integrations generic api
{
"code": "PROVIDER_SERVICE_CHECK",
"type": "integration",
"descr": "PROVIDER_SERVICE_CHECK",
"integrationSteps": [
{
"code": "PROVIDER_SERVICE_CHECK",
"sequence": 1,
"subtype":"CUSTOM",
"outputName":"PROVIDER_SERVICE_CHECK",
"destination": {
"code": "capitation"
},
"typeConfig": {"customFunctionCode" :"PROVIDER_SERVICE_CHECK"}
}
]
}
For a blocking call, this integration must be invoked with the following HTTP Headers
Description | |
---|---|
ohi-exchange-allowed-time-ms |
The maximum allowed time in milliseconds a client is willing to wait for the exchange to complete. Typically in the order of magnitude of 1 to 5 seconds. |
ohi-exchange-execute-blocking |
true |