iComposer & AI
iComposer
iComposer Language Ref Example
Sidebar On this page

Table of Contents

Utility classes:

Specifications:

For method tables, see iComposer Language Reference.

Introduction

This document serves as an in-depth guide to the iComposer language and provides detailed explanations and code examples for the customization methods and utility classes introduced in the iComposer Language Reference Summary. It is designed to assist developers in understanding and effectively utilizing the powerful features of the iComposer language to streamline development on the InsureMO platform. The comprehensive examples demonstrate how to implement various functionalities, including handling API calls, processing data, and managing transactions. Whether you are a beginner or an experienced developer, this guide aims to enhance your proficiency in using the iComposer language.

Basic Code Structure

A Sample RESTful API Script

Below are key features for a sample RESTful API:

  • Endpoint Limitation: A single RESTful API should expose only one endpoint and serve as the starting point for execution.
  • Service Invocation: For better code usage, it may invoke other service functions or APIs.
  • Code Clarity: All code must be written plainly without method encapsulation.
  • Request Handling: Only RESTful APIs can return results as API responses.

Below is a sample script for a typical restful API implementation:

//Define Platform Static Method (3)
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import com.insuremo.icomposer.builtins.methods.IComposerSystem;
import com.insuremo.icomposer.utils.IComposerGlobalTxContext;
import com.insuremo.icomposer.utils.IComposerAppContext;

ProposalCalculate proposalCalculate = (ProposalCalculate) getCommonService("ProposalCalculate"); //Define Tenant Service Function (7)
ProposalCreateOrSave proposalCreateOrSave = (ProposalCreateOrSave) getCommonService("ProposalCreateOrSave");
AuthorityService authorityService = (AuthorityService) getCommonService("AuthorityService");
PartyService partyService = (PartyService) getCommonService("PartyService");
BinderService binderServiceImpl = (BinderService) getCommonService("BinderService");
GroupPolicyHelper groupPolicyHelper = (GroupPolicyHelper) getCommonService("GroupPolicyHelper");

Map policyInfo = (Map) IComposerSystem.getRequestBody(); //Get API Request Body (1)

//start TCC global transaction
IComposerGlobalTxContext.beginGlobalTx(IComposerAppContext.getTenantCode() + "-wfCalculate")//Call Platform API (6)

partyService.validatePolicyBranchAuth(policyInfo); //Call Tenant Service Function (8)

Boolean groupPolicyFlag = groupPolicyHelper.isGroupPolicy(policyInfo)

if (StringUtils.isNotBlank(MapUtils.getString(policyInfo, "BinderArrNo"))) { //Use Platform Static Method (4)
Map mapValidate = binderServiceImpl.validateCoversInBinder(policyInfo);
if (!mapValidate.get("BinderCTStatus").equals("Success")) {
return mapValidate; //Return API Response Body (2)
}
}

if (groupPolicyFlag == true) {
policyInfo = proposalCreateOrSave.createOrSave(policyInfo);
Long jobId = proposalCalculate.recalculateGroupPolicyBatch(policyInfo);
Map map = new HashMap();
map.put("jobId", jobId);
return map

} else {
policyInfo = proposalCalculate.calculate(policyInfo);
policyInfo = proposalCreateOrSave.createOrSave(policyInfo);
return policyInfo;
}

A Sample Service Function Script

A service function supports all method invocation structures and also be organized to have multiple implementation methods to improve business logic and group them. It’s designed for reusability and cannot be directly executed except via a test UI.

Service functions consist of two code parts:

  • Imports, Variables, or Service Function Invocations: These should always be defined at the top of the file, outside of any methods.
  • Implementation Code: This should always be encapsulated within different methods.

However, in service function, for places outside any of the method, users can only do definition operation such as import or declare variable.

Below is a sample script for a typical service function implementation:

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.collections4.MapUtils;
import com.insuremo.sdk.services.batch.BatchSdkClient;
import com.insuremo.sdk.services.proposal.ProposalSdkClient;
import com.insuremo.sdk.services.batch.model.BatchExecutionBase;

BatchSdkClient batchSdkClient = (BatchSdkClient) getSDK("com.insuremo.sdk.services.batch.BatchSdkClient");
ProposalSdkClient proposalSdkClient = (ProposalSdkClient) getSDK("com.insuremo.sdk.services.proposal.ProposalSdkClient");

PolicyConstants policyConstants = (PolicyConstants) getCommonService("PolicyConstants");
GroupPolicyHelper groupPolicyHelper = (GroupPolicyHelper) getCommonService("GroupPolicyHelper");
IsoRatingService peRatingService = (IsoRatingService) getCommonService("IsoRatingService");
BinderService binderServiceImpl = (BinderService) getCommonService("BinderService");
ExcelRatingService excelRatingService = (ExcelRatingService) getCommonService("ExcelRatingService");

/*
Service Function - Method 1
*/
def Map calculate(Map policyInfo) {

Boolean groupPolicyFlag = groupPolicyHelper.isGroupPolicy(policyInfo)

if (groupPolicyFlag == true) {
groupPolicyHelper.preCheckOperation(MapUtils.getString(policyInfo, policyConstants.getPolicyConstants("PROPOSAL_NO")));
}

String productCode = policyInfo.get("ProductCode") != null ? policyInfo.get("ProductCode").toString() : "";
Map result = com.google.common.collect.Maps.newHashMap();

if ((productCode.indexOf("ISO_") != -1) || (productCode.indexOf("X_") != -1)) {
if (productCode.indexOf("EXL") != -1) {
debug("invoking Excel Rater service for calculation..");
policyInfo = excelRatingService.excelCalculate(policyInfo);
} else {
debug("invoking pe service for calculation..");
policyInfo = peRatingService.calculate(policyInfo);
}
}

policyInfo = proposalSdkClient.proposalApi().newAttachElementRequestBuilder().eventCode("AttachElement4Proposal").requestBody(policyInfo).doRequest().getBody();
policyInfo = proposalSdkClient.proposalApi().newCalculateRequestBuilder().requestBody(policyInfo).doRequest().getBody();
policyInfo = proposalSdkClient.proposalApi().newGenerateClauseContentRequestBuilder().requestBody(policyInfo).doRequest().getBody();

if (StringUtils.isNotBlank(MapUtils.getString(policyInfo, "BinderArrNo"))) {
policyInfo = binderServiceImpl.getPremiumAndCTValidate(policyInfo);
} else {
if (policyInfo.containsKey("BinderArrNo")) {
policyInfo.remove("BinderArrNo");
}
if (policyInfo.containsKey("BinderGroupList")) {
policyInfo.remove("BinderGroupList");
}
}
return policyInfo
}

/*
Service Function - Method 2
*/
def Long recalculateGroupPolicyBatch(Map policyInfo) {

Long policyId = MapUtils.getLong(policyInfo, policyConstants.getPolicyConstants("POLICY_ID"));
Map<String, Object> batchParams = new HashMap <> ();
batchParams.put("targetPolicyId", policyId);

BatchExecutionBase batchExecutionBase = batchSdkClient.batchRuntimeApi().newSubmitJobWithBusinessKeyRequestBuilder().jobBindBusinessKey(MapUtils.getString(policyInfo, policyConstants.getPolicyConstants("PROPOSAL_NO"))).jobName("groupPolicyRecalculateBatch").requestBody(batchParams).doRequest().getBody();

Long jobExecutionId = batchExecutionBase.getJobExecutionId();

debug(" trigger groupPolicyRecalculateBatch result,jobExecutionId:{}", jobExecutionId);
return jobExecutionId;
}

Customization Methods

The IComposerSystem class provides a suite of custom methods designed to streamline access to request and response data and facilitate the invocation of common services and SDKs. These methods enable developers to efficiently obtain information from HTTP requests, call service functions, utilize SDKs, and manage logs.

Retrieve Request Data

In iComposer, data transmission in the request body is done using the JSON format. Given the variety of JSON formats, the corresponding processing methods vary as well. Specifically, a JSON object that begins and ends with {} is identified as a Map, while a JSON array that starts and ends with [] is recognized as a List. To access the request body, the IComposerSystem.getRequestBody() method is employed, which parses the JSON data into the appropriate data structures. This chapter will introduce how to handle data in different JSON formats and provide examples for each scenario.

JSON Array ([])

If the JSON starts and ends with [], iComposer will recognize it as a List.

Simple List

Request BodyScript Code

[
“Alice”,
“Allen”,
“Cherry”
]

import com.insuremo.icomposer.builtins.methods.IComposerSystem
List requestStr = (List) IComposerSystem.getRequestBody()
info(“requestStrClass : {}”, requestStr.getClass())

Test Log:

requestStrClass : class java.util.ArrayList

List of Maps

Request BodyScript Code

[
{“name”:“Alice”,“age”:25,“gender”:“F”},
{“name”:“Allen”,“age”:30,“gender”:“M”}
]

import com.insuremo.icomposer.builtins.methods.IComposerSystem
List requestTemp = (List) IComposerSystem.getRequestBody()
requestTemp.each { item ->
info(“name : {}”, item.get(“name”))
}

Test Log:

name : Alice
name : Allen

JSON Object ({})

If the JSON starts and ends with {}, iComposer will recognize it as a Map.

Simple Map

Request BodyScript Code

{
“name”: “Alice”,
“age”: 25,
“gender”: “F”
}

import com.insuremo.icomposer.builtins.methods.IComposerSystem
Map requestStr = (Map) IComposerSystem.getRequestBody()
info(“requestStrClass : {}”, requestStr.getClass())

Test Log:

requestStrClass : class java.util.LinkedHashMap

Nested Map

Request BodyScript Code

