Socotra
Configuration GuidePlugins

Plugins Overview

Plugins are software components within the Socotra Insurance Suite that allow you to implement custom business logic written in Java and modify system processes such as underwriting, rating, and payment execution.

Once plugin implementations have been deployed, the system will automatically execute plugin code when entities move to a specific stage of their lifecycles, in response to system events, or when calling certain API endpoints. See the feature guide for each plugin for more information.

The following plugins are available in the Socotra Insurance Suite:

Implementation

Plugins are implemented as Java classes.

Implementations can be classified as either Global or Product implementations. Global implementations are located in the top-level configuration-name/plugins/java folder within the configuration folder structure, and Product implementations are located in product folders using the following folder structure: configuration-name/productName/plugins/java.

If both a Global and a Product implementation of a plugin are currently deployed, the system will only execute the Product implementation.

Automation Plugin implementations must be Global.

Once an implementation has been deployed, Global implementations will be moved to the src/main/java/com/socotra/deployment/customer folder, and Product implementations will be moved to a subfolder using the following folder structure: src/main/java/com/socotra/deployment/customer/productname. Implementations can be created and modified directly within these folder structures instead of the configuration folder structures.

To implement a plugin, create a Java class in one of the above folders, implement the interface for the plugin, and override the method specific to your target entity type.

For example, the following class implements the Validation Plugin and validates commercial accounts, commercial auto quotes, and commercial policy transactions:

// Validates commercial accounts, commercial auto quotes, and commercial policy transactions

public class ValidationPluginImpl implements ValidationPlugin {
    private static final Logger log = LoggerFactory.getLogger(ValidationPluginImpl.class);

    @Override
    public ValidationItem validate(CommercialAccountRequest commercialAccountRequest) {
        return ValidationItem.builder().build();
    }

    @Override
    public ValidationItem validate(CommercialAutoQuoteRequest commercialAutoQuoteRequest) {
        return ValidationItem.builder().build();
    }

    @Override
    public ValidationItem validate(CommercialAutoRequest commercialAutoRequest) {
        return ValidationItem.builder().build();
    }
}

The implementation defined above can only be deployed if two configuration objects are also deployed: An account configuration named CommercialAccount and a product configuration named CommercialAuto.

Execution

Once plugin implementations have been deployed, the system will automatically execute plugin code when entities move to a specific stage of their lifecycles, in response to system events, or when calling certain API endpoints. See the feature guide for each plugin for more information.

Certain plugins are triggered when quotes and policy transactions move to a specific lifecycle state:

StatePlugins
DraftN/A
ValidationPrecommit, Validation
PricingRating
UnderwritingUnderwriting
AcceptN/A
IssueN/A

Plugin Execution Context

The PluginExecutionContext class provides all plugins with a set of built-in methods for retrieving metadata related to the current plugin execution.

It can be used to access contextual information associated with the current plugin execution, such as the tenant locator or user locator.

The PluginExecutionContext class contains the following methods:

  • getRequestId()
  • getTenantLocator()
  • getBusinessAccount()
  • getUserLocator()
  • getUserRoles()

For example, the following code retrieves the requestId:

public class ValidationPluginImpl implements ValidationPlugin {

    @Override
    public ValidationItem validate(CommercialAutoQuoteRequest commercialAutoQuoteRequest) {
        PluginExecutionContext context = PluginExecutionContext.get();
        String requestId = context.getRequestId();

        return ValidationItem.builder().build();
    }
}

Data Fetcher

All plugins have access to the DataFetcher class, which can be used to retrieve data from a wide variety of entities, including quotes, policies, and policy transactions.

For example, the following code retrieves an account using an account locator:

// Retrieve an account using an account locator

@Override
public ValidationItem validate(CommercialAutoQuoteRequest commercialAutoQuoteRequest) {
    var account = DataFetcherFactory.get().getAccount(commercialAutoQuoteRequest.quote().accountLocator());

    return ValidationItem.builder().build();
}

