From 9e67eb79f13bfc4bd536dae5ddaf12b8aa8a5dca Mon Sep 17 00:00:00 2001 From: "aditya.puthuparambil" Date: Thu, 30 Apr 2020 15:59:43 +0100 Subject: [PATCH] Apex-pdp documentation changed Code to Github Link + fix for errors and warnings Issue-ID: POLICY-2399 Signed-off-by: aditya.puthuparambil Change-Id: Ic5cfe700028fa7b27d89fc90f36d1bb8f14f7997 --- docs/apex/APEX-DecisionMakerExample.rst | 5 - docs/apex/APEX-Install-Guide.rst | 2 +- docs/apex/APEX-MyFirstPolicyExample.rst | 1026 +---------- docs/apex/APEX-PCVS-Example.rst | 2232 ++---------------------- docs/apex/APEX-User-Manual.rst | 2882 +++---------------------------- 5 files changed, 381 insertions(+), 5766 deletions(-) diff --git a/docs/apex/APEX-DecisionMakerExample.rst b/docs/apex/APEX-DecisionMakerExample.rst index 9bd6a564..57791ad6 100644 --- a/docs/apex/APEX-DecisionMakerExample.rst +++ b/docs/apex/APEX-DecisionMakerExample.rst @@ -68,11 +68,6 @@ APEX Examples Decision Maker .. |makeDecisionExtraMode_Server_link| raw:: html HTML Server: Extra Mode - -.. |apexConfigRESTServer_link| raw:: html - - APEX Configuration: Rest Server - .. |answerInitTask_link| raw:: html Task Logic: Answer Init diff --git a/docs/apex/APEX-Install-Guide.rst b/docs/apex/APEX-Install-Guide.rst index a264a119..0cff1317 100644 --- a/docs/apex/APEX-Install-Guide.rst +++ b/docs/apex/APEX-Install-Guide.rst @@ -1027,7 +1027,7 @@ Verify Installation - run an Example .. container:: content .. code:: bash - :number-lines: + :number-lines: # $APEX_HOME/bin/apexEngine.sh -c $APEX_HOME/examples/config/SampleDomain/Stdin2StdoutJsonEventJava.json (1) # $APEX_HOME/bin/apexEngine.sh -c C:/apex/apex-full-2.0.0-SNAPSHOT/examples/config/SampleDomain/Stdin2StdoutJsonEventJava.json (2) diff --git a/docs/apex/APEX-MyFirstPolicyExample.rst b/docs/apex/APEX-MyFirstPolicyExample.rst index 52991add..7a608f83 100644 --- a/docs/apex/APEX-MyFirstPolicyExample.rst +++ b/docs/apex/APEX-MyFirstPolicyExample.rst @@ -48,8 +48,8 @@ Data Models .. container:: sect2 - .. rubric:: Sales Decision Event - :name: sales_decision_event + .. rubric:: Sales Input Event + :name: sales_input_event .. container:: paragraph @@ -247,7 +247,7 @@ Policy Step 1 .. container:: ulist - - Alcohol cannot be sold before 11:30am... container:: + - Alcohol cannot be sold before 11:30am... New Policy Model ---------------- @@ -285,13 +285,13 @@ New Policy Model .. container:: content - |File > New to create a new Policy Model| + |File > New to create a new Policy Model| .. container:: imageblock .. container:: content - |Create a new Policy Model| + |Create a new Policy Model| Events ------ @@ -426,8 +426,6 @@ Events for ``SALE_INPUT`` and ``SALE_AUTH`` and add some parameter fields. - .. container:: admonitionblock tip - .. TIP:: .. container:: paragraph @@ -483,8 +481,6 @@ Events Remember to click the 'Submit' button at the bottom of the event definition pane. - .. container:: admonitionblock tip - .. TIP:: .. container:: paragraph @@ -672,7 +668,7 @@ New Policy .. container:: paragraph - For simplicity use the following code for the task logic. + For simplicity use the code for the task logic here(|taskLogicMvel_link|). Paste the script text into the 'Task Logic' box, and use "MVEL" as the 'Task Logic Type / Flavour'. @@ -690,92 +686,6 @@ New Policy of the other supported languages please refer to APEX Programmers Guide. - .. container:: listingblock - - .. container:: content - - .. code:: CodeRay - - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - import java.util.Date; - import java.util.Calendar; - import java.util.TimeZone; - import java.text.SimpleDateFormat; - - logger.info("Task Execution: '"+subject.id+"'. Input Fields: '"+inFields+"'"); - - outFields.put("amount" , inFields.get("amount")); - outFields.put("assistant_ID", inFields.get("assistant_ID")); - outFields.put("notes" , inFields.get("notes")); - outFields.put("quantity" , inFields.get("quantity")); - outFields.put("branch_ID" , inFields.get("branch_ID")); - outFields.put("item_ID" , inFields.get("item_ID")); - outFields.put("time" , inFields.get("time")); - outFields.put("sale_ID" , inFields.get("sale_ID")); - - item_id = inFields.get("item_ID"); - - //The events used later to test this task use GMT timezone! - gmt = TimeZone.getTimeZone("GMT"); - timenow = Calendar.getInstance(gmt); - df = new SimpleDateFormat("HH:mm:ss z"); - df.setTimeZone(gmt); - timenow.setTimeInMillis(inFields.get("time")); - - midnight = timenow.clone(); - midnight.set( - timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), - timenow.get(Calendar.DATE),0,0,0); - eleven30 = timenow.clone(); - eleven30.set( - timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), - timenow.get(Calendar.DATE),11,30,0); - - itemisalcohol = false; - if(item_id != null && item_id >=1000 && item_id < 2000) - itemisalcohol = true; - - if( itemisalcohol - && timenow.after(midnight) && timenow.before(eleven30)){ - outFields.put("authorised", false); - outFields.put("message", "Sale not authorised by policy task "+subject.taskName+ - " for time "+df.format(timenow.getTime())+ - ". Alcohol can not be sold between "+df.format(midnight.getTime())+ - " and "+df.format(eleven30.getTime())); - return true; - } - else{ - outFields.put("authorised", true); - outFields.put("message", "Sale authorised by policy task "+subject.taskName+ - " for time "+df.format(timenow.getTime())); - return true; - } - - /* - This task checks if a sale request is for an item that is an alcoholic drink. - If the local time is between 00:00:00 GMT and 11:30:00 GMT then the sale is not - authorised. Otherwise the sale is authorised. - In this implementation we assume that items with item_ID value between 1000 and - 2000 are all alcoholic drinks :-) - */ .. container:: imageblock @@ -786,95 +696,9 @@ New Policy .. container:: paragraph An alternative version of the same logic is available in - JavaScript. Just use "JAVASCRIPT" as the 'Task Logic Type + JavaScript(|taskLogicJS_link|). Just use "JAVASCRIPT" as the 'Task Logic Type / Flavour' instead. - .. container:: listingblock - - .. container:: content - - .. code:: CodeRay - - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - - var returnValueType = Java.type("java.lang.Boolean"); - var returnValue = new returnValueType(true); - - // Load compatibility script for imports etc - load("nashorn:mozilla_compat.js"); - importPackage(java.text); - importClass(java.text.SimpleDateFormat); - - executor.logger.info("Task Execution: '"+executor.subject.id+"'. Input Fields: '"+executor.inFields+"'"); - - executor.outFields.put("amount" , executor.inFields.get("amount")); - executor.outFields.put("assistant_ID", executor.inFields.get("assistant_ID")); - executor.outFields.put("notes" , executor.inFields.get("notes")); - executor.outFields.put("quantity" , executor.inFields.get("quantity")); - executor.outFields.put("branch_ID" , executor.inFields.get("branch_ID")); - executor.outFields.put("item_ID" , executor.inFields.get("item_ID")); - executor.outFields.put("time" , executor.inFields.get("time")); - executor.outFields.put("sale_ID" , executor.inFields.get("sale_ID")); - - item_id = executor.inFields.get("item_ID"); - - //All times in this script are in GMT/UTC since the policy and events assume time is in GMT. - var timenow_gmt = new Date(Number(executor.inFields.get("time"))); - - var midnight_gmt = new Date(Number(executor.inFields.get("time"))); - midnight_gmt.setUTCHours(0,0,0,0); - - var eleven30_gmt = new Date(Number(executor.inFields.get("time"))); - eleven30_gmt.setUTCHours(11,30,0,0); - - var timeformatter = new java.text.SimpleDateFormat("HH:mm:ss z"); - - var itemisalcohol = false; - if(item_id != null && item_id >=1000 && item_id < 2000) - itemisalcohol = true; - - if( itemisalcohol - && timenow_gmt.getTime() >= midnight_gmt.getTime() - && timenow_gmt.getTime() < eleven30_gmt.getTime()) { - - executor.outFields.put("authorised", false); - executor.outFields.put("message", "Sale not authorised by policy task " + - executor.subject.taskName+ " for time " + timeformatter.format(timenow_gmt.getTime()) + - ". Alcohol can not be sold between " + timeformatter.format(midnight_gmt.getTime()) + - " and " + timeformatter.format(eleven30_gmt.getTime())); - } - else{ - executor.outFields.put("authorised", true); - executor.outFields.put("message", "Sale authorised by policy task " + - executor.subject.taskName + " for time "+timeformatter.format(timenow_gmt.getTime())); - } - - /* - This task checks if a sale request is for an item that is an alcoholic drink. - If the local time is between 00:00:00 GMT and 11:30:00 GMT then the sale is not - authorised. Otherwise the sale is authorised. - In this implementation we assume that items with item_ID value between 1000 and - 2000 are all alcoholic drinks :-) - */ - .. container:: paragraph The task definition is now complete so click the 'Submit' @@ -954,11 +778,10 @@ New Policy default task is automatically selected and no 'Task Selection Logic' is required. - .. container:: admonitionblock note - .. NOTE:: .. container:: paragraph + In a 'Policy' 'State' a 'State Output Mapping' has 3 roles: 1) Select which 'State' should be executed next, 2) Select the type of the state’s 'Outgoing Event', and 3) Populate the state’s 'Outgoing Event'. This is how states are chained together @@ -1074,7 +897,7 @@ Test The Policy .. container:: paragraph To start a new APEX Engine you can use the following - configuration. In a full APEX installation you can find + |policy1_configuration|. In a full APEX installation you can find this configuration in ``$APEX_HOME/examples/config/MyFirstPolicy/1/MyFirstPolicyConfigStdin2StdoutJsonEvent.json``. This configuration expects incoming events to be in @@ -1087,59 +910,6 @@ Test The Policy the full path to wherever you stored the exported policy model file. - .. container:: listingblock - - .. container:: content - - .. code:: CodeRay - - { - "engineServiceParameters" : { - "name" : "MyFirstPolicyApexEngine", - "version" : "0.0.1", - "id" : 101, - "instanceCount" : 4, - "deploymentPort" : 12345, - "policyModelFileName" : "examples/models/MyFirstPolicy/1/MyFirstPolicyModel_0.0.1.json", - "engineParameters" : { - "executorParameters" : { - "MVEL" : { - "parameterClassName" : "org.onap.policy.apex.plugins.executor.mvel.MVELExecutorParameters" - }, - "JAVASCRIPT" : { - "parameterClassName" : "org.onap.policy.apex.plugins.executor.javascript.JavascriptExecutorParameters" - } - } - } - }, - "eventOutputParameters": { - "FirstProducer": { - "carrierTechnologyParameters" : { - "carrierTechnology" : "FILE", - "parameters" : { - "standardIO" : true - } - }, - "eventProtocolParameters" : { - "eventProtocol" : "JSON" - } - } - }, - "eventInputParameters": { - "FirstConsumer": { - "carrierTechnologyParameters" : { - "carrierTechnology" : "FILE", - "parameters" : { - "standardIO" : true - } - }, - "eventProtocolParameters" : { - "eventProtocol" : "JSON" - } - } - } - } - .. container:: paragraph To test the policy try paste the following events into @@ -1166,7 +936,7 @@ Test The Policy :language: JSON - .. container:: paragraph - Request to buy alcohol item (`item_ID=1249`) at _08:41:06_ on _Monday, 02 January 2017_. + Request to buy alcohol item (`item_ID=1249`) at 08:41:06 on Monday, 02 January 2017. Sale is not authorized. * - .. literalinclude:: events/1/EventIn_BoozeItem_201713GMT.json :language: JSON @@ -1174,7 +944,7 @@ Test The Policy :language: JSON - .. container:: paragraph - Request to buy alcohol (`item_ID=1943`) at _20:17:13_ on _Tuesday, 20 December 2016_. + Request to buy alcohol (`item_ID=1943`) at 20:17:13 on Tuesday, 20 December 2016. Sale is authorized. @@ -1194,187 +964,11 @@ CLI Editor File policy model can again be generated using the APEX CLI editor. A sample APEX CLI script is shown below: - .. container:: listingblock + .. container:: ulist - .. container:: content + - |policy1ModelMvel_link| + - |policy1ModelJs_link| - .. code:: CodeRay - - #------------------------------------------------------------------------------- - # ============LICENSE_START======================================================= - # Copyright (C) 2016-2018 Ericsson. All rights reserved. - # ================================================================================ - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. - # - # SPDX-License-Identifier: Apache-2.0 - # ============LICENSE_END========================================================= - #------------------------------------------------------------------------------- - - model create name=MyFirstPolicyModel version=0.0.1 uuid=540226fb-55ee-4f0e-a444-983a0494818e description="This is my first Apex Policy Model." - - schema create name=assistant_ID_type version=0.0.1 uuid=36df4c71-9616-4206-8b53-976a5cd4bd87 description="A type for 'assistant_ID' values" flavour=Java schema=java.lang.Long - - schema create name=authorised_type version=0.0.1 uuid=d48b619e-d00d-4008-b884-02d76ea4350b description="A type for 'authorised' values" flavour=Java schema=java.lang.Boolean - - schema create name=branch_ID_type version=0.0.1 uuid=6468845f-4122-4128-8e49-0f52c26078b5 description="A type for 'branch_ID' values" flavour=Java schema=java.lang.Long - - schema create name=item_ID_type version=0.0.1 uuid=4f227ff1-aee0-453a-b6b6-9a4b2e0da932 description="A type for 'item_ID' values" flavour=Java schema=java.lang.Long - - schema create name=message_type version=0.0.1 uuid=ad1431bb-3155-4e73-b5a3-b89bee498749 description="A type for 'message' values" flavour=Java schema=java.lang.String - - schema create name=notes_type version=0.0.1 uuid=eecfde90-896c-4343-8f9c-2603ced94e2d description="A type for 'notes' values" flavour=Java schema=java.lang.String - - schema create name=price_type version=0.0.1 uuid=52c2fc45-fd8c-463c-bd6f-d91b0554aea7 description="A type for 'amount'/'price' values" flavour=Java schema=java.lang.Long - - schema create name=quantity_type version=0.0.1 uuid=ac3d9842-80af-4a98-951c-bd79a431c613 description="A type for 'quantity' values" flavour=Java schema=java.lang.Integer - - schema create name=sale_ID_type version=0.0.1 uuid=cca47d74-7754-4a61-b163-ca31f66b157b description="A type for 'sale_ID' values" flavour=Java schema=java.lang.Long - - schema create name=timestamp_type version=0.0.1 uuid=fd594e88-411d-4a94-b2be-697b3a0d7adf description="A type for 'time' values" flavour=Java schema=java.lang.Long - - task create name=MorningBoozeCheck version=0.0.1 uuid=3351b0f4-cf06-4fa2-8823-edf67bd30223 description=LS - This task checks if the sales request is for an item that contains alcohol. - If the local time is between 00:00:00 and 11:30:00 then the sale is not authorised. Otherwise the sale is authorised. - In this implementation we assume that all items with item_ID values between 1000 and 2000 contain alcohol :-) - LE - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=amount schemaName=price_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=quantity schemaName=quantity_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=time schemaName=timestamp_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=amount schemaName=price_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=quantity schemaName=quantity_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=authorised schemaName=authorised_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=time schemaName=timestamp_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=message schemaName=message_type schemaVersion=0.0.1 optional=true - task logic create name=MorningBoozeCheck version=0.0.1 logicFlavour=MVEL logic=LS - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - import java.util.Date; - import java.util.Calendar; - import java.util.TimeZone; - import java.text.SimpleDateFormat; - - logger.info("Task Execution: '"+subject.id+"'. Input Fields: '"+inFields+"'"); - - outFields.put("amount" , inFields.get("amount")); - outFields.put("assistant_ID", inFields.get("assistant_ID")); - outFields.put("notes" , inFields.get("notes")); - outFields.put("quantity" , inFields.get("quantity")); - outFields.put("branch_ID" , inFields.get("branch_ID")); - outFields.put("item_ID" , inFields.get("item_ID")); - outFields.put("time" , inFields.get("time")); - outFields.put("sale_ID" , inFields.get("sale_ID")); - - item_id = inFields.get("item_ID"); - - //The events used later to test this task use GMT timezone! - gmt = TimeZone.getTimeZone("GMT"); - timenow = Calendar.getInstance(gmt); - df = new SimpleDateFormat("HH:mm:ss z"); - df.setTimeZone(gmt); - timenow.setTimeInMillis(inFields.get("time")); - - midnight = timenow.clone(); - midnight.set( - timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), - timenow.get(Calendar.DATE),0,0,0); - eleven30 = timenow.clone(); - eleven30.set( - timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), - timenow.get(Calendar.DATE),11,30,0); - - itemisalcohol = false; - if(item_id != null && item_id >=1000 && item_id < 2000) - itemisalcohol = true; - - if( itemisalcohol - && timenow.after(midnight) && timenow.before(eleven30)){ - outFields.put("authorised", false); - outFields.put("message", "Sale not authorised by policy task "+subject.taskName+ - " for time "+df.format(timenow.getTime())+ - ". Alcohol can not be sold between "+df.format(midnight.getTime())+ - " and "+df.format(eleven30.getTime())); - return true; - } - else{ - outFields.put("authorised", true); - outFields.put("message", "Sale authorised by policy task "+subject.taskName+ - " for time "+df.format(timenow.getTime())); - return true; - } - - /* - This task checks if a sale request is for an item that is an alcoholic drink. - If the local time is between 00:00:00 GMT and 11:30:00 GMT then the sale is not - authorised. Otherwise the sale is authorised. - In this implementation we assume that items with item_ID value between 1000 and - 2000 are all alcoholic drinks :-) - */ - LE - - event create name=SALE_AUTH version=0.0.1 uuid=c4500941-3f98-4080-a9cc-5b9753ed050b description="An event emitted by the Policy to indicate whether the sale of an item has been authorised" nameSpace=com.hyperm source="APEX" target="POS" - event parameter create name=SALE_AUTH version=0.0.1 parName=amount schemaName=price_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=authorised schemaName=authorised_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=message schemaName=message_type schemaVersion=0.0.1 optional=true - event parameter create name=SALE_AUTH version=0.0.1 parName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true - event parameter create name=SALE_AUTH version=0.0.1 parName=quantity schemaName=quantity_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=time schemaName=timestamp_type schemaVersion=0.0.1 - - event create name=SALE_INPUT version=0.0.1 uuid=4f04aa98-e917-4f4a-882a-c75ba5a99374 description="An event raised by the PoS system each time an item is scanned for purchase" nameSpace=com.hyperm source="POS" target="APEX" - event parameter create name=SALE_INPUT version=0.0.1 parName=amount schemaName=price_type schemaVersion=0.0.1 - event parameter create name=SALE_INPUT version=0.0.1 parName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_INPUT version=0.0.1 parName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_INPUT version=0.0.1 parName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_INPUT version=0.0.1 parName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true - event parameter create name=SALE_INPUT version=0.0.1 parName=quantity schemaName=quantity_type schemaVersion=0.0.1 - event parameter create name=SALE_INPUT version=0.0.1 parName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_INPUT version=0.0.1 parName=time schemaName=timestamp_type schemaVersion=0.0.1 - - - policy create name=MyFirstPolicy version=0.0.1 uuid=6c5e410f-489a-46ff-964e-982ce6e8b6d0 description="This is my first Apex policy. It checks if a sale should be authorised or not." template=FREEFORM firstState=BoozeAuthDecide - policy state create name=MyFirstPolicy version=0.0.1 stateName=BoozeAuthDecide triggerName=SALE_INPUT triggerVersion=0.0.1 defaultTaskName=MorningBoozeCheck defaultTaskVersion=0.0.1 - policy state output create name=MyFirstPolicy version=0.0.1 stateName=BoozeAuthDecide outputName=MorningBoozeCheck_Output_Direct eventName=SALE_AUTH eventVersion=0.0.1 nextState=NULL - policy state taskref create name=MyFirstPolicy version=0.0.1 stateName=BoozeAuthDecide taskLocalName=MorningBoozeCheck taskName=MorningBoozeCheck taskVersion=0.0.1 outputType=DIRECT outputName=MorningBoozeCheck_Output_Direct Policy Step 2 ^^^^^^^^^^^^^ @@ -1384,7 +978,7 @@ Policy Step 2 .. container:: sect1 .. rubric:: Scenario - :name: scenario + :name: scenario_policy2 .. container:: paragraph @@ -1430,8 +1024,7 @@ Extend Policy Model the same input and output fields that we used earlier when we defined the ``MorningBoozeCheck`` task earlier. - .. table:: Table 1. Input fields for - ``MorningBoozeCheckAlt1`` task + .. table:: Table 1. Input fields for ``MorningBoozeCheckAlt1`` task +-----------------------------------+-----------------------------------+ | Parameter Name | Parameter Type | @@ -1453,8 +1046,7 @@ Extend Policy Model | notes | notes_type | +-----------------------------------+-----------------------------------+ - .. table:: Table 2. Output fields for - ``MorningBoozeCheckAlt1`` task + .. table:: Table 2. Output fields for ``MorningBoozeCheckAlt1`` task +-----------------------------------+-----------------------------------+ | Parameter Name | Parameter Type | @@ -1487,7 +1079,7 @@ Extend Policy Model .. container:: paragraph - For simplicity use the following code for the task logic. + For simplicity use the following code for the task logic (|policy2_taskLogic_link|). It again assumes that all items with ``item_ID`` between 1000 and 2000 contain alcohol. We again use the standard ``Java`` time utilities to check if the current time is @@ -1507,98 +1099,9 @@ Extend Policy Model of the other supported languages please refer to APEX Programmers Guide. - .. container:: listingblock - - .. container:: content - - .. code:: CodeRay - - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - import java.util.Date; - import java.util.Calendar; - import java.util.TimeZone; - import java.text.SimpleDateFormat; - - logger.info("Task Execution: '"+subject.id+"'. Input Event: '"+inFields+"'"); - - outFields.put("amount" , inFields.get("amount")); - outFields.put("assistant_ID", inFields.get("assistant_ID")); - outFields.put("notes" , inFields.get("notes")); - outFields.put("quantity" , inFields.get("quantity")); - outFields.put("branch_ID" , inFields.get("branch_ID")); - outFields.put("item_ID" , inFields.get("item_ID")); - outFields.put("time" , inFields.get("time")); - outFields.put("sale_ID" , inFields.get("sale_ID")); - - item_id = inFields.get("item_ID"); - - //The events used later to test this task use CET timezone! - cet = TimeZone.getTimeZone("CET"); - timenow = Calendar.getInstance(cet); - df = new SimpleDateFormat("HH:mm:ss z"); - df.setTimeZone(cet); - timenow.setTimeInMillis(inFields.get("time")); - - midnight = timenow.clone(); - midnight.set( - timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), - timenow.get(Calendar.DATE),0,0,0); - onepm = timenow.clone(); - onepm.set( - timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), - timenow.get(Calendar.DATE),13,0,0); - - itemisalcohol = false; - if(item_id != null && item_id >=1000 && item_id < 2000) - itemisalcohol = true; - - if( itemisalcohol && - ( (timenow.after(midnight) && timenow.before(onepm)) - || - (timenow.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) - )){ - outFields.put("authorised", false); - outFields.put("message", "Sale not authorised by policy task "+subject.taskName+ - " for time "+df.format(timenow.getTime())+ - ". Alcohol can not be sold between "+df.format(midnight.getTime())+ - " and "+df.format(onepm.getTime()) +" or on Sunday"); - return true; - } - else{ - outFields.put("authorised", true); - outFields.put("message", "Sale authorised by policy task "+subject.taskName+ - " for time "+df.format(timenow.getTime())); - return true; - } - - /* - This task checks if a sale request is for an item that is an alcoholic drink. - If the local time is between 00:00:00 CET and 13:00:00 CET then the sale is not authorised. - Also alcohol sales are not allowed on Sundays. Otherwise the sale is authorised. - In this implementation we assume that items with item_ID between 1000 and 2000 are all alcoholic drinks :-) - */ + .. container:: imageblock - .. container:: imageblock - - .. container:: content + .. container:: content |Create a new alternative task \`MorningBoozeCheckAlt1\`| @@ -1618,7 +1121,7 @@ Extend Policy Model Navigate to the ``BoozeAuthDecide`` state in the 'states' section at the bottom of the policy definition pane. - .. container:: imageblock + .. container:: imageblock .. container:: content @@ -1661,9 +1164,7 @@ Extend Policy Model logic using the ```JavaScript`` `__ scripting language. Sample task selection logic code - (specified in - ```JavaScript`` `__) - is given below. Paste the script text into the 'Task + is given here (|policy2_taskSelectionLogic_link|). Paste the script text into the 'Task Selection Logic' box, and use "JAVASCRIPT" as the 'Task Selection Logic Type / Flavour'. It is necessary to mark one of the tasks as the 'Default Task' so that the task @@ -1672,62 +1173,8 @@ Extend Policy Model case the ``MorningBoozeCheck`` task can be the default task. - .. container:: listingblock - - .. container:: content - .. code:: CodeRay - - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - - - var returnValueType = Java.type("java.lang.Boolean"); - var returnValue = new returnValueType(true); - - executor.logger.info("Task Selection Execution: '"+executor.subject.id+ - "'. Input Event: '"+executor.inFields+"'"); - - branchid = executor.inFields.get("branch_ID"); - taskorig = executor.subject.getTaskKey("MorningBoozeCheck"); - taskalt = executor.subject.getTaskKey("MorningBoozeCheckAlt1"); - taskdef = executor.subject.getDefaultTaskKey(); - - if(branchid >=0 && branchid <1000){ - taskorig.copyTo(executor.selectedTask); - } - else if (branchid >=1000 && branchid <2000){ - taskalt.copyTo(executor.selectedTask); - } - else{ - taskdef.copyTo(executor.selectedTask); - } - - /* - This task selection logic selects task "MorningBoozeCheck" for branches with - 0<=branch_ID<1000 and selects task "MorningBoozeCheckAlt1" for branches with - 1000<=branch_ID<2000. Otherwise the default task is selected. - In this case the default task is also "MorningBoozeCheck" - */ - - .. container:: imageblock + .. container:: imageblock .. container:: content @@ -1770,66 +1217,13 @@ Test The Policy .. container:: paragraph To start a new APEX Engine you can use the following - configuration. In a full APEX installation you can find + |policy2_configuration_link|. In a full APEX installation you can find this configuration in ``$APEX_HOME/examples/config/MyFirstPolicy/2/MyFirstPolicyConfigStdin2StdoutJsonEvent.json``. Note, this has changed from the configuration file in Step 1 to enable the ``JAVASCRIPT`` executor for our new 'Task Selection Logic'. - .. container:: listingblock - - .. container:: content - - .. code:: CodeRay - - { - "engineServiceParameters" : { - "name" : "MyFirstPolicyApexEngine", - "version" : "0.0.1", - "id" : 102, - "instanceCount" : 4, - "deploymentPort" : 12345, - "policyModelFileName" : "examples/models/MyFirstPolicy/2/MyFirstPolicyModel_0.0.1.json", - "engineParameters" : { - "executorParameters" : { - "MVEL" : { - "parameterClassName" : "org.onap.policy.apex.plugins.executor.mvel.MVELExecutorParameters" - }, - "JAVASCRIPT" : { - "parameterClassName" : "org.onap.policy.apex.plugins.executor.javascript.JavascriptExecutorParameters" - } - } - } - }, - "eventOutputParameters": { - "FirstProducer": { - "carrierTechnologyParameters" : { - "carrierTechnology" : "FILE", - "parameters" : { - "standardIO" : true - } - }, - "eventProtocolParameters" : { - "eventProtocol" : "JSON" - } - } - }, - "eventInputParameters": { - "FirstConsumer": { - "carrierTechnologyParameters" : { - "carrierTechnology" : "FILE", - "parameters" : { - "standardIO" : true - } - }, - "eventProtocolParameters" : { - "eventProtocol" : "JSON" - } - } - } - } - .. container:: paragraph To test the policy try paste the following events into @@ -1853,7 +1247,7 @@ Test The Policy :language: JSON - .. container:: paragraph - Request to buy alcohol item (`item_ID=1249`) at _08:41:06 GMT_ on _Monday, 02 January 2017_. + Request to buy alcohol item (`item_ID=1249`) at 08:41:06 GMT on Monday, 02 January 2017. Sale is not authorized. Uses the `MorningBoozeCheck` task. * - .. literalinclude:: events/2/EventIn_BoozeItem_101433CET_thurs.json @@ -1862,7 +1256,7 @@ Test The Policy :language: JSON - .. container:: paragraph - Request to buy alcohol (`item_ID=1047`) at _10:14:33_ on _Thursday, 22 December 2016_. + Request to buy alcohol (`item_ID=1047`) at 10:14:33 on Thursday, 22 December 2016. Sale is not authorized. Uses the `MorningBoozeCheckAlt1` task. * - .. literalinclude:: events/2/EventIn_BoozeItem_171937CET_sun.json @@ -1871,7 +1265,7 @@ Test The Policy :language: JSON - .. container:: paragraph - Request to buy alcohol (`item_ID=1443`) at _17:19:37_ on _Sunday, 18 December 2016_. + Request to buy alcohol (`item_ID=1443`) at 17:19:37 on Sunday, 18 December 2016. Sale is not authorized. Uses the `MorningBoozeCheckAlt1` task. * - .. literalinclude:: events/2/EventIn_NonBoozeItem_111309CET_mon.json @@ -1880,7 +1274,7 @@ Test The Policy :language: JSON - .. container:: paragraph - Request to buy non-alcoholic item (`item_ID=5321`) at _11:13:09_ on _Monday, 2 January 2017_. + Request to buy non-alcoholic item (`item_ID=5321`) at 11:13:09 on Monday, 2 January 2017. Sale is authorized. Uses the `MorningBoozeCheckAlt1` task. CLI Editor File @@ -1899,342 +1293,9 @@ CLI Editor File policy model can again be generated using the APEX CLI editor. A sample APEX CLI script is shown below: - .. container:: listingblock - - .. container:: content + .. container:: ulist - .. code:: CodeRay - - #------------------------------------------------------------------------------- - # ============LICENSE_START======================================================= - # Copyright (C) 2016-2018 Ericsson. All rights reserved. - # ================================================================================ - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. - # - # SPDX-License-Identifier: Apache-2.0 - # ============LICENSE_END========================================================= - #------------------------------------------------------------------------------- - - model create name=MyFirstPolicyModel version=0.0.1 uuid=540226fb-55ee-4f0e-a444-983a0494818e description="This is my first Apex Policy Model." - - schema create name=assistant_ID_type version=0.0.1 uuid=36df4c71-9616-4206-8b53-976a5cd4bd87 description="A type for 'assistant_ID' values" flavour=Java schema=java.lang.Long - - schema create name=authorised_type version=0.0.1 uuid=d48b619e-d00d-4008-b884-02d76ea4350b description="A type for 'authorised' values" flavour=Java schema=java.lang.Boolean - - schema create name=branch_ID_type version=0.0.1 uuid=6468845f-4122-4128-8e49-0f52c26078b5 description="A type for 'branch_ID' values" flavour=Java schema=java.lang.Long - - schema create name=item_ID_type version=0.0.1 uuid=4f227ff1-aee0-453a-b6b6-9a4b2e0da932 description="A type for 'item_ID' values" flavour=Java schema=java.lang.Long - - schema create name=message_type version=0.0.1 uuid=ad1431bb-3155-4e73-b5a3-b89bee498749 description="A type for 'message' values" flavour=Java schema=java.lang.String - - schema create name=notes_type version=0.0.1 uuid=eecfde90-896c-4343-8f9c-2603ced94e2d description="A type for 'notes' values" flavour=Java schema=java.lang.String - - schema create name=price_type version=0.0.1 uuid=52c2fc45-fd8c-463c-bd6f-d91b0554aea7 description="A type for 'amount'/'price' values" flavour=Java schema=java.lang.Long - - schema create name=quantity_type version=0.0.1 uuid=ac3d9842-80af-4a98-951c-bd79a431c613 description="A type for 'quantity' values" flavour=Java schema=java.lang.Integer - - schema create name=sale_ID_type version=0.0.1 uuid=cca47d74-7754-4a61-b163-ca31f66b157b description="A type for 'sale_ID' values" flavour=Java schema=java.lang.Long - - schema create name=timestamp_type version=0.0.1 uuid=fd594e88-411d-4a94-b2be-697b3a0d7adf description="A type for 'time' values" flavour=Java schema=java.lang.Long - - task create name=MorningBoozeCheck version=0.0.1 uuid=3351b0f4-cf06-4fa2-8823-edf67bd30223 description=LS - This task checks if the sales request is for an item that contains alcohol. - If the local time is between 00:00:00 and 11:30:00 then the sale is not authorised. Otherwise the sale is authorised. - In this implementation we assume that all items with item_ID values between 1000 and 2000 contain alcohol :-) - LE - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=amount schemaName=price_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=quantity schemaName=quantity_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=time schemaName=timestamp_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=amount schemaName=price_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=quantity schemaName=quantity_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=authorised schemaName=authorised_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=time schemaName=timestamp_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=message schemaName=message_type schemaVersion=0.0.1 optional=true - task logic create name=MorningBoozeCheck version=0.0.1 logicFlavour=MVEL logic=LS - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - import java.util.Date; - import java.util.Calendar; - import java.util.TimeZone; - import java.text.SimpleDateFormat; - - logger.info("Task Execution: '"+subject.id+"'. Input Fields: '"+inFields+"'"); - - outFields.put("amount" , inFields.get("amount")); - outFields.put("assistant_ID", inFields.get("assistant_ID")); - outFields.put("notes" , inFields.get("notes")); - outFields.put("quantity" , inFields.get("quantity")); - outFields.put("branch_ID" , inFields.get("branch_ID")); - outFields.put("item_ID" , inFields.get("item_ID")); - outFields.put("time" , inFields.get("time")); - outFields.put("sale_ID" , inFields.get("sale_ID")); - - item_id = inFields.get("item_ID"); - - //The events used later to test this task use GMT timezone! - gmt = TimeZone.getTimeZone("GMT"); - timenow = Calendar.getInstance(gmt); - df = new SimpleDateFormat("HH:mm:ss z"); - df.setTimeZone(gmt); - timenow.setTimeInMillis(inFields.get("time")); - - midnight = timenow.clone(); - midnight.set( - timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), - timenow.get(Calendar.DATE),0,0,0); - eleven30 = timenow.clone(); - eleven30.set( - timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), - timenow.get(Calendar.DATE),11,30,0); - - itemisalcohol = false; - if(item_id != null && item_id >=1000 && item_id < 2000) - itemisalcohol = true; - - if( itemisalcohol - && timenow.after(midnight) && timenow.before(eleven30)){ - outFields.put("authorised", false); - outFields.put("message", "Sale not authorised by policy task "+subject.taskName+ - " for time "+df.format(timenow.getTime())+ - ". Alcohol can not be sold between "+df.format(midnight.getTime())+ - " and "+df.format(eleven30.getTime())); - return true; - } - else{ - outFields.put("authorised", true); - outFields.put("message", "Sale authorised by policy task "+subject.taskName+ - " for time "+df.format(timenow.getTime())); - return true; - } - - /* - This task checks if a sale request is for an item that is an alcoholic drink. - If the local time is between 00:00:00 GMT and 11:30:00 GMT then the sale is not - authorised. Otherwise the sale is authorised. - In this implementation we assume that items with item_ID value between 1000 and - 2000 are all alcoholic drinks :-) - */ - LE - - task create name=MorningBoozeCheckAlt1 version=0.0.1 uuid=bc6d90c9-c902-4686-afd3-925b30e39990 description=LS - This task checks if a sale request is for an item that is an alcoholic drink. - If the local time is between 00:00:00 CET and 13:00:00 CET then the sale is not authorised. - Also alcohol sales are not allowed on Sundays. Otherwise the sale is authorised. - In this implementation we assume that items with item_ID between 1000 and 2000 are all alcoholic drinks - LE - task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=amount schemaName=price_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true - task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=quantity schemaName=quantity_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=time schemaName=timestamp_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=amount schemaName=price_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true - task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=quantity schemaName=quantity_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=authorised schemaName=authorised_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=time schemaName=timestamp_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=message schemaName=message_type schemaVersion=0.0.1 optional=true - task logic create name=MorningBoozeCheckAlt1 version=0.0.1 logicFlavour=MVEL logic=LS - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - import java.util.Date; - import java.util.Calendar; - import java.util.TimeZone; - import java.text.SimpleDateFormat; - - logger.info("Task Execution: '"+subject.id+"'. Input Event: '"+inFields+"'"); - - outFields.put("amount" , inFields.get("amount")); - outFields.put("assistant_ID", inFields.get("assistant_ID")); - outFields.put("notes" , inFields.get("notes")); - outFields.put("quantity" , inFields.get("quantity")); - outFields.put("branch_ID" , inFields.get("branch_ID")); - outFields.put("item_ID" , inFields.get("item_ID")); - outFields.put("time" , inFields.get("time")); - outFields.put("sale_ID" , inFields.get("sale_ID")); - - item_id = inFields.get("item_ID"); - - //The events used later to test this task use CET timezone! - cet = TimeZone.getTimeZone("CET"); - timenow = Calendar.getInstance(cet); - df = new SimpleDateFormat("HH:mm:ss z"); - df.setTimeZone(cet); - timenow.setTimeInMillis(inFields.get("time")); - - midnight = timenow.clone(); - midnight.set( - timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), - timenow.get(Calendar.DATE),0,0,0); - onepm = timenow.clone(); - onepm.set( - timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), - timenow.get(Calendar.DATE),13,0,0); - - itemisalcohol = false; - if(item_id != null && item_id >=1000 && item_id < 2000) - itemisalcohol = true; - - if( itemisalcohol && - ( (timenow.after(midnight) && timenow.before(onepm)) - || - (timenow.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) - )){ - outFields.put("authorised", false); - outFields.put("message", "Sale not authorised by policy task "+subject.taskName+ - " for time "+df.format(timenow.getTime())+ - ". Alcohol can not be sold between "+df.format(midnight.getTime())+ - " and "+df.format(onepm.getTime()) +" or on Sunday"); - return true; - } - else{ - outFields.put("authorised", true); - outFields.put("message", "Sale authorised by policy task "+subject.taskName+ - " for time "+df.format(timenow.getTime())); - return true; - } - - /* - This task checks if a sale request is for an item that is an alcoholic drink. - If the local time is between 00:00:00 CET and 13:00:00 CET then the sale is not authorised. - Also alcohol sales are not allowed on Sundays. Otherwise the sale is authorised. - In this implementation we assume that items with item_ID between 1000 and 2000 are all alcoholic drinks :-) - */ - LE - - event create name=SALE_AUTH version=0.0.1 uuid=c4500941-3f98-4080-a9cc-5b9753ed050b description="An event emitted by the Policy to indicate whether the sale of an item has been authorised" nameSpace=com.hyperm source="APEX" target="POS" - event parameter create name=SALE_AUTH version=0.0.1 parName=amount schemaName=price_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=authorised schemaName=authorised_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=message schemaName=message_type schemaVersion=0.0.1 optional=true - event parameter create name=SALE_AUTH version=0.0.1 parName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true - event parameter create name=SALE_AUTH version=0.0.1 parName=quantity schemaName=quantity_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=time schemaName=timestamp_type schemaVersion=0.0.1 - - event create name=SALE_INPUT version=0.0.1 uuid=4f04aa98-e917-4f4a-882a-c75ba5a99374 description="An event raised by the PoS system each time an item is scanned for purchase" nameSpace=com.hyperm source="POS" target="APEX" - event parameter create name=SALE_INPUT version=0.0.1 parName=amount schemaName=price_type schemaVersion=0.0.1 - event parameter create name=SALE_INPUT version=0.0.1 parName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_INPUT version=0.0.1 parName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_INPUT version=0.0.1 parName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_INPUT version=0.0.1 parName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true - event parameter create name=SALE_INPUT version=0.0.1 parName=quantity schemaName=quantity_type schemaVersion=0.0.1 - event parameter create name=SALE_INPUT version=0.0.1 parName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_INPUT version=0.0.1 parName=time schemaName=timestamp_type schemaVersion=0.0.1 - - - policy create name=MyFirstPolicy version=0.0.1 uuid=6c5e410f-489a-46ff-964e-982ce6e8b6d0 description="This is my first Apex policy. It checks if a sale should be authorised or not." template=FREEFORM firstState=BoozeAuthDecide - policy state create name=MyFirstPolicy version=0.0.1 stateName=BoozeAuthDecide triggerName=SALE_INPUT triggerVersion=0.0.1 defaultTaskName=MorningBoozeCheck defaultTaskVersion=0.0.1 - policy state output create name=MyFirstPolicy version=0.0.1 stateName=BoozeAuthDecide outputName=MorningBoozeCheck_Output_Direct eventName=SALE_AUTH eventVersion=0.0.1 nextState=NULL - policy state taskref create name=MyFirstPolicy version=0.0.1 stateName=BoozeAuthDecide taskLocalName=MorningBoozeCheckAlt1 taskName=MorningBoozeCheckAlt1 taskVersion=0.0.1 outputType=DIRECT outputName=MorningBoozeCheck_Output_Direct - policy state taskref create name=MyFirstPolicy version=0.0.1 stateName=BoozeAuthDecide taskLocalName=MorningBoozeCheck taskName=MorningBoozeCheck taskVersion=0.0.1 outputType=DIRECT outputName=MorningBoozeCheck_Output_Direct - policy state selecttasklogic create name=MyFirstPolicy version=0.0.1 stateName=BoozeAuthDecide logicFlavour=JAVASCRIPT logic=LS - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - - var returnValueType = Java.type("java.lang.Boolean"); - var returnValue = new returnValueType(true); - - executor.logger.info("Task Selection Execution: '"+executor.subject.id+"'. Input Event: '"+executor.inFields+"'"); - - branchid = executor.inFields.get("branch_ID"); - taskorig = executor.subject.getTaskKey("MorningBoozeCheck"); - taskalt = executor.subject.getTaskKey("MorningBoozeCheckAlt1"); - taskdef = executor.subject.getDefaultTaskKey(); - - if(branchid >=0 && branchid <1000){ - taskorig.copyTo(executor.selectedTask); - } - else if (branchid >=1000 && branchid <2000){ - taskalt.copyTo(executor.selectedTask); - } - else{ - taskdef.copyTo(executor.selectedTask); - } - - /* - This task selection logic selects task "MorningBoozeCheck" for branches with 0<=branch_ID<1000 and selects task "MorningBoozeCheckAlt1" for branches with 1000<=branch_ID<2000. Otherwise the default task is selected. In this case the default task is also "MorningBoozeCheck" - */ - LE + - |policy2_Model_link| .. container:: @@ -2261,8 +1322,33 @@ CLI Editor File .. |Add a Task and Output Mapping| image:: images/mfp/MyFirstPolicy_P1_newState2.png .. |Validate the policy model for error using the 'Model' > 'Validate' menu item| image:: images/mfp/MyFirstPolicy_P1_validatePolicyModel.png .. |Download the completed policy model using the 'File' > 'Download' menu item| image:: images/mfp/MyFirstPolicy_P1_exportPolicyModel1.png -.. |Create a new alternative task \`MorningBoozeCheckAlt1\`| image:: images/mfp/MyFirstPolicy_P2_newTask1.png +.. |Create a new alternative task `MorningBoozeCheckAlt1`| image:: images/mfp/MyFirstPolicy_P2_newTask1.png .. |Right click to edit a policy| image:: images/mfp/MyFirstPolicy_P2_editPolicy1.png .. |State definition with 2 Tasks and Task Selection Logic| image:: images/mfp/MyFirstPolicy_P2_editState1.png +.. |taskLogicMvel_link| raw:: html + + Task Logic: MorningBoozeCheck.mvel +.. |taskLogicJs_link| raw:: html + + Task Logic: MorningBoozeCheck.js +.. |policy1_configuration| raw:: html + + configuration +.. |policy1ModelMvel_link| raw:: html + + APEX CLI Editor code for Policy 1 using .Mvel Task Logic +.. |policy1ModelJs_link| raw:: html + + APEX CLI Editor code for Policy 1 using .Js Task Logic +.. |policy2_taskLogic_link| raw:: html + + `MorningBoozeCheckAlt1` task logic (`MVEL`) +.. |policy2_taskSelectionLogic_link| raw:: html + + `BoozeAuthDecide` task selection logic (`JavaScript`) +.. |policy2_configuration_link| raw:: html + configuration +.. |policy2_Model_link| raw:: html + APEX CLI Editor code for Policy 2 diff --git a/docs/apex/APEX-PCVS-Example.rst b/docs/apex/APEX-PCVS-Example.rst index fc420303..b3b843ca 100644 --- a/docs/apex/APEX-PCVS-Example.rst +++ b/docs/apex/APEX-PCVS-Example.rst @@ -16,12 +16,11 @@ Introduction .. container:: paragraph - This module contains several demos for - Policy-controlled Video Streaming (PCVS). Each demo - defines a policy using AVRO and Javascript (or other - scripting languages for the policy logic). To run the - demo, a vanilla Ubuntu server with some extra software - packages is required: + This module contains several demos for + Policy-controlled Video Streaming (PCVS). Each demo + defines a policy using AVRO and Javascript (or other + scripting languages for the policy logic). To run the + demo, a vanilla Ubuntu server with some extra software packages is required: .. container:: ulist @@ -585,60 +584,11 @@ Context Schemas model edges and nodes for the topology, customers, and problems with all information on detected problems. - .. container:: listingblock - - .. container:: content - - .. code:: CodeRay - - { - "type" : "record", - "name" : "TopologyEdges", - "fields" : [ - {"name": "name", "type": "string", "doc": "Name of the Edge, typically a link name"}, - {"name": "start", "type": "string", "doc": "Edge endpoint: start - a node name"}, - {"name": "end", "type": "string", "doc": "Edge endpoint: end - a node name"}, - {"name": "active", "type": "boolean", "doc": "Flag for active/inactive edges, inactive means a link is down"} - ] - } - - .. container:: listingblock - - .. container:: content - - .. code:: CodeRay - - { - "type" : "record", - "name" : "TopologyNodes", - "fields" : [ - {"name" : "name", "type" : "string", "doc": "The name of the node"}, - {"name" : "mnname", "type" : "string", "doc": "The name of the node in Mininet"} - ] - } - - .. container:: listingblock - - .. container:: content + .. container:: ulist - .. code:: CodeRay - - { - "type" : "record", - "name" : "Customer", - "fields" : [ - {"name" : "customerName", "type" : "string"}, - {"name" : "dtSLA" , "type" : "int"}, - {"name" : "dtYTD" , "type" : "int"}, - {"name" : "priority" , "type" : "boolean"}, - {"name" : "satisfaction", "type" : "int"}, - { - "name": "links", - "doc": "Links used by this customer", - "type": {"type" : "array", "items" : "string"} - } - ] - } + - |avroSchemaEdges_link| + - |avroSchemaNodes_link| + - |avroSchemaCustomers_link| Trigger Schemas @@ -652,24 +602,11 @@ Trigger Schemas The trigger event provides a status as ``UP`` or ``DOWN``. To avoid tests for these strings in the - logic, we defined an Avro schema for an enumeration. + logic, we defined an Avro schema for an enumeration (|avroSchemaLinkStatus_link|). This does not impact the trigger system (it can still send the strings), but makes the task logic simpler. - .. container:: listingblock - - .. container:: content - .. code:: CodeRay - - { - "type": "enum", - "name": "Status", - "symbols" : [ - "UP", - "DOWN" - ] - } Context Logic Nodes -------------------- @@ -682,77 +619,7 @@ Context Logic Nodes The node context logic simply takes the trigger event (for context) and creates a new node in the local - context topology. - - .. container:: listingblock - - .. container:: content - - .. code:: CodeRay - - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - - load("nashorn:mozilla_compat.js"); - - var logger = executor.logger; - logger.trace("start: " + executor.subject.id); - logger.trace("-- infields: " + executor.inFields); - - var ifNodeName = executor.inFields["nodeName"]; - var ifMininetName = executor.inFields["mininetName"]; - - var albumTopoNodes = executor.getContextAlbum("albumTopoNodes"); - - logger.trace("-- got infields, testing existing node"); - - var ctxtNode = albumTopoNodes.get(ifNodeName); - if (ctxtNode != null) { - albumTopoNodes.remove(ifNodeName); - logger.trace("-- removed node: <" + ifNodeName + ">"); - } - - logger.trace("-- creating node: <" + ifNodeName + ">"); - ctxtNode = "{name:" + ifNodeName + ", mnname:" + ifMininetName + "}"; - albumTopoNodes.put(ifNodeName, ctxtNode); - - if (logger.isTraceEnabled()) { - logger.trace(" >> *** Nodes ***"); - if (albumTopoNodes != null) { - for (var i = 0; i < albumTopoNodes.values().size(); i++) { - logger.trace(" >> >> " + albumTopoNodes.values().get(i).get("name") + " : " - + albumTopoNodes.values().get(i).get("mnname")); - } - } else { - logger.trace(" >> >> node album is null"); - } - } - - executor.outFields["report"] = "node ctxt :: added node " + ifNodeName; - - logger.info("vpnsla: ctxt added node " + ifNodeName); - - var returnValueType = Java.type("java.lang.Boolean"); - var returnValue = new returnValueType(true); - logger.trace("finished: " + executor.subject.id); - logger.debug("."); + context topology (|cntxtNodes_link|). Context Logic Edges -------------------- @@ -765,79 +632,8 @@ Context Logic Edges The edge context logic simply takes the trigger event (for context) and creates a new edge in the local - context topology. + context topology (|cntxtEdges_link|). - .. container:: listingblock - - .. container:: content - - .. code:: CodeRay - - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - - load("nashorn:mozilla_compat.js"); - - var logger = executor.logger; - logger.trace("start: " + executor.subject.id); - logger.trace("-- infields: " + executor.inFields); - - var ifEdgeName = executor.inFields["edgeName"]; - var ifEdgeStatus = executor.inFields["status"]; - - var albumTopoEdges = executor.getContextAlbum("albumTopoEdges"); - - logger.trace("-- got infields, testing existing edge"); - - var ctxtEdge = albumTopoEdges.get(ifEdgeName); - if (ctxtEdge != null) { - albumTopoEdges.remove(ifEdgeName); - logger.trace("-- removed edge: <" + ifEdgeName + ">"); - } - - logger.trace("-- creating edge: <" + ifEdgeName + ">"); - ctxtEdge = "{name:" + ifEdgeName + ", start:" + executor.inFields["start"] + ", end:" + executor.inFields["end"] - + ", active:" + ifEdgeStatus + "}"; - albumTopoEdges.put(ifEdgeName, ctxtEdge); - - if (logger.isTraceEnabled()) { - logger.trace(" >> *** Edges ***"); - if (albumTopoEdges != null) { - for (var i = 0; i < albumTopoEdges.values().size(); i++) { - logger.trace(" >> >> " + albumTopoEdges.values().get(i).get("name") + " \t " - + albumTopoEdges.values().get(i).get("start") + " --> " + albumTopoEdges.values().get(i).get("end") - + " \t " + albumTopoEdges.values().get(i).get("active")); - } - } else { - logger.trace(" >> >> edge album is null"); - } - } - - executor.outFields["report"] = "edge ctxt :: added edge " + ifEdgeName; - - logger.info("vpnsla: ctxt added edge " + ifEdgeName); - - var returnValueType = Java.type("java.lang.Boolean"); - var returnValue = new returnValueType(true); - logger.trace("finished: " + executor.subject.id); - logger.debug("."); Context Logic Customer ---------------------- @@ -850,94 +646,8 @@ Context Logic Customer The customer context logic simply takes the trigger event (for context) and creates a new customer in the - local context topology. + local context topology (|cntxtCustomer_link|). - .. container:: listingblock - - .. container:: content - - .. code:: CodeRay - - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - - load("nashorn:mozilla_compat.js"); - - var logger = executor.logger; - logger.trace("start: " + executor.subject.id); - logger.trace("-- infields: " + executor.inFields); - - var ifCustomerName = executor.inFields["customerName"]; - var ifLinks = executor.inFields["links"]; - - logger.trace("-- got infields, testing existing customer"); - var ctxtCustomer = executor.getContextAlbum("albumCustomerMap").get(ifCustomerName); - if (ctxtCustomer != null) { - executor.getContextAlbum("albumCustomerMap").remove(ifCustomerName); - logger.trace("-- removed customer: <" + ifCustomerName + ">"); - } - - logger.trace("-- creating customer: <" + ifCustomerName + ">"); - var links = new Array(); - for (var i = 0; i < ifLinks.split(" ").length; i++) { - var link = executor.getContextAlbum("albumTopoEdges").get(ifLinks.split(" ")[i]); - if (link != null) { - logger.trace("-- link: <" + ifLinks.split(" ")[i] + ">"); - links.push(ifLinks.split(" ")[i]); - } else { - logger.trace("-- unknown link: <" + ifLinks.split(" ")[i] + "> for customer <" + ifCustomerName + ">"); - } - } - logger.trace("-- links: <" + links + ">"); - ctxtCustomer = "{customerName:" + ifCustomerName + ", dtSLA:" + executor.inFields["dtSLA"] + ", dtYTD:" - + executor.inFields["dtYTD"] + ", priority:" + executor.inFields["priority"] + ", satisfaction:" - + executor.inFields["satisfaction"] + ", links:[" + links + "]}"; - - executor.getContextAlbum("albumCustomerMap").put(ifCustomerName, ctxtCustomer); - - if (logger.isTraceEnabled()) { - logger.trace(" >> *** Customers ***"); - if (executor.getContextAlbum("albumCustomerMap") != null) { - for (var i = 0; i < executor.getContextAlbum("albumCustomerMap").values().size(); i++) { - logger.trace(" >> >> " + executor.getContextAlbum("albumCustomerMap").values().get(i).get("customerName") - + " : " + "dtSLA=" + executor.getContextAlbum("albumCustomerMap").values().get(i).get("dtSLA") - + " : " + "dtYTD=" + executor.getContextAlbum("albumCustomerMap").values().get(i).get("dtYTD") - + " : " + "links=" + executor.getContextAlbum("albumCustomerMap").values().get(i).get("links") - + " : " + "priority=" - + executor.getContextAlbum("albumCustomerMap").values().get(i).get("priority") + " : " - + "satisfaction=" - + executor.getContextAlbum("albumCustomerMap").values().get(i).get("satisfaction")); - } - } else { - logger.trace(" >> >> customer album is null"); - } - } - - executor.outFields["report"] = "customer ctxt :: added customer: " + ifCustomerName; - - logger.info("vpnsla: ctxt added customer " + ifCustomerName); - - var returnValueType = Java.type("java.lang.Boolean"); - var returnValue = new returnValueType(true); - logger.trace("finished: " + executor.subject.id); - logger.debug("."); Logic: Match ------------ @@ -952,94 +662,8 @@ Logic: Match simple. Beside taking the trigger event, it also creates a timestamp. This timestamp is later used for SLA and downtime calculations as well as for some - performance information of the policy. - - .. container:: listingblock - - .. container:: content - - .. code:: CodeRay - - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - - load("nashorn:mozilla_compat.js"); - - var now = new Date().getTime(); - executor.outFields["matchStart"] = now; - - importClass(org.slf4j.LoggerFactory); - - var logger = executor.logger; - logger.trace("start: " + executor.subject.id); - logger.trace("-- infields: " + executor.inFields); - - var rootLogger = LoggerFactory.getLogger(logger.ROOT_LOGGER_NAME); - - var ifEdgeName = executor.inFields["edgeName"]; - var ifLinkStatus = executor.inFields["status"]; - - var albumTopoEdges = executor.getContextAlbum("albumTopoEdges"); - - logger.trace("-- got infields, checking albumTopoEdges changes"); - - var active = false; - switch (ifLinkStatus.toString()) { - case "UP": - active = true; - break; - case "DOWN": - active = false; - break; - default: - active = false; - logger.error("-- trigger sent unknown link status <" + ifLinkStatus + "> for link <" + ifEdgeName + ">"); - rootLogger.error(executor.subject.id + " " + "-- trigger sent unknown link status <" + ifLinkStatus - + "> for link <" + ifEdgeName + ">"); - } - - var link = albumTopoEdges.get(ifEdgeName); - if (link == null) { - logger.trace("-- link <" + ifEdgeName + "> not in albumTopoEdges"); - } else { - logger.trace("-- found link <" + link + "> in albumTopoEdges"); - logger.trace("-- active <" + active + "> : link.active <" + link.get("active") + ">"); - if (active != link.get("active")) { - link.put("active", active); - logger.trace("-- link <" + ifEdgeName + "> status changed to "); - executor.outFields["hasChanged"] = true; - } else { - logger.trace("-- link <" + ifEdgeName + "> status not changed "); - executor.outFields["hasChanged"] = false; - } - } - - executor.outFields["edgeName"] = ifEdgeName; - executor.outFields["status"] = ifLinkStatus; - - logger.info("vpnsla: detected " + ifEdgeName + " as " + ifLinkStatus); - - var returnValueType = Java.type("java.lang.Boolean"); - var returnValue = new returnValueType(true); - logger.trace("finished: " + executor.subject.id); - logger.debug(".m"); + performance information of the policy . + Sample |taskMatch_link| Logic: Policy Establish State @@ -1065,183 +689,7 @@ Logic: Policy Establish State problem still exists). It also calculates customer SLA downtime and checks for any SLA violations. Finally, it creates a situation object. - - .. container:: listingblock - - .. container:: content - - .. code:: CodeRay - - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - - load("nashorn:mozilla_compat.js"); - importClass(org.slf4j.LoggerFactory); - - importClass(java.util.ArrayList); - - importClass(org.apache.avro.generic.GenericData.Array); - importClass(org.apache.avro.generic.GenericRecord); - importClass(org.apache.avro.Schema); - - var logger = executor.logger; - logger.trace("start: " + executor.subject.id); - logger.trace("-- infields: " + executor.inFields); - - var rootLogger = LoggerFactory.getLogger(logger.ROOT_LOGGER_NAME); - - var ifEdgeName = executor.inFields["edgeName"]; - var ifEdgeStatus = executor.inFields["status"].toString(); - var ifhasChanged = executor.inFields["hasChanged"]; - var ifMatchStart = executor.inFields["matchStart"]; - - var albumCustomerMap = executor.getContextAlbum("albumCustomerMap"); - var albumProblemMap = executor.getContextAlbum("albumProblemMap"); - - var linkProblem = albumProblemMap.get(ifEdgeName); - - // create outfiled for situation - var situation = executor.subject.getOutFieldSchemaHelper("situation").createNewInstance(); - situation.put("violatedSLAs", new ArrayList()); - - // create a string as states+hasChanged+linkProblem and switch over it - var switchTest = ifEdgeStatus + ":" + ifhasChanged + ":" + (linkProblem == null ? "no" : "yes"); - switch (switchTest) { - case "UP:false:no": - logger.trace("-- edge <" + ifEdgeName + "> UP:false:no => everything ok"); - logger.info("vpnsla: everything ok"); - situation.put("problemID", "NONE"); - break; - case "UP:false:yes": - logger.trace("-- edge <" + ifEdgeName + "> UP:false:yes ==> did we miss earlier up?, removing problem"); - albumProblemMap.remove(ifEdgeName); - linkProblem = null; - situation.put("problemID", "NONE"); - break; - case "UP:true:no": - logger.trace("-- edge <" + ifEdgeName + "> UP:true:no ==> did we miss the earlier down?, creating new problem"); - situation.put("problemID", ifEdgeName); - break; - case "UP:true:yes": - logger.trace("-- edge <" + ifEdgeName + "> UP:true:yes ==> detected solution, link up again"); - logger.info("vpnsla: problem solved"); - linkProblem.put("endTime", ifMatchStart); - linkProblem.put("status", "SOLVED"); - situation.put("problemID", "NONE"); - break; - case "DOWN:false:no": - logger.trace("-- edge <" + ifEdgeName + "> DOWN:false:no ==> did we miss an earlier down?, creating new problem"); - situation.put("problemID", ifEdgeName); - break; - case "DOWN:false:yes": - logger.trace("-- edge <" + ifEdgeName + "> DOWN:false:yes ==> problem STILL exists"); - logger.info("vpnsla: problem still exists"); - linkProblem.put("status", "STILL"); - situation.put("problemID", ifEdgeName); - break; - case "DOWN:true:no": - logger.trace("-- edge <" + ifEdgeName + "> DOWN:true:no ==> found NEW problem"); - logger.info("vpnsla: this is a new problem"); - situation.put("problemID", ifEdgeName); - break; - case "DOWN:true:yes": - logger.trace("-- edge <" + ifEdgeName - + "> DOWN:true:yes ==> did we miss to remove an earlier problem?, remove and create new problem"); - linkProblem = null; - situation.put("problemID", ifEdgeName); - break; - - default: - logger.error("-- input wrong for edge" + ifEdgeName + ": edge status <" + ifEdgeStatus - + "> unknown or null on hasChanged <" + ifhasChanged + ">"); - rootLogger.error("-- input wrong for edge" + ifEdgeName + ": edge status <" + ifEdgeStatus - + "> unknown or null on hasChanged <" + ifhasChanged + ">"); - } - - // create new problem if situation requires it - if (situation.get("problemID").equals(ifEdgeName) && linkProblem == null) { - logger.trace("-- edge <" + ifEdgeName + "> creating new problem"); - linkProblem = albumProblemMap.getSchemaHelper().createNewInstance(); - linkProblem.put("edge", ifEdgeName); - linkProblem.put("startTime", ifMatchStart); - linkProblem.put("lastUpdate", ifMatchStart); - linkProblem.put("endTime", 0); - linkProblem.put("status", "NEW"); - linkProblem.put("edgeUsedBy", new ArrayList()); - linkProblem.put("impededLast", new ArrayList()); - - for (var i = 0; i < albumCustomerMap.values().size(); i++) { - var customer = albumCustomerMap.values().get(i); - var customerLinks = albumCustomerMap.values().get(i).get("links"); - for (var k = 0; k < customerLinks.size(); k++) { - if (customerLinks.get(k) == ifEdgeName) { - linkProblem.get("edgeUsedBy").add(customer.get("customerName")); - } - } - } - albumProblemMap.put(ifEdgeName, linkProblem); - logger.trace("-- edge <" + ifEdgeName + "> problem created as <" + linkProblem + ">"); - } - - // set dtYTD if situation requires it - if (linkProblem != null && (linkProblem.get("status") == "STILL" || linkProblem.get("status") == "SOLVED")) { - var linkDownTimeinSecs = (ifMatchStart - linkProblem.get("lastUpdate")) / 1000; - logger.trace("-- edge <" + ifEdgeName + "> down time: " + linkDownTimeinSecs + " s"); - for (var k = 0; k < linkProblem.get("impededLast").size(); k++) { - for (var i = 0; i < albumCustomerMap.values().size(); i++) { - var customer = albumCustomerMap.values().get(i); - if (customer.get("customerName").equals(linkProblem.get("impededLast").get(k))) { - logger.info("-- vpnsla: customer " + customer.get("customerName") + " YDT downtime increased from " - + customer.get("dtYTD") + " to " + (customer.get("dtYTD") + linkDownTimeinSecs)); - customer.put("dtYTD", (customer.get("dtYTD") + linkDownTimeinSecs)) - } - } - } - // set lastUpdate to this policy execution for next execution calculation - linkProblem.put("lastUpdate", ifMatchStart); - } - - // check SLA violations if situation requires it - if (linkProblem != null && linkProblem.get("status") != "SOLVED") { - logger.info(">e> customer\tDT SLA\tDT YTD\tviolation"); - for (var i = 0; i < albumCustomerMap.values().size(); i++) { - var customer = albumCustomerMap.values().get(i); - if (customer.get("dtYTD") > customer.get("dtSLA")) { - situation.get("violatedSLAs").add(customer.get("customerName")); - logger.info(">e> " + customer.get("customerName") + "\t\t" + customer.get("dtSLA") + "s\t" - + customer.get("dtYTD") + "s\t" + "!!"); - } else { - logger.info(">e> " + customer.get("customerName") + "\t\t" + customer.get("dtSLA") + "s\t" - + customer.get("dtYTD") + "s"); - } - } - } - - executor.outFields["situation"] = situation; - - logger.trace("-- out fields <" + executor.outFields + ">"); - - var returnValueType = Java.type("java.lang.Boolean"); - var returnValue = new returnValueType(true); - logger.trace("finished: " + executor.subject.id); - logger.debug(".e"); + Sample |taskEstablish_link| Logic: Policy Decide State -------------------------- @@ -1257,410 +705,21 @@ Logic: Policy Decide State Task Selection Logic (TSL). This TSL select a task in the current policy execution (i.e. potentially a different one per execution). - - .. container:: listingblock - - .. container:: content - - .. code:: CodeRay - - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - - load("nashorn:mozilla_compat.js"); - importClass(org.slf4j.LoggerFactory); - - var logger = executor.logger; - logger.trace("start: " + executor.subject.id + " - TSL"); - - var rootLogger = LoggerFactory.getLogger(logger.ROOT_LOGGER_NAME); - - var ifSituation = executor.inFields["situation"]; - - var albumProblemMap = executor.getContextAlbum("albumProblemMap"); - - var returnValueType = Java.type("java.lang.Boolean"); - if (ifSituation.get("problemID") == "NONE") { - logger.trace("-- situation has no problem, selecting "); - executor.subject.getTaskKey("VpnSlaPolicyDecideNoneTask").copyTo(executor.selectedTask); - var returnValue = new returnValueType(true); - } else if (albumProblemMap.get(ifSituation.get("problemID")).get("status") == "SOLVED") { - logger.trace("-- situation is solved, selecting "); - executor.subject.getTaskKey("VpnSlaPolicyDecideSolvedTask").copyTo(executor.selectedTask); - var returnValue = new returnValueType(true); - } else if (ifSituation.get("violatedSLAs") != null && ifSituation.get("violatedSLAs").size() > 0) { - logger.trace("-- situation is problem with violations, selecting "); - executor.subject.getTaskKey("VpnSlaPolicyDecidePriorityTask").copyTo(executor.selectedTask); - var returnValue = new returnValueType(true); - } else if (ifSituation.get("violatedSLAs") != null && ifSituation.get("violatedSLAs").size() == 0) { - logger.trace("-- situation is problem without violations, selecting "); - executor.subject.getTaskKey("VpnSlaPolicyDecideSlaTask").copyTo(executor.selectedTask); - var returnValue = new returnValueType(true); - } else { - logger.error("-- detected unknown decision for situation <" + ifSituation.get("problemID") + ">"); - rootLogger.error(executor.subject.id + " " + "-- detected unknown decision for situation <" - + ifSituation.get("problemID") + ">"); - var returnValue = new returnValueType(false); - } - - logger.trace("finished: " + executor.subject.id); - logger.debug(".d-tsl"); + Sample |tslDecide_Link| .. container:: paragraph The actual task logic are then ``none``, ``solved``, ``sla``, and ``priority``. + Sample task logic are as given below : -Logic: Decide None -------------------- - - .. container:: sect1 - - .. container:: sectionbody - - .. container:: listingblock - - .. container:: content - - .. code:: CodeRay - - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - - load("nashorn:mozilla_compat.js"); - importClass(org.slf4j.LoggerFactory); - - importClass(java.util.ArrayList); - - importClass(org.apache.avro.generic.GenericData.Array); - importClass(org.apache.avro.generic.GenericRecord); - importClass(org.apache.avro.Schema); - - var logger = executor.logger; - logger.trace("start: " + executor.subject.id); - logger.trace("-- infields: " + executor.inFields); - - var rootLogger = LoggerFactory.getLogger(logger.ROOT_LOGGER_NAME); - - var ifSituation = executor.inFields["situation"]; - - // create outfiled for decision - var decision = executor.subject.getOutFieldSchemaHelper("decision").createNewInstance(); - decision.put("description", "None, everything is ok"); - decision.put("decision", "NONE"); - decision.put("customers", new ArrayList()); - - var returnValueType = Java.type("java.lang.Boolean"); - if (ifSituation.get("problemID") == "NONE") { - logger.trace("-- no problem, everything ok"); - var returnValue = new returnValueType(true); - } else { - logger.trace("-- wrong problemID <" + problemID + "> for NONE task, we should not be here"); - rootLogger.error(executor.subject.id + " " + "-- wrong problemID <" + problemID - + "> for NONE task, we should not be here"); - var returnValue = new returnValueType(false); - } - - executor.outFields["decision"] = decision; - - logger.trace("finished: " + executor.subject.id); - logger.debug(".d-non"); - -Logic: Decide Solved ---------------------- - - .. container:: sect1 - - .. container:: sectionbody - - .. container:: listingblock - - .. container:: content - - .. code:: CodeRay - - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - - load("nashorn:mozilla_compat.js"); - importClass(org.slf4j.LoggerFactory); - - importClass(java.util.ArrayList); - - importClass(org.apache.avro.generic.GenericData.Array); - importClass(org.apache.avro.generic.GenericRecord); - importClass(org.apache.avro.Schema); - - var logger = executor.logger; - logger.trace("start: " + executor.subject.id); - logger.trace("-- infields: " + executor.inFields); - - var rootLogger = LoggerFactory.getLogger(logger.ROOT_LOGGER_NAME); - - var ifSituation = executor.inFields["situation"]; - - var albumProblemMap = executor.getContextAlbum("albumProblemMap"); - - // create outfiled for decision - var decision = executor.subject.getOutFieldSchemaHelper("decision").createNewInstance(); - decision.put("description", "None, everything is ok"); - decision.put("decision", "REBUILD"); - decision.put("customers", new ArrayList()); - decision.put("problemID", ifSituation.get("problemID")); - - var returnValueType = Java.type("java.lang.Boolean"); - if (albumProblemMap.get(ifSituation.get("problemID")).get("status") == "SOLVED") { - logger.trace("-- problem solved"); - var returnValue = new returnValueType(true); - } else { - logger.trace("-- wrong problemID <" + problemID + "> for SOLVED task, we should not be here"); - rootLogger.error(executor.subject.id + " " + "-- wrong problemID <" + problemID - + "> for SOLVED task, we should not be here"); - var returnValue = new returnValueType(false); - } - - executor.outFields["decision"] = decision; - - logger.info("vpnsla: sla solved, problem solved"); - - logger.trace("finished: " + executor.subject.id); - logger.debug(".d-non"); - -Logic: Decide SLA ------------------- - - .. container:: sect1 - - .. container:: sectionbody - - .. container:: listingblock - - .. container:: content + .. container:: ulist - .. code:: CodeRay - - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - - load("nashorn:mozilla_compat.js"); - importClass(org.slf4j.LoggerFactory); - - importClass(java.util.ArrayList); - - importClass(org.apache.avro.generic.GenericData.Array); - importClass(org.apache.avro.generic.GenericRecord); - importClass(org.apache.avro.Schema); - - var logger = executor.logger; - logger.trace("start: " + executor.subject.id); - logger.trace("-- infields: " + executor.inFields); - - var rootLogger = LoggerFactory.getLogger(logger.ROOT_LOGGER_NAME); - - var ifSituation = executor.inFields["situation"]; - - var albumCustomerMap = executor.getContextAlbum("albumCustomerMap"); - var albumProblemMap = executor.getContextAlbum("albumProblemMap"); - - // create outfiled for decision - var decision = executor.subject.getOutFieldSchemaHelper("decision").createNewInstance(); - decision.put("description", "Impede given customers selected based on maximum SLA delta"); - decision.put("decision", "IMPEDE"); - decision.put("problemID", ifSituation.get("problemID")); - decision.put("customers", new ArrayList()); - - var problem = albumProblemMap.get(ifSituation.get("problemID")); - var returnValueType = Java.type("java.lang.Boolean"); - if (problem != null && ifSituation.get("violatedSLAs").size() == 0) { - logger.trace("-- impede by maximum SLA"); - var customer = ""; - var customerSla = 0; - for (var i = 0; i < problem.get("edgeUsedBy").size(); i++) { - customerCtxt = albumCustomerMap.get(problem.get("edgeUsedBy").get(i).toString()); - if (customerSla == 0) { - customerSla = customerCtxt.get("dtSLA") - customerCtxt.get("dtYTD"); - } - if ((customerCtxt.get("dtSLA") - customerCtxt.get("dtYTD")) >= customerSla) { - customer = customerCtxt.get("customerName"); - customerSla = (customerCtxt.get("dtSLA") - customerCtxt.get("dtYTD")); - } - } - decision.get("customers").add(customer); - var returnValue = new returnValueType(true); - } else { - logger.trace("-- wrong problemID <" + ifSituation.get("problemID") + "> for SLA task, we should not be here"); - rootLogger.error(executor.subject.id + " " + "-- wrong problemID <" + ifSituation.get("problemID") - + "> for SLA task, we should not be here"); - var returnValue = new returnValueType(false); - } - - // set impededLast to decision[customers] - problem.get("impededLast").clear(); - problem.get("impededLast").addAll(decision.get("customers")); - - executor.outFields["decision"] = decision; - logger.trace("-- decision: " + decision); - - logger.info("vpnsla: sla balance, impeding customers " + decision.get("customers")); - - logger.trace("finished: " + executor.subject.id); - logger.debug(".d-sla"); - -Logic: Decide Priority ----------------------- + - |taskDecideNone_link| + - |taskDecideSolved_Link| + - |taskDecideSla_link| + - |taskDecidePriority_Link| - .. container:: sect2 - - .. container:: listingblock - - .. container:: content - - .. code:: CodeRay - - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - - load("nashorn:mozilla_compat.js"); - importClass(org.slf4j.LoggerFactory); - - importClass(java.util.ArrayList); - - importClass(org.apache.avro.generic.GenericData.Array); - importClass(org.apache.avro.generic.GenericRecord); - importClass(org.apache.avro.Schema); - - var logger = executor.logger; - logger.trace("start: " + executor.subject.id); - logger.trace("-- infields: " + executor.inFields); - - var rootLogger = LoggerFactory.getLogger(logger.ROOT_LOGGER_NAME); - - var ifSituation = executor.inFields["situation"]; - - var albumCustomerMap = executor.getContextAlbum("albumCustomerMap"); - var albumProblemMap = executor.getContextAlbum("albumProblemMap"); - - // create outfiled for decision - var decision = executor.subject.getOutFieldSchemaHelper("decision").createNewInstance(); - decision.put("description", "None, everything is ok"); - decision.put("decision", "IMPEDE"); - decision.put("problemID", ifSituation.get("problemID")); - decision.put("customers", new ArrayList()); - - var problem = albumProblemMap.get(ifSituation.get("problemID")); - var returnValueType = Java.type("java.lang.Boolean"); - if (problem != null && ifSituation.get("violatedSLAs").size() > 0) { - logger.trace("-- impede by priority"); - for (var i = 0; i < problem.get("edgeUsedBy").size(); i++) { - customerCtxt = albumCustomerMap.get(problem.get("edgeUsedBy").get(i).toString()); - if (customerCtxt.get("priority") == false) { - decision.get("customers").add(customerCtxt.get("customerName")); - } - } - var returnValue = new returnValueType(true); - } else { - logger.trace("-- wrong problemID <" + ifSituation.get("problemID") + "> for PRIORITY task, we should not be here"); - rootLogger.error(executor.subject.id + " " + "-- wrong problemID <" + ifSituation.get("problemID") - + "> for PRIORITY task, we should not be here"); - var returnValue = new returnValueType(false); - } - - // set impededLast to decision[customers] - problem.get("impededLast").clear(); - problem.get("impededLast").addAll(decision.get("customers")); - - executor.outFields["decision"] = decision; - logger.trace("-- decision: " + decision); - - logger.info("vpnsla: priority, impeding customers " + decision.get("customers")); - - logger.trace("finished: " + executor.subject.id); - logger.debug(".d-pri"); Logic: Policy Act State ------------------------ @@ -1674,82 +733,7 @@ Logic: Policy Act State This is the logic for the act state. It is simply selecting an action, and creating the repsonse event for the orchestrator (the output of the policy). - - .. container:: listingblock - - .. container:: content - - .. code:: CodeRay - - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - - load("nashorn:mozilla_compat.js"); - - var logger = executor.logger; - logger.trace("start: " + executor.subject.id); - logger.trace("-- infields: " + executor.inFields); - - var ifDecision = executor.inFields["decision"]; - var ifMatchStart = executor.inFields["matchStart"]; - - var albumCustomerMap = executor.getContextAlbum("albumCustomerMap"); - var albumProblemMap = executor.getContextAlbum("albumProblemMap"); - - switch (ifDecision.get("decision").toString()) { - case "NONE": - executor.outFields["edgeName"] = ""; - executor.outFields["action"] = ""; - break; - case "IMPEDE": - for (var i = 0; i < ifDecision.get("customers").size(); i++) { - customer = albumCustomerMap.get(ifDecision.get("customers").get(i).toString()); - executor.outFields["edgeName"] = customer.get("links").get(0); - executor.outFields["action"] = "firewall"; - } - break; - case "REBUILD": - // finally solved, remove problem - albumProblemMap.remove(ifDecision.get("problemID")); - executor.outFields["edgeName"] = "L10"; // this is ###static### - executor.outFields["action"] = "rebuild"; // this is ###static### - break; - default: - - } - - var returnValueType = Java.type("java.lang.Boolean"); - var returnValue = new returnValueType(true); - - if (executor.outFields["action"] != "") { - logger.info("vpnsla: action is to " + executor.outFields["action"] + " " + executor.outFields["edgeName"]); - } else { - logger.info("vpnsla: no action required"); - } - - logger.trace("-- outfields: " + executor.outFields); - logger.trace("finished: " + executor.subject.id); - logger.debug(".a"); - - var now = new Date().getTime(); - logger.info("VPN SLA finished in " + (now - ifMatchStart) + " ms"); + Sample |taskAct_link| CLI Spec -------- @@ -1767,337 +751,8 @@ CLI Spec APEX CLI Editor. The script below shows the actual policy specification. All logic and schemas are included (as macro file). + Sample |vpnsla-apex_link| - .. container:: listingblock - - .. container:: content - - .. code:: CodeRay - - #------------------------------------------------------------------------------- - # ============LICENSE_START======================================================= - # Copyright (C) 2016-2018 Ericsson. All rights reserved. - # ================================================================================ - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. - # - # SPDX-License-Identifier: Apache-2.0 - # ============LICENSE_END========================================================= - #------------------------------------------------------------------------------- - - # ============LICENSE_START======================================================= - # Copyright (C) 2016-2018 Ericsson. All rights reserved. - # ================================================================================ - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. - # - # SPDX-License-Identifier: Apache-2.0 - # ============LICENSE_END========================================================= - - model create name=PCVS-VpnSla version=1.0.0 description="Policies-Controlled Video Streaming, VPN SLA Policy Model" - - - - schema create name=reportDecl version=1.0.0 description="Report of activities of a policy/task" flavour=Java schema=java.lang.String - event create name=ReportOut version=1.0.0 description="Report of a policy (issued by a task)" nameSpace=org.onap.policy.apex.examples.pcvs.vpnsla source="APEX" target="CtxtManagement" - event parameter create name=ReportOut version=1.0.0 parName=report schemaName=reportDecl schemaVersion=1.0.0 - - schema create name=timestampDecl version=1.0.0 description="Timestamp" flavour=Java schema=java.lang.Long - - - - schema create name=ctxtEdgeNameDecl version=1.0.0 description="Topology Edges: edge (link) name" flavour=Java schema=java.lang.String - schema create name=ctxtEdgeStartDecl version=1.0.0 description="Topology Edges: edge endpoint (start)" flavour=Java schema=java.lang.String - schema create name=ctxtEdgeEndDecl version=1.0.0 description="Topology Edges: edge endpoint (end)" flavour=Java schema=java.lang.String - schema create name=ctxtEdgeStatusDecl version=1.0.0 description="Topology Edges: edge status as up (true) or down (false)" flavour=Java schema=java.lang.Boolean - - schema create name=ctxtTopologyEdgesDecl version=1.0.0 description="Topology Edges Context Map" flavour=Avro schema=LS - #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/avro/topology-edges.avsc" - LE - album create name=albumTopoEdges scope=global writable=true schemaName=ctxtTopologyEdgesDecl - - - task create name=EdgeContextTask version=1.0.0 description="This task adds event context to edge context" - task inputfield create name=EdgeContextTask version=1.0.0 fieldName=edgeName schemaName=ctxtEdgeNameDecl schemaVersion=1.0.0 - task inputfield create name=EdgeContextTask version=1.0.0 fieldName=start schemaName=ctxtEdgeStartDecl schemaVersion=1.0.0 - task inputfield create name=EdgeContextTask version=1.0.0 fieldName=end schemaName=ctxtEdgeEndDecl schemaVersion=1.0.0 - task inputfield create name=EdgeContextTask version=1.0.0 fieldName=status schemaName=ctxtEdgeStatusDecl schemaVersion=1.0.0 - task outputfield create name=EdgeContextTask version=1.0.0 fieldName=report schemaName=reportDecl schemaVersion=1.0.0 - task contextref create name=EdgeContextTask albumName=albumTopoEdges - task logic create name=EdgeContextTask logicFlavour=JAVASCRIPT logic=LS - #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/logic/ctxt-edges.js" - LE - - event create name=EdgeContextEventIn version=1.0.0 description="Event to add an Edge to engine Context" nameSpace=org.onap.policy.apex.examples.pcvs.vpnsla source="CtxtManagement" target="APEX" - event parameter create name=EdgeContextEventIn version=1.0.0 parName=edgeName schemaName=ctxtEdgeNameDecl schemaVersion=1.0.0 - event parameter create name=EdgeContextEventIn version=1.0.0 parName=start schemaName=ctxtEdgeStartDecl schemaVersion=1.0.0 - event parameter create name=EdgeContextEventIn version=1.0.0 parName=end schemaName=ctxtEdgeEndDecl schemaVersion=1.0.0 - event parameter create name=EdgeContextEventIn version=1.0.0 parName=status schemaName=ctxtEdgeStatusDecl schemaVersion=1.0.0 - - policy create name=EdgeContextPolicy version=1.0.0 description="Policy that adds an edge to context" template=FREEFORM firstState=EdgeContextState - policy state create name=EdgeContextPolicy version=1.0.0 stateName=EdgeContextState triggerName=EdgeContextEventIn triggerVersion=1.0.0 defaultTaskName=EdgeContextTask defaultTaskVersion=1.0.0 - policy state output create name=EdgeContextPolicy version=1.0.0 stateName=EdgeContextState outputName=EdgeContextState_Output_Direct eventName=ReportOut eventVersion=1.0.0 nextState=NULL - policy state taskref create name=EdgeContextPolicy version=1.0.0 stateName=EdgeContextState taskLocalName=doContext taskName=EdgeContextTask taskVersion=1.0.0 outputType=DIRECT outputName=EdgeContextState_Output_Direct - - - - schema create name=ctxtNodeNameDecl version=1.0.0 description="Topology Nodes: node name" flavour=Java schema=java.lang.String - schema create name=ctxtNodeMininetNameDecl version=1.0.0 description="Topology Nodes: node name in Mininet" flavour=Java schema=java.lang.String - - schema create name=ctxtTopologyNodesDecl version=1.0.0 description="Topology Nodes Context Map" flavour=Avro schema=LS - #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/avro/topology-nodes.avsc" - LE - album create name=albumTopoNodes scope=global writable=true schemaName=ctxtTopologyNodesDecl - - task create name=NodeContextTask version=1.0.0 description="This task adds event context to node context" - task inputfield create name=NodeContextTask version=1.0.0 fieldName=nodeName schemaName=ctxtNodeNameDecl schemaVersion=1.0.0 - task inputfield create name=NodeContextTask version=1.0.0 fieldName=mininetName schemaName=ctxtNodeMininetNameDecl schemaVersion=1.0.0 - task outputfield create name=NodeContextTask version=1.0.0 fieldName=report schemaName=reportDecl schemaVersion=1.0.0 - task contextref create name=NodeContextTask albumName=albumTopoNodes - task logic create name=NodeContextTask logicFlavour=JAVASCRIPT logic=LS - #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/logic/ctxt-nodes.js" - LE - - event create name=NodeContextEventIn version=1.0.0 description="Event to add Node to engine Context" nameSpace=org.onap.policy.apex.examples.pcvs.vpnsla source="CtxtManagement" target="APEX" - event parameter create name=NodeContextEventIn version=1.0.0 parName=nodeName schemaName=ctxtNodeNameDecl schemaVersion=1.0.0 - event parameter create name=NodeContextEventIn version=1.0.0 parName=mininetName schemaName=ctxtNodeMininetNameDecl schemaVersion=1.0.0 - - policy create name=NodeContextPolicy version=1.0.0 description="Policy that adds an node to context" template=FREEFORM firstState=NodeContextState - policy state create name=NodeContextPolicy version=1.0.0 stateName=NodeContextState triggerName=NodeContextEventIn triggerVersion=1.0.0 defaultTaskName=NodeContextTask defaultTaskVersion=1.0.0 - policy state output create name=NodeContextPolicy version=1.0.0 stateName=NodeContextState outputName=NodeContextState_Output_Direct eventName=ReportOut eventVersion=1.0.0 nextState=NULL - policy state taskref create name=NodeContextPolicy version=1.0.0 stateName=NodeContextState taskLocalName=doContext taskName=NodeContextTask taskVersion=1.0.0 outputType=DIRECT outputName=NodeContextState_Output_Direct - - - - - schema create name=ctxtCustomerNameDecl version=1.0.0 description="Customer Context: customer name" flavour=Java schema=java.lang.String - schema create name=ctxtCustomerPriorityDecl version=1.0.0 description="Customer Context: priority flag" flavour=Java schema=java.lang.Boolean - schema create name=ctxtCustomerSatisfactionDecl version=1.0.0 description="Customer Context: satisfaction in percent" flavour=Java schema=java.lang.Integer - schema create name=ctxtCustomerDowntimeSLADecl version=1.0.0 description="Customer Context: contracted downtime as per SLA" flavour=Java schema=java.lang.Integer - schema create name=ctxtCustomerDowntimeYTDDecl version=1.0.0 description="Customer Context: year-to-date downtime experienced" flavour=Java schema=java.lang.Integer - schema create name=ctxtCustomerLinksDecl version=1.0.0 description="Customer Context: links a customer uses (for events/task)" flavour=Java schema=java.lang.String - - schema create name=ctxtCustomerMapDecl version=1.0.0 description="Map of customers with all known information" flavour=Avro schema=LS - #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/avro/customers.avsc" - LE - album create name=albumCustomerMap scope=global writable=true schemaName=ctxtCustomerMapDecl - - task create name=CustomerContextTask version=1.0.0 description="This task adds event context to customer context" - task inputfield create name=CustomerContextTask version=1.0.0 fieldName=customerName schemaName=ctxtCustomerNameDecl schemaVersion=1.0.0 - task inputfield create name=CustomerContextTask version=1.0.0 fieldName=priority schemaName=ctxtCustomerPriorityDecl schemaVersion=1.0.0 - task inputfield create name=CustomerContextTask version=1.0.0 fieldName=satisfaction schemaName=ctxtCustomerSatisfactionDecl schemaVersion=1.0.0 - task inputfield create name=CustomerContextTask version=1.0.0 fieldName=dtSLA schemaName=ctxtCustomerDowntimeSLADecl schemaVersion=1.0.0 - task inputfield create name=CustomerContextTask version=1.0.0 fieldName=dtYTD schemaName=ctxtCustomerDowntimeYTDDecl schemaVersion=1.0.0 - task inputfield create name=CustomerContextTask version=1.0.0 fieldName=links schemaName=ctxtCustomerLinksDecl schemaVersion=1.0.0 - task outputfield create name=CustomerContextTask version=1.0.0 fieldName=report schemaName=reportDecl schemaVersion=1.0.0 - task contextref create name=CustomerContextTask albumName=albumCustomerMap - task contextref create name=CustomerContextTask albumName=albumTopoEdges - task logic create name=CustomerContextTask logicFlavour=JAVASCRIPT logic=LS - #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/logic/ctxt-customer.js" - LE - - event create name=CustomerContextEventIn version=1.0.0 description="Event to add Customers to engine Context" nameSpace=org.onap.policy.apex.examples.pcvs.vpnsla source="CtxtManagement" target="APEX" - event parameter create name=CustomerContextEventIn version=1.0.0 parName=customerName schemaName=ctxtCustomerNameDecl schemaVersion=1.0.0 - event parameter create name=CustomerContextEventIn version=1.0.0 parName=priority schemaName=ctxtCustomerPriorityDecl schemaVersion=1.0.0 - event parameter create name=CustomerContextEventIn version=1.0.0 parName=satisfaction schemaName=ctxtCustomerSatisfactionDecl schemaVersion=1.0.0 - event parameter create name=CustomerContextEventIn version=1.0.0 parName=dtSLA schemaName=ctxtCustomerDowntimeSLADecl schemaVersion=1.0.0 - event parameter create name=CustomerContextEventIn version=1.0.0 parName=dtYTD schemaName=ctxtCustomerDowntimeYTDDecl schemaVersion=1.0.0 - event parameter create name=CustomerContextEventIn version=1.0.0 parName=links schemaName=ctxtCustomerLinksDecl schemaVersion=1.0.0 - - policy create name=CustomerContextPolicy version=1.0.0 description="Policy that adds Customer information to engine context" template=FREEFORM firstState=CustomerContextState - policy state create name=CustomerContextPolicy version=1.0.0 stateName=CustomerContextState triggerName=CustomerContextEventIn triggerVersion=1.0.0 defaultTaskName=CustomerContextTask defaultTaskVersion=1.0.0 - policy state output create name=CustomerContextPolicy version=1.0.0 stateName=CustomerContextState outputName=CustomerContextState_Output_Direct eventName=ReportOut eventVersion=1.0.0 nextState=NULL - policy state taskref create name=CustomerContextPolicy version=1.0.0 stateName=CustomerContextState taskLocalName=doContext taskName=CustomerContextTask taskVersion=1.0.0 outputType=DIRECT outputName=CustomerContextState_Output_Direct - - - - - schema create name=edgeNameDecl version=1.0.0 description="Edge name" flavour=Java schema=java.lang.String - schema create name=edgeStatusDecl version=1.0.0 description="Statuf of the edge (UP, DOWN)" flavour=Avro schema=LS - #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/avro/link-status.avsc" - LE - schema create name=edgeChangedDecl version=1.0.0 description="Status Change (true:change, false:no change)" flavour=Java schema=java.lang.Boolean - - task create name=VpnSlaPolicyMatchTask version=1.0.0 description="Pre-process an edge event" - task inputfield create name=VpnSlaPolicyMatchTask version=1.0.0 fieldName=edgeName schemaName=edgeNameDecl schemaVersion=1.0.0 - task inputfield create name=VpnSlaPolicyMatchTask version=1.0.0 fieldName=status schemaName=edgeStatusDecl schemaVersion=1.0.0 - task outputfield create name=VpnSlaPolicyMatchTask version=1.0.0 fieldName=edgeName schemaName=edgeNameDecl schemaVersion=1.0.0 - task outputfield create name=VpnSlaPolicyMatchTask version=1.0.0 fieldName=status schemaName=edgeStatusDecl schemaVersion=1.0.0 - task outputfield create name=VpnSlaPolicyMatchTask version=1.0.0 fieldName=hasChanged schemaName=edgeChangedDecl schemaVersion=1.0.0 - task outputfield create name=VpnSlaPolicyMatchTask version=1.0.0 fieldName=matchStart schemaName=timestampDecl schemaVersion=1.0.0 - task contextref create name=VpnSlaPolicyMatchTask albumName=albumTopoEdges - task logic create name=VpnSlaPolicyMatchTask logicFlavour=JAVASCRIPT logic=LS - #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/logic/task-match.js" - LE - - - - - schema create name=problemMapDecl version=1.0.0 description="Map of problems with all known Information" flavour=Avro schema=LS - #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/avro/problems.avsc" - LE - album create name=albumProblemMap scope=global writable=true schemaName=problemMapDecl - - schema create name=establishSituationDecl version=1.0.0 description="Establish: the situation that was established" flavour=Avro schema=LS - #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/avro/situation.avsc" - LE - - task create name=VpnSlaPolicyEstablishTask version=1.0.0 description="Task taking a match event and establishing a situation" - task inputfield create name=VpnSlaPolicyEstablishTask version=1.0.0 fieldName=edgeName schemaName=edgeNameDecl schemaVersion=1.0.0 - task inputfield create name=VpnSlaPolicyEstablishTask version=1.0.0 fieldName=status schemaName=edgeStatusDecl schemaVersion=1.0.0 - task inputfield create name=VpnSlaPolicyEstablishTask version=1.0.0 fieldName=hasChanged schemaName=edgeChangedDecl schemaVersion=1.0.0 - task inputfield create name=VpnSlaPolicyEstablishTask version=1.0.0 fieldName=matchStart schemaName=timestampDecl schemaVersion=1.0.0 - task outputfield create name=VpnSlaPolicyEstablishTask version=1.0.0 fieldName=situation schemaName=establishSituationDecl schemaVersion=1.0.0 - task outputfield create name=VpnSlaPolicyEstablishTask version=1.0.0 fieldName=matchStart schemaName=timestampDecl schemaVersion=1.0.0 - task contextref create name=VpnSlaPolicyEstablishTask albumName=albumProblemMap - task contextref create name=VpnSlaPolicyEstablishTask albumName=albumCustomerMap - task logic create name=VpnSlaPolicyEstablishTask logicFlavour=JAVASCRIPT logic=LS - #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/logic/task-establish.js" - LE - - - - - schema create name=decideDecisionDecl version=1.0.0 description="Decide: the taken decision" flavour=Avro schema=LS - #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/avro/decision.avsc" - LE - - task create name=VpnSlaPolicyDecideNoneTask version=1.0.0 description="Decide task for a 'none' problem" - task inputfield create name=VpnSlaPolicyDecideNoneTask version=1.0.0 fieldName=situation schemaName=establishSituationDecl schemaVersion=1.0.0 - task inputfield create name=VpnSlaPolicyDecideNoneTask version=1.0.0 fieldName=matchStart schemaName=timestampDecl schemaVersion=1.0.0 - task outputfield create name=VpnSlaPolicyDecideNoneTask version=1.0.0 fieldName=decision schemaName=decideDecisionDecl schemaVersion=1.0.0 - task outputfield create name=VpnSlaPolicyDecideNoneTask version=1.0.0 fieldName=matchStart schemaName=timestampDecl schemaVersion=1.0.0 - task logic create name=VpnSlaPolicyDecideNoneTask logicFlavour=JAVASCRIPT logic=LS - #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/logic/task-decide-none.js" - LE - - - task create name=VpnSlaPolicyDecideSlaTask version=1.0.0 description="Decide task solving the problem by balancing SLAs" - task inputfield create name=VpnSlaPolicyDecideSlaTask version=1.0.0 fieldName=situation schemaName=establishSituationDecl schemaVersion=1.0.0 - task inputfield create name=VpnSlaPolicyDecideSlaTask version=1.0.0 fieldName=matchStart schemaName=timestampDecl schemaVersion=1.0.0 - task outputfield create name=VpnSlaPolicyDecideSlaTask version=1.0.0 fieldName=decision schemaName=decideDecisionDecl schemaVersion=1.0.0 - task outputfield create name=VpnSlaPolicyDecideSlaTask version=1.0.0 fieldName=matchStart schemaName=timestampDecl schemaVersion=1.0.0 - task contextref create name=VpnSlaPolicyDecideSlaTask albumName=albumCustomerMap - task contextref create name=VpnSlaPolicyDecideSlaTask albumName=albumProblemMap - task logic create name=VpnSlaPolicyDecideSlaTask logicFlavour=JAVASCRIPT logic=LS - #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/logic/task-decide-sla.js" - LE - - - task create name=VpnSlaPolicyDecidePriorityTask version=1.0.0 description="Decide task solving the problem by using customer priorities" - task inputfield create name=VpnSlaPolicyDecidePriorityTask version=1.0.0 fieldName=situation schemaName=establishSituationDecl schemaVersion=1.0.0 - task inputfield create name=VpnSlaPolicyDecidePriorityTask version=1.0.0 fieldName=matchStart schemaName=timestampDecl schemaVersion=1.0.0 - task outputfield create name=VpnSlaPolicyDecidePriorityTask version=1.0.0 fieldName=decision schemaName=decideDecisionDecl schemaVersion=1.0.0 - task outputfield create name=VpnSlaPolicyDecidePriorityTask version=1.0.0 fieldName=matchStart schemaName=timestampDecl schemaVersion=1.0.0 - task contextref create name=VpnSlaPolicyDecidePriorityTask albumName=albumCustomerMap - task contextref create name=VpnSlaPolicyDecidePriorityTask albumName=albumProblemMap - task logic create name=VpnSlaPolicyDecidePriorityTask logicFlavour=JAVASCRIPT logic=LS - #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/logic/task-decide-priority.js" - LE - - - task create name=VpnSlaPolicyDecideSolvedTask version=1.0.0 description="Decide task solving the problem by using customer priorities" - task inputfield create name=VpnSlaPolicyDecideSolvedTask version=1.0.0 fieldName=situation schemaName=establishSituationDecl schemaVersion=1.0.0 - task inputfield create name=VpnSlaPolicyDecideSolvedTask version=1.0.0 fieldName=matchStart schemaName=timestampDecl schemaVersion=1.0.0 - task outputfield create name=VpnSlaPolicyDecideSolvedTask version=1.0.0 fieldName=decision schemaName=decideDecisionDecl schemaVersion=1.0.0 - task outputfield create name=VpnSlaPolicyDecideSolvedTask version=1.0.0 fieldName=matchStart schemaName=timestampDecl schemaVersion=1.0.0 - task contextref create name=VpnSlaPolicyDecideSolvedTask albumName=albumProblemMap - task logic create name=VpnSlaPolicyDecideSolvedTask logicFlavour=JAVASCRIPT logic=LS - #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/logic/task-decide-solved.js" - LE - - - - - schema create name=actionDecl version=1.0.0 description="An action for the actioning system" flavour=Java schema=java.lang.String - - task create name=VpnSlaPolicyActTask version=1.0.0 description="Task issueing an action for taken decision" - task inputfield create name=VpnSlaPolicyActTask version=1.0.0 fieldName=decision schemaName=decideDecisionDecl schemaVersion=1.0.0 - task inputfield create name=VpnSlaPolicyActTask version=1.0.0 fieldName=matchStart schemaName=timestampDecl schemaVersion=1.0.0 - task outputfield create name=VpnSlaPolicyActTask version=1.0.0 fieldName=edgeName schemaName=edgeNameDecl schemaVersion=1.0.0 - task outputfield create name=VpnSlaPolicyActTask version=1.0.0 fieldName=action schemaName=actionDecl schemaVersion=1.0.0 - task contextref create name=VpnSlaPolicyActTask albumName=albumCustomerMap - task contextref create name=VpnSlaPolicyActTask albumName=albumProblemMap - task logic create name=VpnSlaPolicyActTask logicFlavour=JAVASCRIPT logic=LS - #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/logic/task-act.js" - LE - - - - - - - - event create name=VpnSlaTrigger version=1.0.0 description="Event triggering the VPN SLA policy" nameSpace=org.onap.policy.apex.examples.pcvs.vpnsla source="TriggerSys" target="VpnSlaMatch" - event parameter create name=VpnSlaTrigger version=1.0.0 parName=edgeName schemaName=edgeNameDecl schemaVersion=1.0.0 - event parameter create name=VpnSlaTrigger version=1.0.0 parName=status schemaName=edgeStatusDecl schemaVersion=1.0.0 - - event create name=VpnSlaMatchOut version=1.0.0 description="Event with matched trigger for the VPN SLA policy" nameSpace=org.onap.policy.apex.examples.pcvs.vpnsla source="VpnSlaMatch" target="VpnSlaEstablish" - event parameter create name=VpnSlaMatchOut version=1.0.0 parName=edgeName schemaName=edgeNameDecl schemaVersion=1.0.0 - event parameter create name=VpnSlaMatchOut version=1.0.0 parName=status schemaName=edgeStatusDecl schemaVersion=1.0.0 - event parameter create name=VpnSlaMatchOut version=1.0.0 parName=hasChanged schemaName=edgeChangedDecl schemaVersion=1.0.0 - event parameter create name=VpnSlaMatchOut version=1.0.0 parName=matchStart schemaName=timestampDecl schemaVersion=1.0.0 - - event create name=VpnSlaEstablishOut version=1.0.0 description="Event with situation for the SLA policy" nameSpace=org.onap.policy.apex.examples.pcvs.vpnsla source="SlaEstablish" target="SlaDecide" - event parameter create name=VpnSlaEstablishOut version=1.0.0 parName=situation schemaName=establishSituationDecl schemaVersion=1.0.0 - event parameter create name=VpnSlaEstablishOut version=1.0.0 parName=matchStart schemaName=timestampDecl schemaVersion=1.0.0 - - event create name=VpnSlaDecideOut version=1.0.0 description="Event with a decision for the SLA policy" nameSpace=org.onap.policy.apex.examples.pcvs.vpnsla source="SlaDecide" target="SlaAct" - event parameter create name=VpnSlaDecideOut version=1.0.0 parName=decision schemaName=decideDecisionDecl schemaVersion=1.0.0 - event parameter create name=VpnSlaDecideOut version=1.0.0 parName=matchStart schemaName=timestampDecl schemaVersion=1.0.0 - - event create name=VpnSlaActOut version=1.0.0 description="Event action" nameSpace=org.onap.policy.apex.examples.pcvs.vpnsla source="SlaAct" target="ActioningSystem" - event parameter create name=VpnSlaActOut version=1.0.0 parName=edgeName schemaName=edgeNameDecl schemaVersion=1.0.0 - event parameter create name=VpnSlaActOut version=1.0.0 parName=action schemaName=actionDecl schemaVersion=1.0.0 - - - policy create name=VpnSlaPolicy version=1.0.0 description="Policy deciding customer treatment based on SLAs as MEDA policy" template=FREEFORM firstState=VpnSlaPolicyMatchState - - policy state create name=VpnSlaPolicy version=1.0.0 stateName=VpnSlaPolicyActState triggerName=VpnSlaDecideOut triggerVersion=1.0.0 defaultTaskName=VpnSlaPolicyActTask defaultTaskVersion=1.0.0 - policy state output create name=VpnSlaPolicy version=1.0.0 stateName=VpnSlaPolicyActState outputName=SlaPolicyAct_Output_Direct eventName=VpnSlaActOut eventVersion=1.0.0 nextState=NULL - policy state taskref create name=VpnSlaPolicy version=1.0.0 stateName=VpnSlaPolicyActState taskLocalName=act taskName=VpnSlaPolicyActTask taskVersion=1.0.0 outputType=DIRECT outputName=SlaPolicyAct_Output_Direct - - policy state create name=VpnSlaPolicy version=1.0.0 stateName=VpnSlaPolicyDecideState triggerName=VpnSlaEstablishOut triggerVersion=1.0.0 defaultTaskName=VpnSlaPolicyDecideSlaTask defaultTaskVersion=1.0.0 - policy state contextref create name=VpnSlaPolicy version=1.0.0 stateName=VpnSlaPolicyDecideState albumName=albumProblemMap - policy state selecttasklogic create name=VpnSlaPolicy stateName=VpnSlaPolicyDecideState logicFlavour=JAVASCRIPT logic=LS - #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/logic/tsl-decide.js" - LE - policy state output create name=VpnSlaPolicy version=1.0.0 stateName=VpnSlaPolicyDecideState outputName=VpnSlaPolicyDecide_Output_Direct eventName=VpnSlaDecideOut eventVersion=1.0.0 nextState=VpnSlaPolicyActState - policy state taskref create name=VpnSlaPolicy version=1.0.0 stateName=VpnSlaPolicyDecideState taskLocalName=decideNone taskName=VpnSlaPolicyDecideNoneTask taskVersion=1.0.0 outputType=DIRECT outputName=VpnSlaPolicyDecide_Output_Direct - policy state taskref create name=VpnSlaPolicy version=1.0.0 stateName=VpnSlaPolicyDecideState taskLocalName=decideNone taskName=VpnSlaPolicyDecideSolvedTask taskVersion=1.0.0 outputType=DIRECT outputName=VpnSlaPolicyDecide_Output_Direct - policy state taskref create name=VpnSlaPolicy version=1.0.0 stateName=VpnSlaPolicyDecideState taskLocalName=decideSla taskName=VpnSlaPolicyDecideSlaTask taskVersion=1.0.0 outputType=DIRECT outputName=VpnSlaPolicyDecide_Output_Direct - policy state taskref create name=VpnSlaPolicy version=1.0.0 stateName=VpnSlaPolicyDecideState taskLocalName=decidePriority taskName=VpnSlaPolicyDecidePriorityTask taskVersion=1.0.0 outputType=DIRECT outputName=VpnSlaPolicyDecide_Output_Direct - - policy state create name=VpnSlaPolicy version=1.0.0 stateName=VpmSlaPolicyEstablishState triggerName=VpnSlaMatchOut triggerVersion=1.0.0 defaultTaskName=VpnSlaPolicyEstablishTask defaultTaskVersion=1.0.0 - policy state output create name=VpnSlaPolicy version=1.0.0 stateName=VpmSlaPolicyEstablishState outputName=VpnSlaPolicyEstablish_Output_Direct eventName=VpnSlaEstablishOut eventVersion=1.0.0 nextState=VpnSlaPolicyDecideState - policy state taskref create name=VpnSlaPolicy version=1.0.0 stateName=VpmSlaPolicyEstablishState taskLocalName=establish taskName=VpnSlaPolicyEstablishTask taskVersion=1.0.0 outputType=DIRECT outputName=VpnSlaPolicyEstablish_Output_Direct - - policy state create name=VpnSlaPolicy version=1.0.0 stateName=VpnSlaPolicyMatchState triggerName=VpnSlaTrigger triggerVersion=1.0.0 defaultTaskName=VpnSlaPolicyMatchTask defaultTaskVersion=1.0.0 - policy state output create name=VpnSlaPolicy version=1.0.0 stateName=VpnSlaPolicyMatchState outputName=VpnSlaPolicyMatch_Output_Direct eventName=VpnSlaMatchOut eventVersion=1.0.0 nextState=VpmSlaPolicyEstablishState - policy state taskref create name=VpnSlaPolicy version=1.0.0 stateName=VpnSlaPolicyMatchState taskLocalName=match taskName=VpnSlaPolicyMatchTask taskVersion=1.0.0 outputType=DIRECT outputName=VpnSlaPolicyMatch_Output_Direct - - - - validate - quit Context Events Nodes -------------------- @@ -2110,112 +765,10 @@ Context Events Nodes The following events create all nodes of the topology. - .. container:: listingblock + .. container:: ulist - .. container:: content + - |ctxtNodesJson_link| - .. code:: CodeRay - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "NodeContextEventIn", - "version": "1.0.0", - "source": "CtxtManagement", - "target" : "VpnSlaPolicy_NodeContext", - "nodeName": "A1", - "mininetName": "nn" - } - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "NodeContextEventIn", - "version": "1.0.0", - "source": "CtxtManagement", - "target" : "VpnSlaPolicy_NodeContext", - "nodeName": "A2", - "mininetName": "nn" - } - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "NodeContextEventIn", - "version": "1.0.0", - "source": "CtxtManagement", - "target" : "VpnSlaPolicy_NodeContext", - "nodeName": "B1", - "mininetName": "nn" - } - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "NodeContextEventIn", - "version": "1.0.0", - "source": "CtxtManagement", - "target" : "VpnSlaPolicy_NodeContext", - "nodeName": "B2", - "mininetName": "nn" - } - - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "NodeContextEventIn", - "version": "1.0.0", - "source": "CtxtManagement", - "target" : "VpnSlaPolicy_NodeContext", - "nodeName": "A1CO", - "mininetName": "s1" - } - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "NodeContextEventIn", - "version": "1.0.0", - "source": "CtxtManagement", - "target" : "VpnSlaPolicy_NodeContext", - "nodeName": "A2CO", - "mininetName": "s2" - } - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "NodeContextEventIn", - "version": "1.0.0", - "source": "CtxtManagement", - "target" : "VpnSlaPolicy_NodeContext", - "nodeName": "B1CO", - "mininetName": "s3" - } - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "NodeContextEventIn", - "version": "1.0.0", - "source": "CtxtManagement", - "target" : "VpnSlaPolicy_NodeContext", - "nodeName": "B2CO", - "mininetName": "s4" - } - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "NodeContextEventIn", - "version": "1.0.0", - "source": "CtxtManagement", - "target" : "VpnSlaPolicy_NodeContext", - "nodeName": "BBL", - "mininetName": "s5" - } - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "NodeContextEventIn", - "version": "1.0.0", - "source": "CtxtManagement", - "target" : "VpnSlaPolicy_NodeContext", - "nodeName": "BBR", - "mininetName": "s6" - } Context Events Edges -------------------- @@ -2228,131 +781,10 @@ Context Events Edges The following events create all edges of the topology. - .. container:: listingblock + .. container:: ulist - .. container:: content + - |ctxtEdgesJson_link| - .. code:: CodeRay - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "EdgeContextEventIn", - "version": "1.0.0", - "source": "CtxtManagement", - "target" : "VpnSlaPolicy_EdgeContext", - "edgeName": "L01", - "start": "A1", - "end": "A1CO", - "status": true - } - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "EdgeContextEventIn", - "version": "1.0.0", - "source": "CtxtManagement", - "target" : "VpnSlaPolicy_EdgeContext", - "edgeName": "L02", - "start": "B1", - "end": "B1CO", - "status": true - } - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "EdgeContextEventIn", - "version": "1.0.0", - "source": "CtxtManagement", - "target" : "VpnSlaPolicy_EdgeContext", - "edgeName": "L03", - "start": "A2", - "end": "A2CO", - "status": true - } - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "EdgeContextEventIn", - "version": "1.0.0", - "source": "CtxtManagement", - "target" : "VpnSlaPolicy_EdgeContext", - "edgeName": "L04", - "start": "B2", - "end": "B2CO", - "status": true - } - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "EdgeContextEventIn", - "version": "1.0.0", - "source": "CtxtManagement", - "target" : "VpnSlaPolicy_EdgeContext", - "edgeName": "L05", - "start": "A1CO", - "end": "BBL", - "status": true - } - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "EdgeContextEventIn", - "version": "1.0.0", - "source": "CtxtManagement", - "target" : "VpnSlaPolicy_EdgeContext", - "edgeName": "L06", - "start": "B1CO", - "end": "BBL", - "status": true - } - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "EdgeContextEventIn", - "version": "1.0.0", - "source": "CtxtManagement", - "target" : "VpnSlaPolicy_EdgeContext", - "edgeName": "L07", - "start": "A2CO", - "end": "BBR", - "status": true - } - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "EdgeContextEventIn", - "version": "1.0.0", - "source": "CtxtManagement", - "target" : "VpnSlaPolicy_EdgeContext", - "edgeName": "L08", - "start": "B2CO", - "end": "BBR", - "status": true - } - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "EdgeContextEventIn", - "version": "1.0.0", - "source": "CtxtManagement", - "target" : "VpnSlaPolicy_EdgeContext", - "edgeName": "L09", - "start": "BBL", - "end": "BBR", - "status": true - } - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "EdgeContextEventIn", - "version": "1.0.0", - "source": "CtxtManagement", - "target" : "VpnSlaPolicy_EdgeContext", - "edgeName": "L10", - "start": "BBR", - "end": "BBL", - "status": true - } Context Events Customers ------------------------ @@ -2363,42 +795,12 @@ Context Events Customers .. container:: paragraph - The following events create all customers of the - topology. + The following events create all customers of the topology. - .. container:: listingblock + .. container:: ulist - .. container:: content + - |ctxtCustomerJson_link| - .. code:: CodeRay - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "CustomerContextEventIn", - "version": "1.0.0", - "source": "CtxtManagement", - "target" : "VpnSlaPolicy_CustomerContext", - "customerName": "A", - "links": "L01 L05 L09 L10", - "dtSLA": 180, - "dtYTD": 10, - "priority": false, - "satisfaction": 80 - } - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "CustomerContextEventIn", - "version": "1.0.0", - "source": "CtxtManagement", - "target" : "VpnSlaPolicy_CustomerContext", - "customerName": "B", - "links": "L02 L07 L09 L10", - "dtSLA": 180, - "dtYTD": 120, - "priority": true, - "satisfaction": 99 - } Trigger Examples ---------------- @@ -2411,61 +813,9 @@ Trigger Examples The following events are examples for trigger events - .. container:: listingblock - - .. container:: content + .. container:: ulist - .. code:: CodeRay - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "VpnSlaTrigger", - "version": "1.0.0", - "source": "ExampleEvents", - "target" : "VpnSlaPolicy", - "edgeName": "L09", - "status": "UP" - } - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "VpnSlaTrigger", - "version": "1.0.0", - "source": "ExampleEvents", - "target" : "VpnSlaPolicy", - "edgeName": "L09", - "status": "UP" - } - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "VpnSlaTrigger", - "version": "1.0.0", - "source": "ExampleEvents", - "target" : "VpnSlaPolicy", - "edgeName": "L09", - "status": "DOWN" - } - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "VpnSlaTrigger", - "version": "1.0.0", - "source": "ExampleEvents", - "target" : "VpnSlaPolicy", - "edgeName": "L09", - "status": "DOWN" - } - - { - "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla", - "name": "VpnSlaTrigger", - "version": "1.0.0", - "source": "ExampleEvents", - "target" : "VpnSlaPolicy", - "edgeName": "L09", - "status": "UP" - } + - |triggerEdgeJson_link| Link Monitor ------------ @@ -2480,227 +830,7 @@ Link Monitor sends the context events to APEX to initialize the topology and the customers. Then it takes events from Kafka and sends them to APEX. - - .. container:: listingblock - - .. container:: content - - .. code:: CodeRay - - # ============LICENSE_START======================================================= - # Copyright (C) 2016-2018 Ericsson. All rights reserved. - # ================================================================================ - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. - # - # SPDX-License-Identifier: Apache-2.0 - # ============LICENSE_END========================================================= - - import http.client - import json - import time - from kafka import KafkaConsumer, KafkaProducer - - class StaticFlowPusher(object): - - def __init__(self, server): - self.server = server - - def get(self, data): - ret = self.rest_call({}, 'GET') - return json.loads(ret[2]) - - def set(self, data): - ret = self.rest_call(data, 'POST') - return ret[0] == 200 - - def remove(self, objtype, data): - ret = self.rest_call(data, 'DELETE') - return ret[0] == 200 - - def getControllerSummary(self, data): - ret = self.rest_call_controller_summary({}, 'GET') - return json.loads(ret[2]) - - def getLinks(self, data): - ret = self.rest_call_links({}, 'GET') - return json.loads(ret[2].decode()) - - def rest_call(self, data, action): - path = '/wm/staticflowpusher/json' - headers = { - 'Content-type': 'application/json', - 'Accept': 'application/json', - } - body = json.dumps(data) - conn = http.client.HTTPConnection(self.server, 8080) - conn.request(action, path, body, headers) - response = conn.getresponse() - ret = (response.status, response.reason, response.read()) - print(ret) - conn.close() - return ret - - def rest_call_controller_summary(self, data, action): - path = '/wm/core/controller/summary/json' - headers = { - 'Content-type': 'application/json', - 'Accept': 'application/json', - } - body = json.dumps(data) - conn = http.client.HTTPConnection(self.server, 8080) - conn.request(action, path, body, headers) - response = conn.getresponse() - ret = (response.status, response.reason, response.read()) - print(ret) - conn.close() - return ret - - def rest_call_links(self, data, action): - path = '/wm/topology/links/json' - headers = { - 'Content-type': 'application/json', - 'Accept': 'application/json', - } - body = json.dumps(data) - conn = http.client.HTTPConnection(self.server, 8080) - conn.request(action, path, body, headers) - response = conn.getresponse() - ret = (response.status, response.reason, response.read()) - conn.close() - return ret - - pusher = StaticFlowPusher('127.0.1.1') - - - def parseLinks(links): - #print("\n\n\n",links) - result = [] - for link in links: - list = [] - #print("\n\n\n",link) - #print("\nsrc-switch : s", link['src-switch'][len(link['src-switch'])-1]) - #print("\ndst-switch : s", link['dst-switch'][len(link['dst-switch'])-1]) - list.append("s") - list.append(link['src-switch'][len(link['src-switch'])-1]) - list.append("-s") - list.append(link['dst-switch'][len(link['dst-switch'])-1]) - result.append(''.join(list)) - #print(result, "\n") - return result - - - - counter =0 - healthyList = [] - testableList = [] - healthyLinks = "" - testableLinks = "" - producer = KafkaProducer(bootstrap_servers='localhost:9092') - while(True): - time.sleep(30) - switchLinks = pusher.getLinks({}) - if counter == 0: - healthyList = parseLinks(switchLinks) - #Build All Links - print("READING LINKS FROM MININET\n") - for l in healthyList: - link = "" - #print(l, "\n") - #Links between switches [s6-s7 is ignored so it matches VPN SCENARIO] - if(l == "s1-s5"): - link = "{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'EdgeContextEventIn','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy_EdgeContext','status': true,'edgeName': 'L05', 'start': 'A1CO','end': 'BBL'}" - producer.send("apex-in-0", bytes(link, encoding="ascii")) - if(l == "s5-s6"): - link = "{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'EdgeContextEventIn','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy_EdgeContext','status': true,'edgeName': 'L09', 'start': 'BBL','end': 'BBR'}" - producer.send("apex-in-0", bytes(link, encoding="ascii")) - if(l == "s2-s6"): - link = "{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'EdgeContextEventIn','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy_EdgeContext','status': true,'edgeName': 'L07', 'start': 'A2CO','end': 'BBR'}" - producer.send("apex-in-0", bytes(link, encoding="ascii")) - if(l == "s5-s7"): - link = "{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'EdgeContextEventIn','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy_EdgeContext','status': true,'edgeName': 'L10', 'start': 'BBR','end': 'BBL'}" - producer.send("apex-in-0", bytes(link, encoding="ascii")) - if(l == "s3-s5"): - link = "{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'EdgeContextEventIn','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy_EdgeContext','status': true,'edgeName': 'L06', 'start': 'B1CO','end': 'BBL'}" - producer.send("apex-in-0", bytes(link, encoding="ascii")) - if(l == "s4-s6"): - link = "{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'EdgeContextEventIn','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy_EdgeContext','status': true,'edgeName': 'L08', 'start': 'B2CO','end': 'BBR'}" - producer.send("apex-in-0", bytes(link, encoding="ascii")) - #Links between switches and hosts [NoT SENT IN FROM FLOODLIGHT] - producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'EdgeContextEventIn','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy_EdgeContext','status': true,'edgeName': 'L01', 'start': 'A1','end': 'A1CO'}") - producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'EdgeContextEventIn','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy_EdgeContext','status': true,'edgeName': 'L02', 'start': 'B1','end': 'B1CO'}") - producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'EdgeContextEventIn','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy_EdgeContext','status': true,'edgeName': 'L03', 'start': 'A2','end': 'A2CO'}") - producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'EdgeContextEventIn','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy_EdgeContext','status': true,'edgeName': 'L04', 'start': 'B2','end': 'B2CO'}") - print("LINKS HAVE BEEN SENT TO APEX\n") - - #Build Customers - print("BUILDING CUSTOMERS\n") - producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'CustomerContextEventIn','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy_CustomerContext','dtYTD': 10,'dtSLA': 180,'links': 'L01 L05 L09 L10','customerName': 'A', 'priority': true,'satisfaction': 80}") - producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'CustomerContextEventIn','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy_CustomerContext','dtYTD': 120,'dtSLA': 180,'links': 'L02 L07 L09 L10','customerName': 'B', 'priority': false,'satisfaction': 99}") - print("CUSTOMERS HAVE BEEN SENT TO APEX\n") - healthyLinks = switchLinks - myfile = open('LinkInfo.json', 'a') - myfile.write(str(healthyLinks)) - myfile.write('\n') - myfile.close() - print("We start off with", len(healthyLinks), "healthy Links!\n") - else: - testableList = parseLinks(switchLinks) - issueLink = ""; - for h in healthyList: - issueLink = h - for t in testableList: - if t == h: - issueLink = "" - if issueLink != "": - print("There is an issue with the links! ", issueLink, " \n") - if(issueLink == "s1-s5"): - link = "{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'DOWN','edgeName': 'L05'}" - producer.send("apex-in-0", bytes(link, encoding="ascii")) - if(issueLink == "s5-s6"): - link = "{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'DOWN','edgeName': 'L09'}" - producer.send("apex-in-0", bytes(link, encoding="ascii")) - if(issueLink == "s2-s6"): - link = "{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'DOWN','edgeName': 'L07'}" - producer.send("apex-in-0", bytes(link, encoding="ascii")) - if(issueLink == "s5-s7"): - link = "{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'DOWN','edgeName': 'L10'}" - producer.send("apex-in-0", bytes(link, encoding="ascii")) - if(issueLink == "s3-s5"): - link = "{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'DOWN','edgeName': 'L06'}" - producer.send("apex-in-0", bytes(link, encoding="ascii")) - if(issueLink == "s4-s6"): - link = "{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'DOWN','edgeName': 'L08'}" - producer.send("apex-in-0", bytes(link, encoding="ascii")) - break - if issueLink == "": - print("All Links are working\n") - producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'UP','edgeName': 'L01'}") - producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'UP','edgeName': 'L02'}") - producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'UP','edgeName': 'L03'}") - producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'UP','edgeName': 'L04'}") - producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'UP','edgeName': 'L05'}") - producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'UP','edgeName': 'L06'}") - producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'UP','edgeName': 'L07'}") - producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'UP','edgeName': 'L08'}") - producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'UP','edgeName': 'L09'}") - producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'UP','edgeName': 'L10'}") - - testableLinks = switchLinks - myfile = open('LinkInfo.json', 'a') - myfile.write(str(testableLinks)) - myfile.write('\n') - myfile.close() - counter += 1 + Sample |linkMonitor_link| Mininet Topology ---------------- @@ -2711,232 +841,11 @@ Mininet Topology .. container:: paragraph - The topology is realized using Mininet. The following - script is use to estalish the topology and to realize + The topology is realized using Mininet. This + script is used to establish the topology and to realize network configurations. + Sample |mininetTopology_link| - .. container:: listingblock - - .. container:: content - - .. code:: CodeRay - - # ============LICENSE_START======================================================= - # Copyright (C) 2016-2018 Ericsson. All rights reserved. - # ================================================================================ - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. - # - # SPDX-License-Identifier: Apache-2.0 - # ============LICENSE_END========================================================= - - #Add Mininet to PATH - import sys - sys.path.insert(0, "/~/mininet") - - #Kafka - import httplib - import json - import time - from kafka import KafkaConsumer, KafkaProducer - - #Mininet - from mininet.clean import * - from mininet.cli import * - from mininet.link import * - from mininet.log import * - from mininet.net import * - from mininet.node import * - from mininet.nodelib import * - from mininet.topo import * - from mininet.topolib import * - - class StaticFlowPusher(object): - def __init__(self, server): - self.server = server - - def enableFirewall(self, data): - path = "/wm/firewall/module/enable/json" - headers = {'Content-Type': 'application/json','Accept': 'application/json',} - body = json.dumps(data) - conn = httplib.HTTPConnection(self.server, 8080) - conn.request("PUT", path, "") - response = conn.getresponse() - ret = (response.status, response.reason, response.read()) - conn.close() - return ret - - def addRule(self, data): - path = '/wm/firewall/rules/json' - headers = {'Content-Type': 'application/json','Accept': 'application/json',} - body = json.dumps(data) - conn = httplib.HTTPConnection(self.server, 8080) - conn.request('POST', path, body, headers) - response = conn.getresponse() - ret = (response.status, response.reason, response.read()) - conn.close() - return ret - - def deleteRule(self, data): - path = '/wm/firewall/rules/json' - headers = {'Content-Type': 'application/json','Accept': 'application/json',} - body = json.dumps(data) - conn = httplib.HTTPConnection(self.server, 8080) - conn.request('DELETE', path, body, headers) - response = conn.getresponse() - ret = (response.status, response.reason, response.read()) - conn.close() - return ret - - #Build Pusher(REST/IN) - pusher = StaticFlowPusher('127.0.0.1') - - net = Mininet(link=TCLink) - - #Create Customers - customerA1 = net.addHost( 'A1' ) - customerA2 = net.addHost( 'A2' ) - customerB1 = net.addHost( 'B1' ) - customerB2 = net.addHost( 'B2' ) - - #Create Switches - switchA1CO = net.addSwitch( 's1' ) - switchA2CO = net.addSwitch( 's2' ) - switchB1CO = net.addSwitch( 's3' ) - switchB2CO = net.addSwitch( 's4' ) - switchBBL = net.addSwitch( 's5' ) - switchBBR = net.addSwitch( 's6' ) - # we need an extra switch here because Mininet does not allow two links between two switches - switchEx = net.addSwitch( 's7' ) - - #Create Links - net.addLink( customerA1, switchA1CO ) - net.addLink( customerA2, switchA2CO ) - net.addLink( customerB1, switchB1CO ) - net.addLink( customerB2, switchB2CO ) - net.addLink( switchA1CO, switchBBL ) - net.addLink( switchB1CO, switchBBL ) - net.addLink( switchA2CO, switchBBR ) - net.addLink( switchB2CO, switchBBR ) - net.addLink( switchBBL, switchBBR) - net.addLink( switchBBR, switchEx, bw=1.2 ) - net.addLink( switchEx, switchBBL ) - - #Create Controller - floodlightController = net.addController(name='c0' , controller=RemoteController , ip='127.0.0.1', port=6653) - - net.start() - - if pusher.enableFirewall({})[0] == 200: - print("Firewall enabled!") - - #print(pusher.addRule({"switchid": "00:00:00:00:00:00:00:01"})[2]) - s1id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:01"})[2])['rule-id'] - s2id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:02"})[2])['rule-id'] - s3id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:03"})[2])['rule-id'] - s4id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:04"})[2])['rule-id'] - s5id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:05"})[2])['rule-id'] - s6id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:06"})[2])['rule-id'] - s7id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:07"})[2])['rule-id'] - - - result = 100 - while result!=0: - result = net.pingAll(None) - print("Network Simulation Complete") - - #Assume control and when finished "exit" - cli = CLI( net ) - - consumer = KafkaConsumer(bootstrap_servers='localhost:9092',auto_offset_reset='latest') - consumer.subscribe(['apex-out']) - print("Starting Message Loop") - for message in consumer: - myOutput = json.loads(message.value.decode()) - action = "" - try: - print("Checking Message") - #print("SWITCHES= ",net.switches) - #print("LINKS= ",net.links) - #print("VALUES= ",net.values) - if myOutput['edgeName'] != '': - print("Message Received: ",myOutput['edgeName']) - pusher.deleteRule({"ruleid": s1id}) - pusher.deleteRule({"ruleid": s2id}) - pusher.deleteRule({"ruleid": s3id}) - pusher.deleteRule({"ruleid": s4id}) - pusher.deleteRule({"ruleid": s5id}) - pusher.deleteRule({"ruleid": s6id}) - pusher.deleteRule({"ruleid": s7id}) - s1id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:01"})[2])['rule-id'] - s2id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:02"})[2])['rule-id'] - s3id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:03"})[2])['rule-id'] - s4id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:04"})[2])['rule-id'] - s5id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:05"})[2])['rule-id'] - s6id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:06"})[2])['rule-id'] - s7id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:07"})[2])['rule-id'] - if myOutput['edgeName'] == "L01": - action = "link s1 s5 down" - #net.configLinkStatus('s1', 's5', "down") - pusher.deleteRule({"ruleid": s1id}) - s1id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:01", "action": "DENY"})[2])['rule-id'] - if myOutput['edgeName'] == "L02": - action = "link s3 s5 down" - #net.configLinkStatus('s3', 's5', "down") - pusher.deleteRule({"ruleid": s3id}) - s3id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:03", "action": "DENY"})[2])['rule-id'] - if myOutput['edgeName'] == "L03": - action = "link s2 s6 down" - #net.configLinkStatus('s2', 's6', "down") - pusher.deleteRule({"ruleid": s1id}) - s1id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:01", "action": "DENY"})[2])['rule-id'] - if myOutput['edgeName'] == "L04": - action = "link s4 s6 down" - #net.configLinkStatus('s4', 's6', "down") - pusher.deleteRule({"ruleid": s3id}) - s3id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:03", "action": "DENY"})[2])['rule-id'] - if myOutput['edgeName'] == "L05": - action = "link s1 s5 down" - #net.configLinkStatus('s1', 's5', "down") - pusher.deleteRule({"ruleid": s1id}) - s1id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:01", "action": "DENY"})[2])['rule-id'] - if myOutput['edgeName'] == "L06": - action = "link s3 s5 down" - #net.configLinkStatus('s3', 's5', "down") - pusher.deleteRule({"ruleid": s3id}) - s3id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:03", "action": "DENY"})[2])['rule-id'] - if myOutput['edgeName'] == "L07": - action = "link s2 s6 down" - #net.configLinkStatus('s2', 's6', "down") - pusher.deleteRule({"ruleid": s2id}) - s2id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:02", "action": "DENY"})[2])['rule-id'] - if myOutput['edgeName'] == "L08": - action = "link s4 s6 down" - #net.configLinkStatus('s4', 's6', "down") - pusher.deleteRule({"ruleid": s4id}) - s4id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:04", "action": "DENY"})[2])['rule-id'] - if myOutput['edgeName'] == "L09": - action = "link s5 s6 down" - #net.configLinkStatus('s5', 's6', "down") - pusher.deleteRule({"ruleid": s7id}) - s7id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:07", "action": "DENY"})[2])['rule-id'] - if myOutput['edgeName'] == "L10": - print("L10") - #print(action) - #print("3") - except KeyError: - print(myOutput) - print("HA") - net.stop() .. container:: :name: footer-text @@ -2951,4 +860,69 @@ Mininet Topology .. |VPN SLA Architecture| image:: images/pcvs/vpnsla-arch.png +.. |avroSchemaEdges_link| raw:: html + + AVRO Schema Edges +.. |avroSchemaNodes_link| raw:: html + + AVRO Schema Nodes +.. |avroSchemaCustomers_link| raw:: html + + AVRO Schema Customers +.. |avroSchemaLinkStatus_link| raw:: html + + AVRO Schema Link Status +.. |cntxtNodes_link| raw:: html + + Logic Node Context +.. |cntxtEdges_link| raw:: html + + Logic Edge Context +.. |cntxtCustomer_link| raw:: html + + Logic Customer Context +.. |taskMatch_link| raw:: html + + Logic Policy Match State +.. |taskEstablish_link| raw:: html + + Logic Policy Establish State +.. |tslDecide_Link| raw:: html + + JS Logic Policy Decide State - TSL +.. |taskDecideNone_link| raw:: html + + Logic: Decide None +.. |taskDecideSolved_Link| raw:: html + + Logic: Decide Solved +.. |taskDecideSla_link| raw:: html + + Logic: Decide SLA +.. |taskDecidePriority_Link| raw:: html + + Logic: Decide Priority +.. |taskAct_link| raw:: html + + Logic Policy Act State +.. |vpnsla-apex_link| raw:: html + + APEX VPN SLA Policy Specification +.. |ctxtNodesJson_link| raw:: html + + Context Events Nodes +.. |ctxtEdgesJson_link| raw:: html + + Context Events Edges +.. |ctxtCustomerJson_link| raw:: html + + Context Events Customers +.. |triggerEdgeJson_link| raw:: html + + Trigger Examples +.. |linkMonitor_link| raw:: html + + Link Monitor +.. |mininetTopology_link| raw:: html + Mininet Topology diff --git a/docs/apex/APEX-User-Manual.rst b/docs/apex/APEX-User-Manual.rst index 10201c0f..50468a22 100644 --- a/docs/apex/APEX-User-Manual.rst +++ b/docs/apex/APEX-User-Manual.rst @@ -1025,12 +1025,12 @@ Verify Installation - run an Example .. container:: content - .. code:: + .. code:: :number-lines: - sudo su - apexuser - export APEX_HOME - export APEX_USER apexuser + sudo su - apexuser + export APEX_HOME + export APEX_USER apexuser .. container:: paragraph @@ -1040,7 +1040,7 @@ Verify Installation - run an Example .. container:: content - .. code:: + .. code:: :number-lines: # $APEX_HOME/bin/apexEngine.sh -c $APEX_HOME/examples/config/SampleDomain/Stdin2StdoutJsonEventJava.json (1) @@ -4535,8 +4535,8 @@ The APEX Full Client ``http://localhost:18989/apexservices``. In a web browser use the URL ``http://localhost:18989``. - The APEX Application Launcher ------------------------------- +The APEX Application Launcher +----------------------------- .. container:: paragraph @@ -4891,2750 +4891,327 @@ Application: Websocket Clients (Echo and Console) A discussion on how to use these two applications to build an APEX system is detailed HowTo-Websockets. -My First Policy -^^^^^^^^^^^^^^^ +APEX Logging +^^^^^^^^^^^^ + +Introduction to APEX Logging +---------------------------- -Introduction ------------- .. container:: paragraph - Consider a scenario where a supermarket chain called - *HyperM* controls how it sells items in a policy-based - manner. Each time an item is processed by *HyperM*'s - point-of-sale (PoS) system an event is generated and - published about that item of stock being sold. This event - can then be used to update stock levels, etc.. + All APEX components make extensive use of logging using the + logging façade `SLF4J `__ with the + backend `Logback `__. Both are used + off-the-shelve, so the standard documentation and + configuration apply to APEX logging. For details on how to + work with logback please see the `logback + manual `__. .. container:: paragraph - *HyperM* want to extend this approach to allow some checks - to be performed before the sale can be completed. This can - be achieved by requesting a policy-controlled decision as - each item is processed by for sale by each PoS system. The - decision process is integrated with *HyperM*'s other IT - systems that manage stock control, sourcing and purchasing, - personnel systems, etc. + The APEX applications is the logback configuration file + ``$APEX_HOME/etc/logback.xml`` (Windows: + ``%APEX_HOME%\etc\logback.xml``). The logging backend is set + to no debug, i.e. logs from the logging framework should be + hidden at runtime. .. container:: paragraph - In this document we will show how APEX and APEX Policies can - be used to achieve this, starting with a simple policy, - building up to more complicated policy that demonstrates the - features of APEX. - -Data Models ------------ + The configurable log levels work as expected: -Sales Input Event -################# + .. container:: ulist - .. container:: paragraph + - *error* (or *ERROR*) is used for serious errors in the + APEX runtime engine - Each time a PoS system processes a sales item an event - with the following format is emitted: + - *warn* (or *WARN*) is used for warnings, which in general + can be ignored but might indicate some deeper problems - .. table:: Table 1. Sale Input Event + - *info* (or *INFO*) is used to provide generally + interesting messages for startup and policy execution - +----------------------+----------------------+-----------------------+ - | Event | Fields | Description | - +======================+======================+=======================+ - | SALE_INPUT | time, sale_ID, | Event indicating a | - | | amount, item_ID, | sale of an item is | - | | quantity, | occurring | - | | assistant_ID, | | - | | branch_ID, notes, …​ | | - +----------------------+----------------------+-----------------------+ + - *debug* (or *DEBUG*) provides more details on startup and + policy execution - .. container:: paragraph + - *trace* (or *TRACE*) gives full details on every aspect + of the APEX engine from start to end - In each ``SALE_INPUT`` event the ``sale_ID`` field is a - unique ID generated by the PoS system. A timestamp for - the event is stored in the ``time`` field. The ``amount`` - field refers to the value of the item(s) to be sold (in - cents). The ``item_ID`` field is a unique identifier for - each item type, and can be used to retrieve more - information about the item from *HyperM*'s stock control - system. The ``quantity`` field refers to the quantity of - the item to be sold. The ``assistant_ID`` field is a - unique identifier for the PoS operator, and can be used - to retrieve more information about the operator from the - *HyperM*'s personnel system. Since *HyperM* has many - branches the ``branch_ID`` identifies the shop. The - ``notes`` field contains arbitrary notes about the sale. - -Sales Decision Event -#################### + .. container:: paragraph - .. container:: paragraph + The loggers can also be configured as expected. The standard + configuration (after installing APEX) uses log level *info* + on all APEX classes (components). - After a ``SALE_INPUT`` event is emitted by the PoS system - *HyperM*'s policy-based controlled sales checking system - emits a Sale Authorization Event indicating whether the - sale is authorized or denied. The PoS system can then - listen for this event before continuing with the sale. - - .. table:: Table 2. Sale Authorisation Event - - +----------------------+----------------------+-----------------------+ - | Event | Fields | Description | - +======================+======================+=======================+ - | SALE_AUTH | sale_ID, time, | Event indicating a | - | | authorized, amount, | sale of an item is | - | | item_ID, quantity, | authorized or denied | - | | assistant_ID, | | - | | branch_ID, notes, | | - | | message…​ | | - +----------------------+----------------------+-----------------------+ + .. container:: paragraph - .. container:: paragraph + The applications and scripts in ``$APEX_HOME/bin`` (Windows: + ``%APEX_HOME\bin``) are configured to use the logback + configuration ``$APEX_HOME/etc/logback.xml`` (Windows: + ``%APEX_HOME\etc\logback.xml``). There are multiple ways to + use different logback configurations, for instance: - In each ``SALE_AUTH`` event the ``sale_ID`` field is - copied from the ``SALE_INPUT`` event that trigger the - decision request. The ``SALE_AUTH`` event is also - timestamped using the ``time`` field, and a field called - ``authorised`` is set to ``true`` or ``false`` depending - on whether the sale is authorized or denied. The - ``message`` field carries an optional message about why a - sale was not authorized. The other fields from the - ``SALE_INPUT`` event are also included for completeness. - -Stock Control: Items -#################### + .. container:: ulist - .. container:: paragraph + - Maintain multiple configurations in ``etc``, for instance + a ``logback-debug.xml`` for deep debugging and a + ``logback-production.xml`` for APEX in production mode, + then copy the required configuration file to the used + ``logback.xml`` prior starting APEX - *HyperM* maintains information about each item for sale - in a database table called ``ITEMS``. + - Edit the scripts in ``bin`` to use a different logback + configuration file (only recommended if you are familiar + with editing bash scripts or windows batch files) - .. table:: Table 3. Items Database +Standard Logging Configuration +------------------------------ - +----------------------+----------------------+-----------------------+ - | Table | Fields | Description | - +======================+======================+=======================+ - | ITEMS | item_ID, | Database table | - | | description, | describing each item | - | | cost_price, barcode, | for sale | - | | supplier_ID, | | - | | category, …​ | | - +----------------------+----------------------+-----------------------+ + .. container:: paragraph - .. container:: paragraph + The standard logging configuration defines a context *APEX*, + which is used in the standard output pattern. The location + for log files is defined in the property ``logDir`` and set + to ``/var/log/onap/policy/apex-pdp``. The standard status + listener is set to *NOP* and the overall logback + configuration is set to no debug. - The database table ``ITEMS`` has a row for each items - that *HyperM* sells. Each item is identified by an - ``item_ID`` value. The ``description`` field stores a - description of the item. The cost price of the item is - given in ``cost_price``. The barcode of the item is - encoded in ``barcode``, while the item supplier is - identified by ``supplier_ID``. Items may also be - classified into categories using the ``category`` field. - Useful categories might include: ``soft drinks``, - ``alcoholic drinks``, ``cigarettes``, ``knives``, - ``confectionery``, ``bakery``, ``fruit&vegetables``, - ``meat``, etc.. - -Personnel System: Assistants -############################ + .. container:: listingblock - .. table:: Table 4. Assistants Database + .. container:: content - +----------------------+----------------------+-----------------------+ - | Table | Fields | Description | - +======================+======================+=======================+ - | ASSISTANTS | assistant_ID, | Database table | - | | surname, firstname, | describing each | - | | middlename, age, | *HyperM* sales | - | | grade, phone_number, | assistant | - | | …​ | | - +----------------------+----------------------+-----------------------+ + .. code:: + :number-lines: - .. container:: paragraph + + - The database table ``ASSISTANTS`` has a row for each - sales assistant employed by *HyperM*. Each assistant is - identified by an ``assistant_ID`` value, with their name - given in the ``firstname``, ``middlename`` and - ``surname`` fields. The assistant’s age in years is given - in ``age``, while their phone number is contained in the - ``phone_number`` field. The assistant’s grade is encoded - in ``grade``. Useful values for ``grade`` might include: - ``trainee``, ``operator``, ``supervisor``, etc.. - -Locations: Branches -#################### + Apex + - .. table:: Table 5. Branches Database + ...appenders + ...loggers + - +----------------------+----------------------+-----------------------+ - | Table | Fields | Description | - +======================+======================+=======================+ - | BRANCHES | branch_ID, | Database table | - | | branch_Name, | describing each | - | | category, street, | *HyperM* branch | - | | city, country, | | - | | postcode, …​ | | - +----------------------+----------------------+-----------------------+ +.. container:: paragraph - .. container:: paragraph + The first appender defined is called ``STDOUT`` for logs to standard + out. - *HyperM* operates a number of branches. Each branch is - described in the ``BRANCHES`` database table. Each branch - is identified by a ``branch_ID``, with a branch name - given in ``branch_Name``. The address for the branch is - encoded in ``street``, ``city``, ``country`` and - ``postcode``. The branch category is given in the - ``category`` field. Useful values for ``category`` might - include: ``Small``, ``Large``, ``Super``, ``Hyper``, - etc.. +.. container:: listingblock -Policy Step 1 -------------- + .. container:: content -Scenario -######### - .. container:: paragraph + .. code:: + :number-lines: - For the first version of our policy, let’s start with - something simple. Let us assume that there exists some - restriction that alcohol products cannot be sold before - 11:30am. In this section we will go through the necessary - steps to define a policy that can enforce this for - *HyperM*. + + + %d %contextName [%t] %level %logger{36} - %msg%n + + - .. container:: ulist +.. container:: paragraph - - Alcohol cannot be sold before 11:30am. + The root level logger then is set to the level *info* using the + standard out appender. -Create the an new empty Policy Model ``MyFirstPolicyModel`` -########################################################### +.. container:: listingblock - .. container:: paragraph + .. container:: content - Since an organisation like *HyperM* may have many - policies covering many different domains, policies should - be grouped into policy sets. In order to edit or deploy a - policy, or policy set, the definition of the policy(ies) - and all required events, tasks, states, etc., are grouped - together into a 'Policy Model'. An organization might - define many Policy Models, each containing a different - set of policies. + .. code:: + :number-lines: - .. container:: paragraph + + + - So the first step is to create a new empty Policy Model - called ``MyFirstPolicyModel``. Using the APEX Policy - Editor, click on the 'File' menus and select 'New'. Then - define our new policy model called - ``MyFirstPolicyModel``. Use the 'Generate UUID' button to - create a new unique ID for the policy model, and fill in - a description for the policy model. Press the ``Submit`` - button to save your changes. +.. container:: paragraph - .. container:: imageblock + The second appender is called ``FILE``. It writes logs to a file + ``apex.log``. - .. container:: content +.. container:: listingblock - |File > New to create a new Policy Model| + .. container:: content - .. container:: title + .. code:: + :number-lines: - Figure 4. Create a new Policy Model 1/2 + + ${logDir}/apex.log + + %d %-5relative [procId=${processId}] [%thread] %-5level %logger{26} - %msg %n %ex{full} + + - .. container:: imageblock +.. container:: paragraph - .. container:: content + The third appender is called ``CTXT_FILE``. It writes logs to a file + ``apex_ctxt.log``. - |Create a new Policy Model| +.. container:: listingblock - .. container:: title + .. container:: content - Figure 5. Create a new Policy Model 2/2 + .. code:: + :number-lines: -Create the input event ``SALE_INPUT`` and the output event ``SALE_AUTH`` -######################################################################## + + ${logDir}/apex_ctxt.log + + %d %-5relative [procId=${processId}] [%thread] %-5level %logger{26} - %msg %n %ex{full} + + - .. container:: paragraph +.. container:: paragraph - Using the APEX Policy Editor, click on the 'Events' tab. - In the 'Events' pane, right click and select 'New': + The last definitions are for specific loggers. The first logger + captures all standard APEX classes. It is configured for log level + *info* and uses the standard output and file appenders. The second + logger captures APEX context classes responsible for context + monitoring. It is configured for log level *trace* and uses the + context file appender. - .. container:: imageblock +.. container:: listingblock - .. container:: content + .. container:: content - |Right click to create a new event| + .. code:: + :number-lines: - .. container:: title - Figure 6. Create a new Event type + + + + - .. container:: paragraph + + + - Create a new event type called ``SALE_INPUT``. Use the - 'Generate UUID' button to create a new unique ID for the - event type, and fill in a description for the event. Add - a namespace, e.g. ``com.hyperm``. We can add hard-coded - strings for the ``Source`` and ``Target``, e.g. ``POS`` - and ``APEX``. At this stage we will not add any parameter - fields, we will leave this until later. Use the - ``Submit`` button to create the event. +Adding Logback Status and Debug +------------------------------- - .. container:: imageblock + .. container:: paragraph - .. container:: content + To activate logback status messages change the status listener + from 'NOP' to for instance console. - |Fill in the necessary information for the - 'SALE_INPUT' event and click 'Submit'| + .. container:: listingblock - .. container:: title + .. container:: content - Figure 7. Populate the ``SALE_INPUT`` event + .. code:: - .. container:: paragraph + - Repeat the same steps for a new event type called - ``SALE_AUTH``. Just use ``APEX`` as source and ``POS`` as - target, since this is the output event coming from APEX - going to the sales point. + .. container:: paragraph - .. container:: paragraph + To activate all logback debugging, for instance to debug a new + logback configuration, activate the debug attribute in the + configuration. - Before we can add parameter fields to an event we must - first define APEX Context Item Schemas that can be used - by those fields. + .. container:: listingblock - .. container:: paragraph + .. container:: content - To create new item schemas, click on the 'Context Item - Schemas' tab. In that 'Context Item Schemas' pane, right - click and select 'Create new ContextSchema'. + .. code:: - .. container:: imageblock + + ... + - .. container:: content +Logging External Components +--------------------------- - |Right click to create a new Item Schema| + .. container:: paragraph - .. container:: title + Logback can also be configured to log any other, external + components APEX is using, if they are using the common logging + framework. - Figure 8. Create new Data Types + .. container:: paragraph - .. container:: paragraph + For instance, the context component of APEX is using *Infinispan* + and one can add a logger for this external component. The + following example adds a logger for *Infinispan* using the + standard output appender. - Create item schemas with the following characteristics, - each with its own unique UUID: - - .. table:: Table 6. Item Schemas - - +-------------------+-----------------+-----------------+----------------------+ - | Name | Schema Flavour | Schema | Description | - | | | Definition | | - +===================+=================+=================+======================+ - | timestamp_type | Java | java.lang.Long | A type for | - | | | | ``time`` values | - +-------------------+-----------------+-----------------+----------------------+ - | sale_ID_type | Java | java.lang.Long | A type for | - | | | | ``sale_ID`` | - | | | | values | - +-------------------+-----------------+-----------------+----------------------+ - | price_type | Java | java.lang.Long | A type for | - | | | | ``amount``/``price`` | - | | | | values | - +-------------------+-----------------+-----------------+----------------------+ - | item_ID_type | Java | java.lang.Long | A type for | - | | | | ``item_ID`` | - | | | | values | - +-------------------+-----------------+-----------------+----------------------+ - | assistant_ID_type | Java | java.lang.Long | A type for | - | | | | ``assistant_ID`` | - | | | | values | - +-------------------+-----------------+-----------------+----------------------+ - | quantity_type | Java | java.lang.Integ | A type for | - | | | er | ``quantity`` | - | | | | values | - +-------------------+-----------------+-----------------+----------------------+ - | branch_ID_type | Java | java.lang.Long | A type for | - | | | | ``branch_ID`` | - | | | | values | - +-------------------+-----------------+-----------------+----------------------+ - | notes_type | Java | java.lang.Strin | A type for | - | | | g | ``notes`` | - | | | | values | - +-------------------+-----------------+-----------------+----------------------+ - | authorised_type | Java | java.lang.Boole | A type for | - | | | an | ``authorised`` | - | | | | values | - +-------------------+-----------------+-----------------+----------------------+ - | message_type | Java | java.lang.Strin | A type for | - | | | g | ``message`` | - | | | | values | - +-------------------+-----------------+-----------------+----------------------+ - - .. container:: imageblock + .. container:: listingblock - .. container:: content + .. container:: content - |Create a new Item Schema| + .. code:: - .. container:: title + + + - Figure 9. Create new Item Schemas + .. container:: paragraph - .. container:: paragraph + Another example is Apache Zookeeper. The following example adds a + logger for Zookeeper using the standard outout appender. - The item schemas can now be seen on the 'Context Item - Schemas' tab, and can be updated at any time by - right-clicking on the item schemas on the 'Context Item - Schemas' tab. Now we can go back to the event definitions - for ``SALE_INPUT`` and ``SALE_AUTH`` and add some - parameter fields. + .. container:: listingblock - .. tip + .. container:: content - .. container:: title + .. code:: - Field Schema types + + + - .. container:: paragraph +Configuring loggers for Policy Logic +------------------------------------ - APEX natively supports schema definitions in ``Java`` and ``Avro``. + .. container:: paragraph - .. container:: paragraph + The logging for the logic inside a policy (task logic, task + selection logic, state finalizer logic) can be configured separate + from standard logging. The logger for policy logic is + ``org.onap.policy.apex.executionlogging``. The following example + defines - ``Java`` schema definitions are simply the name of a Java Class. There are some restrictions: + .. container:: ulist - .. container:: ulist + - a new appender for standard out using a very simple pattern + (simply the actual message) - - the class must be instantiatable, i.e. not an Java interface or abstract class + - a logger for policy logic to standard out using the new + appender and the already described file appender. - - primitive types are not supported, i.e. use ``java.lang.Integer`` instead of ``int``, etc. + .. container:: listingblock - - it must be possible to find the class, i.e. the class must be contained in the Java classpath. + .. container:: content - .. container:: paragraph + .. code:: - ``Avro`` schema definitions can be any valid `Avro `__ - schema. For events using fields defined with ``Avro`` schemas, any incoming event containing that field must - contain a value that conforms to the Avro schema. + + + policy: %msg\n + + - .. container:: paragraph + + + + - Click on the 'Events' tab, then right click the - ``SALE_INPUT`` row and select 'Edit Event - :literal:`SALE_INPUT’. To add a new event parameter use the 'Add Event Parameter' button at the bottom of the screen. For the `SALE_INPUT` - event add the following event parameters: - - .. table:: Table 7. Event Parameter Fields for the ``SALE_INPUT`` Event - - +----------------------+----------------------+-----------------------+ - | Parameter Name | Parameter Type | Optional | - +======================+======================+=======================+ - | time | timestamp_type | no | - +----------------------+----------------------+-----------------------+ - | sale_ID | sale_ID_type | no | - +----------------------+----------------------+-----------------------+ - | amount | price_type | no | - +----------------------+----------------------+-----------------------+ - | item_ID | item_ID_type | no | - +----------------------+----------------------+-----------------------+ - | quantity | quantity_type | no | - +----------------------+----------------------+-----------------------+ - | assistant_ID | assistant_ID_type | no | - +----------------------+----------------------+-----------------------+ - | branch_ID | branch_ID_type | no | - +----------------------+----------------------+-----------------------+ - | notes | notes_type | *yes* | - +----------------------+----------------------+-----------------------+ + .. container:: paragraph - .. container:: paragraph + It is also possible to use specific logging for parts of policy + logic. The following example defines a logger for task logic. - Remember to click the 'Submit' button at the bottom of - the event definition pane. + .. container:: listingblock - .. tip:: - Optional Fields in APEX Events - Parameter fields can be *optional* in events. If a parameter is not marked as *optional* then by default it - is *mandatory*, so it must appear in any input event passed to APEX. If an *optional* field is not set - for an output event then value will be set to ``null``. + .. container:: content - .. container:: imageblock + .. code:: - .. container:: content - - |Add new event parameters to an event| - - .. container:: title - - Figure 10. Add typed parameter fields to an event - - .. container:: paragraph - - Select the ``SALE_AUTH`` event and add the following - event parameters: - - .. table:: Table 8. Event Parameter Fields for the ``SALE_AUTH`` Event - - +----------------------+----------------------+-----------------------+ - | Parameter Name | Parameter Type | no | - +======================+======================+=======================+ - | sale_ID | sale_ID_type | no | - +----------------------+----------------------+-----------------------+ - | time | timestamp_type | no | - +----------------------+----------------------+-----------------------+ - | authorised | authorised_type | no | - +----------------------+----------------------+-----------------------+ - | message | message_type | *yes* | - +----------------------+----------------------+-----------------------+ - | amount | price_type | no | - +----------------------+----------------------+-----------------------+ - | item_ID | item_ID_type | no | - +----------------------+----------------------+-----------------------+ - | assistant_ID | assistant_ID_type | no | - +----------------------+----------------------+-----------------------+ - | quantity | quantity_type | no | - +----------------------+----------------------+-----------------------+ - | branch_ID | branch_ID_type | no | - +----------------------+----------------------+-----------------------+ - | notes | notes_type | *yes* | - +----------------------+----------------------+-----------------------+ - - .. container:: paragraph - - Remember to click the 'Submit' button at the bottom of - the event definition pane. - - .. container:: paragraph - - The events for our policy are now defined. - -Create a new Policy and add the *"No Booze before 11:30"* check -############################################################### - - .. container:: paragraph - - APEX policies are defined using a state-machine model. - Each policy comprises one or more *states* that can be - individually executed. Where there is more than one - *state* the states are chained together to form a - `Directed Acyclic Graph - (DAG) `__ - of states. A *state* is triggered by passing it a single - input (or 'trigger') event and once executed each state - then emits an output event. For each *state* the logic - for the *state* is embedded in one or more *tasks*. Each - *task* contains specific *task logic* that is executed by - the APEX execution environment each time the *task* is - invoked. Where there is more than one *task* in a *state* - then the *state* also defines some *task selection logic* - to select an appropriate task each time the *state* is - executed. - - .. container:: paragraph - - Therefore, to create a new policy we must first define - one or more tasks. - - .. container:: paragraph - - To create a new Task click on the 'Tasks' tab. In the - 'Tasks' pane, right click and select 'Create new Task'. - Create a new Task called ``MorningBoozeCheck``. Use the - 'Generate UUID' button to create a new unique ID for the - task, and fill in a description for the task. - - .. container:: imageblock - - .. container:: content - - |Right click to create a new task| - - .. container:: title - - Figure 11. Create a new Task - - .. container:: paragraph - - Tasks are configured with a set of *input fields* and a - set of *output fields*. To add new input/output fields - for a task use the 'Add Task Input Field' and 'Add Task - Output Field' button. The list of input and out fields to - add for the ``MorningBoozeCheck`` task are given below. - The input fields are drawn from the parameters in the - state’s input event, and the task’s output fields are - used to populate the state’s output event. The task’s - input and output fields must be a subset of the event - parameters defined for the input and output events for - any state that uses that task. (You may have noticed that - the input and output fields for the ``MorningBoozeCheck`` - task have the exact same names and reuse the item schemas - that we used for the parameters in the ``SALE_INPUT`` and - ``SALE_AUTH`` events respectively). - - .. table:: Table 9. Input fields for ``MorningBoozeCheck`` task - - +-----------------------------------+-----------------------------------+ - | Parameter Name | Parameter Type | - +===================================+===================================+ - | time | timestamp_type | - +-----------------------------------+-----------------------------------+ - | sale_ID | sale_ID_type | - +-----------------------------------+-----------------------------------+ - | amount | price_type | - +-----------------------------------+-----------------------------------+ - | item_ID | item_ID_type | - +-----------------------------------+-----------------------------------+ - | quantity | quantity_type | - +-----------------------------------+-----------------------------------+ - | assistant_ID | assistant_ID_type | - +-----------------------------------+-----------------------------------+ - | branch_ID | branch_ID_type | - +-----------------------------------+-----------------------------------+ - | notes | notes_type | - +-----------------------------------+-----------------------------------+ - - .. table:: Table 10. Output fields for ``MorningBoozeCheck`` task - - +-----------------------------------+-----------------------------------+ - | Parameter Name | Parameter Type | - +===================================+===================================+ - | sale_ID | sale_ID_type | - +-----------------------------------+-----------------------------------+ - | time | timestamp_type | - +-----------------------------------+-----------------------------------+ - | authorised | authorised_type | - +-----------------------------------+-----------------------------------+ - | message | message_type | - +-----------------------------------+-----------------------------------+ - | amount | price_type | - +-----------------------------------+-----------------------------------+ - | item_ID | item_ID_type | - +-----------------------------------+-----------------------------------+ - | assistant_ID | assistant_ID_type | - +-----------------------------------+-----------------------------------+ - | quantity | quantity_type | - +-----------------------------------+-----------------------------------+ - | branch_ID | branch_ID_type | - +-----------------------------------+-----------------------------------+ - | notes | notes_type | - +-----------------------------------+-----------------------------------+ - - .. container:: imageblock - - .. container:: content - - |Add input and out fields for the task| - - .. container:: title - - Figure 12. Add input and out fields for the Task - - .. container:: paragraph - - Each task must include some 'Task Logic' that implements - the behaviour for the task. Task logic can be defined in - a number of different ways using a choice of languages. - For this task we will author the logic using the - Java-like scripting language called - ```MVEL`` `__. - - .. container:: paragraph - - For simplicity use the following code for the task logic. - Paste the script text into the 'Task Logic' box, and use - "MVEL" as the 'Task Logic Type / Flavour'. - - .. container:: paragraph - - This logic assumes that all items with ``item_ID`` - between 1000 and 2000 contain alcohol, which is not very - realistic, but we will see a better approach for this - later. It also uses the standard ``Java`` time utilities - to check if the current time is between ``00:00:00 GMT`` - and ``11:30:00 GMT``. For a detailed guide to how to - write your own logic in - ```JavaScript`` `__, - ```MVEL`` `__ or one - of the other supported languages please refer to APEX - Programmers Guide. - - .. container:: listingblock - - .. container:: title - - MVEL code for the ``MorningBoozeCheck`` task - - .. container:: content - - .. code:: - - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - import java.util.Date; - import java.util.Calendar; - import java.util.TimeZone; - import java.text.SimpleDateFormat; - - logger.info("Task Execution: '"+subject.id+"'. Input Fields: '"+inFields+"'"); - - outFields.put("amount" , inFields.get("amount")); - outFields.put("assistant_ID", inFields.get("assistant_ID")); - outFields.put("notes" , inFields.get("notes")); - outFields.put("quantity" , inFields.get("quantity")); - outFields.put("branch_ID" , inFields.get("branch_ID")); - outFields.put("item_ID" , inFields.get("item_ID")); - outFields.put("time" , inFields.get("time")); - outFields.put("sale_ID" , inFields.get("sale_ID")); - - item_id = inFields.get("item_ID"); - - //The events used later to test this task use GMT timezone! - gmt = TimeZone.getTimeZone("GMT"); - timenow = Calendar.getInstance(gmt); - df = new SimpleDateFormat("HH:mm:ss z"); - df.setTimeZone(gmt); - timenow.setTimeInMillis(inFields.get("time")); - - midnight = timenow.clone(); - midnight.set( - timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), - timenow.get(Calendar.DATE),0,0,0); - eleven30 = timenow.clone(); - eleven30.set( - timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), - timenow.get(Calendar.DATE),11,30,0); - - itemisalcohol = false; - if(item_id != null && item_id >=1000 && item_id < 2000) - itemisalcohol = true; - - if( itemisalcohol - && timenow.after(midnight) && timenow.before(eleven30)){ - outFields.put("authorised", false); - outFields.put("message", "Sale not authorised by policy task "+subject.taskName+ - " for time "+df.format(timenow.getTime())+ - ". Alcohol can not be sold between "+df.format(midnight.getTime())+ - " and "+df.format(eleven30.getTime())); - return true; - } - else{ - outFields.put("authorised", true); - outFields.put("message", "Sale authorised by policy task "+subject.taskName+ - " for time "+df.format(timenow.getTime())); - return true; - } - - /* - This task checks if a sale request is for an item that is an alcoholic drink. - If the local time is between 00:00:00 GMT and 11:30:00 GMT then the sale is not - authorised. Otherwise the sale is authorised. - In this implementation we assume that items with item_ID value between 1000 and - 2000 are all alcoholic drinks :-) - */ - - .. container:: imageblock - - .. container:: content - - |Add task logic the task| - - .. container:: title - - Figure 13. Add Task Logic the Task - - .. container:: paragraph - - An alternative version of the same logic is available in - JavaScript. Just use "JAVASCRIPT" as the 'Task Logic Type - / Flavour' instead. - - .. container:: listingblock - - .. container:: title - - Javascript alternative for the ``MorningBoozeCheck`` - task - - .. container:: content - - .. code:: - - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - - var returnValueType = Java.type("java.lang.Boolean"); - var returnValue = new returnValueType(true); - - // Load compatibility script for imports etc - load("nashorn:mozilla_compat.js"); - importPackage(java.text); - importClass(java.text.SimpleDateFormat); - - executor.logger.info("Task Execution: '"+executor.subject.id+"'. Input Fields: '"+executor.inFields+"'"); - - executor.outFields.put("amount" , executor.inFields.get("amount")); - executor.outFields.put("assistant_ID", executor.inFields.get("assistant_ID")); - executor.outFields.put("notes" , executor.inFields.get("notes")); - executor.outFields.put("quantity" , executor.inFields.get("quantity")); - executor.outFields.put("branch_ID" , executor.inFields.get("branch_ID")); - executor.outFields.put("item_ID" , executor.inFields.get("item_ID")); - executor.outFields.put("time" , executor.inFields.get("time")); - executor.outFields.put("sale_ID" , executor.inFields.get("sale_ID")); - - item_id = executor.inFields.get("item_ID"); - - //All times in this script are in GMT/UTC since the policy and events assume time is in GMT. - var timenow_gmt = new Date(Number(executor.inFields.get("time"))); - - var midnight_gmt = new Date(Number(executor.inFields.get("time"))); - midnight_gmt.setUTCHours(0,0,0,0); - - var eleven30_gmt = new Date(Number(executor.inFields.get("time"))); - eleven30_gmt.setUTCHours(11,30,0,0); - - var timeformatter = new java.text.SimpleDateFormat("HH:mm:ss z"); - - var itemisalcohol = false; - if(item_id != null && item_id >=1000 && item_id < 2000) - itemisalcohol = true; - - if( itemisalcohol - && timenow_gmt.getTime() >= midnight_gmt.getTime() - && timenow_gmt.getTime() < eleven30_gmt.getTime()) { - - executor.outFields.put("authorised", false); - executor.outFields.put("message", "Sale not authorised by policy task " + - executor.subject.taskName+ " for time " + timeformatter.format(timenow_gmt.getTime()) + - ". Alcohol can not be sold between " + timeformatter.format(midnight_gmt.getTime()) + - " and " + timeformatter.format(eleven30_gmt.getTime())); - } - else{ - executor.outFields.put("authorised", true); - executor.outFields.put("message", "Sale authorised by policy task " + - executor.subject.taskName + " for time "+timeformatter.format(timenow_gmt.getTime())); - } - - /* - This task checks if a sale request is for an item that is an alcoholic drink. - If the local time is between 00:00:00 GMT and 11:30:00 GMT then the sale is not - authorised. Otherwise the sale is authorised. - In this implementation we assume that items with item_ID value between 1000 and - 2000 are all alcoholic drinks :-) - */ - - .. container:: paragraph - - The task definition is now complete so click the 'Submit' - button to save the task. The task can now be seen on the - 'Tasks' tab, and can be updated at any time by - right-clicking on the task on the 'Task' tab. Now that we - have created our task, we can can create a policy that - uses that task. - - .. container:: paragraph - - To create a new Policy click on the 'Policies' tab. In - the 'Policies' pane, right click and select 'Create new - Policy': - - .. container:: paragraph - - Create a new Policy called ``MyFirstPolicy``. Use the - 'Generate UUID' button to create a new unique ID for the - policy, and fill in a description for the policy. Use - 'FREEFORM' as the 'Policy Flavour'. - - .. container:: paragraph - - Each policy must have at least one state. Since this is - 'freeform' policy we can add as many states as we wish. - Let’s start with one state. Add a new state called - ``BoozeAuthDecide`` to this ``MyFirstPolicy`` policy - using the 'Add new State' button after filling in the - name of our new state. - - .. container:: imageblock - - .. container:: content - - |Create a new policy| - - .. container:: title - - Figure 14. Create a new Policy - - .. container:: paragraph - - Each state must uses one input event type. For this new - state select the ``SALE_INPUT`` event as the input event. - - .. container:: paragraph - - Each policy must define a 'First State' and a 'Policy - Trigger Event'. The 'Policy Trigger Event' is the input - event for the policy as a whole. This event is then - passed to the first state in the chain of states in the - policy, therefore the 'Policy Trigger Event' will be the - input event for the first state. Each policy can only - have one 'First State'. For our ``MyFirstPolicy`` policy, - select ``BoozeAuthDecide`` as the 'First State'. This - will automatically select ``SALE_INPUT`` as the 'Policy - Trigger Event' for our policy. - - .. container:: imageblock - - .. container:: content - - |Create a state| - - .. container:: title - - Figure 15. Create a new State - - .. container:: paragraph - - In this case we will create a reference the pre-existing - ``MorningBoozeCheck`` task that we defined above using - the 'Add New Task' button. Select the - ``MorningBoozeCheck`` task, and use the name of the task - as the 'Local Name' for the task. - - .. container:: paragraph - - in the case where a state references more than one task, - a 'Default Task' must be selected for the state and some - logic ('Task Selection Logic') must be specified to - select the appropriate task at execution time. Since our - new state ``BoozeAuthDecide`` only has one task the - default task is automatically selected and no 'Task - Selection Logic' is required. - - .. note:: - .. container:: title - - State Output Mappings - - .. container:: paragraph - - In a 'Policy' 'State' a 'State Output Mapping' has 3 roles: - 1) Select which 'State' should be executed next, 2) Select - the type of the state’s 'Outgoing Event', and 3) - Populate the state’s 'Outgoing Event'. This is how states are - chained together to form a (`Directed Acyclic Graph - (DAG) `__ ) - of states. The final state(s) of a policy are those that do - not select any 'next' state. Since a 'State' can only - accept a single type of event, the type of the event emitted - by a previous 'State' must be match the incoming event type - of the next 'State'. This is also how the last state(s) in - a policy can emit events of different types. The 'State - Output Mapping' is also responsible for taking the - fields that are output by the task executed in the state and - populating the state’s output event before it is emitted. - - .. container:: paragraph - - Each 'Task' referenced in 'State' must have a defined - 'Output Mapping' to take the output of the task, select an - 'Outgoing Event' type for the state, populate the state’s - outgoing event, and then select the next state to be - executed (if any). - - .. container:: paragraph - - There are 2 basic types of output mappings: - - .. container:: olist arabic - - #. **Direct Output Mappings** have a single value for - 'Next State' and a single value for 'State Output - Event'. The outgoing event for the state is - automatically created, any outgoing event parameters - that were present in the incoming event are copied - into the outgoing event, then any task output fields - that have the same name and type as parameters in the - outgoing event are automatically copied into - the outgoing event. - - #. **Logic-based State Output Mappings / Finalizers** - have some logic defined that dynamically selects - and creates the 'State Outgoing Event', manages - the population of the outgoing event parameters - (perhaps changing or adding to the outputs from the - task), and then dynamically selects the next state to - be executed (if any). - - .. container:: paragraph - - Each task reference must also have an associated 'Output - State Mapping' so we need an 'Output State Mapping' for - the ``BoozeAuthDecide`` state to use when the - ``MorningBoozeCheck`` task is executed. The simplest type - of output mapping is a 'Direct Output Mapping'. - - .. container:: paragraph - - Create a new 'Direct Output Mapping' for the state called - ``MorningBoozeCheck_Output_Direct`` using the 'Add New - Direct State Output Mapping' button. Select ``SALE_AUTH`` - as the output event and select ``None`` for the next - state value. We can then select this output mapping for - use when the the ``MorningBoozeCheck`` task is executed. - Since there is only state, and only one task for that - state, this output mapping ensures that the - ``BoozeAuthDecide`` state is the only state executed and - the state (and the policy) can only emit events of type - ``SALE_AUTH``. (You may remember that the output fields - for the ``MorningBoozeCheck`` task have the exact same - names and reuse the item schemas that we used for the - parameters in ``SALE_AUTH`` event. The - ``MorningBoozeCheck_Output_Direct`` direct output mapping - can now automatically copy the values from the - ``MorningBoozeCheck`` task directly into outgoing - ``SALE_AUTH`` events.) - - .. container:: imageblock - - .. container:: content - - |Add a Task and Output Mapping| - - .. container:: title - - Figure 16. Add a Task and Output Mapping - - .. container:: paragraph - - Click the 'Submit' button to complete the definition of - our ``MyFirstPolicy`` policy. The policy - ``MyFirstPolicy`` can now be seen in the list of policies - on the 'Policies' tab, and can be updated at any time by - right-clicking on the policy on the 'Policies' tab. - - .. container:: paragraph - - The ``MyFirstPolicyModel``, including our - ``MyFirstPolicy`` policy can now be checked for errors. - Click on the 'Model' menu and select 'Validate'. The - model should validate without any 'Warning' or 'Error' - messages. If you see any 'Error' or 'Warning' messages, - carefully read the message as a hint to find where you - might have made a mistake when defining some aspect of - your policy model. - - .. container:: imageblock - - .. container:: content - - |Validate the policy model for error using the 'Model' - > 'Validate' menu item| - - .. container:: title - - Figure 17. Validate a Policy Model - - .. container:: paragraph - - Congratulations, you have now completed your first APEX - policy. The policy model containing our new policy can - now be exported from the editor and saved. Click on the - 'File' menu and select 'Download' to save the policy - model in JSON format. The exported policy model is then - available in the directory you selected, for instance - ``$APEX_HOME/examples/models/MyFirstPolicy/1/MyFirstPolicyModel_0.0.1.json``. - The exported policy can now be loaded into the APEX - Policy Engine, or can be re-loaded and edited by the APEX - Policy Editor. - - .. container:: imageblock - - .. container:: content - - |Download the completed policy model using the 'File' - > 'Download' menu item| - - .. container:: title - - Figure 18. Export a Policy Model - -Test Policy Step 1 -################## - - .. container:: paragraph - - To start a new APEX Engine you can use the following - configuration. In a full APEX installation you can find - this configuration in - ``$APEX_HOME/examples/config/MyFirstPolicy/1/MyFirstPolicyConfigStdin2StdoutJsonEvent.json``. - This configuration expects incoming events to be in - ``JSON`` format and to be passed into the APEX Engine - from ``stdin``, and result events will be printed in - ``JSON`` format to ``stdout``. This configuration loads - the policy model stored in the file - 'MyFirstPolicyModel_0.0.1.json' as exported from the APEX - Editor. Note, you may need to edit this file to provide - the full path to wherever you stored the exported policy - model file. - - .. container:: listingblock - - .. container:: title - - JSON to load and execute *My First Policy*, read input - JSON events from ``stdin``, and emit output events to - ``stdout`` - - .. container:: content - - .. code:: - - { - "engineServiceParameters" : { - "name" : "MyFirstPolicyApexEngine", - "version" : "0.0.1", - "id" : 101, - "instanceCount" : 4, - "deploymentPort" : 12345, - "policyModelFileName" : "examples/models/MyFirstPolicy/1/MyFirstPolicyModel_0.0.1.json", - "engineParameters" : { - "executorParameters" : { - "MVEL" : { - "parameterClassName" : "org.onap.policy.apex.plugins.executor.mvel.MVELExecutorParameters" - }, - "JAVASCRIPT" : { - "parameterClassName" : "org.onap.policy.apex.plugins.executor.javascript.JavascriptExecutorParameters" - } - } - } - }, - "eventOutputParameters": { - "FirstProducer": { - "carrierTechnologyParameters" : { - "carrierTechnology" : "FILE", - "parameters" : { - "standardIO" : true - } - }, - "eventProtocolParameters" : { - "eventProtocol" : "JSON" - } - } - }, - "eventInputParameters": { - "FirstConsumer": { - "carrierTechnologyParameters" : { - "carrierTechnology" : "FILE", - "parameters" : { - "standardIO" : true - } - }, - "eventProtocolParameters" : { - "eventProtocol" : "JSON" - } - } - } - } - - .. container:: paragraph - - To test the policy try paste the following events into - the console as the APEX engine executes: - - .. table:: Table 11. Inputs and Outputs when testing *My First Policy* - - +------------------------------------------+-------------------------------------------+-----------+ - | Input Event (JSON) | Output Event (JSON) | comment | - +==========================================+===========================================+===========+ - | .. container:: | .. container:: | Request | - | | | to buy a | - | .. container:: listingblock | .. container:: listingblock | non-alcoh | - | | | olic | - | | .. container:: content | item | - | .. container:: content | | (``item_I | - | | .. code:: | D=5123``) | - | | | at | - | .. code:: | { | *10:13:09 | - | | "name": "SALE_AUTH", | * | - | | | on | - | { | "version": "0.0.1", | *Tuesday, | - | "nameSpace": "com.hyperm", | "nameSpace": "com.hyperm", | 10 | - | "name" : "SALE_INPUT", | "source": "", | January | - | "version": "0.0.1", | "target": "", | 2017*. | - | "time" : 1483351989000, | "amount": 299, | Sale is | - | "sale_ID": 99999991, | "assistant_ID": 23, | authorize | - | "amount": 299, | "authorised": true, | d. | - | "item_ID": 5123, | "branch_ID": 1, | | - | "quantity": 1, | "item_ID": 5123, | | - | "assistant_ID": 23, | "message": "Sale authorised | | - | "branch_ID": 1, | by policy task MorningBo | | - | "notes": "Special Offer!!" | ozeCheck for time 10:13:09 | | - | } | GMT", | | - | | "notes": "Special Offer!!", | | - | | "quantity": 1, | | - | | "sale_ID": 99999991, | | - | | "time": 1483351989000 | | - | | } | | - | | | | - | | | | - | | | | - +------------------------------------------+-------------------------------------------+-----------+ - | .. container:: | .. container:: | Request | - | | | to buy | - | .. container:: listingblock | .. container:: listingblock | alcohol | - | | | item | - | .. container:: content | .. container:: content | (``item_I | - | | | D=1249``) | - | .. code:: | .. code:: | at | - | | | *08:41:06 | - | { | { | * | - | "nameSpace": "com.hyperm", | "nameSpace": "com.hyperm", | on | - | "name": "SALE_INPUT", | "name": "SALE_AUTH", | *Monday, | - | "version": "0.0.1", | "source": "", | 02 | - | "time": 1483346466000, | "target": "", | January | - | "sale_ID": 99999992, | "amount": 1249, | 2017*. | - | "version": "0.0.1", | "assistant_ID": 12, | | - | "amount": 1249, | "authorised": false, | Sale is | - | "item_ID": 1012, | "branch_ID": 2, | not | - | "quantity": 1, | "item_ID": 1012, | authorize | - | "assistant_ID": 12, | "message": "Sale not | d. | - | "branch_ID": 2 | authorised by policy task | | - | } | MorningBoozeCheck for time | | - | | 08:41:06 GMT. Alcohol can | | - | | not be sold between | | - | | 00:00:00 GMT and 11:30:00 | | - | | GMT", | | - | | "notes": null, | | - | | "quantity": 1, | | - | | "sale_ID": 99999992, | | - | | "time": 1483346466000 | | - | | } | | - +------------------------------------------+-------------------------------------------+-----------+ - | .. container:: | .. container:: | Request | - | | | to buy | - | .. container:: listingblock | .. container:: listingblock | alcohol | - | | | (``item_I | - | | .. container:: content | D=1943``) | - | .. container:: content | | at | - | | .. code:: | *20:17:13 | - | | | * | - | .. code:: | { | on | - | | "name": "SALE_AUTH", | *Tuesday, | - | { | "version": "0.0.1", | 20 | - | "nameSpace": "com.hyperm", | "nameSpace": "com.hyperm", | December | - | "name" : "SALE_INPUT", | "source": "", | 2016*. | - | "version": "0.0.1", | "target": "", | | - | "time" : 1482265033000, | "amount": 4799, | Sale is | - | "sale_ID": 99999993, | "assistant_ID": 9, | authorize | - | "amount": 4799, | "authorised": true, | d. | - | "item_ID": 1943, | "branch_ID": 3, | | - | "quantity": 2, | "item_ID": 1943, | | - | "assistant_ID": 9, | "message": "Sale authorised | | - | "branch_ID": 3 | by policy task MorningBo | | - | } | ozeCheck for time 20:17:13 | | - | | GMT", | | - | | "notes": null, | | - | | "quantity": 2, | | - | | "sale_ID": 99999993, | | - | | "time": 1482265033000 | | - | | } | | - +------------------------------------------+-------------------------------------------+-----------+ - -4.3.6. Policy 1 in CLI Editor -############################# - - .. container:: paragraph - - An equivalent version of the ``MyFirstPolicyModel`` - policy model can again be generated using the APEX CLI - editor. A sample APEX CLI script is shown below: - - .. container:: listingblock - - .. container:: title - - APEX CLI Editor code for Policy 1 - - .. container:: content - - .. code:: - - #------------------------------------------------------------------------------- - # ============LICENSE_START======================================================= - # Copyright (C) 2016-2018 Ericsson. All rights reserved. - # ================================================================================ - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. - # - # SPDX-License-Identifier: Apache-2.0 - # ============LICENSE_END========================================================= - #------------------------------------------------------------------------------- - - model create name=MyFirstPolicyModel version=0.0.1 uuid=540226fb-55ee-4f0e-a444-983a0494818e description="This is my first Apex Policy Model." - - schema create name=assistant_ID_type version=0.0.1 uuid=36df4c71-9616-4206-8b53-976a5cd4bd87 description="A type for 'assistant_ID' values" flavour=Java schema=java.lang.Long - - schema create name=authorised_type version=0.0.1 uuid=d48b619e-d00d-4008-b884-02d76ea4350b description="A type for 'authorised' values" flavour=Java schema=java.lang.Boolean - - schema create name=branch_ID_type version=0.0.1 uuid=6468845f-4122-4128-8e49-0f52c26078b5 description="A type for 'branch_ID' values" flavour=Java schema=java.lang.Long - - schema create name=item_ID_type version=0.0.1 uuid=4f227ff1-aee0-453a-b6b6-9a4b2e0da932 description="A type for 'item_ID' values" flavour=Java schema=java.lang.Long - - schema create name=message_type version=0.0.1 uuid=ad1431bb-3155-4e73-b5a3-b89bee498749 description="A type for 'message' values" flavour=Java schema=java.lang.String - - schema create name=notes_type version=0.0.1 uuid=eecfde90-896c-4343-8f9c-2603ced94e2d description="A type for 'notes' values" flavour=Java schema=java.lang.String - - schema create name=price_type version=0.0.1 uuid=52c2fc45-fd8c-463c-bd6f-d91b0554aea7 description="A type for 'amount'/'price' values" flavour=Java schema=java.lang.Long - - schema create name=quantity_type version=0.0.1 uuid=ac3d9842-80af-4a98-951c-bd79a431c613 description="A type for 'quantity' values" flavour=Java schema=java.lang.Integer - - schema create name=sale_ID_type version=0.0.1 uuid=cca47d74-7754-4a61-b163-ca31f66b157b description="A type for 'sale_ID' values" flavour=Java schema=java.lang.Long - - schema create name=timestamp_type version=0.0.1 uuid=fd594e88-411d-4a94-b2be-697b3a0d7adf description="A type for 'time' values" flavour=Java schema=java.lang.Long - - task create name=MorningBoozeCheck version=0.0.1 uuid=3351b0f4-cf06-4fa2-8823-edf67bd30223 description=LS - This task checks if the sales request is for an item that contains alcohol. - If the local time is between 00:00:00 and 11:30:00 then the sale is not authorised. Otherwise the sale is authorised. - In this implementation we assume that all items with item_ID values between 1000 and 2000 contain alcohol :-) - LE - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=amount schemaName=price_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=quantity schemaName=quantity_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=time schemaName=timestamp_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=amount schemaName=price_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=quantity schemaName=quantity_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=authorised schemaName=authorised_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=time schemaName=timestamp_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=message schemaName=message_type schemaVersion=0.0.1 optional=true - task logic create name=MorningBoozeCheck version=0.0.1 logicFlavour=MVEL logic=LS - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - import java.util.Date; - import java.util.Calendar; - import java.util.TimeZone; - import java.text.SimpleDateFormat; - - logger.info("Task Execution: '"+subject.id+"'. Input Fields: '"+inFields+"'"); - - outFields.put("amount" , inFields.get("amount")); - outFields.put("assistant_ID", inFields.get("assistant_ID")); - outFields.put("notes" , inFields.get("notes")); - outFields.put("quantity" , inFields.get("quantity")); - outFields.put("branch_ID" , inFields.get("branch_ID")); - outFields.put("item_ID" , inFields.get("item_ID")); - outFields.put("time" , inFields.get("time")); - outFields.put("sale_ID" , inFields.get("sale_ID")); - - item_id = inFields.get("item_ID"); - - //The events used later to test this task use GMT timezone! - gmt = TimeZone.getTimeZone("GMT"); - timenow = Calendar.getInstance(gmt); - df = new SimpleDateFormat("HH:mm:ss z"); - df.setTimeZone(gmt); - timenow.setTimeInMillis(inFields.get("time")); - - midnight = timenow.clone(); - midnight.set( - timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), - timenow.get(Calendar.DATE),0,0,0); - eleven30 = timenow.clone(); - eleven30.set( - timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), - timenow.get(Calendar.DATE),11,30,0); - - itemisalcohol = false; - if(item_id != null && item_id >=1000 && item_id < 2000) - itemisalcohol = true; - - if( itemisalcohol - && timenow.after(midnight) && timenow.before(eleven30)){ - outFields.put("authorised", false); - outFields.put("message", "Sale not authorised by policy task "+subject.taskName+ - " for time "+df.format(timenow.getTime())+ - ". Alcohol can not be sold between "+df.format(midnight.getTime())+ - " and "+df.format(eleven30.getTime())); - return true; - } - else{ - outFields.put("authorised", true); - outFields.put("message", "Sale authorised by policy task "+subject.taskName+ - " for time "+df.format(timenow.getTime())); - return true; - } - - /* - This task checks if a sale request is for an item that is an alcoholic drink. - If the local time is between 00:00:00 GMT and 11:30:00 GMT then the sale is not - authorised. Otherwise the sale is authorised. - In this implementation we assume that items with item_ID value between 1000 and - 2000 are all alcoholic drinks :-) - */ - LE - - event create name=SALE_AUTH version=0.0.1 uuid=c4500941-3f98-4080-a9cc-5b9753ed050b description="An event emitted by the Policy to indicate whether the sale of an item has been authorised" nameSpace=com.hyperm source="APEX" target="POS" - event parameter create name=SALE_AUTH version=0.0.1 parName=amount schemaName=price_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=authorised schemaName=authorised_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=message schemaName=message_type schemaVersion=0.0.1 optional=true - event parameter create name=SALE_AUTH version=0.0.1 parName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true - event parameter create name=SALE_AUTH version=0.0.1 parName=quantity schemaName=quantity_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=time schemaName=timestamp_type schemaVersion=0.0.1 - - event create name=SALE_INPUT version=0.0.1 uuid=4f04aa98-e917-4f4a-882a-c75ba5a99374 description="An event raised by the PoS system each time an item is scanned for purchase" nameSpace=com.hyperm source="POS" target="APEX" - event parameter create name=SALE_INPUT version=0.0.1 parName=amount schemaName=price_type schemaVersion=0.0.1 - event parameter create name=SALE_INPUT version=0.0.1 parName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_INPUT version=0.0.1 parName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_INPUT version=0.0.1 parName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_INPUT version=0.0.1 parName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true - event parameter create name=SALE_INPUT version=0.0.1 parName=quantity schemaName=quantity_type schemaVersion=0.0.1 - event parameter create name=SALE_INPUT version=0.0.1 parName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_INPUT version=0.0.1 parName=time schemaName=timestamp_type schemaVersion=0.0.1 - - - policy create name=MyFirstPolicy version=0.0.1 uuid=6c5e410f-489a-46ff-964e-982ce6e8b6d0 description="This is my first Apex policy. It checks if a sale should be authorised or not." template=FREEFORM firstState=BoozeAuthDecide - policy state create name=MyFirstPolicy version=0.0.1 stateName=BoozeAuthDecide triggerName=SALE_INPUT triggerVersion=0.0.1 defaultTaskName=MorningBoozeCheck defaultTaskVersion=0.0.1 - policy state output create name=MyFirstPolicy version=0.0.1 stateName=BoozeAuthDecide outputName=MorningBoozeCheck_Output_Direct eventName=SALE_AUTH eventVersion=0.0.1 nextState=NULL - policy state taskref create name=MyFirstPolicy version=0.0.1 stateName=BoozeAuthDecide taskLocalName=MorningBoozeCheck taskName=MorningBoozeCheck taskVersion=0.0.1 outputType=DIRECT outputName=MorningBoozeCheck_Output_Direct - -Policy Step 2 -------------- - -Scenario -######### - .. container:: paragraph - - *HyperM* have just opened a new branch in a different - country, but that country has different rules about when - alcohol can be sold! In this section we will go through - the necessary steps to extend our policy to enforce this - for *HyperM*. - - .. container:: ulist - - - In some branches alcohol cannot be sold before 1pm, - and not at all on Sundays. - - .. container:: paragraph - - Although there are a number of ways to accomplish this - the easiest approach for us is to define another task and - then select which task is appropriate at runtime - depending on the branch identifier in the incoming event. - -Extend the Policy with the new Scenario -####################################### - - .. container:: paragraph - - To create a new Task click on the 'Tasks' tab. In the - 'Tasks' pane, right click and select 'Create new Task': - - .. container:: paragraph - - Create a new Task called ``MorningBoozeCheckAlt1``. Use - the 'Generate UUID' button to create a new unique ID for - the task, and fill in a description for the task. Select - the same input and output fields that we used earlier - when we defined the ``MorningBoozeCheck`` task earlier. - - .. table:: Table 12. Input fields for ``MorningBoozeCheckAlt1`` task - - +-----------------------------------+-----------------------------------+ - | Parameter Name | Parameter Type | - +===================================+===================================+ - | time | timestamp_type | - +-----------------------------------+-----------------------------------+ - | sale_ID | sale_ID_type | - +-----------------------------------+-----------------------------------+ - | amount | price_type | - +-----------------------------------+-----------------------------------+ - | item_ID | item_ID_type | - +-----------------------------------+-----------------------------------+ - | quantity | quantity_type | - +-----------------------------------+-----------------------------------+ - | assistant_ID | assistant_ID_type | - +-----------------------------------+-----------------------------------+ - | branch_ID | branch_ID_type | - +-----------------------------------+-----------------------------------+ - | notes | notes_type | - +-----------------------------------+-----------------------------------+ - - .. table:: Table 13. Output fields for ``MorningBoozeCheckAlt1`` task - - +-----------------------------------+-----------------------------------+ - | Parameter Name | Parameter Type | - +===================================+===================================+ - | sale_ID | sale_ID_type | - +-----------------------------------+-----------------------------------+ - | time | timestamp_type | - +-----------------------------------+-----------------------------------+ - | authorised | authorised_type | - +-----------------------------------+-----------------------------------+ - | message | message_type | - +-----------------------------------+-----------------------------------+ - | amount | price_type | - +-----------------------------------+-----------------------------------+ - | item_ID | item_ID_type | - +-----------------------------------+-----------------------------------+ - | assistant_ID | assistant_ID_type | - +-----------------------------------+-----------------------------------+ - | quantity | quantity_type | - +-----------------------------------+-----------------------------------+ - | branch_ID | branch_ID_type | - +-----------------------------------+-----------------------------------+ - | notes | notes_type | - +-----------------------------------+-----------------------------------+ - - .. container:: paragraph - - This task also requires some 'Task Logic' to implement - the new behaviour for this task. - - .. container:: paragraph - - For simplicity use the following code for the task logic. - It again assumes that all items with ``item_ID`` between - 1000 and 2000 contain alcohol. We again use the standard - ``Java`` time utilities to check if the current time is - between ``00:00:00 CET`` and ``13:00:00 CET`` or if it is - ``Sunday``. - - .. container:: paragraph - - For this task we will again author the logic using the - ```MVEL`` `__ - scripting language. Sample task logic code (specified in - ```MVEL`` `__) is - given below. For a detailed guide to how to write your - own logic in - ```JavaScript`` `__, - ```MVEL`` `__ or one - of the other supported languages please refer to APEX - Programmers Guide. - - .. container:: listingblock - - .. container:: title - - MVEL code for the ``MorningBoozeCheckAlt1`` task - - .. container:: content - - .. code:: - - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - import java.util.Date; - import java.util.Calendar; - import java.util.TimeZone; - import java.text.SimpleDateFormat; - - logger.info("Task Execution: '"+subject.id+"'. Input Event: '"+inFields+"'"); - - outFields.put("amount" , inFields.get("amount")); - outFields.put("assistant_ID", inFields.get("assistant_ID")); - outFields.put("notes" , inFields.get("notes")); - outFields.put("quantity" , inFields.get("quantity")); - outFields.put("branch_ID" , inFields.get("branch_ID")); - outFields.put("item_ID" , inFields.get("item_ID")); - outFields.put("time" , inFields.get("time")); - outFields.put("sale_ID" , inFields.get("sale_ID")); - - item_id = inFields.get("item_ID"); - - //The events used later to test this task use CET timezone! - cet = TimeZone.getTimeZone("CET"); - timenow = Calendar.getInstance(cet); - df = new SimpleDateFormat("HH:mm:ss z"); - df.setTimeZone(cet); - timenow.setTimeInMillis(inFields.get("time")); - - midnight = timenow.clone(); - midnight.set( - timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), - timenow.get(Calendar.DATE),0,0,0); - onepm = timenow.clone(); - onepm.set( - timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), - timenow.get(Calendar.DATE),13,0,0); - - itemisalcohol = false; - if(item_id != null && item_id >=1000 && item_id < 2000) - itemisalcohol = true; - - if( itemisalcohol && - ( (timenow.after(midnight) && timenow.before(onepm)) - || - (timenow.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) - )){ - outFields.put("authorised", false); - outFields.put("message", "Sale not authorised by policy task "+subject.taskName+ - " for time "+df.format(timenow.getTime())+ - ". Alcohol can not be sold between "+df.format(midnight.getTime())+ - " and "+df.format(onepm.getTime()) +" or on Sunday"); - return true; - } - else{ - outFields.put("authorised", true); - outFields.put("message", "Sale authorised by policy task "+subject.taskName+ - " for time "+df.format(timenow.getTime())); - return true; - } - - /* - This task checks if a sale request is for an item that is an alcoholic drink. - If the local time is between 00:00:00 CET and 13:00:00 CET then the sale is not authorised. - Also alcohol sales are not allowed on Sundays. Otherwise the sale is authorised. - In this implementation we assume that items with item_ID between 1000 and 2000 are all alcoholic drinks :-) - */ - - .. container:: imageblock - - .. container:: content - - |Create a new alternative task MorningBoozeCheckAlt1| - - .. container:: title - - Figure 19. Create a new Task - - .. container:: paragraph - - The task definition is now complete so click the 'Submit' - button to save the task. Now that we have created our - task, we can can add this task to the single pre-existing - state (``BoozeAuthDecide``) in our policy. - - .. container:: paragraph - - To edit the ``BoozeAuthDecide`` state in our policy click - on the 'Policies' tab. In the 'Policies' pane, right - click on our ``MyFirstPolicy`` policy and select 'Edit'. - Navigate to the ``BoozeAuthDecide`` state in the 'states' - section at the bottom of the policy definition pane. - - .. container:: imageblock - - .. container:: content - - |Right click to edit a policy| - - .. container:: title - - Figure 20. Edit a Policy - - .. container:: paragraph - - To add our new task ``MorningBoozeCheckAlt1``, scroll - down to the ``BoozeAuthDecide`` state in the 'States' - section. In the 'State Tasks' section for - ``BoozeAuthDecide`` use the 'Add new task' button. Select - our new ``MorningBoozeCheckAlt1`` task, and use the name - of the task as the 'Local Name' for the task. The - ``MorningBoozeCheckAlt1`` task can reuse the same - ``MorningBoozeCheck_Output_Direct`` 'Direct State Output - Mapping' that we used for the ``MorningBoozeCheck`` task. - (Recall that the role of the 'State Output Mapping' is to - select the output event for the state, and select the - next state to be executed. These both remain the same as - before.) - - .. container:: paragraph - - Since our state has more than one task we must define - some logic to determine which task should be used each - time the state is executed. This *task selection logic* - is defined in the state definition. For our - ``BoozeAuthDecide`` state we want the choice of which - task to use to be based on the ``branch_ID`` from which - the ``SALE_INPUT`` event originated. For simplicity sake - let us assume that branches with ``branch_ID`` between - ``0`` and ``999`` should use the ``MorningBoozeCheck`` - task, and the branches with with ``branch_ID`` between - ``1000`` and ``1999`` should use the - ``MorningBoozeCheckAlt1`` task. - - .. container:: paragraph - - This time, for variety, we will author the task selection - logic using the - ```JavaScript`` `__ - scripting language. Sample task selection logic code - (specified in - ```JavaScript`` `__) - is given below. Paste the script text into the 'Task - Selection Logic' box, and use "JAVASCRIPT" as the 'Task - Selection Logic Type / Flavour'. It is necessary to mark - one of the tasks as the 'Default Task' so that the task - selection logic always has a fallback default option in - cases where a particular task cannot be selected. In this - case the ``MorningBoozeCheck`` task can be the default - task. - - .. container:: listingblock - - .. container:: title - - JavaScript code for the ``BoozeAuthDecide`` task - selection logic - - .. container:: content - - .. code:: - - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - - - var returnValueType = Java.type("java.lang.Boolean"); - var returnValue = new returnValueType(true); - - executor.logger.info("Task Selection Execution: '"+executor.subject.id+ - "'. Input Event: '"+executor.inFields+"'"); - - branchid = executor.inFields.get("branch_ID"); - taskorig = executor.subject.getTaskKey("MorningBoozeCheck"); - taskalt = executor.subject.getTaskKey("MorningBoozeCheckAlt1"); - taskdef = executor.subject.getDefaultTaskKey(); - - if(branchid >=0 && branchid <1000){ - taskorig.copyTo(executor.selectedTask); - } - else if (branchid >=1000 && branchid <2000){ - taskalt.copyTo(executor.selectedTask); - } - else{ - taskdef.copyTo(executor.selectedTask); - } - - /* - This task selection logic selects task "MorningBoozeCheck" for branches with - 0<=branch_ID<1000 and selects task "MorningBoozeCheckAlt1" for branches with - 1000<=branch_ID<2000. Otherwise the default task is selected. - In this case the default task is also "MorningBoozeCheck" - */ - - .. container:: imageblock - - .. container:: content - - |State definition with 2 Tasks and Task Selection - Logic| - - .. container:: title - - Figure 21. State definition with 2 Tasks and Task - Selection Logic - - .. container:: paragraph - - When complete don’t forget to click the 'Submit' button - at the bottom of 'Policies' pane for our - ``MyFirstPolicy`` policy after updating the - ``BoozeAuthDecide`` state. - - .. container:: paragraph - - Congratulations, you have now completed the second step - towards your first APEX policy. The policy model - containing our new policy can again be validated and - exported from the editor and saved as shown in Step 1. - - .. container:: paragraph - - The exported policy model is then available in the - directory you selected, as - `MyFirstPolicyModel_0.0.1.json `__. - The exported policy can now be loaded into the APEX - Policy Engine, or can be re-loaded and edited by the APEX - Policy Editor. - -Test Policy Step 2 -################## - - .. container:: paragraph - - To start a new APEX Engine you can use the following - configuration. In a full APEX installation you can find - this configuration in - ``$APEX_HOME/examples/config/MyFirstPolicy/2/MyFirstPolicyConfigStdin2StdoutJsonEvent.json``. - Note, this has changed from the configuration file in - Step 1 to enable the ``JAVASCRIPT`` executor for our new - 'Task Selection Logic'. - - .. container:: listingblock - - .. container:: title - - JSON to load and execute *My First Policy*, read input - JSON events from ``stdin``, and emit output events to - ``stdout`` - - .. container:: content - - .. code:: - - { - "engineServiceParameters" : { - "name" : "MyFirstPolicyApexEngine", - "version" : "0.0.1", - "id" : 102, - "instanceCount" : 4, - "deploymentPort" : 12345, - "policyModelFileName" : "examples/models/MyFirstPolicy/2/MyFirstPolicyModel_0.0.1.json", - "engineParameters" : { - "executorParameters" : { - "MVEL" : { - "parameterClassName" : "org.onap.policy.apex.plugins.executor.mvel.MVELExecutorParameters" - }, - "JAVASCRIPT" : { - "parameterClassName" : "org.onap.policy.apex.plugins.executor.javascript.JavascriptExecutorParameters" - } - } - } - }, - "eventOutputParameters": { - "FirstProducer": { - "carrierTechnologyParameters" : { - "carrierTechnology" : "FILE", - "parameters" : { - "standardIO" : true - } - }, - "eventProtocolParameters" : { - "eventProtocol" : "JSON" - } - } - }, - "eventInputParameters": { - "FirstConsumer": { - "carrierTechnologyParameters" : { - "carrierTechnology" : "FILE", - "parameters" : { - "standardIO" : true - } - }, - "eventProtocolParameters" : { - "eventProtocol" : "JSON" - } - } - } - } - - .. container:: paragraph - - To test the policy try paste the following events into - the console as the APEX engine executes. Note, all tests - from Step 1 will still work perfectly since none of those - events originate from a branch with ``branch_ID`` between - ``1000`` and ``2000``. The 'Task Selection Logic' will - therefore pick the ``MorningBoozeCheck`` task as - expected, and will therefore give the same results. - - .. table:: Table 14. Inputs and Outputs when testing *My First Policy* - - +----------------------------------------------+------------------------------------------------------------+---------------------------+ - | Input Event (JSON) | Output Event (JSON) | comment | - +==============================================+============================================================+===========================+ - | .. container:: | .. container:: | Request to buy | - | | | alcohol item | - | .. container:: listingblock | .. container:: listingblock | (``item_ID=1249``) | - | | | | - | | | at *08:41:06 | - | | .. container:: content | GMT* on *Monday, | - | .. container:: content | | 02 January | - | | .. code:: | 2017*. | - | | | | - | | { | Sale is not | - | .. code:: | "nameSpace": "com.hyperm", | authorized. Uses | - | | "name": "SALE_AUTH", | the | - | | "version": "0.0.1", | ``MorningBoozeCheck`` | - | { | "source": "", | | - | "nameSpace": "com.hyperm", | "target": "", | task. | - | "name": "SALE_INPUT", | "amount": 1249, | | - | "version": "0.0.1", | "assistant_ID":12, | Note this test | - | "time": 1483346466000, | "authorised": false, | is copied from | - | "sale_ID": 99999992, | "branch_ID": 2, | Step 1 above, | - | "amount": 1249, | "item_ID": 1012, | and demonstrates | - | "item_ID": 1012, | "message": "Sale not authorised by policy ta | that the | - | "quantity": 1, | sk MorningBoozeCheck for time 08:41:06 GMT.| original | - | "assistant_ID": 12, | Alcohol can not be sold between 00:00:00 | ``MorningBoozeCheck`` | - | "branch_ID": 2 | GMT and 11:30:00 GMT", | | - | } | "notes": null, | task is | - | | "quantity": 1, | executed. | - | | "sale_ID": 99999992, | | - | | "time": 1483346466000 | | - | | } | | - +----------------------------------------------+------------------------------------------------------------+---------------------------+ - | .. container:: | .. container:: | Request to buy | - | | | alcohol | - | .. container:: listingblock | .. container:: listingblock | (``item_ID=1047``) | - | | | | - | | | at *10:14:33* on | - | | .. container:: content | *Thursday, 22 | - | .. container:: content | | December 2016*. | - | | .. code:: | | - | | | Sale is not | - | | { | authorized. Uses | - | .. code:: | "nameSpace" : "com.hyperm", | the | - | | "name" : "SALE_AUTH", | ``MorningBoozeCheckAlt1`` | - | | "version" : "0.0.1", | task. | - | { | "source" : "", | | - | | "target" : "", | | - | "nameSpace": "com.hyperm", | "sale_ID" : 99999981, | | - | "name": "SALE_INPUT", | "amount" : 299, | | - | "version": "0.0.1", | "assistant_ID": 1212, | | - | "time": 1482398073000, | "notes" : null, | | - | "sale_ID": 99999981, | "quantity" : 1, | | - | "amount": 299, | "branch_ID" : 1002, | | - | "item_ID": 1047, | "item_ID" : 1047, | | - | "quantity": 1, | "authorised" : false, | | - | "assistant_ID": 1212, | "time" : 1482398073000, | | - | "branch_ID": 1002 | "message" : "Sale not authorised by policy t | | - | } | ask MorningBoozeCheckAlt1 fortime | | - | | 10:14:33 CET. Alcohol can not be sold | | - | | between 00:00:00 CET and 13:00:00 CET or on | | - | | Sunday" | | - | | } | | - +----------------------------------------------+------------------------------------------------------------+---------------------------+ - | .. container:: | .. container:: | Request to buy | - | | | alcohol | - | .. container:: listingblock | .. container:: listingblock | (``item_ID=1443``) | - | | | | - | | | at *17:19:37* on | - | | .. container:: content | *Sunday, 18 | - | .. container:: content | | December 2016*. | - | | .. code:: | | - | | | Sale is not | - | | { | authorized. Uses | - | .. code:: | "nameSpace" : "com.hyperm", | the | - | | | ``MorningBoozeCheckAlt1`` | - | | "name" : "SALE_AUTH", | task. | - | { | | | - | "nameSpace": "com.hyperm", | "version" : "0.0.1", | | - | "name": "SALE_INPUT", | "source" : "", | | - | "version": "0.0.1", | "target" : "", | | - | "time": 1482077977000, | "sale_ID" : 99999982, | | - | "sale_ID": 99999982, | "amount" : 2199, | | - | "amount": 2199, | "assistant_ID" : 94, | | - | "item_ID": 1443, | "notes" : "Buy 3, get 1 free!!", | | - | "quantity": 12, | "quantity" : 12, | | - | "assistant_ID": 94, | "branch_ID" : 1003, | | - | "branch_ID": 1003, | "item_ID" : 1443, | | - | "notes": "Buy 3, get 1 free!!" | "authorised" : false, | | - | } | "time" : 1482077977000, | | - | | "message" : "Sale not authorised by policy t | | - | | ask MorningBoozeCheckAlt1 for | | - | | time 17:19:37 CET. Alcohol c | | - | | an not be sold between 00:00: | | - | | 00 CET and 13:00:00 CET or on | | - | | Sunday" | | - +----------------------------------------------+------------------------------------------------------------+---------------------------+ - | .. container:: | .. container:: | Request to buy | - | | | non-alcoholic | - | .. container:: listingblock | .. container:: listingblock | item | - | | | (``item_ID=5321``) | - | | | | - | | .. container:: content | at *11:13:09* on | - | .. container:: content | | *Monday, 2 | - | | .. code:: | January 2017*. | - | | | | - | | { | Sale is | - | .. code:: | "nameSpace" : "com.hyperm", | authorized. Uses | - | | "name" : "SALE_AUTH", | the | - | { | "version" : "0.0.1", | ``MorningBoozeCheckAlt1`` | - | "nameSpace": "com.hyperm", | "source" : "", | task. | - | "name": "SALE_INPUT", | "target" : "", | | - | "version": "0.0.1", | "sale_ID" : 99999983, | | - | "time": 1483351989000, | "amount" : 699, | | - | "sale_ID": 99999983, | "assistant_ID" : 2323, | | - | "amount": 699, | "notes" : "", | | - | "item_ID": 5321, | "quantity" : 1, | | - | "quantity": 1, | "branch_ID" : 1001, | | - | "assistant_ID": 2323, | "item_ID" : 5321, | | - | "branch_ID": 1001, | "authorised" : true, | | - | "notes": "" | "time" : 1483351989000, | | - | } | "message" : "Sale authorised by policy task | | - | | MorningBoozeCheckAlt1 for time 11:13:09 CET"| | - | | } | | - +----------------------------------------------+------------------------------------------------------------+---------------------------+ - -Policy 2 in CLI Editor -###################### - - .. container:: paragraph - - An equivalent version of the ``MyFirstPolicyModel`` - policy model can again be generated using the APEX CLI - editor. A sample APEX CLI script is shown below: - - .. container:: listingblock - - .. container:: title - - APEX CLI Editor code for Policy 2 - - .. container:: content - - .. code:: - - #------------------------------------------------------------------------------- - # ============LICENSE_START======================================================= - # Copyright (C) 2016-2018 Ericsson. All rights reserved. - # ================================================================================ - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. - # - # SPDX-License-Identifier: Apache-2.0 - # ============LICENSE_END========================================================= - #------------------------------------------------------------------------------- - - model create name=MyFirstPolicyModel version=0.0.1 uuid=540226fb-55ee-4f0e-a444-983a0494818e description="This is my first Apex Policy Model." - - schema create name=assistant_ID_type version=0.0.1 uuid=36df4c71-9616-4206-8b53-976a5cd4bd87 description="A type for 'assistant_ID' values" flavour=Java schema=java.lang.Long - - schema create name=authorised_type version=0.0.1 uuid=d48b619e-d00d-4008-b884-02d76ea4350b description="A type for 'authorised' values" flavour=Java schema=java.lang.Boolean - - schema create name=branch_ID_type version=0.0.1 uuid=6468845f-4122-4128-8e49-0f52c26078b5 description="A type for 'branch_ID' values" flavour=Java schema=java.lang.Long - - schema create name=item_ID_type version=0.0.1 uuid=4f227ff1-aee0-453a-b6b6-9a4b2e0da932 description="A type for 'item_ID' values" flavour=Java schema=java.lang.Long - - schema create name=message_type version=0.0.1 uuid=ad1431bb-3155-4e73-b5a3-b89bee498749 description="A type for 'message' values" flavour=Java schema=java.lang.String - - schema create name=notes_type version=0.0.1 uuid=eecfde90-896c-4343-8f9c-2603ced94e2d description="A type for 'notes' values" flavour=Java schema=java.lang.String - - schema create name=price_type version=0.0.1 uuid=52c2fc45-fd8c-463c-bd6f-d91b0554aea7 description="A type for 'amount'/'price' values" flavour=Java schema=java.lang.Long - - schema create name=quantity_type version=0.0.1 uuid=ac3d9842-80af-4a98-951c-bd79a431c613 description="A type for 'quantity' values" flavour=Java schema=java.lang.Integer - - schema create name=sale_ID_type version=0.0.1 uuid=cca47d74-7754-4a61-b163-ca31f66b157b description="A type for 'sale_ID' values" flavour=Java schema=java.lang.Long - - schema create name=timestamp_type version=0.0.1 uuid=fd594e88-411d-4a94-b2be-697b3a0d7adf description="A type for 'time' values" flavour=Java schema=java.lang.Long - - task create name=MorningBoozeCheck version=0.0.1 uuid=3351b0f4-cf06-4fa2-8823-edf67bd30223 description=LS - This task checks if the sales request is for an item that contains alcohol. - If the local time is between 00:00:00 and 11:30:00 then the sale is not authorised. Otherwise the sale is authorised. - In this implementation we assume that all items with item_ID values between 1000 and 2000 contain alcohol :-) - LE - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=amount schemaName=price_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=quantity schemaName=quantity_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=time schemaName=timestamp_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=amount schemaName=price_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=quantity schemaName=quantity_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=authorised schemaName=authorised_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=time schemaName=timestamp_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=message schemaName=message_type schemaVersion=0.0.1 optional=true - task logic create name=MorningBoozeCheck version=0.0.1 logicFlavour=MVEL logic=LS - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - import java.util.Date; - import java.util.Calendar; - import java.util.TimeZone; - import java.text.SimpleDateFormat; - - logger.info("Task Execution: '"+subject.id+"'. Input Fields: '"+inFields+"'"); - - outFields.put("amount" , inFields.get("amount")); - outFields.put("assistant_ID", inFields.get("assistant_ID")); - outFields.put("notes" , inFields.get("notes")); - outFields.put("quantity" , inFields.get("quantity")); - outFields.put("branch_ID" , inFields.get("branch_ID")); - outFields.put("item_ID" , inFields.get("item_ID")); - outFields.put("time" , inFields.get("time")); - outFields.put("sale_ID" , inFields.get("sale_ID")); - - item_id = inFields.get("item_ID"); - - //The events used later to test this task use GMT timezone! - gmt = TimeZone.getTimeZone("GMT"); - timenow = Calendar.getInstance(gmt); - df = new SimpleDateFormat("HH:mm:ss z"); - df.setTimeZone(gmt); - timenow.setTimeInMillis(inFields.get("time")); - - midnight = timenow.clone(); - midnight.set( - timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), - timenow.get(Calendar.DATE),0,0,0); - eleven30 = timenow.clone(); - eleven30.set( - timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), - timenow.get(Calendar.DATE),11,30,0); - - itemisalcohol = false; - if(item_id != null && item_id >=1000 && item_id < 2000) - itemisalcohol = true; - - if( itemisalcohol - && timenow.after(midnight) && timenow.before(eleven30)){ - outFields.put("authorised", false); - outFields.put("message", "Sale not authorised by policy task "+subject.taskName+ - " for time "+df.format(timenow.getTime())+ - ". Alcohol can not be sold between "+df.format(midnight.getTime())+ - " and "+df.format(eleven30.getTime())); - return true; - } - else{ - outFields.put("authorised", true); - outFields.put("message", "Sale authorised by policy task "+subject.taskName+ - " for time "+df.format(timenow.getTime())); - return true; - } - - /* - This task checks if a sale request is for an item that is an alcoholic drink. - If the local time is between 00:00:00 GMT and 11:30:00 GMT then the sale is not - authorised. Otherwise the sale is authorised. - In this implementation we assume that items with item_ID value between 1000 and - 2000 are all alcoholic drinks :-) - */ - LE - - task create name=MorningBoozeCheckAlt1 version=0.0.1 uuid=bc6d90c9-c902-4686-afd3-925b30e39990 description=LS - This task checks if a sale request is for an item that is an alcoholic drink. - If the local time is between 00:00:00 CET and 13:00:00 CET then the sale is not authorised. - Also alcohol sales are not allowed on Sundays. Otherwise the sale is authorised. - In this implementation we assume that items with item_ID between 1000 and 2000 are all alcoholic drinks - LE - task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=amount schemaName=price_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true - task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=quantity schemaName=quantity_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 - task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=time schemaName=timestamp_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=amount schemaName=price_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true - task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=quantity schemaName=quantity_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=authorised schemaName=authorised_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=time schemaName=timestamp_type schemaVersion=0.0.1 - task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=message schemaName=message_type schemaVersion=0.0.1 optional=true - task logic create name=MorningBoozeCheckAlt1 version=0.0.1 logicFlavour=MVEL logic=LS - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - import java.util.Date; - import java.util.Calendar; - import java.util.TimeZone; - import java.text.SimpleDateFormat; - - logger.info("Task Execution: '"+subject.id+"'. Input Event: '"+inFields+"'"); - - outFields.put("amount" , inFields.get("amount")); - outFields.put("assistant_ID", inFields.get("assistant_ID")); - outFields.put("notes" , inFields.get("notes")); - outFields.put("quantity" , inFields.get("quantity")); - outFields.put("branch_ID" , inFields.get("branch_ID")); - outFields.put("item_ID" , inFields.get("item_ID")); - outFields.put("time" , inFields.get("time")); - outFields.put("sale_ID" , inFields.get("sale_ID")); - - item_id = inFields.get("item_ID"); - - //The events used later to test this task use CET timezone! - cet = TimeZone.getTimeZone("CET"); - timenow = Calendar.getInstance(cet); - df = new SimpleDateFormat("HH:mm:ss z"); - df.setTimeZone(cet); - timenow.setTimeInMillis(inFields.get("time")); - - midnight = timenow.clone(); - midnight.set( - timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), - timenow.get(Calendar.DATE),0,0,0); - onepm = timenow.clone(); - onepm.set( - timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), - timenow.get(Calendar.DATE),13,0,0); - - itemisalcohol = false; - if(item_id != null && item_id >=1000 && item_id < 2000) - itemisalcohol = true; - - if( itemisalcohol && - ( (timenow.after(midnight) && timenow.before(onepm)) - || - (timenow.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) - )){ - outFields.put("authorised", false); - outFields.put("message", "Sale not authorised by policy task "+subject.taskName+ - " for time "+df.format(timenow.getTime())+ - ". Alcohol can not be sold between "+df.format(midnight.getTime())+ - " and "+df.format(onepm.getTime()) +" or on Sunday"); - return true; - } - else{ - outFields.put("authorised", true); - outFields.put("message", "Sale authorised by policy task "+subject.taskName+ - " for time "+df.format(timenow.getTime())); - return true; - } - - /* - This task checks if a sale request is for an item that is an alcoholic drink. - If the local time is between 00:00:00 CET and 13:00:00 CET then the sale is not authorised. - Also alcohol sales are not allowed on Sundays. Otherwise the sale is authorised. - In this implementation we assume that items with item_ID between 1000 and 2000 are all alcoholic drinks :-) - */ - LE - - event create name=SALE_AUTH version=0.0.1 uuid=c4500941-3f98-4080-a9cc-5b9753ed050b description="An event emitted by the Policy to indicate whether the sale of an item has been authorised" nameSpace=com.hyperm source="APEX" target="POS" - event parameter create name=SALE_AUTH version=0.0.1 parName=amount schemaName=price_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=authorised schemaName=authorised_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=message schemaName=message_type schemaVersion=0.0.1 optional=true - event parameter create name=SALE_AUTH version=0.0.1 parName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true - event parameter create name=SALE_AUTH version=0.0.1 parName=quantity schemaName=quantity_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_AUTH version=0.0.1 parName=time schemaName=timestamp_type schemaVersion=0.0.1 - - event create name=SALE_INPUT version=0.0.1 uuid=4f04aa98-e917-4f4a-882a-c75ba5a99374 description="An event raised by the PoS system each time an item is scanned for purchase" nameSpace=com.hyperm source="POS" target="APEX" - event parameter create name=SALE_INPUT version=0.0.1 parName=amount schemaName=price_type schemaVersion=0.0.1 - event parameter create name=SALE_INPUT version=0.0.1 parName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_INPUT version=0.0.1 parName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_INPUT version=0.0.1 parName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_INPUT version=0.0.1 parName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true - event parameter create name=SALE_INPUT version=0.0.1 parName=quantity schemaName=quantity_type schemaVersion=0.0.1 - event parameter create name=SALE_INPUT version=0.0.1 parName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 - event parameter create name=SALE_INPUT version=0.0.1 parName=time schemaName=timestamp_type schemaVersion=0.0.1 - - - policy create name=MyFirstPolicy version=0.0.1 uuid=6c5e410f-489a-46ff-964e-982ce6e8b6d0 description="This is my first Apex policy. It checks if a sale should be authorised or not." template=FREEFORM firstState=BoozeAuthDecide - policy state create name=MyFirstPolicy version=0.0.1 stateName=BoozeAuthDecide triggerName=SALE_INPUT triggerVersion=0.0.1 defaultTaskName=MorningBoozeCheck defaultTaskVersion=0.0.1 - policy state output create name=MyFirstPolicy version=0.0.1 stateName=BoozeAuthDecide outputName=MorningBoozeCheck_Output_Direct eventName=SALE_AUTH eventVersion=0.0.1 nextState=NULL - policy state taskref create name=MyFirstPolicy version=0.0.1 stateName=BoozeAuthDecide taskLocalName=MorningBoozeCheckAlt1 taskName=MorningBoozeCheckAlt1 taskVersion=0.0.1 outputType=DIRECT outputName=MorningBoozeCheck_Output_Direct - policy state taskref create name=MyFirstPolicy version=0.0.1 stateName=BoozeAuthDecide taskLocalName=MorningBoozeCheck taskName=MorningBoozeCheck taskVersion=0.0.1 outputType=DIRECT outputName=MorningBoozeCheck_Output_Direct - policy state selecttasklogic create name=MyFirstPolicy version=0.0.1 stateName=BoozeAuthDecide logicFlavour=JAVASCRIPT logic=LS - /* - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - - var returnValueType = Java.type("java.lang.Boolean"); - var returnValue = new returnValueType(true); - - executor.logger.info("Task Selection Execution: '"+executor.subject.id+"'. Input Event: '"+executor.inFields+"'"); - - branchid = executor.inFields.get("branch_ID"); - taskorig = executor.subject.getTaskKey("MorningBoozeCheck"); - taskalt = executor.subject.getTaskKey("MorningBoozeCheckAlt1"); - taskdef = executor.subject.getDefaultTaskKey(); - - if(branchid >=0 && branchid <1000){ - taskorig.copyTo(executor.selectedTask); - } - else if (branchid >=1000 && branchid <2000){ - taskalt.copyTo(executor.selectedTask); - } - else{ - taskdef.copyTo(executor.selectedTask); - } - - /* - This task selection logic selects task "MorningBoozeCheck" for branches with 0<=branch_ID<1000 and selects task "MorningBoozeCheckAlt1" for branches with 1000<=branch_ID<2000. Otherwise the default task is selected. In this case the default task is also "MorningBoozeCheck" - */ - LE - -APEX Logging -^^^^^^^^^^^^ - -Introduction to APEX Logging ----------------------------- - - .. container:: paragraph - - All APEX components make extensive use of logging using the - logging façade `SLF4J `__ with the - backend `Logback `__. Both are used - off-the-shelve, so the standard documentation and - configuration apply to APEX logging. For details on how to - work with logback please see the `logback - manual `__. - - .. container:: paragraph - - The APEX applications is the logback configuration file - ``$APEX_HOME/etc/logback.xml`` (Windows: - ``%APEX_HOME%\etc\logback.xml``). The logging backend is set - to no debug, i.e. logs from the logging framework should be - hidden at runtime. - - .. container:: paragraph - - The configurable log levels work as expected: - - .. container:: ulist - - - *error* (or *ERROR*) is used for serious errors in the - APEX runtime engine - - - *warn* (or *WARN*) is used for warnings, which in general - can be ignored but might indicate some deeper problems - - - *info* (or *INFO*) is used to provide generally - interesting messages for startup and policy execution - - - *debug* (or *DEBUG*) provides more details on startup and - policy execution - - - *trace* (or *TRACE*) gives full details on every aspect - of the APEX engine from start to end - - .. container:: paragraph - - The loggers can also be configured as expected. The standard - configuration (after installing APEX) uses log level *info* - on all APEX classes (components). - - .. container:: paragraph - - The applications and scripts in ``$APEX_HOME/bin`` (Windows: - ``%APEX_HOME\bin``) are configured to use the logback - configuration ``$APEX_HOME/etc/logback.xml`` (Windows: - ``%APEX_HOME\etc\logback.xml``). There are multiple ways to - use different logback configurations, for instance: - - .. container:: ulist - - - Maintain multiple configurations in ``etc``, for instance - a ``logback-debug.xml`` for deep debugging and a - ``logback-production.xml`` for APEX in production mode, - then copy the required configuration file to the used - ``logback.xml`` prior starting APEX - - - Edit the scripts in ``bin`` to use a different logback - configuration file (only recommended if you are familiar - with editing bash scripts or windows batch files) - -Standard Logging Configuration ------------------------------- - - .. container:: paragraph - - The standard logging configuration defines a context *APEX*, - which is used in the standard output pattern. The location - for log files is defined in the property ``logDir`` and set - to ``/var/log/onap/policy/apex-pdp``. The standard status - listener is set to *NOP* and the overall logback - configuration is set to no debug. - - .. container:: listingblock - - .. container:: content - - .. code:: - :number-lines: - - - - - Apex - - - ...appenders - ...loggers - - -.. container:: paragraph - - The first appender defined is called ``STDOUT`` for logs to standard - out. - -.. container:: listingblock - - .. container:: content - - .. code:: - :number-lines: - - - - %d %contextName [%t] %level %logger{36} - %msg%n - - - -.. container:: paragraph - - The root level logger then is set to the level *info* using the - standard out appender. - -.. container:: listingblock - - .. container:: content - - .. code:: - :number-lines: - - - - - -.. container:: paragraph - - The second appender is called ``FILE``. It writes logs to a file - ``apex.log``. - -.. container:: listingblock - - .. container:: content - - .. code:: - :number-lines: - - - ${logDir}/apex.log - - %d %-5relative [procId=${processId}] [%thread] %-5level %logger{26} - %msg %n %ex{full} - - - -.. container:: paragraph - - The third appender is called ``CTXT_FILE``. It writes logs to a file - ``apex_ctxt.log``. - -.. container:: listingblock - - .. container:: content - - .. code:: - :number-lines: - - - ${logDir}/apex_ctxt.log - - %d %-5relative [procId=${processId}] [%thread] %-5level %logger{26} - %msg %n %ex{full} - - - -.. container:: paragraph - - The last definitions are for specific loggers. The first logger - captures all standard APEX classes. It is configured for log level - *info* and uses the standard output and file appenders. The second - logger captures APEX context classes responsible for context - monitoring. It is configured for log level *trace* and uses the - context file appender. - -.. container:: listingblock - - .. container:: content - - .. code:: - :number-lines: - - - - - - - - - - - -Adding Logback Status and Debug -------------------------------- - - .. container:: paragraph - - To activate logback status messages change the status listener - from 'NOP' to for instance console. - - .. container:: listingblock - - .. container:: content - - .. code:: - - - - .. container:: paragraph - - To activate all logback debugging, for instance to debug a new - logback configuration, activate the debug attribute in the - configuration. - - .. container:: listingblock - - .. container:: content - - .. code:: - - - ... - - -Logging External Components ---------------------------- - - .. container:: paragraph - - Logback can also be configured to log any other, external - components APEX is using, if they are using the common logging - framework. - - .. container:: paragraph - - For instance, the context component of APEX is using *Infinispan* - and one can add a logger for this external component. The - following example adds a logger for *Infinispan* using the - standard output appender. - - .. container:: listingblock - - .. container:: content - - .. code:: - - - - - - .. container:: paragraph - - Another example is Apache Zookeeper. The following example adds a - logger for Zookeeper using the standard outout appender. - - .. container:: listingblock - - .. container:: content - - .. code:: - - - - - -Configuring loggers for Policy Logic ------------------------------------- - - .. container:: paragraph - - The logging for the logic inside a policy (task logic, task - selection logic, state finalizer logic) can be configured separate - from standard logging. The logger for policy logic is - ``org.onap.policy.apex.executionlogging``. The following example - defines - - .. container:: ulist - - - a new appender for standard out using a very simple pattern - (simply the actual message) - - - a logger for policy logic to standard out using the new - appender and the already described file appender. - - .. container:: listingblock - - .. container:: content - - .. code:: - - - - policy: %msg\n - - - - - - - - - .. container:: paragraph - - It is also possible to use specific logging for parts of policy - logic. The following example defines a logger for task logic. - - .. container:: listingblock - - .. container:: content - - .. code:: - - - - + + + Rolling File Appenders ---------------------- @@ -8398,22 +5975,5 @@ Send Events .. |REST Editor Start Screen| image:: images/install-guide/rest-start.png .. |REST Editor with loaded SampleDomain Policy Model| image:: images/install-guide/rest-loaded.png .. |APEX Configuration Matrix| image:: images/apex-intro/ApexEngineConfig.png -.. |File > New to create a new Policy Model| image:: images/mfp/MyFirstPolicy_P1_newPolicyModel1.png -.. |Create a new Policy Model| image:: images/mfp/MyFirstPolicy_P1_newPolicyModel2.png -.. |Right click to create a new event| image:: images/mfp/MyFirstPolicy_P1_newEvent1.png -.. |Fill in the necessary information for the 'SALE_INPUT' event and click 'Submit'| image:: images/mfp/MyFirstPolicy_P1_newEvent2.png -.. |Right click to create a new Item Schema| image:: images/mfp/MyFirstPolicy_P1_newItemSchema1.png -.. |Create a new Item Schema| image:: images/mfp/MyFirstPolicy_P1_newItemSchema2.png -.. |Add new event parameters to an event| image:: images/mfp/MyFirstPolicy_P1_newEvent3.png -.. |Right click to create a new task| image:: images/mfp/MyFirstPolicy_P1_newTask1.png -.. |Add input and out fields for the task| image:: images/mfp/MyFirstPolicy_P1_newTask2.png -.. |Add task logic the task| image:: images/mfp/MyFirstPolicy_P1_newTask3.png -.. |Create a new policy| image:: images/mfp/MyFirstPolicy_P1_newPolicy1.png -.. |Create a state| image:: images/mfp/MyFirstPolicy_P1_newState1.png -.. |Add a Task and Output Mapping| image:: images/mfp/MyFirstPolicy_P1_newState2.png -.. |Validate the policy model for error using the 'Model' > 'Validate' menu item| image:: images/mfp/MyFirstPolicy_P1_validatePolicyModel.png -.. |Download the completed policy model using the 'File' > 'Download' menu item| image:: images/mfp/MyFirstPolicy_P1_exportPolicyModel1.png -.. |Create a new alternative task MorningBoozeCheckAlt1| image:: images/mfp/MyFirstPolicy_P2_newTask1.png -.. |Right click to edit a policy| image:: images/mfp/MyFirstPolicy_P2_editPolicy1.png -.. |State definition with 2 Tasks and Task Selection Logic| image:: images/mfp/MyFirstPolicy_P2_editState1.png + -- 2.16.6