{
“name”: “Alice”,
“age”: 25,
“gender”: “F”,
“address”: {
“street”: “123 Maple Street”,
“apartment”: “Apt. 4B”,
“city”: “Springfield”,
“state”: “IL”,
“postalCode”: “62704”,
“country”: “United States”
}
}

import com.insuremo.icomposer.builtins.methods.IComposerSystem
def requestTemp = (Map) IComposerSystem.getRequestBody()
info(“name : {}”, requestTemp.get(“name”))

def address = (Map) requestTemp.get(“address”)
info(“Country : {}”, address.get(“country”))

Test Log:

name : Alice
Country : United States

Map with List

Request BodyScript Code

{
“employees”: [
{“name”:“Alice”,“age”:25,“gender”:“F”},
{“name”:“Jason”,“age”:30,“gender”:“M”}
]
}

import com.insuremo.icomposer.builtins.methods.IComposerSystem
def requestTemp = (Map) IComposerSystem.getRequestBody()
def employees = (List) requestTemp.get(“employees”)

employees.each { item ->
info(“name : {}”, item.get(“name”))
}

Test Log:

name : Alice
name : Jason

Map with Nested List

Request BodyScript Code

{
“order”: {
“order_id”: “12345”,
“date”: “2024-04-01T12:00:00Z”,
“items”: [
{“product_id”: “A001”,“name”: “Widget”,“quantity”: 2,“price”: 19.99},
{“product_id”: “A002”,“name”: “Gadget”,“quantity”: 1,“price”: 29.99}
],
“total”: 69.97
}
}

import com.insuremo.icomposer.builtins.methods.IComposerSystem
def requestTemp = (Map) IComposerSystem.getRequestBody()
def order = (Map) requestTemp.get(“order”)

info(“date : {}”, order.get(“date”))
info(“total : {}”, order.get(“total”))

def items = (List) order.get(“items”)

items.each { item ->
info(“name : {}”, item.get(“name”))
info(“quantity : {}”, item.get(“quantity”))
info(“price : {}”, item.get(“price”))
}

Test Log:

date : 2024-04-01T12:00:00Z
total : 69.97
name : Widget
quantity : 2
price : 19.99
name : Gadget
quantity : 1
price : 29.99

Retrieve Request Parameter

Obtain the request parameter from ServletHttpRequest for a POST/GET API.

import com.insuremo.icomposer.builtins.methods.IComposerSystem;

def requestParameter = (Map<Object,Object>)IComposerSystem.getRequestParameter();

Return API Response

return xxx

Call Service Function (Common Service)

Acquire the function of iComposer with the function name.

import com.insuremo.icomposer.builtins.methods.IComposerSystem;

Map policyInfo = (Map)IComposerSystem.getRequestBody()
EmailService emailService = (EmailService)IComposerSystem.getCommonService("EmailService");
emailService.prepareEmail(policyInfo)

Call InsureMO SDK

Below is an example to demonstrate the use of the Collection API of BcpSdkClient in iComposer.

  1. Initialize the BCP SDK Obtain an instance of the BcpSdkClient using the getSDK method.

    import com.insuremo.sdk.services.bcp.BcpSdkClient;

    BcpSdkClient bcpRestfulSDK = (BcpSdkClient) getSDK("com.insuremo.sdk.services.bcp.BcpSdkClient");
  2. Invoke the collectionForm Method Call the collectionForm method through the bcpRestfulSDK instance.

    import com.insuremo.sdk.services.bcp.BcpSdkClient;
    import com.insuremo.sdk.services.bcp.model.CollectionForm;

    BcpSdkClient bcpRestfulSDK = (BcpSdkClient) getSDK("com.insuremo.sdk.services.bcp.BcpSdkClient");
    CollectionForm collectionFormResponse = bcpRestfulSDK.collectionApi()
    .newCollectionApplicationRequestBuilder()
    .collectionForm(new CollectionForm())
    .doRequest()
    .getBody();
  3. Handling the collectionForm Parameter The collectionForm parameter required in the processing method is handled similarly to the V1 SDK. If the data passed in the Request Body matches the format of the CollectionForm, the complete code is as follows:

    Request Body:

    {
    "Collection": {
    "detailList": [
    {
    "@type": "BcpCollectionDetail-CollectionDetail",
    "amount": 1004.4,
    "currencyCode": "USD",
    "bookingCurrencyCode": "USD",
    "localCurrencyCode": "USD"
    }
    ],
    "@type": "BcpCollection-Collection",
    "amount": 1004.4,
    "branchCode": "10006",
    "currencyCode": "USD",
    "bookingCurrencyCode": "USD",
    "localCurrencyCode": "USD",
    "paymentMethod": "100",
    "payerPayeeName": "PolicyCollection"
    },
    "arapList": [
    {
    "@Type": "BcpArap-Arap",
    "ArapId": "10991127910,74B78C5CF6F02D5BBCC499B3C470FBAF",
    "IsOffsetByCommission": "N",
    "OffsetByCommissionAmount": 93
    }
    ]
    }

    Script Code:

    import com.insuremo.sdk.services.bcp.BcpSdkClient;
    import com.insuremo.sdk.services.bcp.model.CollectionForm;
    import com.insuremo.icomposer.utils.IComposerJsonUtils;
    import com.insuremo.icomposer.builtins.methods.IComposerSystem;

    BcpSdkClient bcpRestfulSDK = (BcpSdkClient) getSDK("com.insuremo.sdk.services.bcp.BcpSdkClient");
    CollectionForm collectionForm = IComposerJsonUtils.fromJSON(IComposerJsonUtils.toJSON(IComposerSystem.getRequestBody()), CollectionForm.class);
    CollectionForm collectionFormResponse = bcpRestfulSDK.collectionApi()
    .newCollectionApplicationRequestBuilder()
    .collectionForm(collectionForm)
    .doRequest()
    .getBody();
import com.insuremo.icomposer.builtins.methods.IComposerSystem;

String variable1= "xxxxxx"
String variable2= "xxxxxx"
IComposerSystem.println ("values:{} {}", variable1,variable2) //print log(for development debug), output logs on the online test UI without log4j.
IComposerSystem.debug ("values:{} {}", variable1,variable2) //debug log(useful log for runtime debug), output debug logs using log4j.
IComposerSystem.info ("values:{} {}", variable1,variable2) //info log(critical log for runtime debug), output info logs using log4j.

getUploadFiles()

Obtain the request files from ServletHttpRequest.

import com.insuremo.icomposer.builtins.methods.IComposerSystem;
import com.insuremo.sdk.services.claimconfiguration.model.ClaimResponse;
import com.insuremo.sdk.core.model.MOInputStream;
import org.springframework.web.multipart.MultipartFile;
import com.insuremo.sdk.services.claimconfiguration.ClaimconfigurationSdkClient;

def claimconfigurationSdkClient = (ClaimconfigurationSdkClient)IComposerSystem.getSDK("com.insuremo.sdk.services.claimconfiguration.ClaimconfigurationSdkClient");
List<MultipartFile> files = IComposerSystem.getUploadFiles();
info("files = {}", files);
MOInputStream requestFile;
for (MultipartFile file : files) {
requestFile = new MOInputStream(file.getInputStream());
requestFile.withFilename(file.getOriginalFilename());
requestFile.withContentType(file.getContentType());
info("requestFile = {}", requestFile);
}

ClaimResponse claimResponse = claimconfigurationSdkClient.blackListApi().newUploadBlacklistFileRequestBuilder().files(requestFile).doRequest().getBody();

return claimResponse

getICmpHttpServletRequest()

Acquire any specific request header from ServletHttpRequest.

import com.insuremo.icomposer.builtins.methods.IComposerSystem;

def httpServletRequest = IComposerSystem.getICmpHttpServletRequest();
String token = httpServletRequest.getHeader("Authorization");
debug("token={}", token);

getICmpHttpServletResponse()

Manage response and response header from ServletHttpResponse, facilitating efficient file export and stream outputs.

import java.time.format.DateTimeFormatter;
import com.insuremo.icomposer.builtins.methods.IComposerSystem;
import com.insuremo.sdk.core.client.ResponseTransformer;
import com.insuremo.icomposer.utils.IComposerDateContext;
import com.insuremo.sdk.services.proposal.ProposalSdkClient;

ProposalSdkClient proposalSdkClient = (ProposalSdkClient)IComposerSystem.getSDK("com.insuremo.sdk.services.proposal.ProposalSdkClient");
Map paramMap = (Map)IComposerSystem.getRequestBody();

def nowLocalTime = IComposerDateContext.getLocalDateTimeForCurrentUser();
def now_yyyyMMddHHmmss = IComposerDateContext.getLocalDateTimeForCurrentUser().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
String fileName = "Policy"+now_yyyyMMddHHmmss+".xls";

proposalSdkClient.proposalApi().newExportPolicyRequestBuilder().requestBody(paramMap).doRequest(ResponseTransformer.toOutputStream(IComposerSystem.getICmpHttpServletResponse().getOutputStream()))

IComposerSystem.getICmpHttpServletResponse().setContentType("application/octet-stream");
IComposerSystem.getICmpHttpServletResponse().setHeader("Content-Disposition", "attachment;filename="+fileName);

Utility Classes

The iComposer developer utility classes offer a comprehensive suite of powerful tools covering key development areas such as data processing, application context management, file operations, and API calls. These classes are designed to streamline development by providing ready-to-use implementations, which solve common programming challenges and reduce repetitive code.

Utilities via UI

You can easily discover and explore available utility classes directly within the iComposer UI using the SDK AI Assistant:

  1. Open API Editor - Navigate to any API script editor
  2. Click SDK AI Assistant - Find the SDK AI Assistant link in the editor toolbar
  3. Select Utility Table - Choose “Utility Table” from the assistant menu
  4. Browse Available Utilities - A comprehensive list of all supported utility classes will be displayed
  5. Get Sample Code - Click the small rocket icon (🚀) next to any utility to instantly generate sample code snippets