The following is a complete list of all methods available through the DataFetcher class:

MethodParametersResponse
getAccount()accountLocatorAccountResponse
getQuickQuote()quickQuoteLocatorQuickQuoteResponse
getQuote()quoteLocatorQuoteResponse
getQuoteUnderwritingFlags()quoteLocatorQuoteUnderwritingFlagsResponse
getQuotePricing()quoteLocatorQuotePriceResponse
getQuoteDocuments()quoteLocatorDocumentListResponse
getQuoteStaticData()locatorstatic
getTransaction()transactionLocatorPolicyTransactionResponse
getTransactionUnderwritingFlags()transactionLocatorTransactionUnderwritingFlagsResponse
getTransactionPricing()transactionLocatorTransactionPriceResponse
getDocumentsAttachedToTransaction()transactionLocatorDocumentListResponse
getAffectedTransactions()transactionLocatorAffectedTransaction[]
getPolicy()policyLocatorPolicyResponse
getPolicyStaticData()locatorstatic
getTerm()termLocatorTermResponse
getTermCharges()termLocatormap<transactionLocator, PolicyChargeResponse[]>
getTermSubsegmentSummaries()termLocatorStreamingEntity<SubsegmentSummary>, excluding documentSummary
getSegment()segmentLocatorSegmentResponse
getSegments() DeprecatedtransactionLocatorSegmentResponse[]
getSegmentByTransaction()transactionLocatorSegmentResponse
getSegmentDocuments()segmentLocatorDocumentListResponse
getAuxData()locator, keyAuxDataResponse
getAuxDataKeys()locator, offset, countAuxDataKeySetResponse
getUnderwritingFlag()underwritingFlagLocatorUnderwritingFlagResponse
getDiaries()referenceType, referenceLocator, offset, countDiaryEntryResponse[]
getPreferences()transactionLocatorPreferencesResponse
getInstallmentLattice()installmentLatticeLocatorInstallmentLatticeResponse
getInstallment()installmentLocatorInstallment
getInvoice()invoiceLocatorInvoiceResponse
getInvoiceDetails()invoiceLocatorInvoiceDetailsResponse
getPayment()paymentLocatorPaymentResponse
getDelinquencyEvents()delinquencyLocator, offset, countDelinquencyEventsResponse
getTask()taskLocatorTask
getUserAssociation()userAssociationLocatorUserAssociation
getFnol()fnolLocatorFnolResponse
getFnolLosses()fnolLocatorFnolLoss[]
getFnolClaims()fnolLocatorclaims
getFnolContacts()fnolLocatorContactRoles[]
getContact()locatorContactRoles

Aux Data

Aux data refers to general-purpose key-value pairs stored within the Socotra Insurance Suite. All plugins have access to aux data via the Data Fetcher.

The following aux data methods are available to all plugins via the Data Fetcher:

  • getAuxDataKeys()
  • getAuxData()
  • setAuxData()
  • deleteAuxData()

Here's a demonstration of each aux data method:

@Override
public ValidationItem validate(CommercialAutoQuoteRequest commercialAutoQuoteRequest) {
    String quoteLocator = commercialAutoQuoteRequest.quote().locator().toString();

    // Parameters: getAuxDataKeys(locator, offsetValue, pageSize)
    AuxDataKeysSet keySet = DataFetcher.getInstance().getAuxDataKeys(quoteLocator, 0, 100);

    if (!keySet.auxDataKeys().isEmpty()) {
        String key = keySet.auxDataKeys().stream().findFirst().get().key();
        String value = DataFetcher.getInstance().getAuxData(quoteLocator, key).value();

        Collection<AuxDataSet> auxDataSets = new ArrayList<>();

        AuxDataSet createRequest = AuxDataSet.builder().key(key).value(value).build();

        auxDataSets.add(createRequest);

        createRequest = AuxDataSet.builder().uiType(UiType.normal).key("keyToDelete").value(value).build();

        auxDataSets.add(createRequest);

        AuxDataSetCreateRequest setCreateRequest = AuxDataSetCreateRequest.builder()
                .auxDataSettingsName("ShortExpire")
                .auxData(auxDataSets).build();

        AuxDataService.getInstance().setAuxData(quoteLocator, setCreateRequest);
        AuxDataService.getInstance().deleteAuxData(quoteLocator, "keyToDelete");
    }

    return ValidationItem.builder().build();
}

