File Upload
Oracle Insurance Gateway supports uploading of files to OHI application. This essential means read a file, transform the file contents to OHI format, and deliver it to OHI application. This file upload feature can be used to maintain configuration or operational data within OHI applications by setting up integrations which in turn make use of OHI Application capabilities, like
1) Generic API e.g. POST/PUT/PATCH on a resource,
2) Activity based File Import feature.
3) Specific IPs e.g. Group client IP, Claims In IP.
To get an idea on the possibilities around Integration use cases, consider the following use cases
-
Enrollment product upload - In this example, a record delimited file gets read and gets transformed to JSON request(s). Through Generic API POST/PUT on /enrollmentproducts resource enrollment products can be created or updated in OHI Enterprise Policy Administration application. For this use case, a TRANSFORM step is used to read the file, and send a POST or PUT request to create /update enrollment products
NOTE:This is not recommended for high volume files.
-
Provider upload - In this example data, a record delimited file gets read and gets transformed to OHI specific XML file. The XML file is then uploaded as a data file to the OHI Claims Adjudication and Pricing application. As a next step, Activity Provider Import gets triggered to process the providers in the OHI Claims Adjudication application. This use case can be implemented by having a TRANSFORM step followed by an ACTIVITY step
-
Group upload - In this example data is read from a CSV file and is transformed into a Group Configuration integration point JSON request. Using the Group Configuration integration point, the group client, and group accounts are created in the OHI Enterprise Policy Administration application. This use case can be implemented by having a TRANSFORM step
The Oracle Insurance Gateway configuration for all the examples in this chapter is shown using API/IPs. The same is also possible using Oracle Insurance Gateway user interface.
The examples below assume that the reader is familiar with OHI applications integration capabilities (especially HTTP API/IP concepts). For details refer to chapters on HTTP API/IP concepts in the Integration Guide.
The examples uses transformation dynamic logic to transform the file data into format as needed by OHI applications. For more details on transformation possibilities refer to chapter Transformation Dynamic Logic in the guide
Enrollment product upload
The first step is to identify the Destinations. Here, OHI Enterprise Policy Administration is the interfacing application with Oracle Insurance Gateway application. Oracle Insurance Gateway needs to invoke methods POST/PUT on /enrollmentproducts generic API to create or update enrollment products in OHI Enterprise Policy Administration. Therefore, for this use case a REST destination to communicate with OHI Enterprise Policy Administration must be set up.
Configure the rest destination "policies" as follows:
Fields | Configuration | Remarks | ||
---|---|---|---|---|
code |
policies |
|||
credentialKey |
policy_user |
The following must be done to set up credential key "policy_user"
Example: To setup credential key "policy_user" using Credential IP the following must be done PUT: http(s)://{host:port}/{oig application context}/credentials/credential/policy_user with payload
Example: To set up authentication using Generic API - /properties (assuming the polices application uses basic authentication) the following must be done POST : http(s)://{host:port}/{oig application context}/generic/properties with payload
|
||
addressKey |
address.key.policies.baseurl |
The address key can be setup using Generic API /properties or properties page Example : 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} |
The path and http method are parameterized (recommended). This way a single rest destination can be used by multiple integrations with the policies application. Note: for the given use case, the path and http method configuration will be driven by the 'Callout' rule. See dynamic logic below for clarification. |
An example of the JSON payload for the creation of polices destination using API /restdestinations is given below.
{
"code": "policies",
"credentialKey": "policy_user",
"addressKey": "address.key.policies.baseurl",
"destinationType": "REST",
"typeConfig": {
"path": "{path}",
"httpMethod": "{httpMethod}"
}
}
The next step is to setup the dynamic logic - Data Transformation Payload.
Suppose, if the file that needs to be uploaded has the following structure:
CODE;NAME;PLAN_NUMBER;AMT_DIST;PPR
DENTAL;Dental;DENTAL_BASIC,D,D
PPO;PPO;PPO_BASIC,D,D
then the logic would look something like
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
import org.apache.commons.csv.*
import javax.ws.rs.core.Response;
trigger.dataFiles.each {
df ->
char delimiter = ';'
def csvParsers = fileReader.csvParser(df, CSVFormat.DEFAULT.withFirstRecordAsHeader().withIgnoreHeaderCase().withTrim().withDelimiter(delimiter))
csvParsers.each { csvRecord ->
def jsonBuilder = new JsonBuilder()
def enrollmentProduct = new JsonBuilder()
def enrollmentProductexists = false
String enrollmentProductID = ""
def q = "code.eq('" + csvRecord['CODE'] + "')"
Response enrollmentProductResponse = webTarget("policies")
.path("generic").path("enrollmentproducts")
.queryParam("q", q)
.request()
.header("Accept", "application/json")
.buildGet()
.invoke()
if (enrollmentProductResponse.status == 200) {
enrollmentProductID = (new JsonSlurper()
.parseText(enrollmentProductResponse.readEntity(String.class)))
.items[0].id
enrollmentProductexists = true;
}
def products = new ArrayList()
def product = {
product {
code csvRecord['PLAN_NUMBER']
}
}
products.add(product)
enrollmentProduct {
amountDistribution csvRecord['AMT_DIST']
descr csvRecord['NAME']
code csvRecord['CODE']
displayName csvRecord['NAME']
partialPeriodResolution csvRecord['PPR']
lineOfBusiness {
code "HEALTH_INSURANCE"
}
currencyParameter {
code "USD"
}
currencyPremium {
code "USD"
}
enrollmentProductDetailList(jsonBuilder.call(products))
}
if (enrollmentProductexists) {
enrollmentUploadResponseSt = webTarget("policies")
.path('generic').path('enrollmentproducts').path(enrollmentProductID)
.request()
.header("Accept", "application/json")
.buildPut(Entity.json(enrollmentProduct.toString()))
.invoke()
.readEntity(String.class);
} else {
enrollmentUploadResponseSt = webTarget("policies")
.path('generic').path('enrollmentproducts')
.request()
.header("Accept", "application/json")
.buildPost(Entity.json(enrollmentProduct.toString()))
.invoke()
.readEntity(String.class);
}
exchangeStep.addLogEntry("Enrollment Product Created/Updated: "
+ new JsonSlurper().parseText(enrollmentUploadResponseSt).code)
}
}
The dynamic logic can be created by sending in POST request on /generic/dynamiclogic (generic resource)
{
"code": "enrollmentProductFileupload",
"active": true,
"descr": "Enrollment Product Upload",
"subtype": "FUNC",
"logic": " groovy logic",
"signature": {
"name": "Data Transformation Payload"
}
}
The next step is to create an Integration using the building blocks mentioned above. This is done by sending the following request using POST Method to Generic API resource /integrations.
{
"code": "enrollmentProductFileupload",
"type": "integration",
"descr": "Enrollment Product Upload",
"integrationSteps": [
{
"code": "enrollmentProductFileupload",
"sequence": 1,
"subtype":"TRANSFORM",
"outputName":"enrollmentProductFileupload",
"functionTransformation": {
"code" :"enrollmentProductFileupload"
}
}
]
}
Exchange Integration Point - With the File option can be used to invoke this integration. The image below shows integration invocation using a REST client.