Utility Query Steps Utility Query Steps Utility Query Steps

Utility Reference

This section serves as a supplementary reference to the UI-based samples. For the most up-to-date and comprehensive method references with live code examples, please use the SDK AI Assistant’s Utility Table.

IComposerDbDataUtils

note

For tenants already using IComposerDataService or IComposerDbDataUtils, we recommend continuing with IComposerDbDataUtils.

IComposerDbDataUtils class is a service designed to handle the dynamic storage data of IComposer. It offers interfaces to interact with the database table t_icmp_entity_data, enabling efficient reading and writing of various data formats. By leveraging the indexes defined in the table (unique indexes and regular indexes), this service optimizes query performance and serves as a core component for developing applications that rely on IComposer’s dynamic storage capabilities.

The following is a partial screenshot of the database table structure, along with explanations of some important fields in the dynamic table, to help users better understand how dynamic storage is implemented.

FieldDescription
Entity_NameFor business definitions in EntityData, such as email sending log “EmailSendLog” and printing log “PrintLog”
Entity_DataRecord specific business definitions, such as logging a print log.
Example: { "TransactionDate": "2025-01-14 10:25", "PrintStatus": "PrintedSuccessfully", "FailureMessage": "", "Operator": "TestUser", "Template": "defaultTemplate" }
Index_Value(1~10)1 to 10 indexes can be defined based on the data in Entity_Data.
Unique_Index_Value(1~10)1 to 10 unique indexes can be defined based on the data in Entity_Data.
icomposer_Database icomposer_Database
Method NameDescription
IComposerEntityVo insert(IComposerEntityVo vo)Inserts a new entity using the default table
IComposerEntityVo update(IComposerEntityVo vo)Updates an existing entity using the default table
void deleteById(Long id)Deletes an entity by its ID using the default table
void deleteByVo(IComposerEntityVo vo)Deletes entities matching the given condition using the default table
List<IComposerEntityVo> findListByIndexes(IComposerEntityVo vo)Finds a list of entities based on index fields using the default table
IComposerEntityVo findByIndexes(IComposerEntityVo vo)Finds a single entity based on index fields using the default table
IComposerEntityData getEntityByIndexes(IComposerEntityVo vo)Gets entity data based on index fields using the default table
List<IComposerEntityData> findAllArchiveData(LocalDateTime archiveTimeFrom, Long recordId, int maxRecords)Finds all archived data within the specified time range and record ID
IComposerEntityVo insert(IComposerTablesEnum table, IComposerEntityVo vo)Inserts a new entity into the specified table
IComposerEntityVo update(IComposerTablesEnum table, IComposerEntityVo vo)Updates an existing entity in the specified table
void deleteById(IComposerTablesEnum table, Long id)Deletes an entity by its ID from the specified table
void deleteByVo(IComposerTablesEnum table, IComposerEntityVo vo)Deletes entities matching the given condition from the specified table
List<IComposerEntityVo> findListByIndexes(IComposerTablesEnum table, IComposerEntityVo vo)Finds a list of entities based on index fields from the specified table
IComposerEntityVo findByIndexes(IComposerTablesEnum table, IComposerEntityVo vo)Finds a single entity based on index fields from the specified table
<T extends BaseEntity> T getEntityByIndexes(IComposerTablesEnum table, IComposerEntityVo vo)Gets entity data based on index fields from the specified table
List<T> findAllArchiveData(IComposerTablesEnum table, LocalDateTime archiveTimeFrom, Long recordId, int maxRecords)Finds all archived data within the specified time range and record ID from the specified table
PagedResult<T> pagedQuery(IComposerEntityVo condition)Performs a paged query using the default table in ascending order
PagedResult<T> pagedQueryDesc(IComposerEntityVo condition)Performs a paged query using the default table in descending order
<T extends BaseEntity> T getEntityByIndexes(IComposerTablesEnum table, IComposerEntityVo vo)Gets entity data based on index fields from the specified table
IComposerDataService getDataService()Gets the IComposerDataService instance from Spring context

Sample Code of IComposerDbDataUtils

CodeDescription
EntityIndexVo indexVo = new EntityIndexVo("String Index")Define index object ( the same as the code below EntityIndexVo indexVo = new EntityIndexVo(); indexVo.setIndexValue1(String indexValue1); )
indexVo.setIndexValue1(String indexValue1)Define index
indexVo.setUniqueIndex1("uniqueIndexName1", "uniqueIndexValue1")Define UniqueIndex
IComposerEntityVo vo2 = new IComposerEntityVo("entityName", "entityData", indexVo)Define Data
IComposerDbDataUtils.insert(com.insuremo.icomposer.vo.IComposerEntityVo vo)Add New Data to the default table
IComposerDbDataUtils.update(com.insuremo.icomposer.vo.IComposerEntityVo vo)Update Data
IComposerDbDataUtils.deleteByVo(com.insuremo.icomposer.vo.IComposerEntityVo vo)Delete Data
List<IComposerEntityVo> result = IComposerDbDataUtils.findListByIndexes(com.insuremo.icomposer.vo.IComposerEntityVo vo)Query Data

Add New Data

Defined as IndexName_IndexValue(TransactionNo=POTBTI01265112)

import com.insuremo.icomposer.utils.IComposerDbDataUtils;
import com.insuremo.icomposer.vo.EntityIndexVo;
import com.insuremo.icomposer.vo.IComposerEntityVo;

String entityData =
'''
{
"TransactionNo": "POTBTI01265112",
"TransactionDate": "2025-01-14 10:25",
"PrintStatus": "PrintedSuccessfully",
"FailureMessage": "",
"Operator": "TestUser",
"Template": "defaultTemplate"
}
'''
EntityIndexVo indexVo = new EntityIndexVo("TransactionNo=POTBTI01265112");
IComposerEntityVo vo = new IComposerEntityVo("PrintLog",entityData, indexVo);
//insert the data to the default table t_icmp_entity_data
vo = IComposerDbDataUtils.insert(vo);

After executing the code, check the results in the database.

icomposer_Database

Check the results in the menu iComposer -> Dynamic Entity. icomposer_Database

Define the IndexName without defining the IndexValue

import com.insuremo.icomposer.utils.IComposerDbDataUtils;
import com.insuremo.icomposer.vo.EntityIndexVo;
import com.insuremo.icomposer.vo.IComposerEntityVo;

String entityData =
'''
{
"TransactionNo": "POATOU01265112",
"TransactionDate": "2024-08-14 10:25",
"PrintStatus": "PrintedSuccessfully",
"FailureMessage": "",
"Operator": "TestUser",
"Template": "defaultTemplate"
}
'''
EntityIndexVo indexVo = new EntityIndexVo("TransactionNo");
IComposerEntityVo vo = new IComposerEntityVo("PrintLog",entityData, indexVo);
vo = IComposerDbDataUtils.insert(vo);

After executing the code, check the results in the menu iComposer -> Dynamic Entity. icomposer_Database

UniqueIndex

note

UniqueIndex requires that the same value in the same column can only be stored once. If the same value is stored again, the system will report a conflict.

import com.insuremo.icomposer.utils.IComposerDbDataUtils;
import com.insuremo.icomposer.vo.EntityIndexVo;
import com.insuremo.icomposer.vo.IComposerEntityVo;

String entityData =
'''
{
"TransactionId": "10000068008001",
"TransactionNo": "POPGA00000001",
"TransactionDate": "2024-12-14 10:25",
"PrintStatus": "PrintedSuccessfully",
"FailureMessage": "",
"Operator": "TestUser",
"Template": "defaultTemplate"

}
'''
EntityIndexVo indexVo = new EntityIndexVo("TransactionNo");
indexVo.setUniqueIndex1("TransactionId","10000068008001")
IComposerEntityVo vo = new IComposerEntityVo("PrintLog",entityData, indexVo);
vo = IComposerDbDataUtils.insert(vo);

After executing the code, check the results in the database. icomposer_Database

Update Data

import com.insuremo.icomposer.utils.IComposerDbDataUtils;
import com.insuremo.icomposer.vo.EntityIndexVo;
import com.insuremo.icomposer.vo.IComposerEntityVo;

EntityIndexVo indexVo = new EntityIndexVo("TransactionNo=POTBTI01265113");
IComposerEntityVo vo = new IComposerEntityVo(null,null, indexVo);

List<IComposerEntityVo> result = (List<IComposerEntityVo>)IComposerDbDataUtils.findListByIndexes(vo)

String updateData =
'''
{
"TransactionNo": "1265112"
}
'''
IComposerEntityVo voUpdate = new IComposerEntityVo();
for(int i= 0; i < result.size(); i++){
IComposerEntityVo voTemp = result.get(i);
info("{}= BeforeUpdateData:{}",i,voTemp.getEntityData())
voTemp.setEntityData(updateData);
voUpdate = IComposerDbDataUtils.update(voTemp);
info("After UpdateData:{}",voUpdate.getEntityData())
}

Test Log

0= BeforeUpdateData:
{
"TransactionNo": "POTBTI01265112",
"TransactionDate": "2025-01-14 10:25",
"PrintStatus": "PrintedSuccessfully"
}
After UpdateData:
{
"TransactionNo": "1265112"
}

Delete Data

The operation of deleting data follows the same pattern as querying data, with the distinction that the findListByIndexes method is used for querying while the deleteByVo method is used for deletion. The following is a code example for deleting data. For the method of deleting data based on entity name or Index, refer to the relevant sections on querying data and the following examples.