Resource Selector

All plugins have access to the ResourceSelector class, which can be used to retrieve data from resources such as documents, tables, and secrets.

The ResourceSelector automatically selects resource instances based on resource selection rules. See the Versioned Resource Selection feature guide for more information.

For example, the following code retrieves a record from a table named VehicleTypeFactor:

public class RatingPluginImpl implements RatePlugin {
   private static final Logger log = LoggerFactory.getLogger(RatingPluginImpl.class);

    // Retrieve a record from the VehicleTypeFactor table

    @Override
    public RatingSet rate(CommercialAutoQuoteRequest commercialAutoQuoteRequest) {
        CommercialAutoQuote commercialAutoQuote = commercialAutoQuoteRequest.quote();
        List<RatingItem> ratingItems = new ArrayList<>();

        Vehicle vehicle = commercialAutoQuote.vehicleSchedule().vehicles().stream().findFirst().orElseThrow();

        Optional<VehicleTypeFactor> vehicleTypeFactor = ResourceSelectorFactory.getInstance()
                .getSelector(commercialAutoQuote)
                .getTable(VehicleTypeFactor.class)
                .getRecord(VehicleTypeFactor.makeKey(vehicle.data().vehicleMake(), vehicle.data().vehicleModel(), vehicle.data().vehicleYear()));

        BigDecimal rate = vehicleTypeFactor.orElseThrow().rate();

        ratingItems.add(RatingItem.builder()
                .elementLocator(vehicle.locator())
                .chargeType(ChargeType.premium)
                .rate(rate)
                .build());

        return RatingSet.builder().ok(true).ratingItems(ratingItems).build();
    }
}

In the example above, a CommercialAutoQuote functions as the reference point for resource selection logic. However, you can also specify a time as the reference point instead.

For example:

Optional<VehicleTypeFactor> vehicleTypeFactor = ResourceSelectorFactory.getInstance()
        .getSelector(Instant.now())
        .getTable(VehicleTypeFactor.class)
        .getRecord(VehicleTypeFactor.makeKey(vehicle.data().vehicleMake(), vehicle.data().vehicleModel(), vehicle.data().vehicleYear()));

Here's an example of the VehicleTypeFactor table:

makeSymbolmodelSymbolmodelYeartypeFactorcollFactor
keykeykeyvaluevalue
ToyotaCamry20230.842210.86764
FordExplorer20220.878390.91023

External API Calls

All plugins can call external API endpoints via the Java HttpClient.

For example:

try (HttpClient client = HttpClient.newHttpClient()) {
    HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://example.com/some-data"))
            .GET()
            .build();

    HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

    log.info("Response: {}", response.toString());

} catch (Exception e) {
    log.error("Exception: {}", e.toString());
}

The Java HttpClient is the only HTTP client currently supported by the platform. The Automation Plugin is the only plugin that can call Socotra API endpoints directly.

Plugin Restrictions

The following restrictions apply to all classes that implement a Socotra plugin interface:

  • Classes cannot be declared abstract and must be instantiable.
  • Classes cannot have a constructor with one or more arguments. A no-argument constructor is allowed and will be generated automatically if not provided.

The system will block the deployment of plugin classes that violate these rules.

Each plugin is executed in an isolated memory space. Accessing plugin fields or calling methods belonging to a different plugin is not supported and should not be attempted.

Next Steps

See Also

On this page