Provider Upload
In this use case, Oracle Insurance Gateway needs to communicate with OHI Claims Adjudication application for two things 1) update data file and 2) invoke provider import activity. Oracle Insurance Gateway provides out of the box capability to upload data files to OHI applications. This mechanism gets triggered when the system sees the delivery destination is of type 'FILEUPLOAD'. For this use case two destinations must be set up 1) FILEUPLOAD destination 'claims_fileUpload' and 2) REST destination 'claims'
The FILEUPLOAD destination "claims_fileUpload" is configured as :
Fields | Configuration | Remarks | ||
---|---|---|---|---|
code |
claims_fileUpload |
|||
credentialKey |
claims_user |
The following must be done to set up credential key "claims_user" __Step 1: Create credential using credential IP or Credential Page __ Example: To setup credential key "claims_user" using Credential IP the following must be done PUT: http(s)://{host:port}/{oig application context}/credentials/credential/claims_user with payload
Step 2: Set the authentication mechanism using generic api - properties or using property configuration page Example: To set up authentication using Generic API - /properties (assuming the polices application uses basic authentication) the following must be done POST : http(s)://{host:port}/{oig application context}/generic/properties with payload
|
||
addressKey |
address.key.claims.baseurl |
The address key can be setup using generic api /properties or properties page Example : 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 |
FILEUPLOAD |
The configuration of the rest destination "claims" is similar to "policies" rest destination
The next step is to configure dynamic logic to transform CSV file to OHI provider XML structure. Suppose, if the file that needs to be uploaded has the following structure:
Provider No;Therapy Code;Commencement Date;Suspended date;Expelled Date;Surname;First Name;Second Name;Title;Address Line 1;[..more columns..]
T38407R;REM;15-3-2019;;;-;Jane;;Ms;unit 10/112 Wellington Street;;;SUBIACO;WA;6155;0422 866 212;0422 221 676;X
AW03812R;REM;13-3-2019;14-3-2019;;ABBOTT;Bryan;;Mr;Suite 801, Level 2, 151;Carlton Street;;NEWCITY;NSW;2000;02 9264 3321;0431 443 950;
then the dynamic logic "providerFile_transform" would look something like:
import org.apache.commons.csv.*
import javax.ws.rs.core.Response
import groovy.json.JsonSlurper
import groovy.xml.StreamingMarkupBuilder
// Note: this example assumes a single datafile in a set
trigger.dataFiles.each { df ->
// define the CSV structure that is capable of parsing the csv input
char delimiter = ';'
def csvParser = fileReader.csvParser(df, CSVFormat.DEFAULT
.withFirstRecordAsHeader()
.withIgnoreHeaderCase()
.withTrim()
.withDelimiter(delimiter))
// this closure defines the XML payload
def individualProvidersXML = { xml ->
individualProviders {
csvParser.each { csvRecord ->
// variables that we will be reusing
incomingProviderCode = csvRecord['Provider No']
startDate = formatDate(csvRecord['Commencement Date'])
endDate = formatDate(csvRecord['Suspended date'])
// get existing subscriptionRecords
// maybe add accept header too for dynamic data
Response providerResponse = webTarget("claims")
.path('generic')..path("generic")
.path("individualproviders")
.queryParam("q", "code.eq('${incomingProviderCode}')")
.request()
.accept("application/json;expand=all")
.get()
def existingSubscriptions = []
if (providerResponse.status == 200) {
existProvider = new JsonSlurper().parseText(providerResponse.readEntity(String.class))
existingSubscriptions = existProvider.items[0].subscriptions
}
// xml element for the individual provider
individualProvider(
code: incomingProviderCode,
flexCodeDefinitionCode: "PROVIDER",
startDate: startDate,
endDate: endDate,
titleCode: csvRecord['Title'],
name: csvRecord['Surname'],
firstName: csvRecord['First Name'],
outputLanguageCode: "en",
nameFormatCode: "NAFMDFLTPROV"
) {
renderingAddressList {
renderingAddress(startDate: startDate) {
serviceAddress(
street: csvRecord['Address Line 1']?.toUpperCase(),
city: csvRecord['City/Suburb'],
postalCode: csvRecord['Postcode'],
countryCode: "US",
countryRegionCode: "RI",
phoneNumberBusiness: csvRecord['Phone Number']
)
}
}
subscriptions {
existingSubscriptions.each { s ->
record(commencementDate: s['commencementDate'],
suspendedDate: s['suspendedDate'],
expelledDate: s['expelledDate']
)
}
record(commencementDate: startDate,
suspendedDate: endDate,
expelledDate: formatDate(csvRecord['Expelled Date'])
)
}
}
}
}
}
def builder = new StreamingMarkupBuilder()
builder.encoding = "UTF-8"
outputWriter << builder.bind(individualProvidersXML)
}
// formats the dateString to a regular date, or returns null/empty string
String formatDate(String dateString) {
if (dateString?.trim()) {
return Date.parse("dd-MM-yyyy", dateString).format("yyyy-MM-dd")
} else {
return dateString
}
}
In the dynamic logic, a check is made to lookup for the provider in the OHI application. If the provider exits with the specified 'Provider No' in the OHI application then the dynamic record subscriptionRecords is updated with additional details from the file. Everything else is overwritten by the information from the file.
Depending on the use case at hand, various possibilities can be realized by making appropriate changes to the dynamic logic, to name a few 1)Overwrite completely with the details from file 2)Overwrite select few (as shown in the example), and 3)No overwrites, only add if missing and so on.
The next step is to create an Integration using the building blocks mentioned above. This is done by sending the following request using POST Method to Generic API resource /integrations.
{
"code": "provider_import_invocation",
"type": "integration",
"descr": "Provider Import Invocation With Notification",
"integrationSteps": [
{
"code": "file_upload_step",
"sequence": 1,
"subtype": "DELIVERY",
"destination": {
"code": "claims_fileUPload"
},
"functionTransformation": {
"code": "providerFile_transform"
}
},
{
"code": "invoke_provider_import",
"sequence": 2,
"subtype": "ACTIVITY",
"indicatorExpectNotification": "true",
"outputName": "invoke_provider_import",
"typeConfig": {
"code": "PROVIDER_IMPORT",
"level": "GL",
"description": "Provider Import",
"parameters": [
{
"name": "dataFileSetCode",
"value": "{dataFileSetCode}"
},
{
"name": "responseDataFileSetCode",
"value": "{responseDataFileSetCode}"
}
]
},
"destination": {
"code": "claims"
}
}
]
}
Here, indicatorExpectNotification is set to true, this would put the exchange into waiting mode, until the activity concludes and informs OHI Oracle Insurance Gateway that the import is successful or not.
Additional configuration is needed for OHI Claims Adjudication and Pricing to come back with the notification to Oracle Insurance Gateway. To do this, the system property ohi.activityprocessing.notification.endpoint.PROVIDER_IMPORT in OHI Claims Adjudication must be set to the notification endpoint in Oracle Insurance Gateway - "http(s)://{host:port}/{oig application context}/notification.
Also, in OHI Claims Adjudication and Pricing application, the credential and authentication property must be set for the key "PROVIDER_IMPORT". This is similar to the setting of credential and authentication for the key policies_user as explained in the enrollment product upload example
Another thing to note here is, that, this example uses bind parameters for dataFileSetCode and responseDataFileSetCode. The value for these is provided by exchange properties. In the configuration of any step, the exchange properties can be used as bind parameters. For more details on properties, refer to Gateway Dynamic Logic Bindings
Exchange property by the name 'dataFileSetCode' is set by the system when a delivery step in combination to destination type file upload is used to upload a file in OHI application. The value of the property is set to the data file set code under which the file is uploaded by the system to the OHI application.
Value for 'description' and 'responseDataFileSetCode' can either be 1) input parameters at the time of invocation or 2) properties added in the dynamic logic function post process of the DELIVERY step.
Exchange Integration Point - With the File option can be used to invoke this integration.
Group Upload
The group upload is similar to enrollment product upload, here the group file gets transformed using transformation dynamic logic to Group Configuration IP JSON request format. Using the webTarget predefined method the request can be sent to Group Configuration IP endpoint.
String groupRS = webTarget("policies")
.path('groupclients')
.request()
.header("Accept", "application/json")
.buildPut(Entity.json(groupReq.toString()))
.invoke()
.readEntity(String.class);
// groupReq holds the OHI JSON format as specified by the group configuration IP