import com.insuremo.icomposer.utils.IComposerDbDataUtils;
import com.insuremo.icomposer.vo.EntityIndexVo;
import com.insuremo.icomposer.vo.IComposerEntityVo;

EntityIndexVo indexVo = new EntityIndexVo();
indexVo.setUniqueIndex1("TransactionId","10000068008001")
IComposerEntityVo vo = new IComposerEntityVo(null,null, indexVo);
IComposerDbDataUtils.deleteByVo(vo);

No log results are provided here since the data is deleted upon code execution.

Query Data

The following query operations are performed based on the data provided below.

icomposer_Database

Query based on EntityName

import com.insuremo.icomposer.utils.IComposerDbDataUtils;
import com.insuremo.icomposer.utils.IComposerJsonUtils;
import com.insuremo.icomposer.vo.EntityIndexVo;
import com.insuremo.icomposer.vo.IComposerEntityVo;

EntityIndexVo indexVo = new EntityIndexVo();
IComposerEntityVo vo = new IComposerEntityVo("PrintLog",null, indexVo);

List<IComposerEntityVo> result = (List<IComposerEntityVo>)IComposerDbDataUtils.findListByIndexes(vo)

for(int i= 0; i < result.size(); i++){
info("{}=EntityName:{}, Index:{}",i,result.get(i).getEntityName(),IComposerJsonUtils.toJSON(result.get(i).getEntityIndexVo()))
}

Test Log

0=EntityName:PrintLog, Index:{"IndexValue1":"TransactionNo"}
1=EntityName:PrintLog, Index:{"IndexValue1":"TransactionNo=POTBTI01265112"}
2=EntityName:PrintLog, Index:{"IndexValue1":"TransactionNo","UniqueIndexName1":"TransactionId","UniqueIndexValue1":"10000068008001"}

Query based on IndexName

import com.insuremo.icomposer.utils.IComposerDbDataUtils;
import com.insuremo.icomposer.utils.IComposerJsonUtils;
import com.insuremo.icomposer.vo.EntityIndexVo;
import com.insuremo.icomposer.vo.IComposerEntityVo;

EntityIndexVo indexVo = new EntityIndexVo("TransactionNo");
IComposerEntityVo vo = new IComposerEntityVo(null,null, indexVo);

List<IComposerEntityVo> result = (List<IComposerEntityVo>)IComposerDbDataUtils.findListByIndexes(vo)

for(int i= 0; i < result.size(); i++){
info("{}=EntityName:{}, Index:{}",i,result.get(i).getEntityName(),IComposerJsonUtils.toJSON(result.get(i).getEntityIndexVo()))
}

Test Log

0=EntityName:PrintLog, Index:{"IndexValue1":"TransactionNo"}
1=EntityName:PrintLog, Index:{"IndexValue1":"TransactionNo","UniqueIndexName1":"TransactionId","UniqueIndexValue1":"10000068008001"}
2=EntityName:PrintLog1, Index:{"IndexValue1":"TransactionNo"}

Query based on IndexName_IndexValue

import com.insuremo.icomposer.utils.IComposerDbDataUtils;
import com.insuremo.icomposer.utils.IComposerJsonUtils;
import com.insuremo.icomposer.vo.EntityIndexVo;
import com.insuremo.icomposer.vo.IComposerEntityVo;

EntityIndexVo indexVo = new EntityIndexVo("TransactionNo=POTBTI01265112");
IComposerEntityVo vo = new IComposerEntityVo(null,null, indexVo);

List<IComposerEntityVo> result = (List<IComposerEntityVo>)IComposerDbDataUtils.findListByIndexes(vo)

for(int i= 0; i < result.size(); i++){
info("{}=EntityName:{}, Index:{}",i,result.get(i).getEntityName(),IComposerJsonUtils.toJSON(result.get(i).getEntityIndexVo()))
}

Test Log

0=EntityName:PrintLog, Index:{"IndexValue1":"TransactionNo=POTBTI01265112"}

Query based on UniqueIndex

import com.insuremo.icomposer.utils.IComposerDbDataUtils;
import com.insuremo.icomposer.utils.IComposerJsonUtils;
import com.insuremo.icomposer.vo.EntityIndexVo;
import com.insuremo.icomposer.vo.IComposerEntityVo;

EntityIndexVo indexVo = new EntityIndexVo();
indexVo.setUniqueIndex1("TransactionId","10000068008001")
IComposerEntityVo vo = new IComposerEntityVo(null,null, indexVo);

List<IComposerEntityVo> result = (List<IComposerEntityVo>)IComposerDbDataUtils.findListByIndexes(vo)

for(int i= 0; i < result.size(); i++){
info("{}=EntityName:{}, Index:{}",i,result.get(i).getEntityName(),IComposerJsonUtils.toJSON(result.get(i).getEntityIndexVo()))
}

Test Log

0=EntityName:PrintLog, Index:{"IndexValue1":"TransactionNo","UniqueIndexName1":"TransactionId","UniqueIndexValue1":"10000068008001"}

Query based on EntityName, Index

import com.insuremo.icomposer.utils.IComposerDbDataUtils;
import com.insuremo.icomposer.utils.IComposerJsonUtils;
import com.insuremo.icomposer.vo.EntityIndexVo;
import com.insuremo.icomposer.vo.IComposerEntityVo;

EntityIndexVo indexVo = new EntityIndexVo("TransactionNo");
IComposerEntityVo vo = new IComposerEntityVo("PrintLog",null, indexVo);

List<IComposerEntityVo> result = (List<IComposerEntityVo>)IComposerDbDataUtils.findListByIndexes(vo)

for(int i= 0; i < result.size(); i++){
info("{}=EntityName:{}, Index:{}",i,result.get(i).getEntityName(),IComposerJsonUtils.toJSON(result.get(i).getEntityIndexVo()))
}

Test Log

0=EntityName:PrintLog, Index:{"IndexValue1":"TransactionNo"}
1=EntityName:PrintLog, Index:{"IndexValue1":"TransactionNo","UniqueIndexName1":"TransactionId","UniqueIndexValue1":"10000068008001"}

IComposerDataAccessorUtils

note

We’ve upgraded IComposerDataService and IComposerDbDataUtils; tenants implementing this functionality for the first time should use IComposerDataAccessorUtils for better data-processing efficiency.

IComposerDataAccessorUtils class provides utility methods for data access operations in the iComposer platform, including querying, inserting, updating, deleting, and paginated queries using the iComposer data access framework. Compared to the previous dynamic-storage approach, this includes several optimizations:

  1. Sharded tables: Data definition and content are now split into two separate tables to boost query performance.
  2. Date-range index: A new date-index type supports efficient range searches.
  3. Spring Specification: Query conditions can be freely combined (AND/OR) and LIKE-based fuzzy search is fully supported.
  4. Tables: We have pre-provisioned 20 tables; if none is specified, data will be stored in the default TABLE_01.
icomposer_Database icomposer_Database
Method NameDescription
IComposerDataAccessorFactoryManager getDataAccessorFactoryManager()Gets the iComposer data accessor factory manager from the Spring application context
IComposerQuery getNewIComposerQuery(IComposerTableNames table)Creates a new iComposer query instance for the specified table
IComposerQuery getNewIComposerQuery()Creates a new iComposer query instance for the default table (TABLE_01)
IComposerBaseEntity getNewEntity(IComposerTableNames table)Creates a new entity instance for the specified table
IComposerBaseEntity getNewEntity()Creates a new entity instance for the default table (TABLE_01)
DataAccessorFactory getDataAccessorFactory(IComposerTableNames table)Gets the data accessor factory for the specified table
DataAccessorFactory getDataAccessorFactory()Gets the data accessor factory for the default table (TABLE_01)
List<IComposerBaseEntity> findAll(IComposerTableNames table, IComposerQueryBuilder specification)Finds all entities matching the given specification for the specified table
List<IComposerBaseEntity> findAll(IComposerQueryBuilder specification)Finds all entities matching the given specification for the default table (TABLE_01)
IComposerBaseEntity findOne(IComposerBaseEntity entity)Finds a single entity matching the properties of the given entity using example matching
IComposerBaseEntity insertOrUpdate(IComposerBaseEntity entity)Inserts or updates the given entity in the database
void deleteById(IComposerTableNames table, Long id)Deletes an entity by its ID from the specified table
void deleteById(Long id)Deletes an entity by its ID from the default table (TABLE_01)
void deleteByVo(IComposerBaseEntity entity)Deletes an entity by its value object representation
PagedResult<T> pagedQuery(IComposerBaseEntity entity, Integer pageIndex, Integer pageSize)Performs a paginated query based on the properties of the given entity
PagedResult<T> pagedQuery(IComposerBaseEntity entity, IComposerQueryBuilder specification, Integer pageIndex, Integer pageSize)Performs a paginated query based on the given entity and specification
PagedResult<T> pagedQuery(String tableName, IComposerQueryBuilder specification, Integer pageIndex, Integer pageSize)Performs a paginated query based on the given table name and specification

The sample code below includes Query, Delete, Insert, and Update operations.

import com.insuremo.icomposer.utils.IComposerDataAccessorUtils;
import com.insuremo.icomposer.specifications.IComposerQuery;
import com.insuremo.icomposer.specifications.IComposerQueryBuilder;
import com.insuremo.icomposer.consts.IComposerTableNames;
import com.insuremo.icomposer.domain.IComposerBaseEntity;
import com.insuremo.icomposer.utils.IComposerJsonUtils;

// query
IComposerQuery query = IComposerDataAccessorUtils.getNewIComposerQuery()

