Currently in APEX-PDP, there can only be 1 single output from a task and a state. But, there can be different use cases which require different outputs from a state.
A typical use case would be to send log events to DMaaP/Kafka topic along with any action taken, say AAI/CDS call. - POLICY-3324Getting issue details... STATUS was actually created to support this.
But supporting multiple outputs from a state - - POLICY-3336Getting issue details... STATUS can be considered as more generic APEX solution compared to implementing a utility method for specifically sending an event to DMaaP/Kafka.
Solution
The solution is to allow multiple output events from a State only when that state is the final state and there are no next states to it, because multiple output events makes more sense at Apex Policy concept level.
When there are next states, or in case of task selection logic or state finalizer logic, there will still be only 1 event output from the current state.
Steps
1. Fix the way tasks are defined
Tasks currently take 1 input event and produce 1 output event which is then consumed by its state. The fields expected in the input event and output event are defined in the command file (.apex file).
For example:
task create name=HandleAAISuccessResponseTask task inputfield create name=HandleAAISuccessResponseTask fieldName=vnf-id schemaName=SimpleStringType task inputfield create name=HandleAAISuccessResponseTask fieldName=vnf-name schemaName=SimpleStringType task inputfield create name=HandleAAISuccessResponseTask fieldName=vnf-type schemaName=SimpleStringType task inputfield create name=HandleAAISuccessResponseTask fieldName=service-id schemaName=SimpleStringType task inputfield create name=HandleAAISuccessResponseTask fieldName=prov-status schemaName=SimpleStringType task inputfield create name=HandleAAISuccessResponseTask fieldName=orchestration-status schemaName=SimpleStringType task inputfield create name=HandleAAISuccessResponseTask fieldName=in-maint schemaName=SimpleBooleanType task inputfield create name=HandleAAISuccessResponseTask fieldName=is-closed-loop-disabled schemaName=SimpleBooleanType task inputfield create name=HandleAAISuccessResponseTask fieldName=resource-version schemaName=SimpleStringType task inputfield create name=HandleAAISuccessResponseTask fieldName=model-invariant-id schemaName=SimpleStringType task inputfield create name=HandleAAISuccessResponseTask fieldName=model-version-id schemaName=SimpleStringType task inputfield create name=HandleAAISuccessResponseTask fieldName=model-customization-id schemaName=SimpleStringType task inputfield create name=HandleAAISuccessResponseTask fieldName=relationship-list schemaName=VnfRelationShipListType task outputfield create name=HandleAAISuccessResponseTask fieldName=commonHeader schemaName=CDSRequestCommonHeaderType task outputfield create name=HandleAAISuccessResponseTask fieldName=actionIdentifiers schemaName=CDSActionIdentifiersType task outputfield create name=HandleAAISuccessResponseTask fieldName=payload schemaName=CDSRequestPayloadType task contextref create name=HandleAAISuccessResponseTask albumName=EventDetailsAlbum task logic create name=HandleAAISuccessResponseTask logicFlavour=JAVASCRIPT logic=LS #MACROFILE:"src/main/resources/logic/HandleAAISuccessResponseTask.js" LE
A lot of this task definition contains redundant information and can be cleaned up, as the inputfields and outputfields are already defined as part of the event definition.
After cleanup:
task create name=ApexExample_HandleAAISuccessResponseTask task contextref create name=ApexExample_HandleAAISuccessResponseTask albumName=ApexExample_EventDetailsAlbum task logic create name=ApexExample_HandleAAISuccessResponseTask logicFlavour=JAVASCRIPT logic=LS #MACROFILE:"src/main/resources/logic/HandleAAISuccessResponseTask.js" LE
Input event(single trigger event) and output events(multiple output events from a final state - if this gets implemented) can be populated to a task as part of the policy/state definition because the event tagging is done there anyway.
2. Change the state output definition to support multiple outgoing events, and make all the related changes
Once the task definition is simplified, and refactored to support multiple outputs, the state output definitions can also be changed to support multiple outgoing events.
From a policy author point of view, the change to support multiple output events will look something like this:
policy state output create name=AAISuccessResponseHandlerPolicy stateName=ReceiveAAISuccessResponseState outputName=AAISuccessStateOutput eventName=CDSConfigModifyRequestEvent nextState=NULL policy state output create name=AAISuccessResponseHandlerPolicy stateName=ReceiveAAISuccessResponseState outputName=AAISuccessStateOutput eventName=LogEvent nextState=NULL
In the above example, ReceiveAAISuccessResponseState is the final state in AAISuccessResponseHandlerPolicy, and the state will have 2 outgoing events as part of the state output - CDSConfigModifyRequestEvent and LogEvent
3. Updates to TaskLogic
With these changes, if multiple output events are expected from a task, then they can be populated in the logic.
For example:
var event1Fieldsmap = java.util.HashMap(); event1Fieldsmap.put("event1field", "val"); var event2Fieldsmap = java.util.HashMap(); event2Fieldsmap.put("event2field", "val"); executor.addFieldsToOutputList(event1Fieldsmap); executor.addFieldsToOutputList(event2Fieldsmap);
A simple utility method "addFieldsToOutputList" can be added to TaskExecutionContext that matches the fields to the right event and updates its values.
If the use case doesn't really need multiple event outputs, then the policy author could go with either the above option - by adding only a single event's fields, or simple use the existing way - "executor.outfields.put(.......)"
Backward compatibility
With all these changes implemented, there will be 1 change required in all the existing policies to avoid breakage: cleanup the task definition as mentioned in step 1
Simply removing the inputfields and outputfields from the task definition should make everything else working as usual - even this change can be avoided if needed by simply logging a warning message and not actually use the fields definition at the task level.