X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=docs%2Fapex%2FAPEX-User-Manual.rst;h=b10dcf8a0cafac142e310edec47f0425472315fd;hb=75e2bbf70872274890757c8de6c3c6262cb1e3bc;hp=61143d98f1d29243c1802b59a7b2d0bf3f24940e;hpb=6487e3f517472906998dc1f90c16468c0bc27af6;p=policy%2Fparent.git diff --git a/docs/apex/APEX-User-Manual.rst b/docs/apex/APEX-User-Manual.rst index 61143d98..b10dcf8a 100644 --- a/docs/apex/APEX-User-Manual.rst +++ b/docs/apex/APEX-User-Manual.rst @@ -28,11 +28,11 @@ Installation Requirements .. container:: ulist - Downloaded distribution: JAVA runtime environment - (JRE, Java 8 or later, APEX is tested with the - Oracle Java) + (JRE, Java 11 or later, APEX is tested with the + OpenJDK Java) - Building from source: JAVA development kit (JDK, - Java 8 or later, APEX is tested with the Oracle + Java 11 or later, APEX is tested with the OpenJDK Java) - A web archive capable webserver, for instance for @@ -65,12 +65,6 @@ Installation Requirements - Windows for instance `7Zip `__ - - RPM to install from the RPM distribution - - .. container:: ulist - - - Install: ``sudo apt-get install rpm`` - - DPKG to install from the DEB distribution .. container:: ulist @@ -172,11 +166,6 @@ Build APEX repository. The first standard build (and any first specific build) requires Internet access to download those dependencies. - .. important:: - Building RPM distributions - RPM images are only build if the ``rpm`` package is installed (Unix). To install ``rpm`` run ``sudo apt-get install rpm``, - then build APEX. - .. container:: paragraph Use Maven to for a standard build without any tests. @@ -192,8 +181,8 @@ Build APEX | :number-lines: | :number-lines: | | | | | # cd /usr/local/src/apex-pdp | >c: | - | # mvn clean install -Pdocker -DskipTest | >cd \dev\apex | - | | >mvn clean install -DskipTests | + | # mvn clean install -Pdocker -DskipTests | >cd \dev\apex | + | | >mvn clean install -Pdocker -DskipTests | +-------------------------------------------------------+--------------------------------------------------------+ .. container:: paragraph @@ -305,7 +294,7 @@ Install APEX .. container:: ulist - - Unix: automatically using ``rpm`` or ``dpkg`` from ``.rpm`` or + - Unix: automatically using ``dpkg`` from ``.deb`` archive - Windows, Unix, Cygwin: manually from a ``.tar.gz`` archive @@ -313,11 +302,14 @@ Install APEX - Windows, Unix, Cygwin: build from source using Maven, then install manually -Install with RPM and DPKG -######################### +Install with DPKG +################# .. container:: paragraph + You can get the APEX debian package from the + `ONAP Nexus Repository `__. + The install distributions of APEX automatically install the system. The installation directory is ``/opt/app/policy/apex-pdp``. Log files are located in @@ -332,29 +324,6 @@ Install with RPM and DPKG the standard APEX start scripts to run APEX with this user’s permissions. - +-----------------------------------------------------------------------+ - | RPM Installation | - +=======================================================================+ - | .. container:: | - | | - | .. container:: listingblock | - | | - | .. container:: content | - | | - | .. code:: | - | :number-lines: | - | | - | # sudo rpm -i apex-pdp-package-full-2.0.0-SNAPSHOT.rpm | - | ********************preinst******************* | - | arguments 1 | - | ********************************************** | - | creating group apexuser . . . | - | creating user apexuser . . . | - | ********************postinst**************** | - | arguments 1 | - | *********************************************** | - +-----------------------------------------------------------------------+ - +--------------------------------------------------------------------------------------+ | DPKG Installation | +======================================================================================+ @@ -393,7 +362,10 @@ Install Manually from Archive (Unix, Cygwin) .. container:: paragraph - Download a ``tar.gz`` archive. Create a directory where APEX + You can download a ``tar.gz`` archive from the + `ONAP Nexus Repository `__. + + Create a directory where APEX should be installed. Extract the ``tar`` archive. The following example shows how to install APEX in ``/opt/apex`` and create a link to ``/opt/apex/apex`` for the most recent installation. @@ -417,7 +389,10 @@ Install Manually from Archive (Windows, 7Zip, GUI) .. container:: paragraph - Download a ``tar.gz`` archive and copy the file into the install + You can download a ``tar.gz`` archive from the + `ONAP Nexus Repository `__. + + Copy the ``tar.gz`` file into the install folder (in this example ``C:\apex``). Assuming you are using 7Zip, right click on the file and extract the ``tar`` archive. Note: the screenshots might show an older version than you have. @@ -455,7 +430,10 @@ Install Manually from Archive (Windows, 7Zip, CMD) .. container:: paragraph - Download a ``tar.gz`` archive and copy the file into the install + You can download a ``tar.gz`` archive from the + `ONAP Nexus Repository `__. + + Copy the ``tar.gz`` file into the install folder (in this example ``C:\apex``). Start ``cmd``, for instance typing ``Windows+R`` and then ``cmd`` in the dialog. Assuming ``7Zip`` is installed in the standard folder, simply run the @@ -492,11 +470,6 @@ Build and Install Manually (Unix, Windows, Cygwin) from the created artifacts (``rpm``, ``deb``, ``tar.gz``, or copying manually). - .. important:: - Building RPM distributions - RPM images are only build if the ``rpm`` package is installed (Unix). To install ``rpm`` run - ``sudo apt-get install rpm``, then build APEX. - .. container:: paragraph The following example shows how to build the APEX system, @@ -520,8 +493,8 @@ Build and Install Manually (Unix, Windows, Cygwin) | :number-lines: | :number-lines: | | | | | # cd /usr/local/src/apex | >c: | - | # mvn clean install -DskipTests | >cd \dev\apex | - | | >mvn clean install -DskipTests | + | # mvn clean install -Pdocker -DskipTests | >cd \dev\apex | + | | >mvn clean install -Pdocker -DskipTests | +-------------------------------------------------------+--------------------------------------------------------+ .. container:: paragraph @@ -910,7 +883,7 @@ Edit the APEX Logging Settings .. container:: paragraph - ```` + ```` .. container:: paragraph @@ -918,7 +891,7 @@ Edit the APEX Logging Settings .. container:: paragraph - ```` + ```` .. container:: paragraph @@ -926,7 +899,7 @@ Edit the APEX Logging Settings .. container:: paragraph - ```` + ```` .. container:: paragraph @@ -1025,12 +998,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 +1013,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) @@ -1138,14 +1111,14 @@ Verify Installation - run an Example Terminate APEX by simply using ``CTRL+C`` in the console. -Verify a Full Installation - REST Editor +Verify a Full Installation - REST Client ######################################## .. container:: paragraph - APEX has a REST application for viewing policy models. The + APEX has a REST application for deploying, monitoring, and viewing policy models. The application can also be used to create new policy models close to - the engine native policy language. Start the REST editor as + the engine native policy language. Start the REST client as follows. .. container:: listingblock @@ -1155,7 +1128,7 @@ Verify a Full Installation - REST Editor .. code:: :number-lines: - # $APEX_HOME/bin/apexApps.sh rest-editor + # $APEX_HOME/bin/apexApps.sh full-client .. container:: listingblock @@ -1164,13 +1137,13 @@ Verify a Full Installation - REST Editor .. code:: :number-lines: - >%APEX_HOME%\bin\apexApps.bat rest-editor + >%APEX_HOME%\bin\apexApps.bat full-client .. container:: paragraph The script will start a simple web server (`Grizzly `__) and deploy a - ``war`` web archive in it. Once the editor is started, it will be + ``war`` web archive in it. Once the client is started, it will be available on ``localhost:18989``. The last few line of the messages should be: @@ -1181,29 +1154,30 @@ Verify a Full Installation - REST Editor .. code:: :number-lines: - Apex Editor REST endpoint (ApexEditorMain: Config=[ApexEditorParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=READY) starting at http://localhost:18989/apexservices/ . . . - Sep 05, 2018 10:35:57 PM org.glassfish.grizzly.http.server.NetworkListener start + Apex Editor REST endpoint (ApexServicesRestMain: Config=[ApexServicesRestParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=READY) starting at http://localhost:18989/apexservices/ . . . + Jul 02, 2020 2:57:39 PM org.glassfish.grizzly.http.server.NetworkListener start INFO: Started listener bound to [localhost:18989] - Sep 05, 2018 10:35:57 PM org.glassfish.grizzly.http.server.HttpServer start + Jul 02, 2020 2:57:39 PM org.glassfish.grizzly.http.server.HttpServer start INFO: [HttpServer] Started. - Apex Editor REST endpoint (ApexEditorMain: Config=[ApexEditorParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=RUNNING) started at http://localhost:18989/apexservices/ + Apex Editor REST endpoint (ApexServicesRestMain: Config=[ApexServicesRestParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=RUNNING) started at http://localhost:18989/apexservices/ + .. container:: paragraph Now open a browser (Firefox, Chrome, Opera, Internet Explorer) and use the URL ``http://localhost:18989/``. This will connect the - browser to the started REST editor. The start screen should be as + browser to the started REST client. Click on the "Policy Editor" button and the Policy Editor start screen should be as follows. .. container:: imageblock .. container:: content - |REST Editor Start Screen| + |Policy Editor Start Screen| .. container:: title - Figure 1. REST Editor Start Screen + Figure 1. Policy Editor Start Screen .. container:: paragraph @@ -1218,32 +1192,32 @@ Verify a Full Installation - REST Editor .. container:: content - |REST Editor with loaded SampleDomain Policy Model| + |Policy Editor with loaded SampleDomain Policy Model| .. container:: title - Figure 2. REST Editor with loaded SampleDomain Policy Model + Figure 2. Policy Editor with loaded SampleDomain Policy Model .. container:: paragraph - Now you can use the REST editor. To finish this verification, simply + Now you can use the Policy editor. To finish this verification, simply terminate your browser (or the tab), and then use ``CTRL+C`` in the - console where you started the REST editor. + console where you started the Policy editor. -Installing WAR Applications ---------------------------- +Installing the WAR Application +------------------------------ .. container:: paragraph - APEX comes with a set of WAR files. These are complete - applications that can be installed and run in an application - server. All of these applications are realized as servlets. You - can find the WAR applications in ``$APEX_HOME/war`` (UNIX, Cygwin) - or ``%APEX_HOME%\war`` (Windows). + The three APEX clients are packaged in a WAR file. This is a complete + application that can be installed and run in an application + server. The application is realized as a servlet. You + can find the WAR application in the `ONAP Nexus Repository `__. + .. container:: paragraph - Installing and using the WAR applications requires a web server + Installing and using the WAR application requires a web server that can execute ``war`` web archives. We recommend to use `Apache Tomcat `__, however other web servers can be used as well. @@ -1257,7 +1231,7 @@ Installing WAR Applications .. container:: paragraph - There are multiple ways to install the APEX WAR applications: + There are multiple ways to install the APEX WAR application: .. container:: ulist @@ -1287,23 +1261,7 @@ Installing WAR Applications .. container:: paragraph - The current APEX version provides the following WAR applications: - - .. container:: ulist - - - client-deployment-2.0.0-SNAPSHOT.war - a client to deploy new - policy models to a running engine - - - client-editor-2.0.0-SNAPSHOT.war - the standard policy REST - editor GUI - - - client-monitoring-2.0.0-SNAPSHOT.war - a client for monitoring - a running APEX engine - - - client-full-2.0.0-SNAPSHOT.war - a full client with a - one-stop-access to deployment, monitoring, and REST editor - - - examples-servlet-2.0.0-SNAPSHOT.war - an example APEX servlet + The WAR application file has a name similar to *apex-client-full-.war*. Running APEX in Docker ---------------------- @@ -1461,31 +1419,32 @@ General Configuration Format "engineServiceParameters":{ ... (1) "engineParameters":{ (2) - "engineParameters":{...}, (3) + "executorParameters":{...}, (3) "contextParameters":{...} (4) + "taskParameters":[...] (5) } }, - "eventInputParameters":{ (5) - "input1":{ (6) + "eventInputParameters":{ (6) + "input1":{ (7) "carrierTechnologyParameters":{...}, "eventProtocolParameters":{...} }, - "input2":{...}, (7) + "input2":{...}, (8) "carrierTechnologyParameters":{...}, "eventProtocolParameters":{...} }, - ... (8) + ... (9) }, - "eventOutputParameters":{ (9) - "output1":{ (10) + "eventOutputParameters":{ (10) + "output1":{ (11) "carrierTechnologyParameters":{...}, "eventProtocolParameters":{...} }, - "output2":{ (11) + "output2":{ (12) "carrierTechnologyParameters":{...}, "eventProtocolParameters":{...} }, - ... (12) + ... (13) } } @@ -1506,31 +1465,35 @@ General Configuration Format | | for context schemas, persistence, | | | etc. | +-----------------------------------+-----------------------------------+ - | **5** | configuration of the input | + | **5** | list of task parameters that | + | | should be made available in task | + | | logic (optional). | + +-----------------------------------+-----------------------------------+ + | **6** | configuration of the input | | | interface | +-----------------------------------+-----------------------------------+ - | **6** | an example input called | + | **7** | an example input called | | | ``input1`` with carrier | | | technology and event protocol | +-----------------------------------+-----------------------------------+ - | **7** | an example input called | + | **8** | an example input called | | | ``input2`` with carrier | | | technology and event protocol | +-----------------------------------+-----------------------------------+ - | **8** | any further input configuration | + | **9** | any further input configuration | +-----------------------------------+-----------------------------------+ - | **9** | configuration of the output | + | **10** | configuration of the output | | | interface | +-----------------------------------+-----------------------------------+ - | **10** | an example output called | + | **11** | an example output called | | | ``output1`` with carrier | | | technology and event protocol | +-----------------------------------+-----------------------------------+ - | **11** | an example output called | + | **12** | an example output called | | | ``output2`` with carrier | | | technology and event protocol | +-----------------------------------+-----------------------------------+ - | **12** | any further output configuration | + | **13** | any further output configuration | +-----------------------------------+-----------------------------------+ Engine Service Parameters @@ -1554,11 +1517,13 @@ Engine Service Parameters "id" : 45, (3) "instanceCount" : 4, (4) "deploymentPort" : 12345, (5) - "policyModelFileName" : "examples/models/VPN/VPNPolicyModelJava.json", (6) + "policyModelFileName" : "examples/models/VPN/VPNPolicyModelJava.json", (6a) + "policy_type_impl" : {...}, (6b) "periodicEventPeriod": 1000, (7) "engineParameters":{ (8) - "engineParameters":{...}, (9) - "contextParameters":{...} (10) + "executorParameters":{...}, (9) + "contextParameters":{...}, (10) + "taskParameters":[...] (11) } } @@ -1595,8 +1560,19 @@ Engine Service Parameters | | Websocket connection to the | | | engine | +-----------------------------------+-----------------------------------+ - | **6** | the model file to load into the | - | | engine on startup (optional) | + | **6a** | the APEX policy model file to | + | | load into the engine on startup | + | | when APEX is running native | + | | policies in standalone mode | + | | (optional) | + +-----------------------------------+-----------------------------------+ + | **6b** | the APEX policy model as a JSON | + | | or YAML block to load into the | + | | engine on startup when | + | | APEX is running a policy that has | + | | its logic and parameters | + | | specified in TOSCA | + | | (optional) | +-----------------------------------+-----------------------------------+ | **7** | an optional timer for periodic | | | policies, in milliseconds (a | @@ -1617,6 +1593,10 @@ Engine Service Parameters | | for context schemas, persistence, | | | etc. | +-----------------------------------+-----------------------------------+ + | **11** | list of task parameters that | + | | should be made available in task | + | | logic (optional). | + +-----------------------------------+-----------------------------------+ .. container:: paragraph @@ -2097,6 +2077,49 @@ Configure AVRO Schema Handler - Since AVRO uses lazy initialization, this rejection might only become visible at runtime +Configure Task Parameters +######################### + + .. container:: paragraph + + The Task Parameters are added to the configuration as + follows: + + .. container:: listingblock + + .. container:: content + + .. code:: + + "engineServiceParameters": { + "engineParameters": { + "taskParameters": [ + { + "key": "ParameterKey1", + "value": "ParameterValue1" + }, + { + "taskId": "Task_Act0", + "key": "ParameterKey2", + "value": "ParameterValue2" + } + ] + } + } + + .. container:: paragraph + + TaskParameters can be used to pass parameters from ApexConfig + to the policy logic. In the config, these are optional. + The list of task parameters provided in the config may be added + to the tasks or existing task parameters in the task will be overriden. + + .. container:: paragraph + + If taskId is provided in ApexConfig for an entry, then that + parameter is updated only for that particular task. Otherwise, + the task parameter is added to all tasks. + Carrier Technologies -------------------- @@ -2815,7 +2838,7 @@ REST Client IO APEX can act as REST client on the input as well as on the output interface. The media type is - ``application/json``, so this plugin does only work with + ``application/json``, so this plugin only works with the JSON Event protocol. REST Client Input @@ -2850,7 +2873,12 @@ REST Client Input "org.onap.policy.apex.plugins.event.carrier.restclient.RESTClientCarrierTechnologyParameters", "parameters" : { "url" : "http://example.org:8080/triggers/events", (2) - "httpCodeFilter" : "[2][0-9][0-9]" (3) + "httpMethod": "GET", (3) + "httpCodeFilter" : "[2][0-9][0-9]", (4) + "httpHeaders" : [ (5) + ["Keep-Alive", "300"], + ["Cache-Control", "no-cache"] + ] } } @@ -2861,7 +2889,14 @@ REST Client Input +-------+--------------------------------------------------+ | **2** | the URL of the HTTP server for events | +-------+--------------------------------------------------+ - | **3** | use HTTP CODE FILTER for filtering status code | + | **3** | the HTTP method to use (GET/PUT/POST/DELETE), | + | | optional, defaults to GET | + +-------+--------------------------------------------------+ + | **4** | use HTTP CODE FILTER for filtering status code, | + | | optional, defaults to [2][0-9][0-9] | + +-------+--------------------------------------------------+ + | **5** | HTTP headers to use on the REST request, | + | | optional | +-------+--------------------------------------------------+ REST Client Output @@ -2897,8 +2932,11 @@ REST Client Output "parameters" : { "url" : "http://example.com:8888/actions/events", (2) "url" : "http://example.{site}.com:8888/{trig}/events", (2') - "httpMethod" : "PUT" (3) - } + "httpMethod" : "PUT". (3) + "httpHeaders" : [ (4) + ["Keep-Alive", "300"], + ["Cache-Control", "no-cache"] + ] } } .. container:: colist arabic @@ -2910,7 +2948,11 @@ REST Client Output +-------+--------------------------------------------------+ | **2'**| the tagged URL of the HTTP server for events | +-------+--------------------------------------------------+ - | **3** | use HTTP PUT (remove this line to use HTTP POST) | + | **3** | the HTTP method to use (GET/PUT/POST/DELETE), | + | | optional, defaults to POST | + +-------+--------------------------------------------------+ + | **4** | HTTP headers to use on the REST request, | + | | optional | +-------+--------------------------------------------------+ REST Server IO @@ -2948,7 +2990,7 @@ REST Server IO - Maximum port: 65535 - The media type is ``application/json``, so this plugin - does only work with the JSON Event protocol. + only works with the JSON Event protocol. .. container:: paragraph @@ -3124,15 +3166,82 @@ REST Requestor IO APEX can act as REST requestor on the input as well as on the output interface. The media type is - ``application/json``, so this plugin does only work with - the JSON Event protocol. + ``application/json``, so this plugin only works with + the JSON Event protocol. This plugin allows APEX to send REST requests + and to receive the reply of that request without tying up APEX resources + while the request is being processed. The REST Requestor pairs a REST + requestor producer and consumer together to handle the REST request + and response. The REST request is created from an APEX output event + and the REST response is input into APEX as a new input event. -REST Requestor Input -==================== +REST Requestor Output (REST Request Producer) +============================================= + + .. container:: paragraph + + APEX sends a REST request when events are output by APEX, the REST + request configuration is specified on the REST Request Consumer (see + below). + + .. container:: listingblock + + .. container:: content + + .. code:: + + "carrierTechnologyParameters": { + "carrierTechnology": "RESTREQUESTOR", (1) + "parameterClassName": "org.onap.policy.apex.plugins.event.carrier.restrequestor.RESTRequestorCarrierTechnologyParameters" + }, + + .. container:: colist arabic + + +-------+------------------------------------------+ + | **1** | set REST requestor as carrier technology | + +-------+------------------------------------------+ + + .. container:: paragraph + + The settings below are required on the producer to + define the event that triggers the REST request and + to specify the peered consumer configuration for the + REST request, for example: + + .. container:: listingblock + + .. container:: content + + .. code:: + + "eventNameFilter": "GuardRequestEvent", (1) + "requestorMode": true, (2) + "requestorPeer": "GuardRequestorConsumer", (3) + "requestorTimeout": 500 (4) + + .. container:: colist arabic + + +-------+-------------------------------------------+ + | **1** | a filter on the event | + +-------+-------------------------------------------+ + | **2** | requestor mode must be set to *true* | + +-------+-------------------------------------------+ + | **3** | the peered consumer for REST requests, | + | | that consumer specifies the full | + | | configuration for REST requests | + +-------+-------------------------------------------+ + | **4** | the request timeout in milliseconds, | + | | overridden by timeout on consumer if that | + | | is set, optional defaults to 500 | + | | millisconds | + +-------+-------------------------------------------+ + +REST Requestor Input (REST Request Consumer) +============================================ .. container:: paragraph - APEX will connect to a given URL to request an input. + APEX will connect to a given URL to issue a REST request and + wait for a REST response. The URL can be configured statically or tagged as ``?example.{site}.org:8080/{trig}/events``, all tags such as ``site`` and ``trig`` in the URL @@ -3163,9 +3272,14 @@ REST Requestor Input "url": "http://localhost:54321/some/path/to/rest/resource", (2) "url": "http://localhost:54321/{site}/path/to/rest/{resValue}", (2') "httpMethod": "POST", (3) - "restRequestTimeout": 2000, (4) - "httpCodeFilter" : "[2][0-9][0-9]" (5) - } + "requestorMode": true, (4) + "requestorPeer": "GuardRequestorProducer", (5) + "restRequestTimeout": 2000, (6) + "httpCodeFilter" : "[2][0-9][0-9]" (7) + "httpHeaders" : [ (8) + ["Keep-Alive", "300"], + ["Cache-Control", "no-cache"] + ] } }, .. container:: colist arabic @@ -3177,17 +3291,31 @@ REST Requestor Input +-------+--------------------------------------------------+ | **2'**| the tagged URL of the HTTP server for events | +-------+--------------------------------------------------+ - | **3** | use HTTP PUT (remove this line to use HTTP POST) | + | **3** | the HTTP method to use (GET/PUT/POST/DELETE), | + | | optional, defaults to GET | + +-------+--------------------------------------------------+ + | **4** | requestor mode must be set to *true* | + +-------+--------------------------------------------------+ + | **5** | the peered producer for REST requests, that | + | | producer specifies the APEX output event that | + | | triggers the REST request | +-------+--------------------------------------------------+ - | **4** | request timeout in milliseconds | + | **6** | request timeout in milliseconds, overrides any | + | | value set in the REST Requestor Producer, | + | | optional, defaults to 500 millisconds | +-------+--------------------------------------------------+ - | **5** | use HTTP CODE FILTER for filtering status code | + | **7** | use HTTP CODE FILTER for filtering status code | + | | optional, defaults to [2][0-9][0-9] | + +-------+--------------------------------------------------+ + | **8** | HTTP headers to use on the REST request, | + | | optional | +-------+--------------------------------------------------+ .. container:: paragraph - Further settings are required on the consumer to - define the event that is requested, for example: + Further settings may be required on the consumer to + define the input event that is produced and forwarded into + APEX, for example: .. container:: listingblock @@ -3196,9 +3324,83 @@ REST Requestor Input .. code:: "eventName": "GuardResponseEvent", (1) - "eventNameFilter": "GuardResponseEvent", (2) + "eventNameFilter": "GuardResponseEvent" (2) + + .. container:: colist arabic + + +-------+---------------------------+ + | **1** | the event name | + +-------+---------------------------+ + | **2** | a filter on the event | + +-------+---------------------------+ + +gRPC IO +####### + + .. container:: paragraph + + APEX can send requests over gRPC at the output side, and get back + response at the input side. This can be used to send requests to CDS + over gRPC. The media type is ``application/json``, so this plugin + only works with the JSON Event protocol. + +gRPC Output +=========== + + .. container:: paragraph + + APEX will connect to a given host to send a request over + gRPC. + + .. container:: listingblock + + .. container:: content + + .. code:: + + "carrierTechnologyParameters": { + "carrierTechnology": "GRPC", (1) + "parameterClassName": "org.onap.policy.apex.plugins.event.carrier.grpc.GrpcCarrierTechnologyParameters", + "parameters": { + "host": "cds-blueprints-processor-grpc", (2) + "port": 9111, (2') + "username": "ccsdkapps", (3) + "password": ccsdkapps, (4) + "timeout" : 10 (5) + } + }, + + .. container:: colist arabic + + +-------+--------------------------------------------------+ + | **1** | set GRPC as carrier technology | + +-------+--------------------------------------------------+ + | **2** | the host to which request is sent | + +-------+--------------------------------------------------+ + | **2'**| the value for port | + +-------+--------------------------------------------------+ + | **3** | username required to initiate connection | + +-------+--------------------------------------------------+ + | **4** | password required to initiate connection | + +-------+--------------------------------------------------+ + | **5** | the timeout value for completing the request | + +-------+--------------------------------------------------+ + + .. container:: paragraph + + Further settings are required on the producer to + define the event that is requested, for example: + + .. container:: listingblock + + .. container:: content + + .. code:: + + "eventName": "GRPCRequestEvent", (1) + "eventNameFilter": "GRPCRequestEvent", (2) "requestorMode": true, (3) - "requestorPeer": "GuardRequestorProducer", (4) + "requestorPeer": "GRPCRequestConsumer", (4) "requestorTimeout": 500 (5) .. container:: colist arabic @@ -3215,13 +3417,13 @@ REST Requestor Input | **5** | a general request timeout | +-------+---------------------------+ -REST Requestor Output -===================== +gRPC Input +========== .. container:: paragraph - APEX will connect to a given URL to send events, but - not receive any events. + APEX will connect to the host specified in the producer + side, anad take in response back at the consumer side. .. container:: listingblock @@ -3230,14 +3432,14 @@ REST Requestor Output .. code:: "carrierTechnologyParameters": { - "carrierTechnology": "RESTREQUESTOR", (1) - "parameterClassName": "org.onap.policy.apex.plugins.event.carrier.restrequestor.RESTRequestorCarrierTechnologyParameters" + "carrierTechnology": "GRPC", (1) + "parameterClassName": "org.onap.policy.apex.plugins.event.carrier.grpc.GrpcCarrierTechnologyParameters" }, .. container:: colist arabic +-------+------------------------------------------+ - | **1** | set REST requestor as carrier technology | + | **1** | set GRPC as carrier technology | +-------+------------------------------------------+ .. container:: paragraph @@ -3251,9 +3453,9 @@ REST Requestor Output .. code:: - "eventNameFilter": "GuardRequestEvent", (1) + "eventNameFilter": "GRPCResponseEvent", (1) "requestorMode": true, (2) - "requestorPeer": "GuardRequestorConsumer", (3) + "requestorPeer": "GRPCRequestProducer", (3) "requestorTimeout": 500 (4) .. container:: colist arabic @@ -4035,16 +4237,20 @@ The APEX CLI Tosca Editor %APEX_HOME%/\bin/\apexCLIToscaEditor.bat -c %APEX_HOME%\examples\PolicyModel.apex -ot %APEX_HOME%\examples\test.json -l %APEX_HOME%\examples\test.log -ac %APEX_HOME%\examples\RESTServerStandaloneJsonEvent.json -t %APEX_HOME%\examples\ToscaTemplate.json -The APEX REST Editor + +The APEX Client -------------------- .. container:: paragraph - The standard way to use the APEX REST Editor is via an - installation of the *war* file on a webserver. However, the - REST editor can also be started via command line. This will - start a Grizzly webserver with the *war* deployed. Access to - the REST Editor is then via the provided URL + The APEX Client combines the Policy Editor, the + Monitoring Client, and the Deployment Client into a single + application. The standard way to use the APEX Full Client is + via an installation of the *war* file on a webserver. + However, the Full Client can also be started via command + line. This will start a Grizzly webserver with the *war* + deployed. Access to the Full Client is then via the provided + URL .. container:: paragraph @@ -4052,11 +4258,8 @@ The APEX REST Editor .. container:: ulist - - ``apexRESTEditor.sh`` - simply starts the webserver with - the REST editor - - - ``apexApps.sh rest-editor`` - simply starts the webserver - with the REST editor + - ``apexApps.sh full-client`` - simply starts the webserver + with the Full Client .. container:: paragraph @@ -4064,30 +4267,8 @@ The APEX REST Editor .. container:: ulist - - ``apexRESTEditor.bat`` - simply starts the webserver with - the REST editor - - - ``apexApps.bat rest-editor`` - simply starts the - webserver with the REST editor - - .. container:: paragraph - - Summary of alternatives to start the APEX REST Editor: - - +-------------------------------------------------------------+---------------------------------------------------------------+ - | Unix, Cygwin | Windows | - +=============================================================+===============================================================+ - | .. container:: | .. container:: | - | | | - | .. container:: listingblock | .. container:: listingblock | - | | | - | .. container:: content | .. container:: content | - | | | - | .. code:: | .. code:: | - | | | - | # $APEX_HOME/bin/apexRESTEditor.sh.sh [args] | > %APEX_HOME%\bin\apexRESTEditor.bat [args] | - | # $APEX_HOME/bin/apexApps.sh rest-editor [args] | > %APEX_HOME%\bin\apexApps.bat rest-editor [args] | - +-------------------------------------------------------------+---------------------------------------------------------------+ + - ``apexApps.bat full-client`` - simply starts the + webserver with the Full Client .. container:: paragraph @@ -4100,17 +4281,14 @@ The APEX REST Editor .. code:: - usage: org.onap.policy.apex.client.editor.rest.ApexEditorMain [options...] + usage: org.onap.policy.apex.client.full.rest.ApexServicesRestMain [options...] -h,--help outputs the usage of this command - -l,--listen
the IP address to listen on. Default value is localhost to restrict access to the - local machine only. - -p,--port port to use for the Apex RESTful editor REST calls. - -t,--time-to-live the amount of time in seconds that the server will run for before terminating. Default - value is -1 to run indefinitely. + -p,--port port to use for the Apex Services REST calls + -t,--time-to-live the amount of time in seconds that the server will run for before terminating .. container:: paragraph - If the REST Editor is started without any arguments the + If the Full Client is started without any arguments the final messages will look similar to this: .. container:: listingblock @@ -4119,30 +4297,28 @@ The APEX REST Editor .. code:: - Apex Editor REST endpoint (ApexEditorMain: Config=[ApexEditorParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=READY) starting at http://localhost:18989/apexservices/ . . . - Sep 05, 2018 11:24:30 PM org.glassfish.grizzly.http.server.NetworkListener start + Apex Editor REST endpoint (ApexServicesRestMain: Config=[ApexServicesRestParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=READY) starting at http://localhost:18989/apexservices/ . . . + Sep 05, 2018 11:28:28 PM org.glassfish.grizzly.http.server.NetworkListener start INFO: Started listener bound to [localhost:18989] - Sep 05, 2018 11:24:30 PM org.glassfish.grizzly.http.server.HttpServer start + Sep 05, 2018 11:28:28 PM org.glassfish.grizzly.http.server.HttpServer start INFO: [HttpServer] Started. - Apex Editor REST endpoint (ApexEditorMain: Config=[ApexEditorParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=RUNNING) started at http://localhost:18989/apexservices/ + Apex Editor REST endpoint (ApexServicesRestMain: Config=[ApexServicesRestParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=RUNNING) started at http://localhost:18989/apexservices/ .. container:: paragraph - The last line states the URL on which the REST Editor can be - accessed. The example above stated - ``http://0.0.0.0:18989/apex/``. In a web browser use the URL - ``http://localhost:18989`` and the REST Editor will start. + The last line states the URL on which the Monitoring Client + can be accessed. The example above stated + ``http://localhost:18989/apexservices``. In a web browser + use the URL ``http://localhost:18989``. -The APEX Monitoring Client --------------------------- +The APEX Application Launcher +----------------------------- .. container:: paragraph - The standard way to use the APEX Monitoring Client is via an - installation of the *war* file on a webserver. However, the - Monitoring Client can also be started via command line. This - will start a Grizzly webserver with the *war* deployed. - Access to the Monitoring Client is then via the provided URL + The standard applications (Engine and CLI Editor) + come with dedicated start scripts. For all other APEX + applications, we provide an application launcher. .. container:: paragraph @@ -4150,8 +4326,7 @@ The APEX Monitoring Client .. container:: ulist - - ``apexApps.sh eng-monitoring`` - simply starts the - webserver with the Monitoring Client + - apexApps.sh\` - simply starts the application launcher .. container:: paragraph @@ -4159,13 +4334,31 @@ The APEX Monitoring Client .. container:: ulist - - ``apexApps.bat eng-monitoring`` - simply starts the - webserver with the Monitoring Client + - ``apexApps.bat`` - simply starts the application launcher .. container:: paragraph - The option ``-h`` provides a help screen with all command - line arguments. + Summary of alternatives to start the APEX application + launcher: + + +-------------------------------------------------+---------------------------------------------------+ + | Unix, Cygwin | Windows | + +=================================================+===================================================+ + | .. container:: | .. container:: | + | | | + | .. container:: listingblock | .. container:: listingblock | + | | | + | .. container:: content | .. container:: content | + | | | + | .. code:: | .. code:: | + | | | + | # $APEX_HOME/bin/apexApps.sh [args] | > %APEX_HOME%\bin\apexApps.bat [args] | + +-------------------------------------------------+---------------------------------------------------+ + + .. container:: paragraph + + The option ``-h`` provides a help screen with all launcher + command line arguments. .. container:: listingblock @@ -4173,15 +4366,19 @@ The APEX Monitoring Client .. code:: - usage: org.onap.policy.apex.client.monitoring.rest.ApexMonitoringRestMain [options...] - -h,--help outputs the usage of this command - -p,--port port to use for the Apex Services REST calls - -t,--time-to-live the amount of time in seconds that the server will run for before terminating + apexApps.sh - runs APEX applications + + Usage: apexApps.sh [options] | [ []] + + Options + -d - describes an application + -l - lists all applications supported by this script + -h - this help screen .. container:: paragraph - If the Monitoring Client is started without any arguments - the final messages will look similar to this: + Using ``-l`` lists all known application the launcher can + start. .. container:: listingblock @@ -4189,240 +4386,8 @@ The APEX Monitoring Client .. code:: - Apex Services REST endpoint (ApexMonitoringRestMain: Config=[ApexMonitoringRestParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=READY) starting at http://localhost:18989/apexservices/ . . . - Sep 05, 2018 11:26:20 PM org.glassfish.grizzly.http.server.NetworkListener start - INFO: Started listener bound to [localhost:18989] - Sep 05, 2018 11:26:20 PM org.glassfish.grizzly.http.server.HttpServer start - INFO: [HttpServer] Started. - Apex Services REST endpoint (ApexMonitoringRestMain: Config=[ApexMonitoringRestParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=RUNNING) started at http://localhost:18989/apexservices/ - - .. container:: paragraph - - The last line states the URL on which the Monitoring Client - can be accessed. The example above stated - ``http://localhost:18989/apexservices``. In a web browser - use the URL ``http://localhost:18989``. - -The APEX Deployment Client --------------------------- - - .. container:: paragraph - - The standard way to use the APEX Deployment Client is via an - installation of the *war* file on a webserver. However, the - Deployment Client can also be started via command line. This - will start a Grizzly webserver with the *war* deployed. - Access to the Deployment Client is then via the provided URL - - .. container:: paragraph - - On UNIX and Cygwin systems use: - - .. container:: ulist - - - ``apexApps.sh eng-deployment`` - simply starts the - webserver with the Deployment Client - - .. container:: paragraph - - On Windows systems use: - - .. container:: ulist - - - ``apexApps.bat eng-deployment`` - simply starts the - webserver with the Deployment Client - - .. container:: paragraph - - The option ``-h`` provides a help screen with all command - line arguments. - - .. container:: listingblock - - .. container:: content - - .. code:: - - usage: org.onap.policy.apex.client.deployment.rest.ApexDeploymentRestMain [options...] - -h,--help outputs the usage of this command - -p,--port port to use for the Apex Services REST calls - -t,--time-to-live the amount of time in seconds that the server will run for before terminating - - .. container:: paragraph - - If the Deployment Client is started without any arguments - the final messages will look similar to this: - - .. container:: listingblock - - .. container:: content - - .. code:: - - Apex Services REST endpoint (ApexDeploymentRestMain: Config=[ApexDeploymentRestParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=READY) starting at http://localhost:18989/apexservices/ . . . - Sep 05, 2018 11:27:09 PM org.glassfish.grizzly.http.server.NetworkListener start - INFO: Started listener bound to [localhost:18989] - Sep 05, 2018 11:27:09 PM org.glassfish.grizzly.http.server.HttpServer start - INFO: [HttpServer] Started. - Apex Services REST endpoint (ApexDeploymentRestMain: Config=[ApexDeploymentRestParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=RUNNING) started at http://localhost:18989/apexservices/ - - .. container:: paragraph - - The last line states the URL on which the Deployment Client - can be accessed. The example above stated - ``http://localhost:18989/apexservices``. In a web browser - use the URL ``http://localhost:18989``. - -The APEX Full Client --------------------- - - .. container:: paragraph - - The APEX Full Client combines the REST Editor, the - Monitoring Client, and the Deployment Client into a single - application. The standard way to use the APEX Full Client is - via an installation of the *war* file on a webserver. - However, the Full Client can also be started via command - line. This will start a Grizzly webserver with the *war* - deployed. Access to the Full Client is then via the provided - URL - - .. container:: paragraph - - On UNIX and Cygwin systems use: - - .. container:: ulist - - - ``apexApps.sh full-client`` - simply starts the webserver - with the Full Client - - .. container:: paragraph - - On Windows systems use: - - .. container:: ulist - - - ``apexApps.bat full-client`` - simply starts the - webserver with the Full Client - - .. container:: paragraph - - The option ``-h`` provides a help screen with all command - line arguments. - - .. container:: listingblock - - .. container:: content - - .. code:: - - usage: org.onap.policy.apex.client.full.rest.ApexServicesRestMain [options...] - -h,--help outputs the usage of this command - -p,--port port to use for the Apex Services REST calls - -t,--time-to-live the amount of time in seconds that the server will run for before terminating - - .. container:: paragraph - - If the Full Client is started without any arguments the - final messages will look similar to this: - - .. container:: listingblock - - .. container:: content - - .. code:: - - Apex Editor REST endpoint (ApexServicesRestMain: Config=[ApexServicesRestParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=READY) starting at http://localhost:18989/apexservices/ . . . - Sep 05, 2018 11:28:28 PM org.glassfish.grizzly.http.server.NetworkListener start - INFO: Started listener bound to [localhost:18989] - Sep 05, 2018 11:28:28 PM org.glassfish.grizzly.http.server.HttpServer start - INFO: [HttpServer] Started. - Apex Editor REST endpoint (ApexServicesRestMain: Config=[ApexServicesRestParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=RUNNING) started at http://localhost:18989/apexservices/ - - .. container:: paragraph - - The last line states the URL on which the Monitoring Client - can be accessed. The example above stated - ``http://localhost:18989/apexservices``. In a web browser - use the URL ``http://localhost:18989``. - - The APEX Application Launcher ------------------------------- - - .. container:: paragraph - - The standard applications (Engine, CLI Editor, REST Editor) - come with dedicated start scripts. For all other APEX - applications, we provide an application launcher. - - .. container:: paragraph - - On UNIX and Cygwin systems use: - - .. container:: ulist - - - apexApps.sh\` - simply starts the application launcher - - .. container:: paragraph - - On Windows systems use: - - .. container:: ulist - - - ``apexApps.bat`` - simply starts the application launcher - - .. container:: paragraph - - Summary of alternatives to start the APEX application - launcher: - - +-------------------------------------------------+---------------------------------------------------+ - | Unix, Cygwin | Windows | - +=================================================+===================================================+ - | .. container:: | .. container:: | - | | | - | .. container:: listingblock | .. container:: listingblock | - | | | - | .. container:: content | .. container:: content | - | | | - | .. code:: | .. code:: | - | | | - | # $APEX_HOME/bin/apexApps.sh [args] | > %APEX_HOME%\bin\apexApps.bat [args] | - +-------------------------------------------------+---------------------------------------------------+ - - .. container:: paragraph - - The option ``-h`` provides a help screen with all launcher - command line arguments. - - .. container:: listingblock - - .. container:: content - - .. code:: - - apexApps.sh - runs APEX applications - - Usage: apexApps.sh [options] | [ []] - - Options - -d - describes an application - -l - lists all applications supported by this script - -h - this help screen - - .. container:: paragraph - - Using ``-l`` lists all known application the launcher can - start. - - .. container:: listingblock - - .. container:: content - - .. code:: - - apexApps.sh: supported applications: - --> ws-echo engine eng-monitoring full-client eng-deployment tpl-event-json model-2-cli rest-editor cli-editor ws-console + apexApps.sh: supported applications: + --> ws-echo engine eng-monitoring full-client eng-deployment tpl-event-json model-2-cli rest-editor cli-editor ws-console .. container:: paragraph @@ -4433,2697 +4398,274 @@ The APEX Full Client .. container:: content - .. code:: - - apexApps.sh: application 'ws-console' - --> a simple console sending events to APEX, connect to APEX consumer port - - .. container:: paragraph - - Launching an application is done by calling the script with - only the application name and any CLI arguments for the - application. For instance, starting the ``ws-echo`` - application with port ``8888``: - - .. container:: listingblock - - .. container:: content - - .. code:: - - apexApps.sh ws-echo -p 8888 - -Application: Create Event Templates ------------------------------------ - - .. container:: paragraph - - **Status: Experimental** - - .. container:: paragraph - - This application takes a policy model (JSON or XML encoded) - and generates templates for events in JSON format. This can - help when a policy defines rather complex trigger or action - events or complex events between states. The application can - produce events for the types: stimuli (policy trigger - events), internal (events between policy states), and - response (action events). - - +----------------------------------------------------------------+------------------------------------------------------------------+ - | Unix, Cygwin | Windows | - +================================================================+==================================================================+ - | .. container:: | .. container:: | - | | | - | .. container:: listingblock | .. container:: listingblock | - | | | - | .. container:: content | .. container:: content | - | | | - | .. code:: | .. code:: | - | | | - | # $APEX_HOME/bin/apexApps.sh tpl-event-json [args] | > %APEX_HOME%\bin\apexApps.bat tpl-event-json [args] | - +----------------------------------------------------------------+------------------------------------------------------------------+ - - .. container:: paragraph - - The option ``-h`` provides a help screen. - - .. container:: listingblock - - .. container:: content - - .. code:: - - gen-model2event v{release-version} - generates JSON templates for events generated from a policy model - usage: gen-model2event - -h,--help prints this help and usage screen - -m,--model set the input policy model file - -t,--type set the event type for generation, one of: - stimuli (trigger events), response (action - events), internal (events between states) - -v,--version prints the application version - - .. container:: paragraph - - The created templates are not valid events, instead they use - some markup for values one will need to change to actual - values. For instance, running the tool with the *Sample - Domain* policy model as: - - .. container:: listingblock - - .. container:: content - - .. code:: - - apexApps.sh tpl-event-json -m $APEX_HOME/examples/models/SampleDomain/SamplePolicyModelJAVA.json -t stimuli - - .. container:: paragraph - - will produce the following status messages: - - .. container:: listingblock - - .. container:: content - - .. code:: - - gen-model2event: starting Event generator - --> model file: examples/models/SampleDomain/SamplePolicyModelJAVA.json - --> type: stimuli - - .. container:: paragraph - - and then run the generator application producing two event - templates. The first template is called ``Event0000``. - - .. container:: listingblock - - .. container:: content - - .. code:: - - { - "name" : "Event0000", - "nameSpace" : "org.onap.policy.apex.sample.events", - "version" : "0.0.1", - "source" : "Outside", - "target" : "Match", - "TestTemperature" : ###double: 0.0###, - "TestTimestamp" : ###long: 0###, - "TestMatchCase" : ###integer: 0###, - "TestSlogan" : "###string###" - } - - .. container:: paragraph - - The values for the keys are marked with ``#`` and the - expected type of the value. To create an actual stimuli - event, all these markers need to be change to actual values, - for instance: - - .. container:: listingblock - - .. container:: content - - .. code:: - - { - "name" : "Event0000", - "nameSpace" : "org.onap.policy.apex.sample.events", - "version" : "0.0.1", - "source" : "Outside", - "target" : "Match", - "TestTemperature" : 25, - "TestTimestamp" : 123456789123456789, - "TestMatchCase" : 1, - "TestSlogan" : "Testing the Match Case with Temperature 25" - } - -Application: Convert a Policy Model to CLI Editor Commands ----------------------------------------------------------- - - .. container:: paragraph - - **Status: Experimental** - - .. container:: paragraph - - This application takes a policy model (JSON or XML encoded) - and generates commands for the APEX CLI Editor. This - effectively reverses a policy specification realized with - the CLI Editor. - - +-------------------------------------------------------------+---------------------------------------------------------------+ - | Unix, Cygwin | Windows | - +=============================================================+===============================================================+ - | .. container:: | .. container:: | - | | | - | .. container:: listingblock | .. container:: listingblock | - | | | - | .. container:: content | .. container:: content | - | | | - | .. code:: | .. code:: | - | | | - | # $APEX_HOME/bin/apexApps.sh model-2-cli [args] | > %APEX_HOME%\bin\apexApps.bat model-2-cli [args] | - +-------------------------------------------------------------+---------------------------------------------------------------+ - - .. container:: paragraph - - The option ``-h`` provides a help screen. - - .. container:: listingblock - - .. container:: content - - .. code:: - - usage: gen-model2cli - -h,--help prints this help and usage screen - -m,--model set the input policy model file - -sv,--skip-validation switch of validation of the input file - -v,--version prints the application version - - .. container:: paragraph - - For instance, running the tool with the *Sample Domain* - policy model as: - - .. container:: listingblock - - .. container:: content - - .. code:: - - apexApps.sh model-2-cli -m $APEX_HOME/examples/models/SampleDomain/SamplePolicyModelJAVA.json - - .. container:: paragraph - - will produce the following status messages: - - .. container:: listingblock - - .. container:: content - - .. code:: - - gen-model2cli: starting CLI generator - --> model file: examples/models/SampleDomain/SamplePolicyModelJAVA.json - - .. container:: paragraph - - and then run the generator application producing all CLI - Editor commands and printing them to standard out. - -Application: Websocket Clients (Echo and Console) -------------------------------------------------- - - .. container:: paragraph - - **Status: Production** - - .. container:: paragraph - - The application launcher also provides a Websocket echo - client and a Websocket console client. The echo client - connects to APEX and prints all events it receives from - APEX. The console client connects to APEX, reads input from - the command line, and sends this input as events to APEX. - - +------------------------------------------------------------+--------------------------------------------------------------+ - | Unix, Cygwin | Windows | - +============================================================+==============================================================+ - | .. container:: | .. container:: | - | | | - | .. container:: listingblock | .. container:: listingblock | - | | | - | .. container:: content | .. container:: content | - | | | - | .. code:: | .. code:: | - | | | - | # $APEX_HOME/bin/apexApps.sh ws-echo [args] | > %APEX_HOME%\bin\apexApps.bat ws-echo [args] | - | # $APEX_HOME/bin/apexApps.sh ws-console [args] | > %APEX_HOME%\bin\apexApps.bat ws-console [args] | - +------------------------------------------------------------+--------------------------------------------------------------+ - - .. container:: paragraph - - The arguments are the same for both applications: - - .. container:: ulist - - - ``-p`` defines the Websocket port to connect to (defaults - to ``8887``) - - - ``-s`` defines the host on which a Websocket server is - running (defaults to ``localhost``) - - .. container:: paragraph - - A discussion on how to use these two applications to build - an APEX system is detailed HowTo-Websockets. - -My First Policy -^^^^^^^^^^^^^^^ - -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.. - - .. 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. - - .. 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 ------------ - -Sales Input Event -################# - - .. container:: paragraph - - Each time a PoS system processes a sales item an event - with the following format is emitted: - - .. table:: Table 1. Sale Input Event - - +----------------------+----------------------+-----------------------+ - | 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, …​ | | - +----------------------+----------------------+-----------------------+ - - .. container:: paragraph - - 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 - - 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 - - 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:: paragraph - - *HyperM* maintains information about each item for sale - in a database table called ``ITEMS``. - - .. table:: Table 3. Items Database - - +----------------------+----------------------+-----------------------+ - | Table | Fields | Description | - +======================+======================+=======================+ - | ITEMS | item_ID, | Database table | - | | description, | describing each item | - | | cost_price, barcode, | for sale | - | | supplier_ID, | | - | | category, …​ | | - +----------------------+----------------------+-----------------------+ - - .. container:: paragraph - - 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 -############################ - - .. table:: Table 4. Assistants Database - - +----------------------+----------------------+-----------------------+ - | Table | Fields | Description | - +======================+======================+=======================+ - | ASSISTANTS | assistant_ID, | Database table | - | | surname, firstname, | describing each | - | | middlename, age, | *HyperM* sales | - | | grade, phone_number, | assistant | - | | …​ | | - +----------------------+----------------------+-----------------------+ - - .. 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 -#################### - - .. table:: Table 5. Branches Database - - +----------------------+----------------------+-----------------------+ - | Table | Fields | Description | - +======================+======================+=======================+ - | BRANCHES | branch_ID, | Database table | - | | branch_Name, | describing each | - | | category, street, | *HyperM* branch | - | | city, country, | | - | | postcode, …​ | | - +----------------------+----------------------+-----------------------+ - - .. container:: paragraph - - *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.. - -Policy Step 1 -------------- - -Scenario -######### - .. container:: paragraph - - 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*. - - .. container:: ulist - - - Alcohol cannot be sold before 11:30am. - -Create the an new empty Policy Model ``MyFirstPolicyModel`` -########################################################### - - .. container:: paragraph - - 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. - - .. 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:: imageblock - - .. container:: content - - |File > New to create a new Policy Model| - - .. container:: title - - Figure 4. Create a new Policy Model 1/2 - - .. container:: imageblock - - .. container:: content - - |Create a new Policy Model| - - .. container:: title - - Figure 5. Create a new Policy Model 2/2 - -Create the input event ``SALE_INPUT`` and the output event ``SALE_AUTH`` -######################################################################## - - .. container:: paragraph - - Using the APEX Policy Editor, click on the 'Events' tab. - In the 'Events' pane, right click and select 'New': - - .. container:: imageblock - - .. container:: content - - |Right click to create a new event| - - .. 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. - - .. container:: imageblock - - .. container:: content - - |Fill in the necessary information for the - 'SALE_INPUT' event and click 'Submit'| - - .. container:: title - - Figure 7. Populate the ``SALE_INPUT`` event - - .. 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 - - 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:: paragraph - - 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'. - - .. container:: imageblock - - .. container:: content - - |Right click to create a new Item Schema| - - .. container:: title - - Figure 8. Create new Data Types - - .. container:: paragraph - - 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:: content - - |Create a new Item Schema| - - .. container:: title - - Figure 9. Create new Item Schemas - - .. container:: paragraph - - 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. - - .. tip - - .. container:: title - - Field Schema types - - .. container:: paragraph - - APEX natively supports schema definitions in ``Java`` and ``Avro``. - - .. container:: paragraph - - ``Java`` schema definitions are simply the name of a Java Class. There are some restrictions: - - .. container:: ulist - - - the class must be instantiatable, i.e. not an Java interface or abstract class - - - primitive types are not supported, i.e. use ``java.lang.Integer`` instead of ``int``, etc. - - - it must be possible to find the class, i.e. the class must be contained in the Java classpath. - - .. container:: paragraph - - ``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. - - .. 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 - - Remember to click the 'Submit' button at the bottom of - the event definition pane. - - .. 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:: imageblock - - .. 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. + .. code:: -Extend the Policy with the new Scenario -####################################### + apexApps.sh: application 'ws-console' + --> a simple console sending events to APEX, connect to APEX consumer port - .. container:: paragraph + .. container:: paragraph - To create a new Task click on the 'Tasks' tab. In the - 'Tasks' pane, right click and select 'Create new Task': + Launching an application is done by calling the script with + only the application name and any CLI arguments for the + application. For instance, starting the ``ws-echo`` + application with port ``8888``: - .. container:: paragraph + .. container:: listingblock - 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. + .. container:: content - .. table:: Table 12. Input fields for ``MorningBoozeCheckAlt1`` task + .. code:: - +-----------------------------------+-----------------------------------+ - | 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 | - +-----------------------------------+-----------------------------------+ + apexApps.sh ws-echo -p 8888 - .. table:: Table 13. Output fields for ``MorningBoozeCheckAlt1`` task +Application: Create Event Templates +----------------------------------- - +-----------------------------------+-----------------------------------+ - | 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 - .. container:: paragraph + **Status: Experimental** - This task also requires some 'Task Logic' to implement - the new behaviour for this task. + .. container:: paragraph - .. container:: paragraph + This application takes a policy model (JSON or XML encoded) + and generates templates for events in JSON format. This can + help when a policy defines rather complex trigger or action + events or complex events between states. The application can + produce events for the types: stimuli (policy trigger + events), internal (events between policy states), and + response (action events). - 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``. + +----------------------------------------------------------------+------------------------------------------------------------------+ + | Unix, Cygwin | Windows | + +================================================================+==================================================================+ + | .. container:: | .. container:: | + | | | + | .. container:: listingblock | .. container:: listingblock | + | | | + | .. container:: content | .. container:: content | + | | | + | .. code:: | .. code:: | + | | | + | # $APEX_HOME/bin/apexApps.sh tpl-event-json [args] | > %APEX_HOME%\bin\apexApps.bat tpl-event-json [args] | + +----------------------------------------------------------------+------------------------------------------------------------------+ - .. container:: paragraph + .. 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. + The option ``-h`` provides a help screen. - .. container:: listingblock + .. container:: listingblock - .. container:: title + .. container:: content - MVEL code for the ``MorningBoozeCheckAlt1`` task + .. code:: - .. container:: content + gen-model2event v{release-version} - generates JSON templates for events generated from a policy model + usage: gen-model2event + -h,--help prints this help and usage screen + -m,--model set the input policy model file + -t,--type set the event type for generation, one of: + stimuli (trigger events), response (action + events), internal (events between states) + -v,--version prints the application version - .. code:: + .. container:: paragraph - /* - * ============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; - } + The created templates are not valid events, instead they use + some markup for values one will need to change to actual + values. For instance, running the tool with the *Sample + Domain* policy model as: - /* - 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:: listingblock - .. container:: imageblock + .. container:: content - .. container:: content + .. code:: - |Create a new alternative task MorningBoozeCheckAlt1| + apexApps.sh tpl-event-json -m $APEX_HOME/examples/models/SampleDomain/SamplePolicyModelJAVA.json -t stimuli - .. container:: title + .. container:: paragraph - Figure 19. Create a new Task + will produce the following status messages: - .. container:: paragraph + .. container:: listingblock - 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:: content - .. container:: paragraph + .. code:: - 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. + gen-model2event: starting Event generator + --> model file: examples/models/SampleDomain/SamplePolicyModelJAVA.json + --> type: stimuli - .. container:: imageblock + .. container:: paragraph - .. container:: content + and then run the generator application producing two event + templates. The first template is called ``Event0000``. - |Right click to edit a policy| + .. container:: listingblock - .. container:: title + .. container:: content - Figure 20. Edit a Policy + .. code:: - .. container:: paragraph + { + "name" : "Event0000", + "nameSpace" : "org.onap.policy.apex.sample.events", + "version" : "0.0.1", + "source" : "Outside", + "target" : "Match", + "TestTemperature" : ###double: 0.0###, + "TestTimestamp" : ###long: 0###, + "TestMatchCase" : ###integer: 0###, + "TestSlogan" : "###string###" + } - 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 - .. container:: paragraph + The values for the keys are marked with ``#`` and the + expected type of the value. To create an actual stimuli + event, all these markers need to be change to actual values, + for instance: - 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:: listingblock - .. container:: paragraph + .. container:: content - 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. + .. code:: - .. container:: listingblock + { + "name" : "Event0000", + "nameSpace" : "org.onap.policy.apex.sample.events", + "version" : "0.0.1", + "source" : "Outside", + "target" : "Match", + "TestTemperature" : 25, + "TestTimestamp" : 123456789123456789, + "TestMatchCase" : 1, + "TestSlogan" : "Testing the Match Case with Temperature 25" + } - .. container:: title +Application: Convert a Policy Model to CLI Editor Commands +---------------------------------------------------------- - JavaScript code for the ``BoozeAuthDecide`` task - selection logic + .. container:: paragraph - .. container:: content + **Status: Experimental** - .. code:: + .. container:: paragraph - /* - * ============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 application takes a policy model (JSON or XML encoded) + and generates commands for the APEX CLI Editor. This + effectively reverses a policy specification realized with + the CLI Editor. - /* - 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" - */ + +-------------------------------------------------------------+---------------------------------------------------------------+ + | Unix, Cygwin | Windows | + +=============================================================+===============================================================+ + | .. container:: | .. container:: | + | | | + | .. container:: listingblock | .. container:: listingblock | + | | | + | .. container:: content | .. container:: content | + | | | + | .. code:: | .. code:: | + | | | + | # $APEX_HOME/bin/apexApps.sh model-2-cli [args] | > %APEX_HOME%\bin\apexApps.bat model-2-cli [args] | + +-------------------------------------------------------------+---------------------------------------------------------------+ - .. container:: imageblock + .. container:: paragraph - .. container:: content + The option ``-h`` provides a help screen. - |State definition with 2 Tasks and Task Selection - Logic| + .. container:: listingblock - .. container:: title + .. container:: content - Figure 21. State definition with 2 Tasks and Task - Selection Logic + .. code:: - .. container:: paragraph + usage: gen-model2cli + -h,--help prints this help and usage screen + -m,--model set the input policy model file + -sv,--skip-validation switch of validation of the input file + -v,--version prints the application version - 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 - .. container:: paragraph + For instance, running the tool with the *Sample Domain* + policy model as: - 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:: listingblock - .. container:: paragraph + .. container:: content - 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. + .. code:: -Test Policy Step 2 -################## + apexApps.sh model-2-cli -m $APEX_HOME/examples/models/SampleDomain/SamplePolicyModelJAVA.json - .. container:: paragraph + .. 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'. + will produce the following status messages: - .. container:: listingblock + .. container:: listingblock - .. container:: title + .. container:: content - JSON to load and execute *My First Policy*, read input - JSON events from ``stdin``, and emit output events to - ``stdout`` + .. code:: - .. container:: content + gen-model2cli: starting CLI generator + --> model file: examples/models/SampleDomain/SamplePolicyModelJAVA.json - .. code:: + .. container:: paragraph - { - "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" - } - } - } - } + and then run the generator application producing all CLI + Editor commands and printing them to standard out. - .. container:: paragraph +Application: Websocket Clients (Echo and Console) +------------------------------------------------- - 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 - .. container:: paragraph + **Status: Production** - 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:: paragraph - .. container:: listingblock + The application launcher also provides a Websocket echo + client and a Websocket console client. The echo client + connects to APEX and prints all events it receives from + APEX. The console client connects to APEX, reads input from + the command line, and sends this input as events to APEX. - .. container:: title + +------------------------------------------------------------+--------------------------------------------------------------+ + | Unix, Cygwin | Windows | + +============================================================+==============================================================+ + | .. container:: | .. container:: | + | | | + | .. container:: listingblock | .. container:: listingblock | + | | | + | .. container:: content | .. container:: content | + | | | + | .. code:: | .. code:: | + | | | + | # $APEX_HOME/bin/apexApps.sh ws-echo [args] | > %APEX_HOME%\bin\apexApps.bat ws-echo [args] | + | # $APEX_HOME/bin/apexApps.sh ws-console [args] | > %APEX_HOME%\bin\apexApps.bat ws-console [args] | + +------------------------------------------------------------+--------------------------------------------------------------+ - APEX CLI Editor code for Policy 2 + .. container:: paragraph - .. container:: content + The arguments are the same for both applications: - .. code:: + .. container:: ulist - #------------------------------------------------------------------------------- - # ============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; - } + - ``-p`` defines the Websocket port to connect to (defaults + to ``8887``) - /* - 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; - } + - ``-s`` defines the host on which a Websocket server is + running (defaults to ``localhost``) - /* - 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); - } + .. container:: paragraph - /* - 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 + A discussion on how to use these two applications to build + an APEX system is detailed HowTo-Websockets. APEX Logging ^^^^^^^^^^^^ @@ -7203,7 +4745,7 @@ Standard Logging Configuration 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 ``VAR_LOG`` and set + 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. @@ -7219,7 +4761,7 @@ Standard Logging Configuration Apex - + ...appenders ...loggers @@ -7272,7 +4814,7 @@ Standard Logging Configuration :number-lines: - ${VAR_LOG}/apex.log + ${logDir}/apex.log %d %-5relative [procId=${processId}] [%thread] %-5level %logger{26} - %msg %n %ex{full} @@ -7291,7 +4833,7 @@ Standard Logging Configuration :number-lines: - ${VAR_LOG}/apex_ctxt.log + ${logDir}/apex_ctxt.log %d %-5relative [procId=${processId}] [%thread] %-5level %logger{26} - %msg %n %ex{full} @@ -7471,11 +5013,11 @@ Rolling File Appenders .. code:: - ${VAR_LOG}/apex.log + ${logDir}/apex.log - ${VAR_LOG}/apex_%d{yyyy-MM-dd}.%i.log.gz + ${logDir}/apex_%d{yyyy-MM-dd}.%i.log.gz 4 @@ -7503,9 +5045,9 @@ Rolling File Appenders - ${VAR_LOG}/apex_ctxt.log + ${logDir}/apex_ctxt.log - ${VAR_LOG}/apex_ctxt_%d{yyyy-MM-dd}.%i.log.gz + ${logDir}/apex_ctxt_%d{yyyy-MM-dd}.%i.log.gz 4 Apex - + @@ -7552,7 +5094,7 @@ Example Configuration for Logging Logic - ${VAR_LOG}/apex.log + ${logDir}/apex.log %d %-5relative [procId=${processId}] [%thread] %-5level%logger{26} - %msg %n %ex{full} @@ -7602,10 +5144,10 @@ Example Configuration for a Production Server Apex - + - ${VAR_LOG}/apex.log + ${logDir}/apex.log %d %-5relative [procId=${processId}] [%thread] %-5level%logger{26} - %msg %n %ex{full} @@ -8201,30 +5743,5 @@ Send Events .. container:: :name: footer-text - 2.0.0-SNAPSHOT - Last updated 2018-09-10 15:38:16 IST - -.. |Extract the TAR archive| image:: images/install-guide/win-extract-tar-gz.png -.. |Extract the APEX distribution| image:: images/install-guide/win-extract-tar.png -.. |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 +