IComposerQueryBuilder builder = IComposerQueryBuilder.where(query.entityNameEquals("test").and(query.indexString1Equals("testIndex2")));
List<IComposerBaseEntity> queryResult = IComposerDataAccessorUtils.findAll(builder);
info("IComposerDataAccessorUtils.findAll(builder) :{}", IComposerJsonUtils.toJSON(queryResult));
for (IComposerBaseEntity entity : queryResult) {
// delete
info("IComposerDataAccessorUtils.deleteByVo(entity) : {}", IComposerJsonUtils.toJSON(entity))
IComposerDataAccessorUtils.deleteByVo(entity);

}

// File 1 – insert
IComposerBaseEntity entityData = IComposerDataAccessorUtils.getNewEntity()
String jsonData = '''
{
"EndoEffectiveDate": "2025-10-08",
"EndoType": 3,
"EndorsementPaymentInfoList": [
{
"InstallmentType": "3",
"IsInstallment": "Y",
"PayModeCode": "30"
}
],
"PolicyNo": "POTBTI00006667",
"ProductCode": "TBTI",
"ProductId": 351925022,
"SubEndoType": "32"
}
'''
entityData.setEntityDataValue(jsonData)
entityData.setEntityName("cc2");
entityData.setIndexString1("cc1Index");
entityData.setModelName("PolicyAdmin")
entityData.setModelType("PolicyCC")

//insert the data to the default table t_icmp_entity_data(default table IComposerTableNames.TABLE_01)
IComposerDataAccessorUtils.insertOrUpdate(entityData);
info("IComposerDataAccessorUtils.insertOrUpdate(entityData) :{}", IComposerJsonUtils.toJSON(entityData));

//If you want to specify a table for storage, for example store it in TABLE_05, refer to the following approach.
IComposerBaseEntity entityData5 = IComposerDataAccessorUtils.getNewEntity(IComposerTableNames.TABLE_05)
entityData5.setEntityName("cc5");
entityData5.setEntityDataValue(jsonData)
IComposerDataAccessorUtils.insertOrUpdate(entityData5);
IComposerQuery queryEntityData5 = IComposerDataAccessorUtils.getNewIComposerQuery(IComposerTableNames.TABLE_05)

// update
entityData.setIndexString1("ccIndex2");
entityData.setModelType("PolicyMM")
return IComposerDataAccessorUtils.insertOrUpdate(entityData);

IComposerExecutorUtils

IComposerExecutorUtils class provides utility methods for executing functions with different transaction contexts and asynchronous execution in the iComposer platform, including methods for executing with new transactions, asynchronous execution with and without transactions, and RESTful API execution.

Method NameDescription
void executeWithNewTransactionNonReturn(Object serviceFunction, String methodName, Object[] methodParams)Executes a method with a new transaction without returning a value
Object executeWithNewTransaction(Object serviceFunction, String methodName, Object[] methodParams)Executes a method with a new transaction and returns the result
void asyncExecuteWithoutTransaction(Object serviceFunction, String methodName, Object[] methodParams)Execute a method asynchronously without transaction
void asyncExecuteWithTransaction(Object serviceFunction, String methodName, Object[] methodParams)Execute a method asynchronously within a new transaction
void asyncExecuteWithTransaction(String transactionName, Object serviceFunction, String methodName, Object[] methodParams)Execute a method asynchronously within a new transaction (deprecated)
void asyncExecuteWithMessage(String businessNo, Long txType, String serviceFunction, String methodName, Object[] methodParams)Execute a method asynchronously with message handling
Object executeFunction(Object serviceFunction, String methodName, Object[] methodParams)Execute a function using Groovy support
void addMainTraceId(String mainTraceId)Adds a main trace ID to the business key context
Object executeRestful(String apiName, Map<String, Object> parameters, Object requestBody)Execute a RESTful API locally
IComposerRestfulLocalExecutor getRestfulLocalExecutor()Get the IComposerRestfulLocalExecutor instance from Spring context
TaskExecutor getTaskExecutor()Get the task executor bean from Spring context
void asyncExecuteWithMessage(String businessNo, Long txType, String serviceFunction, String methodName, Object[] methodParams)Execute a method asynchronously with message handling
import com.insuremo.icomposer.utils.IComposerExecutorUtils;

//Assume this function
def iHubCaller = (ProposalBind) getCommonService("ProposalBind");
// Define the URL for the integration endpoint
def iHubUrl = "https://sandbox-sg-gw.insuremo.com/trialx/1.0/add/pet";
// Define the request body for the integration call
def requestBody = "{ \"name\": \"Fido\", \"tag\": \"dog\" }";

// Use IComposerExecutorUtils to asynchronously execute the integration without a transaction
IComposerExecutorUtils.asyncExecuteWithoutTransaction(iHubCaller, "executeIntegration", requestBody, iHubUrl);

asyncExecuteWithMessage

Assumed scenario: An email notification needs to be sent after a policy is created. First, an email notification function should be established, and then this function will be invoked via a message after the policy is created.

  1. Enable the feature in the Tenant Config Center: icomposer.message.enabled = true.

  2. Create a Function that implements your business logic, e.g. MessageSendMail.

  3. Any consumer (API, Function, or Batch) calls IComposerExecutorUtils.asyncExecuteWithMessage(). The framework immediately persists the message to the tenant’s message table and returns without blocking the caller.

  4. iComposer scans the message table every 5s by default and triggers pending functions. Also can customize the schedule with icomposer.message.cron, e.g. 0 0 0 * * ? (daily at 00:00).

  5. Execution results are saved on the fly:

    • Success → status set to SUCCESS.
    • Failure → automatically retried up to 5 times; after that the status becomes FAIL and the message is ignored by subsequent scans.
  6. Failed messages can be manually retried from the Message management UI.

  7. In clustered mode all nodes scan concurrently; the framework guarantees that each message is processed by exactly one node—no duplicates, no loss.

MesssageSendMail Function

import java.text.MessageFormat;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.collections4.MapUtils;
import org.springframework.web.client.RestTemplate;
import com.insuremo.icomposer.utils.IComposerRestTemplateManager;

RestTemplate restTemplateContainer = IComposerRestTemplateManager.gatewayCall()
PolicyConstants policyConstants = (PolicyConstants) getCommonService("PolicyConstants");

def sendMail(Map policyInfo) {
List<Map> policyCustomerList = (List<Map>) policyInfo.get("PolicyCustomerList");
if (policyCustomerList == null) {
throw new BusinessException("Email cannot be sent because the policyholder’s information is empty.");
return;
}
String sentEmail = (String) policyCustomerList.get(0).get("Email");
if (StringUtils.isBlank(sentEmail)) {
throw new BusinessException("Email cannot be sent because the policyholder’s email address is empty.");
return;
}
String subject = MessageFormat.format("InsureMO Proposal Number {0}", MapUtils.getString(policyInfo, policyConstants.getPolicyConstants("PROPOSAL_NO")));
String templateCode = "issuedEmail";
List<String> consignee = Arrays.asList(sentEmail);
Map map = new HashMap<>();
map.put("subject", subject);
map.put("template_code", templateCode);
map.put("to", consignee);
Map mail = map
String emailUrl = "http://gateway.***/***/1.0/sns/email/send";
Map emailResult = restTemplateContainer.postForObject(emailUrl, mail, Map.class);
return emailResult
}

After creation generates a ProposalNo, consumer use the following logic to consume the MessageSendMail function.

import com.insuremo.icomposer.utils.IComposerExecutorUtils;

String proposalNo = policyInfo.get("ProposalNo")
Object[] methodParams = [policyInfo] as Object[]
IComposerExecutorUtils.asyncExecuteWithMessage(proposalNo, 1, "MesssageSendMail", "sendMail", methodParams)

IComposerIntegrationAdapterService

IComposerIntegrationAdapterService

IComposerIntegrationAdapterService handles transaction synchronization requests and responses in integration scenarios and provides customized logic for external provider interactions.

Method NameDescription
void callProviderAdapter(IntegrationAdapterRequest adapterRequest)Synchronously calls an external provider with the specified request
void callProviderAdapterAsync(IntegrationAdapterRequest adapterRequest)Asynchronously calls an external provider with the specified request
IntegrationAdapterResponse createIntegrationAdapterResponse()Creates a new IntegrationAdapterResponse object for returning results
IntegrationAdapterRequest createTransactionSyncRequest(IntegrationAdapterRequest providerAdapterRequest)Creates a transaction synchronization request based on the provider adapter request
IntegrationAdapterResponse createTransactionSyncResponse()Creates a transaction synchronization response object
void recallProviderAdapter(IntegrationAdapterRequest adapterRequest)Recalls an external provider with the specified request, typically for retry or reprocessing

IComposerIntegrationAdapterRequest

IComposerIntegrationAdapterService is a service class that provides methods to configure, execute, and manage integration requests to external systems or services within the iComposer framework.

Method NameDescription
setIntegrationAdapterRequest()Sets the integration adapter request object, used to configure and pass detailed request information.
getIntegrationAdapterRequest()Retrieves the current integration adapter request object, which can be used for inspection or parameter modification.
execute()Executes the integration adapter request, sending it to the external service and returning the response result.
getIntegrationResponse()Gets the response data after executing the integration adapter request, used to process results returned by the external service.
setInputData()Sets the input data for the integration request, typically used to pass business-related parameters or payloads.
setClientRequestId()Sets a unique identifier for the client request, used for tracking and logging purposes.
setProviderCode()Sets the provider code to specify the target system or service for the request.
setCountryCode()Sets the country code to define the geographical location (country or region) for the business operation.
setTransactionType()Sets the transaction type to define the business operation type of the request (e.g., payment, query).
import com.insuremo.icomposer.sdk.inteadapter.IComposerIntegrationAdapterRequest;
import com.insuremo.icomposer.sdk.inteadapter.IComposerIntegrationAdapterService;

