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-3324 - Getting issue details... STATUS was actually  created to support this.

But supporting multiple outputs from a state - POLICY-3336 - Getting 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=HandleAAISuccessResponseTask
task contextref create name=HandleAAISuccessResponseTask albumName=EventDetailsAlbum
task logic create name=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

For the upcoming release, the implementation will be backward compatible. But the inputfields and outputfields in the task definition will be deprecated simply ignored with a warning message.

In later releases, these fields will be competely removed. So 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.

  • No labels

1 Comment

  1. The changes for POLICY-3336 are threefold then, solving different yet related issues

    1. remove inField and outFiled from Task definition in CLI file, i.e. minimizing partially redundant meta-data
    2. Allow a task to manage (fill) more than 1 output event
    3. Allow states to have multiple outputs with nextState=NULL (original story)


    The impact for (1)

    • inFields and outFields have been part of Task definition, which is done prior to associate a task with a state
    • for the definition of a policy
      • inFields are redundant, since they can be inferred from the single input event of a state and its fields
      • outFields are redundant if the task in the state is associated with a direct output, since the output defines the single output event with its fields
      • outFields of a task are rather ambiguous if the task in the state is associated to a finalizer logic since no single event from the finally selected output can be determined at definition time
    • for policy authoring
      • removing inFields and outFields makes authoring easier, yet the fields a task can/will/should process implicit
    • for policy definition validation
      • tasks associated with a state cannot be validated anymore in terms of inFields and outFields (when associated with a direct output)

    The practical impact for (1)

    • Validation of inFields is removed from CLI Editor
    • Validation for outFields is removed for many cases (i.e. states w/o finalizer logic)
    • Ambiguity for outFields is removed from CLI in case a state has a finalizer logic, since task  outFields cannot be tested/validated at definition time in this case anyway


    The impact for (2)

    • task logic and thus task definition is now somehow associated to where the task is being used later, i.e. in which state
    • the task designer will need to anticipate the potential outFields of potential output events
    • task designer does not need to know the output name and the output name is not encoded in the task(!)

    The practical impact for (2)

    • task design is (probably was all the time) not a completely isolated activity
    • adding a few lines at the end of the logic to deal with different output events seems a low price for the advantages
    • since the task can now handle multiple output maps, it is explicit to the task designer (and the state finalizer designer) how the event flow works (warning)


    The practical impact for (3)

    • removing the limitation of multiple outputs with no next state allows a policy to react in different ways, i.e. create different outputs, w/o adding much overhead (more states)
    • multiple policy output events are handy in different situations. e.g. when different scopes are served (not all outputs need/should-have all fields but are otherwise the same) or when different output is created altogether (e.g. a report or set of actions in different syntaxes, or visualization output; all from the same policy)


    We will need to update the APEX documentation (policy guide) and provide a few examples for this new behavior (changes 2 and 3).