Introduction
Oracle Health Insurance Product Definition provides a facility to express certain behaviour in an object-oriented language. These modules (code snippets) are invoked at particular moments, these are the events to which you can attach Dynamic Logic modules.
The language in which Dynamic Logic modules are written is Groovy. Groovy is a language which is closely related to Java. This manual will not elaborate on the language itself. There are many books and online resources available for this purpose. Dynamic Logic modules can easily be tested in an IDE such as Eclipse, or on a web page such as http://groovyconsole.appspot.com/. It can be difficult however to emulate the application environment in a standalone editor. Therefore, a full test should always take place in the flow in which the module is used.
For reference and to support development of Dynamic Logic, Oracle Health Insurance Product Definition generates Groovy skeleton classes in the directory that is identified by the system property ohi.dynamiclogic.classes.directory which is specified in the ohi-proddef.properties file.
Three types of Dynamic Logic are distinguished: validations, conditions and functions. A validation operates on a single value and returns a Boolean. A condition operates on one or more objects and returns a Boolean. Finally, a function operates on one or more objects and returns a value. These three types are explained in subsequent chapters.
All types of dynamic logic can embed a call to an external service. This call out is also explained in a separate chapter.
Each piece of dynamic logic adheres to a signature. The signature describes both the functional usage (where in the configuration is it used?) and the technical usage (which objects are available in the Groovy code and what is the expected return value?). The following is a list of all existing signatures per logic type.
The following validation signatures exist:
-
Field
The following condition signatures exist:
-
Benefit Specification (Other)
-
Diagnosis
-
Dynamic Field Usage (Allowed)
-
Dynamic Field Usage (Mandatory)
-
Extension
-
HTTP Link
-
Procedure
-
Product Filter
-
Validation Check
The following function signatures exist:
-
HTTP Link
-
Reusable Code
-
URL Composition
In-built Time Out
Writing Dynamic Logic incorrectly can impact performance and stability of the system. One of those specific implications concerns how we manage long running processes or resource hogging by mal-formed units of dynamic logic. The framework plugs-in a TimedInterrupt in every dynamic logic. The value of the timeout is governed by two properties:
Property Name | Data Type | Default Value | Description |
---|---|---|---|
ohi.dynamiclogic.timeout |
integer |
300 |
The global maximum time a unit of dynamic logic can run before the process monitor will interrupt the thread. The value is in seconds, and the default is 300 seconds. |
ohi.dynamiclogic.timeout.<CODE> |
integer |
N/A |
This is a dynamic property. <CODE> matches the code of the unit of dynamic logic, and will override the default time out for that unit of dynamic logic. |
If the timeout expires, the system interrupts the dynamic logic and throws a timeout exception with code OHI-DYLO-008 and message Dynamic Logic with code {code} timed out on line number {line number}: +{exception message}+
Please note that when the dynamic logic timeout property is added/updated, the dynamic logic(s) need to be recompiled for the property change to take effect. This can be done by using the Invalidate Dynamic Logic Integration Point explained Integration Guide.
Considerations when writing Dynamic Logic
Writing Dynamic Logic incorrectly can impact performance and stability of the system. This depends on the place where the logic is used. Is the logic only called in a background process, it may not be bad if the logic takes a few seconds to complete. If the logic is however used in UI pages, for example a dynamic field display condition, where it is called many times, a few seconds is not acceptable.
So when writing Dynamic Logic, make sure to:
-
Understand the use case where the logic is going to be used so you can judge what is and is not acceptable.
-
Avoid costly operations. Costly operations are :
-
Logic that results in a database query. A database query involved network communication and processing on another machine, so this is the most expensive operation in general. Note that a domain method like policy.policyEnrollmentList() may result in a database query as well.
-
Extensive looping over large number or objects.
-
-
Carefully assess the impact of the logic on system performance and stability. This can be done by running a performance test with and without the new/changed logic in place.
-
Test the script (in a test environment) with "timing.dynamicLogic" switched on (see below).
Enable Time Logging of Dynamic Logic Execution
This can be enabled using the log level "trace" for the logger "timing.dynamicLogic":
<logger name="timing.dynamicLogic" level="trace" />
Each dynamic logic execution will now be written to the application log files.
2018-08-02 12:05:02,234 ... TRACE timing.dynamicLogic - NAFMDFLT 0.042289 ms 2018-08-02 12:05:02,280 ... TRACE timing.dynamicLogic - ORGDYNREC1 0.267327 ms
Only enable this in test or development environments, as this will impact performance. |
See the Operations Guide for details about logging configuration |