IComposerIntegrationAdapterService integrationAdapterService = (IComposerIntegrationAdapterService)getBean("com.insuremo.icomposer.sdk.inteadapter.IComposerIntegrationAdapterService");

def prepareEmail(Map policyInfo) {
IComposerIntegrationAdapterRequest request = new IComposerIntegrationAdapterRequest();
request.setInputData(policyInfo);
request.setClientRequestId("Policy_Issue_Mail" + policyInfo.get("PolicyNo"));
request.setProviderCode("Container");
request.setCountryCode("CN");
request.setTransactionType(3);
integrationAdapterService.callProviderAdapter(request);
}

IComposerRestTemplateManager

IComposerRestTemplateManager class provides utility methods for retrieving different types of RestTemplate beans from Spring context in the iComposer platform, providing access to various RestTemplate configurations for different communication scenarios.

Method NameDescription
RestTemplate serviceNameCall()Used to call tenant services deployed within InsureMO, returns a RestTemplate bean for service name calls. For example, when there are other services under a tenant (such as xyz-bff), the calling method is http://serviceName/apiPathxxxx
RestTemplate gatewayCall()Used to make service calls through InsureMO’s gateway especially calling InsureMO platform service, returns a RestTemplate bean for gateway calls. For example, if you want to call a gateway service, the calling method is http://gateway.ebao/apiPathxxxxxx
RestTemplate remoteCall()Used for external service calls, returns a RestTemplate bean for remote calls. For example, when an external service needs to be called, the calling method is https://external-URL/apiPathxxxx
RestTemplate aiCall()Retrieves a RestTemplate configured for AI service calls
RestTemplate aiCallInternally()Retrieves a RestTemplate configured for internal AI service calls

InsureMO URL Analysis

Suppose there’s an API with URL: https://platform-gimc.insuremo.com/api/platform/dd/public/code/mgmt/v1/paged.

Since API URL contains InsureMO, it can be considered as InsureMO internal service rather than an external one. Therefore, there is no need to use remoteCall().

The preferred apporach is to adopt gatewayCall() and change URL to be: http://gateway.ebao/platform/dd/public/code/mgmt/v1/paged.

Also, if user knows service name and make sure iComposer is deployed together, users can adopt serviceNameCall() and change URL to be: http://platform-busi-config.platform/dd/public/code/mgmt/v1/paged. Here platform-busi-config is the service name to host API about dd (data dictionary).

Call InsureMO APIs by Microservice URLs

import org.springframework.web.client.RestTemplate;
import com.insuremo.icomposer.utils.IComposerRestTemplateManager;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpEntity;
import org.springframework.http.MediaType

import com.insuremo.icomposer.builtins.methods.IComposerSystem;
RestTemplate restTemplate = IComposerRestTemplateManager.serviceNameCall();
RestTemplate restTemplateGateway = IComposerRestTemplateManager.gatewayCall()

//get
Long policyId = IComposerSystem.getRequestParameter()
String policyIntUrl = "http://proposal/v1/load?policyId=" + policyId;
Map intPolicyCall = restTemplate.getForObject(policyIntUrl, Map.class);

//post
String emailUrl = "http://gateway.ebao/eBao/1.0/email/send";
String mail = "xxxxxx";
Map emailResult = restTemplateGateway.postForObject(emailUrl, mail, Map.class);

//post with header
String validateTokenURL = "http://gateway.ebao/cas/validate-token"
String token = "xxxxxxxx-xxxxxxx"
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setBearerAuth(token)
HttpEntity formEntity = new HttpEntity<>(new HashMap(), headers);
Map response = restTemplateGateway.postForObject(validateTokenURL,formEntity,Map.class);

Call third-party APIs by External Domain URLs

import org.springframework.http.MediaType;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpHeaders;
import com.insuremo.icomposer.utils.IComposerAppContext;
import com.insuremo.icomposer.utils.IComposerRestTemplateManager;

String token = IComposerAppContext.getAccessToken();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", "Bearer "+ token);
def externalTemplate = IComposerRestTemplateManager.remoteCall();

//get
String externalGetUrl="https://tenantCode-gi-ptdev.insuremo.com/api/platform/api-orchestration-test/v1/flow/test/travel_clause";
String clause = externalTemplate.exchange(externalGetUrl, HttpMethod.GET, new HttpEntity<>(new HashMap(), headers), String.class).getBody();

//post
String externalPostUrl="https://tenantCode-gi-ptdev.insuremo.com/api/platform/api-orchestration-test/v1/flow/test/SampleProposal";
String contentSample = externalTemplate.exchange(externalPostUrl, HttpMethod.POST, new HttpEntity<>(new HashMap(), headers), String.class).getBody();

BadRequestException

BadRequestException is a custom exception class used for handling bad request scenarios in the application and provides constructors for creating exceptions with different parameters.

Method NameDescription
BadRequestException(String message, Object[] args)Constructor that takes a message and optional parameters.
BadRequestException(String message, Throwable cause, Object[] args)Constructor that takes a message, cause, and optional parameters.
BadRequestException(String message, boolean slf4jFormat, Throwable cause, Object[] args)Constructor that takes a message, slf4jFormat flag, cause, and optional parameters.
BadRequestException(String errorCode, Object[] args)Constructor that takes an exception code and optional parameters.
BadRequestException(String errorCode, Throwable cause, Object[] args)Constructor that takes an exception code, cause, and optional parameters.
BadRequestException(String errorCode, boolean slf4jFormat, Throwable cause, Object[] args)Constructor that takes an exception code, slf4jFormat flag, cause, and optional parameters.
// Example for: BadRequestException(String message, Object[] args)
throw new BadRequestException("Invalid input: %s is not a valid value.", "username")

// Example for: BadRequestException(String message, Throwable cause, Object[] args)
def cause1 = new IllegalArgumentException("Username cannot be null")
throw new BadRequestException("Validation failed: %s", cause1, "username")

// Example for: BadRequestException(String message, boolean slf4jFormat, Throwable cause, Object[] args)
def cause2 = new IllegalArgumentException("Password length is insufficient")
throw new BadRequestException("Validation error: {}", true, cause2, "password")

// Example for: BadRequestException(String errorCode, Object[] args)
throw new BadRequestException("ERROR_INVALID_INPUT", "email")

// Example for: BadRequestException(String errorCode, Throwable cause, Object[] args)
def cause3 = new IllegalArgumentException("Email format is incorrect")
throw new BadRequestException("ERROR_INVALID_EMAIL", cause3, "example@invalid")

// Example for: BadRequestException(String errorCode, boolean slf4jFormat, Throwable cause, Object[] args)
def cause4 = new IllegalArgumentException("Phone number is missing country code")
throw new BadRequestException("ERROR_INVALID_PHONE", true, cause4, "+1234567890")

BusinessException

BusinessException is a custom exception class used for handling business-related exceptions in the application and provides constructors for creating exceptions with different parameters.

Method NameDescription
BusinessException(String errorCode, Object[] args)Constructor that takes an exception code and optional parameters.
BusinessException(String errorCode, Throwable cause, Object[] args)Constructor that takes an exception code, cause, and optional parameters.
BusinessException(String errorCode, boolean slf4jFormat, Throwable cause, Object[] args)Constructor that takes an exception code, slf4jFormat flag, cause, and optional parameters.
BusinessException(boolean flag, String errorCode, String message)Constructor that takes a boolean flag, exception code, and message.
// Example for: BusinessException(String errorCode, Object[] args)
throw new BusinessException("BUSINESS_ERROR", "order_id")

// Example for: BusinessException(String errorCode, Throwable cause, Object[] args)
def cause1 = new IllegalArgumentException("Order not found")
throw new BusinessException("BUSINESS_ERROR", cause1, "order_123")

// Example for: BusinessException(String errorCode, boolean slf4jFormat, Throwable cause, Object[] args)
def cause2 = new RuntimeException("Payment failed")
throw new BusinessException("BUSINESS_PAYMENT_ERROR", true, cause2, "payment_456")

// Example for: BusinessException(boolean flag, String errorCode, String message)
throw new BusinessException(true, "BUSINESS_CUSTOM_ERROR", "Custom business error occurred")

IComposerProductSdkUtils

import com.insuremo.icomposer.utils.IComposerProductSdkUtils;
import java.time.LocalDateTime;

// Scenario 1: Resolve the effective product version by code + start date
Map<String, Object> product = IComposerProductSdkUtils.getProductByStartDate("TRAVEL-2026", LocalDateTime.now());
Long productId = (Long) product.get("productId");

// Scenario 2: Full schema with element tree (for UI / rule evaluation)
Map<String, Object> schema = IComposerProductSdkUtils.getProductSchema(productId);

// Scenario 3: Build elementCode -> elementId lookup table for fast access
Map<String, Long> codeToId = IComposerProductSdkUtils.getProductElementIdByCodeMapByProductId(productId);
Long planId = codeToId.get("planCode");
Long sumInsuredId = codeToId.get("sumInsured");

// Scenario 4: Tech-element-code mapping (for integration mappings)
Map<String, String> techCodes = IComposerProductSdkUtils.getTechProductElementCodeMapByProductIdAndElementCodeList(
productId, List.of("planCode", "sumInsured"));

// Scenario 5: Search products by condition
import com.insuremo.unicorn.platform.product.dto.ProductSearchCondition;
ProductSearchCondition condition = new ProductSearchCondition();
condition.setSecondLine(1001);
List<Map<String, Object>> matches = IComposerProductSdkUtils.queryProduct(condition);

See method table in Language Reference.

IComposerTableSdkUtils

import com.insuremo.icomposer.utils.IComposerTableSdkUtils;
import java.time.LocalDateTime;

// Scenario 1: RateTable lookup by versionDate (releaseDate defaults to now)
Map<String, Object> rate = IComposerTableSdkUtils.lookupRateTableRecordByVersionDate(
"TRAVEL_RATE",
Map.of("planCode", "GOLD", "region", "ASIA"),
LocalDateTime.of(2026, 7, 1, 0, 0));

// Scenario 2: All CodeTable values (current user language)
List<Map<String, Object>> currencies = IComposerTableSdkUtils.lookupCodeTableValues("CURRENCY");

// Scenario 3: CodeTable value with conditions + explicit langId
List<Map<String, Object>> usdCurrencies = IComposerTableSdkUtils.lookupCodeTableValues(
"CURRENCY", Map.of("code", "USD"), "en_US");

// Scenario 4: ConfigTable (GlobalParam) lookup
String endpoint = IComposerTableSdkUtils.lookupConfigValue("INTEGRATION", "endpointUrl");

// Scenario 5: DataTable records with conditions
List<Map<String, Object>> rows = IComposerTableSdkUtils.lookupDataTableRecords(
"REGION_MAPPING", Map.of("country", "SG"));

See method table in Language Reference.

IComposerHooksUtils

import com.insuremo.icomposer.utils.IComposerHooksUtils;

// Scenario 1: Invoke a ServiceFunction by name + methodName
Object emailResult = IComposerHooksUtils.executeMethod("emailService", "prepareEmail", policyInfo);

// Scenario 2: Invoke a ServiceFunction's default 'execute' method (methodName null/empty)
Object result = IComposerHooksUtils.executeMethod("ratingService", null, requestData);

// Scenario 3: Register a resource (handler type auto-detects HooksType)
IComposerHooksUtils.registerResource(mySchedulerHandler,
Map.of("id", "nightly-job", "cron", "0 0 22 * * ?"));
IComposerHooksUtils.startResource("nightly-job");

// Scenario 4: Check + cleanup
if (IComposerHooksUtils.isResourceRegistered("nightly-job")) {
IComposerHooksUtils.stopResource("nightly-job");
IComposerHooksUtils.unregisterResource("nightly-job");
}

// Scenario 5: TCC prepare phase (auto-starts a global tx if none bound)
boolean ok = IComposerHooksUtils.prepareTcc("issuePolicy", Map.of("policyId", 123L));

See method table in Language Reference.

IComposerEventBridgeUtils

import com.insuremo.icomposer.utils.IComposerEventBridgeUtils;

// Scenario 1: Build + publish in one chain (minimal required fields)
IComposerEventBridgeUtils.builder()
.withSource("policy-service")
.withType("policy.issued")
.withEventBusName("policy-bus")
.withData(Map.of("policyId", 123L, "policyNo", "P-2026-001"))
.publish();

// Scenario 2: Build with explicit id / time / subject + extensions
import com.insuremo.icomposer.event.bridge.EventData;
EventData event = IComposerEventBridgeUtils.builder()
.withId("evt-" + System.currentTimeMillis())
.withSource("claim-service")
.withSubject("CLM-2026-999")
.withType("claim.submitted")
.withEventBusName("claim-bus")
.withDataContentType("application/json")
.withDataSchemaId(7L)
.withData(claimInfo)
.withExtension("traceId", "abc-123")
.build();
IComposerEventBridgeUtils.publish(event);

// Scenario 3: Re-publish a previously-built EventData
IComposerEventBridgeUtils.publish(cachedEvent);

See method table in Language Reference.

IComposerBeanUtils

import com.insuremo.icomposer.utils.IComposerBeanUtils;

// Scenario 1: Copy properties between two beans (same property names/types)
IComposerBeanUtils.copyProperties(destPolicy, srcPolicy);

// Scenario 2: Get a property by name
Object planCode = IComposerBeanUtils.getPropertyValue(policy, "planCode");

// Scenario 3: Set a property by name
IComposerBeanUtils.setPropertyValue(policy, "effectiveDate", LocalDate.now());

// Scenario 4: Get a nested bean property via getProperty alias
Object inner = IComposerBeanUtils.getProperty(policy, "policyHolder.address.city");

See method table in Language Reference.

IComposerExceptionUtils

import com.insuremo.icomposer.utils.IComposerExceptionUtils;

// Scenario 1: Parse an exception into a formatted log line
String formatted = IComposerExceptionUtils.parseException("Failed to issue policy " + policyNo, e);
logger.error(formatted);

// Scenario 2: Convert platform exception to iComposer BusinessException (returns original if no mapping)
Exception mapped = IComposerExceptionUtils.converIComposerException(e);
if (mapped instanceof BusinessException) {
throw (BusinessException) mapped;
}

// Scenario 3: Extract detail list from an ApiException (HTML-escaped)
List<Map<String, String>> details = IComposerExceptionUtils.getApiExceptionDetailList(apiException);

// Scenario 4: Locate the calling line in a source string
Integer line = IComposerExceptionUtils.getHeaderLine(sourceCodeString);

See method table in Language Reference.

IComposerFunctionUtils

import com.insuremo.icomposer.utils.IComposerFunctionUtils;

// Scenario 1: Invoke a method with one arg
Object prepared = IComposerFunctionUtils.invokeMethod(emailService, "prepareEmail", policyInfo);

// Scenario 2: Invoke with multiple args
Object validated = IComposerFunctionUtils.invokeMethod(ruleService, "validate", policyInfo, "endorsement");

// Scenario 3: Invoke with no args
Object status = IComposerFunctionUtils.invokeMethod(healthService, "ping");

See method table in Language Reference.

IComposerLoggingUtils

import com.insuremo.icomposer.utils.IComposerLoggingUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

Logger logger = LoggerFactory.getLogger("myLogger");

// Scenario 1: Standard Request/Response debug log (non-error)
IComposerLoggingUtils.logRequestResponse(logger, false,
"POST", "/v1/issue", "/v1/issue",
requestHeaders, requestBody,
200, responseHeaders, responseBody, "UTF-8", true);

// Scenario 2: Business log on error (writes MDC + auto-clears)
try {
doIssuePolicy(request);
} catch (Exception e) {
IComposerLoggingUtils.logBusinessLog(e, logger, true,
"POST", "/v1/issue", "/v1/issue",
requestHeaders, requestBody,
500, responseHeaders, responseBody, "UTF-8", false);
throw e;
}

// Scenario 3: Build JSON strings manually (no encryption/compression)
String reqContent = IComposerLoggingUtils.getRequestContent(logger,
"POST", "/v1/issue", "/v1/issue", requestHeaders, requestBody, "UTF-8");

// Scenario 4: Extract body bytes from cached wrapper
byte[] reqBytes = IComposerLoggingUtils.getRequestBody(httpServletRequest);
byte[] respBytes = IComposerLoggingUtils.getResponseBody(httpServletResponse);

// Scenario 5: Check business-log switch
if (IComposerLoggingUtils.isBusinessLongEnabled()) {
// ...business-specific logging...
}

See method table in Language Reference.

IComposerMessageUtils

import com.insuremo.icomposer.utils.IComposerMessageUtils;

// Scenario 1: Append a warning to the thread context
IComposerMessageUtils.warning("POLICY_001", "Policy {} not found", new Object[]{policyNo}, false);

// Scenario 2: Load a localized message
String text = IComposerMessageUtils.loadMessage("POLICY_001", "zh_CN");

// Scenario 3: Format with SLF4J-style placeholders
String formatted = IComposerMessageUtils.format("Policy {} issued at {}", policyNo, now);

// Scenario 4: Read all messages accumulated in the thread context
List<Message> messages = IComposerMessageUtils.getMessageListInThreadContext();

// Scenario 5: Add a list of pre-built Message objects
IComposerMessageUtils.addMessage(preBuiltMessageList);

See method table in Language Reference.

IComposerPdfUtils

import com.insuremo.icomposer.utils.IComposerPdfUtils;
import com.insuremo.icomposer.utils.PageNumberOptions;
import com.insuremo.icomposer.utils.PageNumberPosition;

// Scenario 1: Create a single-page PDF
IComposerPdfUtils.createPdf("/tmp/cover.pdf", "Hello, iComposer!");

// Scenario 2: Merge multiple PDFs into a MultipartFile
MultipartFile merged = IComposerPdfUtils.merge(List.of(pdfA, pdfB), "policy-pack.pdf");

// Scenario 3: Stamp page numbers at bottom-center
byte[] numbered = IComposerPdfUtils.addPageNumbers(merged.getBytes(), "bottom-center");

// Scenario 4: Custom footer template via PageNumberOptions
PageNumberOptions opts = PageNumberOptions.defaults()
.withPosition(PageNumberPosition.BOTTOM_CENTER)
.withFontSize(8f)
.withFooterTemplate("Page {{page}} / {{total}}");
byte[] custom = IComposerPdfUtils.addPageNumbers(numbered, opts);

// Scenario 5: Convert Word bytes to PDF bytes
byte[] pdfBytes = IComposerPdfUtils.convertWordToPdf(wordBytes);

// Scenario 6: Render pages as images (no file write)
List<BufferedImage> images = IComposerPdfUtils.renderPdfPagesAsImages("/tmp/in.pdf", 150, 1, 5);

See method table in Language Reference.

IComposerSftpClient

import com.insuremo.icomposer.utils.IComposerSftpClient;
import java.io.*;
import java.util.List;

// Scenario 1: Password auth, upload + download
IComposerSftpClient client = new IComposerSftpClient("sftp.example.com", "user", "pwd");
try {
client.connect();
try (InputStream in = new FileInputStream("local.txt")) {
client.uploadFile("/data/inbox/local.txt", in);
}
try (OutputStream out = new FileOutputStream("dl/remote.txt")) {
client.downloadFile("/data/outbox/remote.txt", out);
}
} finally {
client.disconnect();
}

// Scenario 2: Private-key auth, list + check existence
client = new IComposerSftpClient("sftp.example.com", 2222, "user", null, privateKeyBytes, "passphrase");
try {
client.connect();
List<String> names = client.listFiles("/data/outbox");
for (String name : names) {
if (client.fileExists("/data/outbox/" + name)) {
// process
}
}
// Stream-mode access
try (InputStream remoteIn = client.getFileStream("/data/outbox/big.csv");
OutputStream localOut = new FileOutputStream("dl/big.csv")) {
remoteIn.transferTo(localOut);
}
} finally {
client.disconnect();
}

// Scenario 3: Rename + create directory
client.createDirectory("/data/archive/2026");
client.renameFile("/data/inbox/old.csv", "/data/archive/2026/new.csv");

See method table in Language Reference.

IComposerSslConnectionUtils

import com.insuremo.icomposer.utils.IComposerSslConnectionUtils;
import org.springframework.web.client.RestTemplate;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;

// Scenario 1: Pool + timeouts only (no client cert)
RestTemplate rt = IComposerSslConnectionUtils.createRestTemplateWithConnectionSettings(5000, 10000);
try {
String resp = rt.getForObject("https://api.example.com/ping", String.class);
} finally {
// The factory owns the HttpClient; only close if you extracted it explicitly.
}

// Scenario 2: Mutual TLS with client cert + truststore + timeouts
RestTemplate mTls = IComposerSslConnectionUtils.createRestTemplateWithClientCertificateAndConnectionSettings(
keyStoreB64, keyStorePwd, "PKCS12",
trustStoreB64, trustStorePwd, "JKS",
5000, 10000);
String resp = mTls.exchange(url, HttpMethod.POST, entity, String.class).getBody();

// Scenario 3: Build a client cert template without custom timeouts
RestTemplate mTlsOnly = IComposerSslConnectionUtils.createRestTemplateWithClientCertificate(
keyStoreB64, keyStorePwd, "PKCS12",
trustStoreB64, trustStorePwd, "JKS");

// Scenario 4: Safely close an HttpClient you own
CloseableHttpClient httpClient = ... ; // obtained elsewhere
IComposerSslConnectionUtils.closeHttpClient(httpClient);

See method table in Language Reference.

IComposerTransactionUtils

import com.insuremo.icomposer.utils.IComposerTransactionUtils;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.transaction.PlatformTransactionManager;

// Scenario 1: Get a fresh TransactionTemplate for programmatic tx control
TransactionTemplate tt = IComposerTransactionUtils.getNewTransactionTemplate();
tt.execute(status -> {
// business code inside the transaction
savePolicy(policy);
saveEndorsement(endo);
return null;
});

// Scenario 2: Access the underlying PlatformTransactionManager directly
PlatformTransactionManager ptm = IComposerTransactionUtils.getPlatformTransactionManager();

// Scenario 3: The existing IComposerTransactionSyncRequest flow (prepare/setResponse) is unrelated;
// it lives in com.insuremo.icomposer.sdk.inteadapter and is wired by the integration-adapter service.

See method table in Language Reference.

IComposerRatingExecutorUtils

import com.insuremo.icomposer.utils.IComposerRatingExecutorUtils;

// Scenario 1: Calculate with inputMap (multiple rating groups comma-separated)
Map<String, Object> inputMap = new HashMap<>();
inputMap.put("Model", modelMap); // DomainModelMapImpl
inputMap.put("Context", contextMap);
Map<String, Object> result = IComposerRatingExecutorUtils.calculate(
"TRAVEL_RATING,DISCOUNT_RATING", inputMap);

// Scenario 2: Calculate with a typed response
PolicyRating rating = IComposerRatingExecutorUtils.calculate(
"TRAVEL_RATING", baseEntity, PolicyRating.class);

// Scenario 3: Single rating group
Map<String, Object> base = IComposerRatingExecutorUtils.calculate("BASE_PREMIUM", inputMap);

See method table in Language Reference.

IComposerRuleV2ExecutorUtils

import com.insuremo.icomposer.utils.IComposerRuleV2ExecutorUtils;

// Scenario 1: Recommended form (contextData passed explicitly)
List<RuleResult> results = IComposerRuleV2ExecutorUtils.executeDomain(
"UNDERWRITING",
Map.of("policyId", 123L, "productCode", "TRAVEL-2026"), // contextData
Map.of("sumInsured", 1_000_000, "age", 35), // contextParameters
true, // isTrackingEnabled
true); // autoConvertDateTimeFields

// Scenario 2: With tracking disabled (production hot path)
List<RuleResult> silent = IComposerRuleV2ExecutorUtils.executeDomain(
"ELIGIBILITY",
Map.of("policyId", 123L),
Map.of("region", "ASIA"),
false,
true);

// Scenario 3: Auto date-field conversion off (caller controls date types)
List<RuleResult> raw = IComposerRuleV2ExecutorUtils.executeDomain(
"UNDERWRITING",
Map.of("policyId", 123L),
Map.of("effectiveDate", LocalDateTime.now()),
true,
false);

See method table in Language Reference.

IComposerZipFileUtils

import com.insuremo.icomposer.utils.IComposerZipFileUtils;
import java.io.File;
import java.util.List;

// Scenario 1: Package a whole directory
IComposerZipFileUtils.zipDirectory("/tmp/policy-pack", "/tmp/policy-pack.zip");

// Scenario 2: ZIP a byte array
byte[] zipped = IComposerZipFileUtils.zip(jsonBytes);

// Scenario 3: GZIP + Base64 a string payload, then reverse
String encoded = IComposerZipFileUtils.gzipAndEncode(jsonPayload);
// ...transmit...
String restored = IComposerZipFileUtils.gunzipAndDecode(encoded);

// Scenario 4: Unzip an uploaded InputStream into a folder
IComposerZipFileUtils.unzip(uploadedInputStream, new File("/tmp/unpacked"));

// Scenario 5: Append more files to an existing zip
IComposerZipFileUtils.appendFilesToZip(new File("/tmp/existing.zip"),
List.of(new File("/tmp/extra1.pdf"), new File("/tmp/extra2.pdf")));

// Scenario 6: Filter multiple source dirs into one zip
File zip = IComposerZipFileUtils.zipDirs("/tmp/out", "bundle.zip",
true, // deleteExisting
f -> f.getName().endsWith(".pdf"), // filePredicate
"/tmp/dir-a", "/tmp/dir-b"); // sourceDirs

See method table in Language Reference.

IComposerQuery

import com.insuremo.icomposer.utils.IComposerDataAccessorUtils;
import com.insuremo.icomposer.specifications.IComposerQuery;
import java.time.LocalDateTime;
import java.util.List;

// Scenario 1: Build a query against entity_01 (single condition)
IComposerQuery query = IComposerDataAccessorUtils.getNewIComposerQuery(IComposerDataAccessorUtils.Table.entity01);
def spec = query.entityNameEquals("POLICY");
List<Map<String, Object>> rows = IComposerDataAccessorUtils.findAll(IComposerDataAccessorUtils.Table.entity01, spec);

// Scenario 2: Multiple optional conditions (null values are skipped automatically)
def spec2 = query.entityNameLike("POLICY_%")
.and(query.indexDate1GreaterThanOrEqualTo(monthStart));
// query.indexString1Equals(null) is null-safe; you can chain without if-null guards

// Scenario 3: Sort + limit
import org.springframework.data.domain.Sort;
def spec3 = query.modelTypeEquals("AUTO")
.and(query.orderBy(Sort.by(Sort.Direction.DESC, "indexDate1")))
.and(query.limit(50));

See method table in Language Reference.

IComposerQueryBuilder

import com.insuremo.icomposer.utils.IComposerDataAccessorUtils;
import com.insuremo.icomposer.specifications.IComposerQueryBuilder;

// Scenario 1: AND-combine two specs
IComposerQuery query = IComposerDataAccessorUtils.getNewIComposerQuery(IComposerDataAccessorUtils.Table.entity01);
def spec = IComposerQueryBuilder.and(
query.entityNameEquals("POLICY"),
query.indexDate1GreaterThanOrEqualTo(monthStart));

// Scenario 2: WHERE root + OR branch
def spec2 = IComposerQueryBuilder.where(query.entityNameEquals("POLICY"))
.or(query.indexString1Like("ENDORSEMENT_%"));

// Scenario 3: Paged query with combined spec
import org.springframework.data.domain.PageRequest;
Page<Map<String, Object>> page = IComposerDataAccessorUtils.pagedQuery(
IComposerDataAccessorUtils.Table.entity01,
spec,
PageRequest.of(0, 20));

See method table in Language Reference.

IComposerEntity01..20Query

import com.insuremo.icomposer.utils.IComposerDataAccessorUtils;
import java.util.List;

// Scenario: Switch between entity tables by changing the Table enum
// entity_01 (policies), entity_02 (endorsements), ... up to entity_20.
// The query API is identical — only the bound table changes.

List<Map<String, Object>> policies = IComposerDataAccessorUtils.findAll(
IComposerDataAccessorUtils.Table.entity01,
IComposerDataAccessorUtils.getNewIComposerQuery(IComposerDataAccessorUtils.Table.entity01)
.entityNameEquals("POLICY"));

List<Map<String, Object>> endorsements = IComposerDataAccessorUtils.findAll(
IComposerDataAccessorUtils.Table.entity02,
IComposerDataAccessorUtils.getNewIComposerQuery(IComposerDataAccessorUtils.Table.entity02)
.entityNameEquals("ENDORSEMENT"));

See description in Language Reference.


Feedback
Was this page helpful?
|
Provide feedback