APEX User Manual update for POLICY-1743
[policy/parent.git] / docs / apex / APEX-User-Manual.rst
1 .. This work is licensed under a Creative Commons Attribution 4.0 International License.
2 .. http://creativecommons.org/licenses/by/4.0
3
4
5 APEX User Manual
6 ****************
7
8 .. contents::
9     :depth: 3
10
11 Installation
12 ^^^^^^^^^^^^
13
14 Requirements
15 ------------
16
17             .. container:: paragraph
18
19                APEX is 100% written in Java and runs on any platform
20                that supports a JVM, e.g. Windows, Unix, Cygwin. Some
21                APEX applications (such as the monitoring application)
22                come as web archives, they do require a war-capable web
23                server installed.
24
25 Installation Requirements
26 #########################
27
28                .. container:: ulist
29
30                   -  Downloaded distribution: JAVA runtime environment
31                      (JRE, Java 8 or later, APEX is tested with the
32                      Oracle Java)
33
34                   -  Building from source: JAVA development kit (JDK,
35                      Java 8 or later, APEX is tested with the Oracle
36                      Java)
37
38                   -  A web archive capable webserver, for instance for
39                      the monitoring application
40
41                      .. container:: ulist
42
43                         -  for instance `Apache
44                            Tomcat <https://tomcat.apache.org/>`__
45
46                   -  Sufficient rights to install APEX on the system
47
48                   -  Installation tools depending on the installation
49                      method used:
50
51                      .. container:: ulist
52
53                         -  ZIP to extract from a ZIP distribution
54
55                            .. container:: ulist
56
57                               -  Windows for instance
58                                  `7Zip <http://www.7-zip.org/>`__
59
60                         -  TAR and GZ to extract from that TAR.GZ
61                            distribution
62
63                            .. container:: ulist
64
65                               -  Windows for instance
66                                  `7Zip <http://www.7-zip.org/>`__
67
68                         -  RPM to install from the RPM distribution
69
70                            .. container:: ulist
71
72                               -  Install: ``sudo apt-get install rpm``
73
74                         -  DPKG to install from the DEB distribution
75
76                            .. container:: ulist
77
78                               -  Install: ``sudo apt-get install dpkg``
79
80 Feature Requirements
81 ####################
82
83                .. container:: paragraph
84
85                   APEX supports a number of features that require extra
86                   software being installed.
87
88                .. container:: ulist
89
90                   -  `Apache Kafka <https://kafka.apache.org/>`__ to
91                      connect APEX to a Kafka message bus
92
93                   -  `Hazelcast <https://hazelcast.com/>`__ to use
94                      distributed hash maps for context
95
96                   -  `Infinispan <http://infinispan.org/>`__ for
97                      distributed context and persistence
98
99                   -  `Docker <https://www.docker.com/>`__ to run APEX
100                      inside a Docker container
101
102 Build (Install from Source) Requirements
103 ########################################
104
105                .. container:: paragraph
106
107                   Installation from source requires a few development
108                   tools
109
110                .. container:: ulist
111
112                   -  GIT to retrieve the source code
113
114                   -  Java SDK, Java version 8 or later
115
116                   -  Apache Maven 3 (the APEX build environment)
117
118 Get the APEX Source Code
119 ------------------------
120
121             .. container:: paragraph
122
123                The first APEX source code was hosted on Github in
124                January 2018. By the end of 2018, APEX was added as a
125                project in the ONAP Policy Framework, released later in
126                the ONAP Casablanca release.
127
128             .. container:: paragraph
129
130                The APEX source code is hosted in ONAP as project APEX.
131                The current stable version is in the master branch.
132                Simply clone the master branch from ONAP using HTTPS.
133
134             .. container:: listingblock
135
136                .. container:: content
137
138                   .. code::
139                      :number-lines:
140
141                      git clone https://gerrit.onap.org/r/policy/apex-pdp
142
143 Build APEX
144 ----------
145
146    .. container:: paragraph
147
148       The examples in this document assume that the APEX source
149       repositories are cloned to:
150
151    .. container:: ulist
152
153       -  Unix, Cygwin: ``/usr/local/src/apex-pdp``
154
155       -  Windows: ``C:\dev\apex-pdp``
156
157       -  Cygwin: ``/cygdrive/c/dev/apex-pdp``
158
159    .. important::
160       A Build requires ONAP Nexus
161       APEX has a dependency to ONAP parent projects. You might need to adjust your Maven M2 settings. The most current
162       settings can be found in the ONAP oparent repo: `Settings <https://git.onap.org/oparent/plain/settings.xml>`__.
163
164    .. important::
165       A Build needs Space
166       Building APEX requires approximately 2-3 GB of hard disc space, 1 GB for the actual build with full
167       distribution and 1-2 GB for the downloaded dependencies
168
169    .. important::
170       A Build requires Internet (for first build)
171       During the build, several (a lot) of Maven dependencies will be downloaded and stored in the configured local Maven
172       repository. The first standard build (and any first specific build) requires Internet access to download those
173       dependencies.
174
175    .. important::
176       Building RPM distributions
177       RPM images are only build if the ``rpm`` package is installed (Unix). To install  ``rpm`` run ``sudo apt-get install rpm``,
178       then build APEX.
179
180    .. container:: paragraph
181
182       Use Maven to for a standard build without any tests.
183
184       +-------------------------------------------------------+--------------------------------------------------------+
185       | Unix, Cygwin                                          | Windows                                                |
186       +=======================================================+========================================================+
187       | .. container::                                        | .. container::                                         |
188       |                                                       |                                                        |
189       |    .. container:: content                             |    .. container:: content                              |
190       |                                                       |                                                        |
191       |       .. code::                                       |       .. code::                                        |
192       |         :number-lines:                                |         :number-lines:                                 |
193       |                                                       |                                                        |
194       |         # cd /usr/local/src/apex-pdp                  |          >c:                                           |
195       |         # mvn clean install -DskipTest                |          >cd \dev\apex                                 |
196       |                                                       |          >mvn clean install -DskipTests                |
197       +-------------------------------------------------------+--------------------------------------------------------+
198
199 .. container:: paragraph
200
201    The build takes 2-3 minutes on a standard development laptop. It
202    should run through without errors, but with a lot of messages from
203    the build process.
204
205 .. container:: paragraph
206
207    When Maven is finished with the build, the final screen should look
208    similar to this (omitting some ``success`` lines):
209
210 .. container:: listingblock
211
212    .. container:: content
213
214       .. code::
215         :number-lines:
216
217         [INFO] tools .............................................. SUCCESS [  0.248 s]
218         [INFO] tools-common ....................................... SUCCESS [  0.784 s]
219         [INFO] simple-wsclient .................................... SUCCESS [  3.303 s]
220         [INFO] model-generator .................................... SUCCESS [  0.644 s]
221         [INFO] packages ........................................... SUCCESS [  0.336 s]
222         [INFO] apex-pdp-package-full .............................. SUCCESS [01:10 min]
223         [INFO] Policy APEX PDP - Docker build 2.0.0-SNAPSHOT ...... SUCCESS [ 10.307 s]
224         [INFO] ------------------------------------------------------------------------
225         [INFO] BUILD SUCCESS
226         [INFO] ------------------------------------------------------------------------
227         [INFO] Total time: 03:43 min
228         [INFO] Finished at: 2018-09-03T11:56:01+01:00
229         [INFO] ------------------------------------------------------------------------
230
231 .. container:: paragraph
232
233    The build will have created all artifacts required for an APEX
234    installation. The following example show how to change to the target
235    directory and how it should look like.
236
237 +----------------------------------------------------------------------------------------------------------------------------+
238 | Unix, Cygwin                                                                                                               |
239 +============================================================================================================================+
240 | .. container::                                                                                                             |
241 |                                                                                                                            |
242 |    .. container:: listingblock                                                                                             |
243 |                                                                                                                            |
244 |       .. container:: content                                                                                               |
245 |                                                                                                                            |
246 |          .. code::                                                                                                         |
247 |             :number-lines:                                                                                                 |
248 |                                                                                                                            |
249 |             -rwxrwx---+ 1 esvevan Domain Users       772 Sep  3 11:55 apex-pdp-package-full_2.0.0~SNAPSHOT_all.changes*    |
250 |             -rwxrwx---+ 1 esvevan Domain Users 146328082 Sep  3 11:55 apex-pdp-package-full-2.0.0-SNAPSHOT.deb*            |
251 |             -rwxrwx---+ 1 esvevan Domain Users     15633 Sep  3 11:54 apex-pdp-package-full-2.0.0-SNAPSHOT.jar*            |
252 |             -rwxrwx---+ 1 esvevan Domain Users 146296819 Sep  3 11:55 apex-pdp-package-full-2.0.0-SNAPSHOT-tarball.tar.gz* |
253 |             drwxrwx---+ 1 esvevan Domain Users         0 Sep  3 11:54 archive-tmp/                                         |
254 |             -rwxrwx---+ 1 esvevan Domain Users        89 Sep  3 11:54 checkstyle-cachefile*                                |
255 |             -rwxrwx---+ 1 esvevan Domain Users     10621 Sep  3 11:54 checkstyle-checker.xml*                              |
256 |             -rwxrwx---+ 1 esvevan Domain Users       584 Sep  3 11:54 checkstyle-header.txt*                               |
257 |             -rwxrwx---+ 1 esvevan Domain Users        86 Sep  3 11:54 checkstyle-result.xml*                               |
258 |             drwxrwx---+ 1 esvevan Domain Users         0 Sep  3 11:54 classes/                                             |
259 |             drwxrwx---+ 1 esvevan Domain Users         0 Sep  3 11:54 dependency-maven-plugin-markers/                     |
260 |             drwxrwx---+ 1 esvevan Domain Users         0 Sep  3 11:54 etc/                                                 |
261 |             drwxrwx---+ 1 esvevan Domain Users         0 Sep  3 11:54 examples/                                            |
262 |             drwxrwx---+ 1 esvevan Domain Users         0 Sep  3 11:55 install_hierarchy/                                   |
263 |             drwxrwx---+ 1 esvevan Domain Users         0 Sep  3 11:54 maven-archiver/                                      |
264 +----------------------------------------------------------------------------------------------------------------------------+
265
266 +--------------------------------------------------------------------------------------------------------+
267 | Windows                                                                                                |
268 +========================================================================================================+
269 | .. container::                                                                                         |
270 |                                                                                                        |
271 |    .. container:: listingblock                                                                         |
272 |                                                                                                        |
273 |       .. container:: content                                                                           |
274 |                                                                                                        |
275 |          .. code::                                                                                     |
276 |             :number-lines:                                                                             |
277 |                                                                                                        |
278 |                03/09/2018  11:55    <DIR>          .                                                   |
279 |                03/09/2018  11:55    <DIR>          ..                                                  |
280 |                03/09/2018  11:55       146,296,819 apex-pdp-package-full-2.0.0-SNAPSHOT-tarball.tar.gz |
281 |                03/09/2018  11:55       146,328,082 apex-pdp-package-full-2.0.0-SNAPSHOT.deb            |
282 |                03/09/2018  11:54            15,633 apex-pdp-package-full-2.0.0-SNAPSHOT.jar            |
283 |                03/09/2018  11:55               772 apex-pdp-package-full_2.0.0~SNAPSHOT_all.changes    |
284 |                03/09/2018  11:54    <DIR>          archive-tmp                                         |
285 |                03/09/2018  11:54                89 checkstyle-cachefile                                |
286 |                03/09/2018  11:54            10,621 checkstyle-checker.xml                              |
287 |                03/09/2018  11:54               584 checkstyle-header.txt                               |
288 |                03/09/2018  11:54                86 checkstyle-result.xml                               |
289 |                03/09/2018  11:54    <DIR>          classes                                             |
290 |                03/09/2018  11:54    <DIR>          dependency-maven-plugin-markers                     |
291 |                03/09/2018  11:54    <DIR>          etc                                                 |
292 |                03/09/2018  11:54    <DIR>          examples                                            |
293 |                03/09/2018  11:55    <DIR>          install_hierarchy                                   |
294 |                03/09/2018  11:54    <DIR>          maven-archiver                                      |
295 |                               8 File(s)    292,652,686 bytes                                           |
296 |                               9 Dir(s)  14,138,720,256 bytes free                                      |
297 +--------------------------------------------------------------------------------------------------------+
298
299 Install APEX
300 ------------
301
302    .. container:: paragraph
303
304       APEX can be installed in different ways:
305
306    .. container:: ulist
307
308       -  Unix: automatically using ``rpm`` or ``dpkg`` from ``.rpm`` or
309          ``.deb`` archive
310
311       -  Windows, Unix, Cygwin: manually from a ``.tar.gz`` archive
312
313       -  Windows, Unix, Cygwin: build from source using Maven, then
314          install manually
315
316 Install with RPM and DPKG
317 #########################
318
319       .. container:: paragraph
320
321          The install distributions of APEX automatically install the
322          system. The installation directory is
323          ``/opt/app/policy/apex-pdp``. Log files are located in
324          ``/var/log/onap/policy/apex-pdp``. The latest APEX version will
325          be available as ``/opt/app/policy/apex-pdp/apex-pdp``.
326
327       .. container:: paragraph
328
329          For the installation, a new user ``apexuser`` and a new group
330          ``apexuser`` will be created. This user owns the installation
331          directories and the log file location. The user is also used by
332          the standard APEX start scripts to run APEX with this user’s
333          permissions.
334
335          +-----------------------------------------------------------------------+
336          | RPM Installation                                                      |
337          +=======================================================================+
338          | .. container::                                                        |
339          |                                                                       |
340          |    .. container:: listingblock                                        |
341          |                                                                       |
342          |       .. container:: content                                          |
343          |                                                                       |
344          |          .. code::                                                    |
345          |             :number-lines:                                            |
346          |                                                                       |
347          |             # sudo rpm -i apex-pdp-package-full-2.0.0-SNAPSHOT.rpm    |
348          |             ********************preinst*******************            |
349          |             arguments 1                                               |
350          |             **********************************************            |
351          |             creating group apexuser . . .                             |
352          |             creating user apexuser . . .                              |
353          |             ********************postinst****************              |
354          |             arguments 1                                               |
355          |             ***********************************************           |
356          +-----------------------------------------------------------------------+
357
358 +--------------------------------------------------------------------------------------+
359 | DPKG Installation                                                                    |
360 +======================================================================================+
361 | .. container::                                                                       |
362 |                                                                                      |
363 |    .. container:: listingblock                                                       |
364 |                                                                                      |
365 |       .. container:: content                                                         |
366 |                                                                                      |
367 |          .. code::                                                                   |
368 |             :number-lines:                                                           |
369 |                                                                                      |
370 |             # sudo dpkg -i apex-pdp-package-full-2.0.0-SNAPSHOT.deb                  |       
371 |             Selecting previously unselected package apex-uservice.                   |
372 |             (Reading database ... 288458 files and directories currently installed.) |
373 |             Preparing to unpack apex-pdp-package-full-2.0.0-SNAPSHOT.deb ...         |
374 |             ********************preinst*******************                           |
375 |             arguments install                                                        |
376 |             **********************************************                           |
377 |             creating group apexuser . . .                                            |
378 |             creating user apexuser . . .                                             |
379 |             Unpacking apex-uservice (2.0.0-SNAPSHOT) ...                             |
380 |             Setting up apex-uservice (2.0.0-SNAPSHOT) ...                            |
381 |             ********************postinst****************                             |
382 |             arguments configure                                                      |
383 |             ***********************************************                          |
384 +--------------------------------------------------------------------------------------+
385
386 .. container:: paragraph
387
388    Once the installation is finished, APEX is fully installed and ready
389    to run.
390
391 Install Manually from Archive (Unix, Cygwin)
392 ############################################
393
394    .. container:: paragraph
395
396       Download a ``tar.gz`` archive. Create a directory where APEX
397       should be installed. Extract the ``tar`` archive. The following
398       example shows how to install APEX in ``/opt/apex`` and create a
399       link to ``/opt/apex/apex`` for the most recent installation.
400
401    .. container:: listingblock
402
403       .. container:: content
404
405          .. code::
406             :number-lines:
407
408             # cd /opt
409             # mkdir apex
410             # cd apex
411             # mkdir apex-full-2.0.0-SNAPSHOT
412             # tar xvfz ~/Downloads/apex-pdp-package-full-2.0.0-SNAPSHOT.tar.gz -C apex-full-2.0.0-SNAPSHOT
413             # ln -s apex apex-pdp-package-full-2.0.0-SNAPSHOT
414
415 Install Manually from Archive (Windows, 7Zip, GUI)
416 ##################################################
417
418    .. container:: paragraph
419
420       Download a ``tar.gz`` archive and copy the file into the install
421       folder (in this example ``C:\apex``). Assuming you are using 7Zip,
422       right click on the file and extract the ``tar`` archive. Note: the
423       screenshots might show an older version than you have.
424
425    .. container:: imageblock
426
427       .. container:: content
428
429          |Extract the TAR archive|
430
431    .. container:: paragraph
432
433       The right-click on the new created TAR file and extract the actual
434       APEX distribution.
435
436    .. container:: imageblock
437
438       .. container:: content
439
440          |Extract the APEX distribution|
441
442    .. container:: paragraph
443
444       Inside the new APEX folder you see the main directories: ``bin``,
445       ``etc``, ``examples``, ``lib``, and ``war``
446
447    .. container:: paragraph
448
449       Once extracted, please rename the created folder to
450       ``apex-full-2.0.0-SNAPSHOT``. This will keep the directory name in
451       line with the rest of this documentation.
452
453 Install Manually from Archive (Windows, 7Zip, CMD)
454 ##################################################
455
456    .. container:: paragraph
457
458       Download a ``tar.gz`` archive and copy the file into the install
459       folder (in this example ``C:\apex``). Start ``cmd``, for instance
460       typing ``Windows+R`` and then ``cmd`` in the dialog. Assuming
461       ``7Zip`` is installed in the standard folder, simply run the
462       following commands (for APEX version 2.0.0-SNAPSHOT full
463       distribution)
464
465    .. container:: listingblock
466
467       .. container:: content
468
469          .. code::
470            :number-lines:
471
472             >c:
473             >cd \apex
474             >"\Program Files\7-Zip\7z.exe" x apex-pdp-package-full-2.0.0-SNAPSHOT.tar.gz -so | "\Program Files\7-Zip\7z.exe" x -aoa -si -ttar -o"apex-full-2.0.0-SNAPSHOT"
475
476 .. container:: paragraph
477
478    APEX is now installed in the folder
479    ``C:\apex\apex-full-2.0.0-SNAPSHOT``.
480
481 Build from Source
482 -----------------
483
484 Build and Install Manually (Unix, Windows, Cygwin)
485 ##################################################
486
487       .. container:: paragraph
488
489          Clone the APEX GIT repositories into a directory. Go to that
490          directory. Use Maven to build APEX (all details on building
491          APEX from source can be found in *APEX HowTo: Build*). Install
492          from the created artifacts (``rpm``, ``deb``, ``tar.gz``, or
493          copying manually).
494
495       .. important::
496          Building RPM distributions
497          RPM images are only build if the ``rpm`` package is installed (Unix). To install ``rpm`` run
498          ``sudo apt-get install rpm``, then build APEX.
499
500       .. container:: paragraph
501
502          The following example shows how to build the APEX system,
503          without tests (``-DskipTests``) to safe some time. It assumes
504          that the APX GIT repositories are cloned to:
505
506       .. container:: ulist
507
508          -  Unix, Cygwin: ``/usr/local/src/apex``
509
510          -  Windows: ``C:\dev\apex``
511
512          +-------------------------------------------------------+--------------------------------------------------------+
513          | Unix, Cygwin                                          | Windows                                                |
514          +=======================================================+========================================================+
515          | .. container::                                        | .. container::                                         |
516          |                                                       |                                                        |
517          |    .. container:: content                             |    .. container:: content                              |
518          |                                                       |                                                        |
519          |       .. code::                                       |       .. code::                                        |
520          |         :number-lines:                                |         :number-lines:                                 |
521          |                                                       |                                                        |
522          |         # cd /usr/local/src/apex                      |         >c:                                            |
523          |         # mvn clean install -DskipTests               |         >cd \dev\apex                                  |
524          |                                                       |         >mvn clean install -DskipTests                 |
525          +-------------------------------------------------------+--------------------------------------------------------+
526
527 .. container:: paragraph
528
529    The build takes about 2 minutes without test and about 4-5 minutes
530    with tests on a standard development laptop. It should run through
531    without errors, but with a lot of messages from the build process. If
532    build with tests (i.e. without ``-DskipTests``), there will be error
533    messages and stack trace prints from some tests. This is normal, as
534    long as the build finishes successful.
535
536 .. container:: paragraph
537
538    When Maven is finished with the build, the final screen should look
539    similar to this (omitting some ``success`` lines):
540
541 .. container:: listingblock
542
543    .. container:: content
544
545       .. code::
546          :number-lines:
547
548          [INFO] tools .............................................. SUCCESS [  0.248 s]
549          [INFO] tools-common ....................................... SUCCESS [  0.784 s]
550          [INFO] simple-wsclient .................................... SUCCESS [  3.303 s]
551          [INFO] model-generator .................................... SUCCESS [  0.644 s]
552          [INFO] packages ........................................... SUCCESS [  0.336 s]
553          [INFO] apex-pdp-package-full .............................. SUCCESS [01:10 min]
554          [INFO] Policy APEX PDP - Docker build 2.0.0-SNAPSHOT ...... SUCCESS [ 10.307 s]
555          [INFO] ------------------------------------------------------------------------
556          [INFO] BUILD SUCCESS
557          [INFO] ------------------------------------------------------------------------
558          [INFO] Total time: 03:43 min
559          [INFO] Finished at: 2018-09-03T11:56:01+01:00
560          [INFO] ------------------------------------------------------------------------
561
562 .. container:: paragraph
563
564    The build will have created all artifacts required for an APEX
565    installation. The following example show how to change to the target
566    directory and how it should look like.
567
568 +-----------------------------------------------------------------------------------------------------------------------------+
569 | Unix, Cygwin                                                                                                                |
570 +=============================================================================================================================+
571 | .. container::                                                                                                              |
572 |                                                                                                                             |
573 |    .. container:: listingblock                                                                                              |
574 |                                                                                                                             |
575 |          .. code::                                                                                                          |
576 |            :number-lines:                                                                                                   |
577 |                                                                                                                             |
578 |            # cd packages/apex-pdp-package-full/target                                                                       |
579 |            # ls -l                                                                                                          |
580 |            -rwxrwx---+ 1 esvevan Domain Users       772 Sep  3 11:55 apex-pdp-package-full_2.0.0~SNAPSHOT_all.changes*      |
581 |            -rwxrwx---+ 1 esvevan Domain Users 146328082 Sep  3 11:55 apex-pdp-package-full-2.0.0-SNAPSHOT.deb*              |
582 |            -rwxrwx---+ 1 esvevan Domain Users     15633 Sep  3 11:54 apex-pdp-package-full-2.0.0-SNAPSHOT.jar*              |
583 |            -rwxrwx---+ 1 esvevan Domain Users 146296819 Sep  3 11:55 apex-pdp-package-full-2.0.0-SNAPSHOT-tarball.tar.gz*   |
584 |            drwxrwx---+ 1 esvevan Domain Users         0 Sep  3 11:54 archive-tmp/                                           |
585 |            -rwxrwx---+ 1 esvevan Domain Users        89 Sep  3 11:54 checkstyle-cachefile*                                  |
586 |            -rwxrwx---+ 1 esvevan Domain Users     10621 Sep  3 11:54 checkstyle-checker.xml*                                |
587 |            -rwxrwx---+ 1 esvevan Domain Users       584 Sep  3 11:54 checkstyle-header.txt*                                 |
588 |            -rwxrwx---+ 1 esvevan Domain Users        86 Sep  3 11:54 checkstyle-result.xml*                                 |
589 |            drwxrwx---+ 1 esvevan Domain Users         0 Sep  3 11:54 classes/                                               |
590 |            drwxrwx---+ 1 esvevan Domain Users         0 Sep  3 11:54 dependency-maven-plugin-markers/                       |
591 |            drwxrwx---+ 1 esvevan Domain Users         0 Sep  3 11:54 etc/                                                   |
592 |            drwxrwx---+ 1 esvevan Domain Users         0 Sep  3 11:54 examples/                                              |
593 |            drwxrwx---+ 1 esvevan Domain Users         0 Sep  3 11:55 install_hierarchy/                                     |
594 |            drwxrwx---+ 1 esvevan Domain Users         0 Sep  3 11:54 maven-archiver/                                        |
595 +-----------------------------------------------------------------------------------------------------------------------------+
596
597 +-----------------------------------------------------------------------------------------------------------------------------+
598 | Windows                                                                                                                     |
599 +=============================================================================================================================+
600 | .. container::                                                                                                              |
601 |                                                                                                                             |
602 |    .. container:: listingblock                                                                                              |
603 |                                                                                                                             |
604 |          .. code::                                                                                                          |
605 |            :number-lines:                                                                                                   |
606 |                                                                                                                             |
607 |            >cd packages\apex-pdp-package-full\target                                                                        |
608 |            >dir                                                                                                             |
609 |            03/09/2018  11:55    <DIR>          .                                                                            |
610 |            03/09/2018  11:55    <DIR>          ..                                                                           |
611 |            03/09/2018  11:55       146,296,819 apex-pdp-package-full-2.0.0-SNAPSHOT-tarball.tar.gz                          |
612 |            03/09/2018  11:55       146,328,082 apex-pdp-package-full-2.0.0-SNAPSHOT.deb                                     |
613 |            03/09/2018  11:54            15,633 apex-pdp-package-full-2.0.0-SNAPSHOT.jar                                     |
614 |            03/09/2018  11:55               772 apex-pdp-package-full_2.0.0~SNAPSHOT_all.changes                             |
615 |            03/09/2018  11:54    <DIR>          archive-tmp                                                                  |
616 |            03/09/2018  11:54                89 checkstyle-cachefile                                                         |
617 |            03/09/2018  11:54            10,621 checkstyle-checker.xml                                                       |
618 |            03/09/2018  11:54               584 checkstyle-header.txt                                                        |
619 |            03/09/2018  11:54                86 checkstyle-result.xml                                                        |
620 |            03/09/2018  11:54    <DIR>          classes                                                                      |
621 |            03/09/2018  11:54    <DIR>          dependency-maven-plugin-markers                                              |
622 |            03/09/2018  11:54    <DIR>          etc                                                                          |
623 |            03/09/2018  11:54    <DIR>          examples                                                                     |
624 |            03/09/2018  11:55    <DIR>          install_hierarchy                                                            |
625 |            03/09/2018  11:54    <DIR>          maven-archiver                                                               |
626 |                           8 File(s)    292,652,686 bytes                                                                    |
627 |                           9 Dir(s)  14,138,720,256 bytes free                                                               |
628 +-----------------------------------------------------------------------------------------------------------------------------+
629
630 .. container:: paragraph
631
632    Now, take the ``.deb`` or the ``.tar.gz`` file and install APEX.
633    Alternatively, copy the content of the folder ``install_hierarchy``
634    to your APEX directory.
635
636 Installation Layout
637 -------------------
638
639    .. container:: paragraph
640
641       A full installation of APEX comes with the following layout.
642
643    .. container:: listingblock
644
645       .. container:: content
646
647          ::
648
649             $APEX_HOME
650                 ├───bin             (1)
651                 ├───etc             (2)
652                 │   ├───editor
653                 │   ├───hazelcast
654                 │   ├───infinispan
655                 │   └───META-INF
656                 ├───examples            (3)
657                 │   ├───config          (4)
658                 │   ├───docker          (5)
659                 │   ├───events          (6)
660                 │   ├───html            (7)
661                 │   ├───models          (8)
662                 │   └───scripts         (9)
663                 ├───lib             (10)
664                 │   └───applications        (11)
665                 └───war             (12)
666
667    .. container:: colist arabic
668
669       +-----------------------------------+-----------------------------------+
670       | **1**                             | binaries, mainly scripts (bash    |
671       |                                   | and bat) to start the APEX engine |
672       |                                   | and applications                  |
673       +-----------------------------------+-----------------------------------+
674       | **2**                             | configuration files, such as      |
675       |                                   | logback (logging) and third party |
676       |                                   | library configurations            |
677       +-----------------------------------+-----------------------------------+
678       | **3**                             | example policy models to get      |
679       |                                   | started                           |
680       +-----------------------------------+-----------------------------------+
681       | **4**                             | configurations for the examples   |
682       |                                   | (with sub directories for         |
683       |                                   | individual examples)              |
684       +-----------------------------------+-----------------------------------+
685       | **5**                             | Docker files and additional       |
686       |                                   | Docker instructions for the       |
687       |                                   | exampples                         |
688       +-----------------------------------+-----------------------------------+
689       | **6**                             | example events for the examples   |
690       |                                   | (with sub directories for         |
691       |                                   | individual examples)              |
692       +-----------------------------------+-----------------------------------+
693       | **7**                             | HTML files for some examples,     |
694       |                                   | e.g. the Decisionmaker example    |
695       +-----------------------------------+-----------------------------------+
696       | **8**                             | the policy models, generated for  |
697       |                                   | each example (with sub            |
698       |                                   | directories for individual        |
699       |                                   | examples)                         |
700       +-----------------------------------+-----------------------------------+
701       | **9**                             | additional scripts for the        |
702       |                                   | examples (with sub directories    |
703       |                                   | for individual examples)          |
704       +-----------------------------------+-----------------------------------+
705       | **10**                            | the library folder with all Java  |
706       |                                   | JAR files                         |
707       +-----------------------------------+-----------------------------------+
708       | **11**                            | applications, also known as jar   |
709       |                                   | with dependencies (or fat jars),  |
710       |                                   | individually deployable           |
711       +-----------------------------------+-----------------------------------+
712       | **12**                            | WAR files for web applications    |
713       +-----------------------------------+-----------------------------------+
714
715 System Configuration
716 --------------------
717
718    .. container:: paragraph
719
720       Once APEX is installed, a few configurations need to be done:
721
722    .. container:: ulist
723
724       -  Create an APEX user and an APEX group (optional, if not
725          installed using RPM and DPKG)
726
727       -  Create environment settings for ``APEX_HOME`` and
728          ``APEX_USER``, required by the start scripts
729
730       -  Change settings of the logging framework (optional)
731
732       -  Create directories for logging, required (execution might fail
733          if directories do not exist or cannot be created)
734
735 APEX User and Group
736 ###################
737
738       .. container:: paragraph
739
740          On smaller installations and test systems, APEX can run as any
741          user or group.
742
743       .. container:: paragraph
744
745          However, if APEX is installed in production, we strongly
746          recommend you set up a dedicated user for running APEX. This
747          will isolate the execution of APEX to that user. We recommend
748          you use the userid ``apexuser`` but you may use any user you
749          choose.
750
751       .. container:: paragraph
752
753          The following example, for UNIX, creates a group called
754          ``apexuser``, an APEX user called ``apexuser``, adds the group
755          to the user, and changes ownership of the APEX installation to
756          the user. Substitute ``<apex-dir>`` with the directory where
757          APEX is installed.
758
759          .. container:: listingblock
760
761             .. container:: content
762
763                .. code::
764                   :number-lines:
765
766                   # sudo groupadd apexuser
767                   # sudo useradd -g apexuser apexuser
768                   # sudo chown -R apexuser:apexuser <apex-dir>
769
770 .. container:: paragraph
771
772    For other operating systems please consult your manual or system
773    administrator.
774
775 Environment Settings: APEX_HOME and APEX_USER
776 #############################################
777
778    .. container:: paragraph
779
780       The provided start scripts for APEX require two environment
781       variables being set:
782
783    .. container:: ulist
784
785       -  ``APEX_USER`` with the user under whos name and permission APEX
786          should be started (Unix only)
787
788       -  ``APEX_HOME`` with the directory where APEX is installed (Unix,
789          Windows, Cygwin)
790
791    .. container:: paragraph
792
793       The first row in the following table shows how to set these
794       environment variables temporary (assuming the user is
795       ``apexuser``). The second row shows how to verify the settings.
796       The last row explains how to set those variables permanently.
797
798    +------------------------------------------------+---------------------------------------------------------+
799    | Unix, Cygwin (bash/tcsh)                       | Windows                                                 |
800    +================================================+=========================================================+
801    | .. container::                                 | .. container::                                          |
802    |                                                |                                                         |
803    |    .. container:: content                      |    .. container:: content                               |
804    |                                                |                                                         |
805    |       .. code::                                |       .. code::                                         |
806    |          :number-lines:                        |         :number-lines:                                  |
807    |                                                |                                                         |
808    |          # export APEX_USER=apexuser           |         >set APEX_HOME=C:\apex\apex-full-2.0.0-SNAPSHOT |
809    |          # cd /opt/app/policy/apex-pdp         |                                                         |
810    |          # export APEX_HOME=`pwd`              |                                                         |
811    |                                                |                                                         |
812    +------------------------------------------------+                                                         |
813    | .. container::                                 |                                                         |
814    |                                                |                                                         |
815    |    .. container:: content                      |                                                         |
816    |                                                |                                                         |
817    |       .. code::tcsh                            |                                                         |
818    |          :number-lines:                        |                                                         |
819    |                                                |                                                         |
820    |          # setenv APEX_USER apexuser           |                                                         |
821    |          # cd /opt/app/policy/apex-pdp         |                                                         |
822    |          # setenv APEX_HOME `pwd`              |                                                         |
823    |                                                |                                                         |
824    +------------------------------------------------+---------------------------------------------------------+
825    | .. container::                                 | .. container::                                          |
826    |                                                |                                                         |
827    |    .. container:: content                      |    .. container:: content                               |
828    |                                                |                                                         |
829    |       .. code::                                |       .. code::                                         |
830    |          :number-lines:                        |          :number-lines:                                 |
831    |                                                |                                                         |
832    |          # env | grep APEX                     |          >set APEX_HOME                                 |
833    |          # APEX_USER=apexuser                  |          APEX_HOME=\apex\apex-full-2.0.0-SNAPSHOT       |
834    |          # APEX_HOME=/opt/app/policy/apex-pdp  |                                                         |
835    |                                                |                                                         |
836    +------------------------------------------------+---------------------------------------------------------+
837
838 Making Environment Settings Permanent (Unix, Cygwin)
839 ====================================================
840
841    .. container:: paragraph
842
843       For a per-user setting, edit the a user’s ``bash`` or ``tcsh``
844       settings in ``~/.bashrc`` or ``~/.tcshrc``. For system-wide
845       settings, edit ``/etc/profiles`` (requires permissions).
846
847 Making Environment Settings Permanent (Windows)
848 ===============================================
849
850    .. container:: paragraph
851
852       On Windows 7 do
853
854    .. container:: ulist
855
856       -  Click on the **Start** Menu
857
858       -  Right click on **Computer**
859
860       -  Select **Properties**
861
862    .. container:: paragraph
863
864       On Windows 8/10 do
865
866    .. container:: ulist
867
868       -  Click on the **Start** Menu
869
870       -  Select **System**
871
872    .. container:: paragraph
873
874       Then do the following
875
876    .. container:: ulist
877
878       -  Select **Advanced System Settings**
879
880       -  On the **Advanced** tab, click the **Environment Variables**
881          button
882
883       -  Edit an existing variable, or create a new System variable:
884          'Variable name'="APEX_HOME", 'Variable
885          value'="C:\apex\apex-full-2.0.0-SNAPSHOT"
886
887    .. container:: paragraph
888
889       For the settings to take effect, an application needs to be
890       restarted (e.g. any open ``cmd`` window).
891
892 Edit the APEX Logging Settings
893 ##############################
894
895    .. container:: paragraph
896
897       Configure the APEX logging settings to your requirements, for
898       instance:
899
900    .. container:: ulist
901
902       -  change the directory where logs are written to, or
903
904       -  change the log levels
905
906    .. container:: paragraph
907
908       Edit the file ``$APEX_HOME/etc/logback.xml`` for any required
909       changes. To change the log directory change the line
910
911    .. container:: paragraph
912
913       ``<property name="VAR_LOG" value="/var/log/onap/policy/apex-pdp/" />``
914
915    .. container:: paragraph
916
917       to
918
919    .. container:: paragraph
920
921       ``<property name="VAR_LOG" value="/PATH/TO/LOG/DIRECTORY/" />``
922
923    .. container:: paragraph
924
925       On Windows, it is recommended to change the log directory to:
926
927    .. container:: paragraph
928
929       ``<property name="VAR_LOG" value="C:/apex/apex-full-2.0.0-SNAPSHOT/logs" />``
930
931    .. container:: paragraph
932
933       Note: Be careful about when to use ``\`` vs. ``/`` as the path
934       separator!
935
936 Create Directories for Logging
937 ##############################
938
939    .. container:: paragraph
940
941       Make sure that the log directory exists. This is important when
942       APEX was installed manually or when the log directory was changed
943       in the settings (see above).
944
945    +------------------------------------------------------------------+-------------------------------------------------------+
946    | Unix, Cygwin                                                     | Windows                                               |
947    +==================================================================+=======================================================+
948    | .. container::                                                   | .. container::                                        |
949    |                                                                  |                                                       |
950    |    .. container:: content                                        |    .. container:: content                             |
951    |                                                                  |                                                       |
952    |       .. code::                                                  |       .. code::                                       |
953    |         :number-lines:                                           |         :number-lines:                                |
954    |                                                                  |                                                       |
955    |         mkdir -p /var/log/onap/policy/apex-pdp                   |         >mkdir C:\apex\apex-full-2.0.0-SNAPSHOT\logs  |
956    |         chown -R apexuser:apexuser /var/log/onap/policy/apex-pdp |                                                       |
957    +------------------------------------------------------------------+-------------------------------------------------------+
958
959 Verify the APEX Installation
960 ----------------------------
961
962    .. container:: paragraph
963
964       When APEX is installed and all settings are realized, the
965       installation can be verified.
966
967 Verify Installation - run Engine
968 ################################
969
970       .. container:: paragraph
971
972          A simple verification of an APEX installation can be done by
973          simply starting the APEX engine without any configuration. On
974          Unix (or Cygwin) start the engine using
975          ``$APEX_HOME/bin/apexEngine.sh``. On Windows start the engine
976          using ``%APEX_HOME%\bin\apexEngine.bat``. The engine will fail
977          to fully start. However, if the output looks similar to the
978          following line, the APEX installation is realized.
979
980       .. container:: listingblock
981
982          .. container:: content
983
984             .. code::
985                :number-lines:
986
987                Starting Apex service with parameters [] . . .
988                start of Apex service failed: Apex configuration file was not specified as an argument
989                2018-09-03 13:11:33,914 Apex [main] ERROR o.o.p.a.service.engine.main.ApexMain - start of Apex service failed
990                org.onap.policy.apex.model.basicmodel.concepts.ApexException: Apex configuration file was not specified as an argument
991                        at org.onap.policy.apex.service.engine.main.ApexCommandLineArguments.validateReadableFile(ApexCommandLineArguments.java:267)
992                        at org.onap.policy.apex.service.engine.main.ApexCommandLineArguments.validate(ApexCommandLineArguments.java:161)
993                        at org.onap.policy.apex.service.engine.main.ApexMain.<init>(ApexMain.java:68)
994                        at org.onap.policy.apex.service.engine.main.ApexMain.main(ApexMain.java:165)
995                usage: org.onap.policy.apex.service.engine.main.ApexMain [options...]
996                options
997                -c,--config-file <CONFIG_FILE>the full path to the configuration file to use, the configuration file must be a Json file
998                                              containing the Apex configuration parameters
999                -h,--help                     outputs the usage of this command
1000                -m,--model-file <MODEL_FILE>  the full path to the model file to use, if set it overrides the model file set in the
1001                                              configuration file
1002                -v,--version                  outputs the version of Apex
1003
1004 Verify Installation - run an Example
1005 ####################################
1006
1007    .. container:: paragraph
1008
1009       A full APEX installation comes with several examples. Here, we can
1010       fully verify the installation by running one of the examples.
1011
1012    .. container:: paragraph
1013
1014       We use the example called *SampleDomain* and configure the engine
1015       to use standard in and standard out for events. Run the engine
1016       with the provided configuration. Note: Cygwin executes scripts as
1017       Unix scripts but runs Java as a Windows application, thus the
1018       configuration file must be given as a Windows path.
1019
1020    .. container:: listingblock
1021
1022       .. container:: content
1023
1024          .. code::
1025                 :number-lines:
1026
1027              # $APEX_HOME/bin/apexEngine.sh -c $APEX_HOME/examples/config/SampleDomain/Stdin2StdoutJsonEventJava.json (1)
1028              # $APEX_HOME/bin/apexEngine.sh -c C:/apex/apex-full-2.0.0-SNAPSHOT/examples/config/SampleDomain/Stdin2StdoutJsonEventJava.json (2)
1029              >%APEX_HOME%\bin\apexEngine.bat -c %APEX_HOME%\examples\config\SampleDomain\Stdin2StdoutJsonEventJava.json :: (3)
1030
1031 .. container:: colist arabic
1032
1033    +-------+---------+
1034    | **1** | UNIX    |
1035    +-------+---------+
1036    | **2** | Cygwin  |
1037    +-------+---------+
1038    | **3** | Windows |
1039    +-------+---------+
1040
1041 .. container:: paragraph
1042
1043    The engine should start successfully. Assuming the logging levels are
1044    not change (default level is ``info``), the output should look
1045    similar to this (last few lines)
1046
1047 .. container:: listingblock
1048
1049    .. container:: content
1050
1051       .. code::
1052          :number-lines:
1053
1054          Starting Apex service with parameters [-c, v:/dev/ericsson/apex/onap/apex-pdp/packages/apex-pdp-package-full/target/install_hierarchy/examples/config/SampleDomain/Stdin2StdoutJsonEventJava.json] . . .
1055          2018-09-05 15:16:42,800 Apex [main] INFO o.o.p.a.s.e.r.impl.EngineServiceImpl - Created apex engine MyApexEngine-0:0.0.1 .
1056          2018-09-05 15:16:42,804 Apex [main] INFO o.o.p.a.s.e.r.impl.EngineServiceImpl - Created apex engine MyApexEngine-1:0.0.1 .
1057          2018-09-05 15:16:42,804 Apex [main] INFO o.o.p.a.s.e.r.impl.EngineServiceImpl - Created apex engine MyApexEngine-2:0.0.1 .
1058          2018-09-05 15:16:42,805 Apex [main] INFO o.o.p.a.s.e.r.impl.EngineServiceImpl - Created apex engine MyApexEngine-3:0.0.1 .
1059          2018-09-05 15:16:42,805 Apex [main] INFO o.o.p.a.s.e.r.impl.EngineServiceImpl - APEX service created.
1060          2018-09-05 15:16:43,962 Apex [main] INFO o.o.p.a.s.e.e.EngDepMessagingService - engine<-->deployment messaging starting . . .
1061          2018-09-05 15:16:43,963 Apex [main] INFO o.o.p.a.s.e.e.EngDepMessagingService - engine<-->deployment messaging started
1062          2018-09-05 15:16:44,987 Apex [main] INFO o.o.p.a.s.e.r.impl.EngineServiceImpl - Registering apex model on engine MyApexEngine-0:0.0.1
1063          2018-09-05 15:16:45,112 Apex [main] INFO o.o.p.a.s.e.r.impl.EngineServiceImpl - Registering apex model on engine MyApexEngine-1:0.0.1
1064          2018-09-05 15:16:45,113 Apex [main] INFO o.o.p.a.s.e.r.impl.EngineServiceImpl - Registering apex model on engine MyApexEngine-2:0.0.1
1065          2018-09-05 15:16:45,113 Apex [main] INFO o.o.p.a.s.e.r.impl.EngineServiceImpl - Registering apex model on engine MyApexEngine-3:0.0.1
1066          2018-09-05 15:16:45,120 Apex [main] INFO o.o.p.a.s.e.r.impl.EngineServiceImpl - Added the action listener to the engine
1067          Started Apex service
1068
1069 .. container:: paragraph
1070
1071    Important are the last two line, stating that APEX has added the
1072    final action listener to the engine and that the engine is started.
1073
1074 .. container:: paragraph
1075
1076    The engine is configured to read events from standard input and write
1077    produced events to standard output. The policy model is a very simple
1078    policy.
1079
1080 .. container:: paragraph
1081
1082    The following table shows an input event in the left column and an
1083    output event in the right column. Past the input event into the
1084    console where APEX is running, and the output event should appear in
1085    the console. Pasting the input event multiple times will produce
1086    output events with different values.
1087
1088 +-------------------------------------------------------------+-------------------------------------------------------------+
1089 | Input Event                                                 | Example Output Event                                        |
1090 +=============================================================+=============================================================+
1091 | .. container::                                              | .. container::                                              |
1092 |                                                             |                                                             |
1093 |    .. container:: content                                   |    .. container:: content                                   |
1094 |                                                             |                                                             |
1095 |       .. code::                                             |       .. code::                                             |
1096 |         :number-lines:                                      |         :number-lines:                                      |
1097 |                                                             |                                                             |
1098 |         {                                                   |         {                                                   |
1099 |          "nameSpace": "org.onap.policy.apex.sample.events", |          "name": "Event0004",                               |
1100 |          "name": "Event0000",                               |          "version": "0.0.1",                                |
1101 |          "version": "0.0.1",                                |          "nameSpace": "org.onap.policy.apex.sample.events", |
1102 |          "source": "test",                                  |          "source": "Act",                                   |
1103 |          "target": "apex",                                  |          "target": "Outside",                               |
1104 |          "TestSlogan": "Test slogan for External Event0",   |          "TestActCaseSelected": 2,                          |
1105 |          "TestMatchCase": 0,                                |          "TestActStateTime": 1536157104627,                 |
1106 |          "TestTimestamp": 1469781869269,                    |          "TestDecideCaseSelected": 0,                       |
1107 |          "TestTemperature": 9080.866                        |          "TestDecideStateTime": 1536157104625,              |
1108 |         }                                                   |          "TestEstablishCaseSelected": 0,                    |
1109 |                                                             |          "TestEstablishStateTime": 1536157104623,           |
1110 |                                                             |          "TestMatchCase": 0,                                |
1111 |                                                             |          "TestMatchCaseSelected": 1,                        |
1112 |                                                             |          "TestMatchStateTime": 1536157104620,               |
1113 |                                                             |          "TestSlogan": "Test slogan for External Event0",   |
1114 |                                                             |          "TestTemperature": 9080.866,                       |
1115 |                                                             |          "TestTimestamp": 1469781869269                     |
1116 |                                                             |          }                                                  |
1117 +-------------------------------------------------------------+-------------------------------------------------------------+
1118
1119 .. container:: paragraph
1120
1121    Terminate APEX by simply using ``CTRL+C`` in the console.
1122
1123 Verify a Full Installation - REST Editor
1124 ########################################
1125
1126    .. container:: paragraph
1127
1128       APEX has a REST application for viewing policy models. The
1129       application can also be used to create new policy models close to
1130       the engine native policy language. Start the REST editor as
1131       follows.
1132
1133    .. container:: listingblock
1134
1135       .. container:: content
1136
1137          .. code::
1138             :number-lines:
1139
1140             # $APEX_HOME/bin/apexApps.sh rest-editor
1141
1142 .. container:: listingblock
1143
1144    .. container:: content
1145
1146       .. code::
1147             :number-lines:
1148
1149             >%APEX_HOME%\bin\apexApps.bat rest-editor
1150
1151 .. container:: paragraph
1152
1153    The script will start a simple web server
1154    (`Grizzly <https://javaee.github.io/grizzly/>`__) and deploy a
1155    ``war`` web archive in it. Once the editor is started, it will be
1156    available on ``localhost:18989``. The last few line of the messages
1157    should be:
1158
1159 .. container:: listingblock
1160
1161    .. container:: content
1162
1163       .. code::
1164          :number-lines:
1165
1166          Apex Editor REST endpoint (ApexEditorMain: Config=[ApexEditorParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=READY) starting at http://localhost:18989/apexservices/ . . .
1167          Sep 05, 2018 10:35:57 PM org.glassfish.grizzly.http.server.NetworkListener start
1168          INFO: Started listener bound to [localhost:18989]
1169          Sep 05, 2018 10:35:57 PM org.glassfish.grizzly.http.server.HttpServer start
1170          INFO: [HttpServer] Started.
1171          Apex Editor REST endpoint (ApexEditorMain: Config=[ApexEditorParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=RUNNING) started at http://localhost:18989/apexservices/
1172
1173 .. container:: paragraph
1174
1175    Now open a browser (Firefox, Chrome, Opera, Internet Explorer) and
1176    use the URL ``http://localhost:18989/``. This will connect the
1177    browser to the started REST editor. The start screen should be as
1178    follows.
1179
1180 .. container:: imageblock
1181
1182    .. container:: content
1183
1184       |REST Editor Start Screen|
1185
1186    .. container:: title
1187
1188       Figure 1. REST Editor Start Screen
1189
1190 .. container:: paragraph
1191
1192    Now load a policy model by clicking the menu ``File`` and then
1193    ``Open``. In the opened dialog, go to the directory where APEX is
1194    installed, then ``examples``, ``models``, ``SampleDomain``, and there
1195    select the file ``SamplePolicyModelJAVA.json``. This will load the
1196    policy model used to verify the policy engine (see above). Once
1197    loaded, the screen should look as follows.
1198
1199 .. container:: imageblock
1200
1201    .. container:: content
1202
1203       |REST Editor with loaded SampleDomain Policy Model|
1204
1205    .. container:: title
1206
1207       Figure 2. REST Editor with loaded SampleDomain Policy Model
1208
1209 .. container:: paragraph
1210
1211    Now you can use the REST editor. To finish this verification, simply
1212    terminate your browser (or the tab), and then use ``CTRL+C`` in the
1213    console where you started the REST editor.
1214
1215 Installing WAR Applications
1216 ---------------------------
1217
1218    .. container:: paragraph
1219
1220       APEX comes with a set of WAR files. These are complete
1221       applications that can be installed and run in an application
1222       server. All of these applications are realized as servlets. You
1223       can find the WAR applications in ``$APEX_HOME/war`` (UNIX, Cygwin)
1224       or ``%APEX_HOME%\war`` (Windows).
1225
1226    .. container:: paragraph
1227
1228       Installing and using the WAR applications requires a web server
1229       that can execute ``war`` web archives. We recommend to use `Apache
1230       Tomcat <https://tomcat.apache.org/>`__, however other web servers
1231       can be used as well.
1232
1233    .. container:: paragraph
1234
1235       Install Apache Tomcat including the ``Manager App``, see `V9.0
1236       Docs <https://tomcat.apache.org/tomcat-9.0-doc/manager-howto.html#Configuring_Manager_Application_Access>`__
1237       for details. Start the Tomcat service, or make sure that Tomcat is
1238       running.
1239
1240    .. container:: paragraph
1241
1242       There are multiple ways to install the APEX WAR applications:
1243
1244    .. container:: ulist
1245
1246       -  copy the ``.war`` file into the Tomcat ``webapps`` folder
1247
1248       -  use the Tomcat ``Manager App`` to deploy via the web interface
1249
1250       -  deploy using a REST call to Tomcat
1251
1252    .. container:: paragraph
1253
1254       For details on how to install ``war`` files please consult the
1255       `Tomcat
1256       Documentation <https://tomcat.apache.org/tomcat-9.0-doc/index.html>`__
1257       or the `Manager App
1258       HOW-TO <https://tomcat.apache.org/tomcat-9.0-doc/manager-howto.html>`__.
1259       Once you installed an APEX WAR application (and wait for
1260       sufficient time for Tomcat to finalize the installation), open the
1261       ``Manager App`` in Tomcat. You should see the APEX WAR application
1262       being installed and running.
1263
1264    .. container:: paragraph
1265
1266       In case of errors, examine the log files in the Tomcat log
1267       directory. In a conventional install, those log files are in the
1268       logs directory where Tomcat is installed.
1269
1270    .. container:: paragraph
1271
1272       The current APEX version provides the following WAR applications:
1273
1274    .. container:: ulist
1275
1276       -  client-deployment-2.0.0-SNAPSHOT.war - a client to deploy new
1277          policy models to a running engine
1278
1279       -  client-editor-2.0.0-SNAPSHOT.war - the standard policy REST
1280          editor GUI
1281
1282       -  client-monitoring-2.0.0-SNAPSHOT.war - a client for monitoring
1283          a running APEX engine
1284
1285       -  client-full-2.0.0-SNAPSHOT.war - a full client with a
1286          one-stop-access to deployment, monitoring, and REST editor
1287
1288       -  examples-servlet-2.0.0-SNAPSHOT.war - an example APEX servlet
1289
1290 Running APEX in Docker
1291 ----------------------
1292
1293    .. container:: paragraph
1294
1295       Since APEX is in ONAP, we provide a full virtualization
1296       environment for the engine.
1297
1298 Run in ONAP
1299 ###########
1300
1301       .. container:: paragraph
1302
1303          Running APEX from the ONAP docker repository only requires 2
1304          commands:
1305
1306       .. container:: olist arabic
1307
1308          #. Log into the ONAP docker repo
1309
1310       .. container:: listingblock
1311
1312          .. container:: content
1313
1314             ::
1315
1316                docker login -u docker -p docker nexus3.onap.org:10003
1317
1318       .. container:: olist arabic
1319
1320          #. Run the APEX docker image
1321
1322       .. container:: listingblock
1323
1324          .. container:: content
1325
1326             ::
1327
1328                docker run -it --rm  nexus3.onap.org:10003/onap/policy-apex-pdp:latest
1329
1330 Build a Docker Image
1331 ####################
1332
1333       .. container:: paragraph
1334
1335          Alternatively, one can use the Dockerfile defined in the Docker
1336          package to build an image.
1337
1338       .. container:: listingblock
1339
1340          .. container:: title
1341
1342             APEX Dockerfile
1343
1344          .. container:: content
1345
1346             .. code::
1347                :number-lines:
1348
1349                #
1350                # Docker file to build an image that runs APEX on Java 8 in Ubuntu
1351                #
1352                FROM ubuntu:16.04
1353
1354                RUN apt-get update && \
1355                        apt-get upgrade -y && \
1356                        apt-get install -y software-properties-common && \
1357                        add-apt-repository ppa:openjdk-r/ppa -y && \
1358                        apt-get update && \
1359                        apt-get install -y openjdk-8-jdk
1360
1361                # Create apex user and group
1362                RUN groupadd apexuser
1363                RUN useradd --create-home -g apexuser apexuser
1364
1365                # Add Apex-specific directories and set ownership as the Apex admin user
1366                RUN mkdir -p /opt/app/policy/apex-pdp
1367                RUN mkdir -p /var/log/onap/policy/apex-pdp
1368                RUN chown -R apexuser:apexuser /var/log/onap/policy/apex-pdp
1369
1370                # Unpack the tarball
1371                RUN mkdir /packages
1372                COPY apex-pdp-package-full.tar.gz /packages
1373                RUN tar xvfz /packages/apex-pdp-package-full.tar.gz --directory /opt/app/policy/apex-pdp
1374                RUN rm /packages/apex-pdp-package-full.tar.gz
1375
1376                # Ensure everything has the correct permissions
1377                RUN find /opt/app -type d -perm 755
1378                RUN find /opt/app -type f -perm 644
1379                RUN chmod a+x /opt/app/policy/apex-pdp/bin/*
1380
1381                # Copy examples to Apex user area
1382                RUN cp -pr /opt/app/policy/apex-pdp/examples /home/apexuser
1383
1384                RUN apt-get clean
1385
1386                RUN chown -R apexuser:apexuser /home/apexuser/*
1387
1388                USER apexuser
1389                ENV PATH /opt/app/policy/apex-pdp/bin:$PATH
1390                WORKDIR /home/apexuser
1391
1392 APEX Configurations Explained
1393 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1394
1395 Introduction to APEX Configuration
1396 ----------------------------------
1397
1398          .. container:: paragraph
1399
1400             An APEX engine can be configured to use various combinations
1401             of event input handlers, event output handlers, event
1402             protocols, context handlers, and logic executors. The system
1403             is build using a plugin architecture. Each configuration
1404             option is realized by a plugin, which can be loaded and
1405             configured when the engine is started. New plugins can be
1406             added to the system at any time, though to benefit from a
1407             new plugin an engine will need to be restarted.
1408
1409          .. container:: imageblock
1410
1411             .. container:: content
1412
1413                |APEX Configuration Matrix|
1414
1415             .. container:: title
1416
1417                Figure 3. APEX Configuration Matrix
1418
1419          .. container:: paragraph
1420
1421             The APEX distribution already comes with a number of
1422             plugins. The figure above shows the provided plugins. Any
1423             combination of input, output, event protocol, context
1424             handlers, and executors is possible.
1425
1426 General Configuration Format
1427 ----------------------------
1428
1429          .. container:: paragraph
1430
1431             The APEX configuration file is a JSON file containing a few
1432             main blocks for different parts of the configuration. Each
1433             block then holds the configuration details. The following
1434             code shows the main blocks:
1435
1436          .. container:: listingblock
1437
1438             .. container:: content
1439
1440                .. code::
1441
1442                   {
1443                     "engineServiceParameters":{
1444                       ... (1)
1445                       "engineParameters":{ (2)
1446                         "engineParameters":{...}, (3)
1447                         "contextParameters":{...} (4)
1448                       }
1449                     },
1450                     "eventInputParameters":{ (5)
1451                       "input1":{ (6)
1452                         "carrierTechnologyParameters":{...},
1453                         "eventProtocolParameters":{...}
1454                       },
1455                       "input2":{...}, (7)
1456                         "carrierTechnologyParameters":{...},
1457                         "eventProtocolParameters":{...}
1458                       },
1459                       ... (8)
1460                     },
1461                     "eventOutputParameters":{ (9)
1462                       "output1":{ (10)
1463                         "carrierTechnologyParameters":{...},
1464                         "eventProtocolParameters":{...}
1465                       },
1466                       "output2":{ (11)
1467                         "carrierTechnologyParameters":{...},
1468                         "eventProtocolParameters":{...}
1469                       },
1470                       ... (12)
1471                     }
1472                   }
1473
1474          .. container:: colist arabic
1475
1476             +-----------------------------------+-----------------------------------+
1477             | **1**                             | main engine configuration         |
1478             +-----------------------------------+-----------------------------------+
1479             | **2**                             | engine parameters for plugin      |
1480             |                                   | configurations (execution         |
1481             |                                   | environments and context          |
1482             |                                   | handling)                         |
1483             +-----------------------------------+-----------------------------------+
1484             | **3**                             | engine specific parameters,       |
1485             |                                   | mainly for executor plugins       |
1486             +-----------------------------------+-----------------------------------+
1487             | **4**                             | context specific parameters, e.g. |
1488             |                                   | for context schemas, persistence, |
1489             |                                   | etc.                              |
1490             +-----------------------------------+-----------------------------------+
1491             | **5**                             | configuration of the input        |
1492             |                                   | interface                         |
1493             +-----------------------------------+-----------------------------------+
1494             | **6**                             | an example input called           |
1495             |                                   | ``input1`` with carrier           |
1496             |                                   | technology and event protocol     |
1497             +-----------------------------------+-----------------------------------+
1498             | **7**                             | an example input called           |
1499             |                                   | ``input2`` with carrier           |
1500             |                                   | technology and event protocol     |
1501             +-----------------------------------+-----------------------------------+
1502             | **8**                             | any further input configuration   |
1503             +-----------------------------------+-----------------------------------+
1504             | **9**                             | configuration of the output       |
1505             |                                   | interface                         |
1506             +-----------------------------------+-----------------------------------+
1507             | **10**                            | an example output called          |
1508             |                                   | ``output1`` with carrier          |
1509             |                                   | technology and event protocol     |
1510             +-----------------------------------+-----------------------------------+
1511             | **11**                            | an example output called          |
1512             |                                   | ``output2`` with carrier          |
1513             |                                   | technology and event protocol     |
1514             +-----------------------------------+-----------------------------------+
1515             | **12**                            | any further output configuration  |
1516             +-----------------------------------+-----------------------------------+
1517
1518 Engine Service Parameters
1519 -------------------------
1520
1521          .. container:: paragraph
1522
1523             The configuration provides a number of parameters to
1524             configure the engine. An example configuration with
1525             explanations of all options is shown below.
1526
1527          .. container:: listingblock
1528
1529             .. container:: content
1530
1531                .. code::
1532
1533                   "engineServiceParameters" : {
1534                     "name"          : "AADMApexEngine", (1)
1535                     "version"        : "0.0.1",  (2)
1536                     "id"             :  45,  (3)
1537                     "instanceCount"  : 4,  (4)
1538                     "deploymentPort" : 12345,  (5)
1539                     "policyModelFileName" : "examples/models/VPN/VPNPolicyModelJava.json", (6)
1540                     "periodicEventPeriod": 1000, (7)
1541                     "engineParameters":{ (8)
1542                       "engineParameters":{...}, (9)
1543                       "contextParameters":{...} (10)
1544                     }
1545                   }
1546
1547          .. container:: colist arabic
1548
1549             +-----------------------------------+-----------------------------------+
1550             | **1**                             | a name for the engine. The engine |
1551             |                                   | name is used to create a key in a |
1552             |                                   | runtime engine. An name matching  |
1553             |                                   | the following regular expression  |
1554             |                                   | can be used here:                 |
1555             |                                   | ``[A-Za-z0-9\\-_\\.]+``           |
1556             +-----------------------------------+-----------------------------------+
1557             | **2**                             | a version of the engine, use      |
1558             |                                   | semantic versioning as explained  |
1559             |                                   | here: `Semantic                   |
1560             |                                   | Versioning <http://semver.org/>`_ |
1561             |                                   | _.                                |
1562             |                                   | This version is used in a runtime |
1563             |                                   | engine to create a version of the |
1564             |                                   | engine. For that reason, the      |
1565             |                                   | version must match the following  |
1566             |                                   | regular expression ``[A-Z0-9.]+`` |
1567             +-----------------------------------+-----------------------------------+
1568             | **3**                             | a numeric identifier for the      |
1569             |                                   | engine                            |
1570             +-----------------------------------+-----------------------------------+
1571             | **4**                             | the number of threads (policy     |
1572             |                                   | instances executed in parallel)   |
1573             |                                   | the engine should use, use ``1``  |
1574             |                                   | for single threaded engines       |
1575             +-----------------------------------+-----------------------------------+
1576             | **5**                             | the port for the deployment       |
1577             |                                   | Websocket connection to the       |
1578             |                                   | engine                            |
1579             +-----------------------------------+-----------------------------------+
1580             | **6**                             | the model file to load into the   |
1581             |                                   | engine on startup (optional)      |
1582             +-----------------------------------+-----------------------------------+
1583             | **7**                             | an optional timer for periodic    |
1584             |                                   | policies, in milliseconds (a      |
1585             |                                   | defined periodic policy will be   |
1586             |                                   | executed every ``X``              |
1587             |                                   | milliseconds), not used of not    |
1588             |                                   | set or ``0``                      |
1589             +-----------------------------------+-----------------------------------+
1590             | **8**                             | engine parameters for plugin      |
1591             |                                   | configurations (execution         |
1592             |                                   | environments and context          |
1593             |                                   | handling)                         |
1594             +-----------------------------------+-----------------------------------+
1595             | **9**                             | engine specific parameters,       |
1596             |                                   | mainly for executor plugins       |
1597             +-----------------------------------+-----------------------------------+
1598             | **10**                            | context specific parameters, e.g. |
1599             |                                   | for context schemas, persistence, |
1600             |                                   | etc.                              |
1601             +-----------------------------------+-----------------------------------+
1602
1603          .. container:: paragraph
1604
1605             The model file is optional, it can also be specified via
1606             command line. In any case, make sure all execution and other
1607             required plug-ins for the loaded model are loaded as
1608             required.
1609
1610 Input and Output Interfaces
1611 ---------------------------
1612
1613          .. container:: paragraph
1614
1615             An APEX engine has two main interfaces:
1616
1617          .. container:: ulist
1618
1619             -  An *input* interface to receive events: also known as
1620                ingress interface or consumer, receiving (consuming)
1621                events commonly named triggers, and
1622
1623             -  An *output* interface to publish produced events: also
1624                known as egress interface or producer, sending
1625                (publishing) events commonly named actions or action
1626                events.
1627
1628          .. container:: paragraph
1629
1630             The input and output interface is configured in terms of
1631             inputs and outputs, respectively. Each input and output is a
1632             combination of a carrier technology and an event protocol.
1633             Carrier technologies and event protocols are provided by
1634             plugins, each with its own specific configuration. Most
1635             carrier technologies can be configured for input as well as
1636             output. Most event protocols can be used for all carrier
1637             technologies. One exception is the JMS object event
1638             protocol, which can only be used for the JMS carrier
1639             technology. Some further restrictions apply (for instance
1640             for carrier technologies using bi- or uni-directional
1641             modes).
1642
1643          .. container:: paragraph
1644
1645             Input and output interface can be configured separately, in
1646             isolation, with any number of carrier technologies. The
1647             resulting general configuration options are:
1648
1649          .. container:: ulist
1650
1651             -  Input interface with one or more inputs
1652
1653                .. container:: ulist
1654
1655                   -  each input with a carrier technology and an event
1656                      protocol
1657
1658                   -  some inputs with optional synchronous mode
1659
1660                   -  some event protocols with additional parameters
1661
1662             -  Output interface with one or more outputs
1663
1664                .. container:: ulist
1665
1666                   -  each output with a carrier technology and an event
1667                      encoding
1668
1669                   -  some outputs with optional synchronous mode
1670
1671                   -  some event protocols with additional parameters
1672
1673          .. container:: paragraph
1674
1675             The configuration for input and output is contained in
1676             ``eventInputParameters`` and ``eventOutputParameters``,
1677             respectively. Inside here, one can configure any number of
1678             inputs and outputs. Each of them needs to have a unique
1679             identifier (name), the content of the name is free form. The
1680             example below shows a configuration for two inputs and two
1681             outputs.
1682
1683          .. container:: listingblock
1684
1685             .. container:: content
1686
1687                .. code::
1688
1689                   "eventInputParameters": { (1)
1690                     "FirstConsumer": { (2)
1691                       "carrierTechnologyParameters" : {...}, (3)
1692                       "eventProtocolParameters":{...}, (4)
1693                       ... (5)
1694                     },
1695                     "SecondConsumer": { (6)
1696                       "carrierTechnologyParameters" : {...}, (7)
1697                       "eventProtocolParameters":{...}, (8)
1698                       ... (9)
1699                     },
1700                   },
1701                   "eventOutputParameters": { (10)
1702                     "FirstProducer": { (11)
1703                       "carrierTechnologyParameters":{...}, (12)
1704                       "eventProtocolParameters":{...}, (13)
1705                       ... (14)
1706                     },
1707                     "SecondProducer": { (15)
1708                       "carrierTechnologyParameters":{...}, (16)
1709                       "eventProtocolParameters":{...}, (17)
1710                       ... (18)
1711                     }
1712                   }
1713
1714          .. container:: colist arabic
1715
1716             +--------+--------------------------------------------------------------------+
1717             | **1**  | input interface configuration, APEX input plugins                  |
1718             +--------+--------------------------------------------------------------------+
1719             | **2**  | first input called ``FirstConsumer``                               |
1720             +--------+--------------------------------------------------------------------+
1721             | **3**  | carrier technology for plugin                                      |
1722             +--------+--------------------------------------------------------------------+
1723             | **4**  | event protocol for plugin                                          |
1724             +--------+--------------------------------------------------------------------+
1725             | **5**  | any other input configuration (e.g. event name filter, see below)  |
1726             +--------+--------------------------------------------------------------------+
1727             | **6**  | second input called ``SecondConsumer``                             |
1728             +--------+--------------------------------------------------------------------+
1729             | **7**  | carrier technology for plugin                                      |
1730             +--------+--------------------------------------------------------------------+
1731             | **8**  | event protocol for plugin                                          |
1732             +--------+--------------------------------------------------------------------+
1733             | **9**  | any other plugin configuration                                     |
1734             +--------+--------------------------------------------------------------------+
1735             | **10** | output interface configuration, APEX output plugins                |
1736             +--------+--------------------------------------------------------------------+
1737             | **11** | first output called ``FirstProducer``                              |
1738             +--------+--------------------------------------------------------------------+
1739             | **12** | carrier technology for plugin                                      |
1740             +--------+--------------------------------------------------------------------+
1741             | **13** | event protocol for plugin                                          |
1742             +--------+--------------------------------------------------------------------+
1743             | **14** | any other plugin configuration                                     |
1744             +--------+--------------------------------------------------------------------+
1745             | **15** | second output called ``SecondProducer``                            |
1746             +--------+--------------------------------------------------------------------+
1747             | **16** | carrier technology for plugin                                      |
1748             +--------+--------------------------------------------------------------------+
1749             | **17** | event protocol for plugin                                          |
1750             +--------+--------------------------------------------------------------------+
1751             | **18** | any other output configuration (e.g. event name filter, see below) |
1752             +--------+--------------------------------------------------------------------+
1753
1754 Event Filters
1755 #############
1756
1757             .. container:: paragraph
1758
1759                APEX will always send an event after a policy execution
1760                is finished. For a successful execution, the event sent
1761                is the output event created by the policy. In case the
1762                policy does not create an output event, APEX will create
1763                a new event with all input event fields plus an
1764                additional field ``exceptionMessage`` with an exception
1765                message.
1766
1767             .. container:: paragraph
1768
1769                There are situations in which this auto-generated error
1770                event might not be required or wanted:
1771
1772             .. container:: ulist
1773
1774                -  when a policy failing should not result in an event
1775                   send out via an output interface
1776
1777                -  when the auto-generated event goes back in an APEX
1778                   engine (or the same APEX engine), this can create
1779                   endless loops
1780
1781                -  the auto-generated event should go to a special output
1782                   interface or channel
1783
1784             .. container:: paragraph
1785
1786                All of these situations are supported by a filter option
1787                using a wildecard (regular expression) configuration on
1788                APEX I/O interfaces. The parameter is called
1789                ``eventNameFilter`` and the value are `Java regular
1790                expressions <https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html>`__
1791                (a
1792                `tutorial <http://www.vogella.com/tutorials/JavaRegularExpressions/article.html>`__).
1793                The following code shows some examples:
1794
1795             .. container:: listingblock
1796
1797                .. container:: content
1798
1799                   .. code::
1800
1801                      "eventInputParameters": {
1802                        "Input1": {
1803                          "carrierTechnologyParameters" : {...},
1804                          "eventProtocolParameters":{...},
1805                          "eventNameFilter" : "^E[Vv][Ee][Nn][Tt][0-9]004$" (1)
1806                        }
1807                      },
1808                      "eventOutputParameters": {
1809                        "Output1": {
1810                          "carrierTechnologyParameters":{...},
1811                          "eventProtocolParameters":{...},
1812                          "eventNameFilter" : "^E[Vv][Ee][Nn][Tt][0-9]104$" (2)
1813                        }
1814                      }
1815
1816 Executors
1817 ---------
1818
1819          .. container:: paragraph
1820
1821             Executors are plugins that realize the execution of logic
1822             contained in a policy model. Logic can be in a task
1823             selector, a task, and a state finalizer. Using plugins for
1824             execution environments makes APEX very flexible to support
1825             virtually any executable logic expressions.
1826
1827          .. container:: paragraph
1828
1829             APEX 2.0.0-SNAPSHOT supports the following executors:
1830
1831          .. container:: ulist
1832
1833             -  Java, for Java implemented logic
1834
1835                .. container:: ulist
1836
1837                   -  This executor requires logic implemented using the
1838                      APEX Java interfaces.
1839
1840                   -  Generated JAR files must be in the classpath of the
1841                      APEX engine at start time.
1842
1843             -  Javascript
1844
1845             -  JRuby,
1846
1847             -  Jython,
1848
1849             -  MVEL
1850
1851                .. container:: ulist
1852
1853                   -  This executor uses the latest version of the MVEL
1854                      engine, which can be very hard to debug and can
1855                      produce unwanted side effects during execution
1856
1857 Configure the Javascript Executor
1858 #################################
1859
1860             .. container:: paragraph
1861
1862                The Javascript executor is added to the configuration as
1863                follows:
1864
1865             .. container:: listingblock
1866
1867                .. container:: content
1868
1869                   .. code::
1870
1871                      "engineServiceParameters":{
1872                        "engineParameters":{
1873                          "executorParameters":{
1874                            "JAVASCRIPT":{
1875                              "parameterClassName" :
1876                              "org.onap.policy.apex.plugins.executor.javascript.JavascriptExecutorParameters"
1877                            }
1878                          }
1879                        }
1880                      }
1881
1882 Configure the Jython Executor
1883 #############################
1884
1885             .. container:: paragraph
1886
1887                The Jython executor is added to the configuration as
1888                follows:
1889
1890             .. container:: listingblock
1891
1892                .. container:: content
1893
1894                   .. code::
1895
1896                      "engineServiceParameters":{
1897                        "engineParameters":{
1898                          "executorParameters":{
1899                            "JYTHON":{
1900                              "parameterClassName" :
1901                              "org.onap.policy.apex.plugins.executor.jython.JythonExecutorParameters"
1902                            }
1903                          }
1904                        }
1905                      }
1906
1907 Configure the JRuby Executor
1908 ############################
1909
1910             .. container:: paragraph
1911
1912                The JRuby executor is added to the configuration as
1913                follows:
1914
1915             .. container:: listingblock
1916
1917                .. container:: content
1918
1919                   .. code::
1920
1921                      "engineServiceParameters":{
1922                        "engineParameters":{
1923                          "executorParameters":{
1924                            "JRUBY":{
1925                              "parameterClassName" :
1926                              "org.onap.policy.apex.plugins.executor.jruby.JrubyExecutorParameters"
1927                            }
1928                          }
1929                        }
1930                      }
1931
1932 Configure the Java Executor
1933 ###########################
1934
1935             .. container:: paragraph
1936
1937                The Java executor is added to the configuration as
1938                follows:
1939
1940             .. container:: listingblock
1941
1942                .. container:: content
1943
1944                   .. code::
1945
1946                      "engineServiceParameters":{
1947                        "engineParameters":{
1948                          "executorParameters":{
1949                            "JAVA":{
1950                              "parameterClassName" :
1951                              "org.onap.policy.apex.plugins.executor.java.JavaExecutorParameters"
1952                            }
1953                          }
1954                        }
1955                      }
1956
1957 Configure the MVEL Executor
1958 ###########################
1959
1960             .. container:: paragraph
1961
1962                The MVEL executor is added to the configuration as
1963                follows:
1964
1965             .. container:: listingblock
1966
1967                .. container:: content
1968
1969                   .. code::
1970
1971                      "engineServiceParameters":{
1972                        "engineParameters":{
1973                          "executorParameters":{
1974                            "MVEL":{
1975                              "parameterClassName" :
1976                              "org.onap.policy.apex.plugins.executor.mvel.MVELExecutorParameters"
1977                            }
1978                          }
1979                        }
1980                      }
1981
1982 Context Handlers
1983 ----------------
1984
1985          .. container:: paragraph
1986
1987             Context handlers are responsible for all context processing.
1988             There are the following main areas:
1989
1990          .. container:: ulist
1991
1992             -  Context schema: use schema handlers other than Java class
1993                (supported by default without configuration)
1994
1995             -  Context distribution: distribute context across multiple
1996                APEX engines
1997
1998             -  Context locking: mechanisms to lock context elements for
1999                read/write
2000
2001             -  Context persistence: mechanisms to persist context
2002
2003          .. container:: paragraph
2004
2005             APEX provides plugins for each of the main areas.
2006
2007 Configure AVRO Schema Handler
2008 #############################
2009
2010             .. container:: paragraph
2011
2012                The AVRO schema handler is added to the configuration as
2013                follows:
2014
2015             .. container:: listingblock
2016
2017                .. container:: content
2018
2019                   .. code::
2020
2021                      "engineServiceParameters":{
2022                        "engineParameters":{
2023                          "contextParameters":{
2024                            "parameterClassName" : "org.onap.policy.apex.context.parameters.ContextParameters",
2025                            "schemaParameters":{
2026                              "Avro":{
2027                                "parameterClassName" :
2028                                  "org.onap.policy.apex.plugins.context.schema.avro.AvroSchemaHelperParameters"
2029                              }
2030                            }
2031                          }
2032                        }
2033                      }
2034
2035             .. container:: paragraph
2036
2037                Using the AVRO schema handler has one limitation: AVRO
2038                only supports field names that represent valid Java class
2039                names. This means only letters and the character ``_``
2040                are supported. Characters commonly used in field names,
2041                such as ``.`` and ``-``, are not supported by AVRO. for
2042                more information see `Avro Spec:
2043                Names <https://avro.apache.org/docs/1.8.1/spec.html#names>`__.
2044
2045             .. container:: paragraph
2046
2047                To work with this limitation, the APEX Avro plugin will
2048                parse a given AVRO definition and replace *all*
2049                occurrences of ``.`` and ``-`` with a ``_``. This means
2050                that
2051
2052             .. container:: ulist
2053
2054                -  In a policy model, if the AVRO schema defined a field
2055                   as ``my-name`` the policy logic should access it as
2056                   ``my_name``
2057
2058                -  In a policy model, if the AVRO schema defined a field
2059                   as ``my.name`` the policy logic should access it as
2060                   ``my_name``
2061
2062                -  There should be no field names that convert to the
2063                   same internal name
2064
2065                   .. container:: ulist
2066
2067                      -  For instance the simultaneous use of
2068                         ``my_name``, ``my.name``, and ``my-name`` should
2069                         be avoided
2070
2071                      -  If not avoided, the event processing might
2072                         create unwanted side effects
2073
2074                -  If field names use any other not-supported character,
2075                   the AVRO plugin will reject it
2076
2077                   .. container:: ulist
2078
2079                      -  Since AVRO uses lazy initialization, this
2080                         rejection might only become visible at runtime
2081
2082 Carrier Technologies
2083 --------------------
2084
2085          .. container:: paragraph
2086
2087             Carrier technologies define how APEX receives (input) and
2088             sends (output) events. They can be used in any combination,
2089             using asynchronous or synchronous mode. There can also be
2090             any number of carrier technologies for the input (consume)
2091             and the output (produce) interface.
2092
2093          .. container:: paragraph
2094
2095             Supported *input* technologies are:
2096
2097          .. container:: ulist
2098
2099             -  Standard input, read events from the standard input
2100                (console), not suitable for APEX background servers
2101
2102             -  File input, read events from a file
2103
2104             -  Kafka, read events from a Kafka system
2105
2106             -  Websockets, read events from a Websocket
2107
2108             -  JMS,
2109
2110             -  REST (synchronous and asynchronous), additionally as
2111                client or server
2112
2113             -  Event Requestor, allows reading of events that have been
2114                looped back into APEX
2115
2116          .. container:: paragraph
2117
2118             Supported *output* technologies are:
2119
2120          .. container:: ulist
2121
2122             -  Standard output, write events to the standard output
2123                (console), not suitable for APEX background servers
2124
2125             -  File output, write events to a file
2126
2127             -  Kafka, write events to a Kafka system
2128
2129             -  Websockets, write events to a Websocket
2130
2131             -  JMS
2132
2133             -  REST (synchronous and asynchronous), additionally as
2134                client or server
2135
2136             -  Event Requestor, allows events to be looped back into
2137                APEX
2138
2139          .. container:: paragraph
2140
2141             New carrier technologies can be added as plugins to APEX or
2142             developed outside APEX and added to an APEX deployment.
2143
2144 Standard IO
2145 ###########
2146
2147             .. container:: paragraph
2148
2149                Standard IO does not require a specific plugin, it is
2150                supported be default.
2151
2152 Standard Input
2153 ==============
2154                .. container:: paragraph
2155
2156                   APEX will take events from its standard input. This
2157                   carrier is good for testing, but certainly not for a
2158                   use case where APEX runs as a server. The
2159                   configuration is as follows:
2160
2161                .. container:: listingblock
2162
2163                   .. container:: content
2164
2165                      ::
2166
2167                         "carrierTechnologyParameters" : {
2168                           "carrierTechnology" : "FILE", (1)
2169                           "parameters" : {
2170                             "standardIO" : true (2)
2171                           }
2172                         }
2173
2174                .. container:: colist arabic
2175
2176                   +-------+---------------------------------------+
2177                   | **1** | standard input is considered a file   |
2178                   +-------+---------------------------------------+
2179                   | **2** | file descriptor set to standard input |
2180                   +-------+---------------------------------------+
2181
2182 Standard Output
2183 ===============
2184
2185                .. container:: paragraph
2186
2187                   APEX will send events to its standard output. This
2188                   carrier is good for testing, but certainly not for a
2189                   use case where APEX runs as a server. The
2190                   configuration is as follows:
2191
2192                .. container:: listingblock
2193
2194                   .. container:: content
2195
2196                      .. code::
2197
2198                         "carrierTechnologyParameters" : {
2199                           "carrierTechnology" : "FILE", (1)
2200                           "parameters" : {
2201                             "standardIO" : true  (2)
2202                           }
2203                         }
2204
2205                .. container:: colist arabic
2206
2207                   +-------+----------------------------------------+
2208                   | **1** | standard output is considered a file   |
2209                   +-------+----------------------------------------+
2210                   | **2** | file descriptor set to standard output |
2211                   +-------+----------------------------------------+
2212
2213 2.7.2. File IO
2214 ##############
2215
2216             .. container:: paragraph
2217
2218                File IO does not require a specific plugin, it is
2219                supported be default.
2220
2221 File Input
2222 ==========
2223
2224                .. container:: paragraph
2225
2226                   APEX will take events from a file. The same file
2227                   should not be used as an output. The configuration is
2228                   as follows:
2229
2230                .. container:: listingblock
2231
2232                   .. container:: content
2233
2234                      .. code::
2235
2236                         "carrierTechnologyParameters" : {
2237                           "carrierTechnology" : "FILE", (1)
2238                           "parameters" : {
2239                             "fileName" : "examples/events/SampleDomain/EventsIn.xmlfile" (2)
2240                           }
2241                         }
2242
2243                .. container:: colist arabic
2244
2245                   +-------+------------------------------------------+
2246                   | **1** | set file input                           |
2247                   +-------+------------------------------------------+
2248                   | **2** | the name of the file to read events from |
2249                   +-------+------------------------------------------+
2250
2251 File Output
2252 ===========
2253                .. container:: paragraph
2254
2255                   APEX will write events to a file. The same file should
2256                   not be used as an input. The configuration is as
2257                   follows:
2258
2259                .. container:: listingblock
2260
2261                   .. container:: content
2262
2263                      .. code::
2264
2265                         "carrierTechnologyParameters" : {
2266                           "carrierTechnology" : "FILE", (1)
2267                           "parameters" : {
2268                             "fileName"  : "examples/events/SampleDomain/EventsOut.xmlfile" (2)
2269                           }
2270                         }
2271
2272                .. container:: colist arabic
2273
2274                   +-------+-----------------------------------------+
2275                   | **1** | set file output                         |
2276                   +-------+-----------------------------------------+
2277                   | **2** | the name of the file to write events to |
2278                   +-------+-----------------------------------------+
2279
2280 Event Requestor IO
2281 ##################
2282
2283             .. container:: paragraph
2284
2285                Event Requestor IO does not require a specific plugin, it
2286                is supported be default. It should only be used with the
2287                APEX event protocol.
2288
2289 Event Requestor Input
2290 =====================
2291
2292                .. container:: paragraph
2293
2294                   APEX will take events from APEX.
2295
2296                .. container:: listingblock
2297
2298                   .. container:: content
2299
2300                      .. code::
2301
2302                         "carrierTechnologyParameters" : {
2303                           "carrierTechnology": "EVENT_REQUESTOR" (1)
2304                         }
2305
2306                .. container:: colist arabic
2307
2308                   +-------+---------------------------+
2309                   | **1** | set event requestor input |
2310                   +-------+---------------------------+
2311
2312 Event Requestor Output
2313 ======================
2314
2315                .. container:: paragraph
2316
2317                   APEX will write events to APEX.
2318
2319                .. container:: listingblock
2320
2321                   .. container:: content
2322
2323                      .. code::
2324
2325                         "carrierTechnologyParameters" : {
2326                           "carrierTechnology": "EVENT_REQUESTOR" (1)
2327                         }
2328
2329 Peering Event Requestors
2330 ========================
2331
2332                .. container:: paragraph
2333
2334                   When using event requestors, they need to be peered.
2335                   This means an event requestor output needs to be
2336                   peered (associated) with an event requestor input. The
2337                   following example shows the use of an event requestor
2338                   with the APEX event protocol and the peering of output
2339                   and input.
2340
2341                .. container:: listingblock
2342
2343                   .. container:: content
2344
2345                      .. code::
2346
2347                         "eventInputParameters": {
2348                           "EventRequestorConsumer": {
2349                             "carrierTechnologyParameters": {
2350                               "carrierTechnology": "EVENT_REQUESTOR" (1)
2351                             },
2352                             "eventProtocolParameters": {
2353                               "eventProtocol": "APEX" (2)
2354                             },
2355                             "eventNameFilter": "InputEvent", (3)
2356                             "requestorMode": true, (4)
2357                             "requestorPeer": "EventRequestorProducer", (5)
2358                             "requestorTimeout": 500 (6)
2359                           }
2360                         },
2361                         "eventOutputParameters": {
2362                           "EventRequestorProducer": {
2363                             "carrierTechnologyParameters": {
2364                               "carrierTechnology": "EVENT_REQUESTOR" (7)
2365                             },
2366                             "eventProtocolParameters": {
2367                               "eventProtocol": "APEX" (8)
2368                             },
2369                             "eventNameFilter": "EventListEvent", (9)
2370                             "requestorMode": true, (10)
2371                             "requestorPeer": "EventRequestorConsumer", (11)
2372                             "requestorTimeout": 500 (12)
2373                           }
2374                         }
2375
2376                .. container:: colist arabic
2377
2378                   +-----------------------------------+-----------------------------------+
2379                   | **1**                             | event requestor on a consumer     |
2380                   +-----------------------------------+-----------------------------------+
2381                   | **2**                             | with APEX event protocol          |
2382                   +-----------------------------------+-----------------------------------+
2383                   | **3**                             | optional filter (best to use a    |
2384                   |                                   | filter to prevent unwanted events |
2385                   |                                   | on the consumer side)             |
2386                   +-----------------------------------+-----------------------------------+
2387                   | **4**                             | activate requestor mode           |
2388                   +-----------------------------------+-----------------------------------+
2389                   | **5**                             | the peer to the output (must      |
2390                   |                                   | match the output carrier)         |
2391                   +-----------------------------------+-----------------------------------+
2392                   | **6**                             | an optional timeout in            |
2393                   |                                   | milliseconds                      |
2394                   +-----------------------------------+-----------------------------------+
2395                   | **7**                             | event requestor on a producer     |
2396                   +-----------------------------------+-----------------------------------+
2397                   | **8**                             | with APEX event protocol          |
2398                   +-----------------------------------+-----------------------------------+
2399                   | **9**                             | optional filter (best to use a    |
2400                   |                                   | filter to prevent unwanted events |
2401                   |                                   | on the consumer side)             |
2402                   +-----------------------------------+-----------------------------------+
2403                   | **10**                            | activate requestor mode           |
2404                   +-----------------------------------+-----------------------------------+
2405                   | **11**                            | the peer to the output (must      |
2406                   |                                   | match the input carrier)          |
2407                   +-----------------------------------+-----------------------------------+
2408                   | **12**                            | an optional timeout in            |
2409                   |                                   | milliseconds                      |
2410                   +-----------------------------------+-----------------------------------+
2411
2412 Kafka IO
2413 ########
2414
2415             .. container:: paragraph
2416
2417                Kafka IO is supported by the APEX Kafka plugin. The
2418                configurations below are examples. APEX will take any
2419                configuration inside the parameter object and forward it
2420                to Kafka. More information on Kafka specific
2421                configuration parameters can be found in the Kafka
2422                documentation:
2423
2424             .. container:: ulist
2425
2426                -  `Kafka Consumer
2427                   Class <https://kafka.apache.org/090/javadoc/org/apache/kafka/clients/consumer/KafkaConsumer.html>`__
2428
2429                -  `Kafka Producer
2430                   Class <https://kafka.apache.org/090/javadoc/org/apache/kafka/clients/producer/KafkaProducer.html>`__
2431
2432 Kafka Input
2433 ===========
2434                .. container:: paragraph
2435
2436                   APEX will receive events from the Apache Kafka
2437                   messaging system. The input is uni-directional, an
2438                   engine will only receive events from the input but not
2439                   send any event to the input.
2440
2441                .. container:: listingblock
2442
2443                   .. container:: content
2444
2445                      .. code::
2446
2447                         "carrierTechnologyParameters" : {
2448                           "carrierTechnology" : "KAFKA", (1)
2449                           "parameterClassName" :
2450                             "org.onap.policy.apex.plugins.event.carrier.kafka.KAFKACarrierTechnologyParameters",
2451                           "parameters" : {
2452                             "bootstrapServers"  : "localhost:49092", (2)
2453                             "groupId"           : "apex-group-id", (3)
2454                             "enableAutoCommit"  : true, (4)
2455                             "autoCommitTime"    : 1000, (5)
2456                             "sessionTimeout"    : 30000, (6)
2457                             "consumerPollTime"  : 100, (7)
2458                             "consumerTopicList" : ["apex-in-0", "apex-in-1"], (8)
2459                             "keyDeserializer"   :
2460                                 "org.apache.kafka.common.serialization.StringDeserializer", (9)
2461                             "valueDeserializer" :
2462                                 "org.apache.kafka.common.serialization.StringDeserializer" (10)
2463                           }
2464                         }
2465
2466                .. container:: colist arabic
2467
2468                   +--------+-------------------------------------+
2469                   | **1**  | set Kafka as carrier technology     |
2470                   +--------+-------------------------------------+
2471                   | **2**  | bootstrap server and port           |
2472                   +--------+-------------------------------------+
2473                   | **3**  | a group identifier                  |
2474                   +--------+-------------------------------------+
2475                   | **4**  | flag for auto-commit                |
2476                   +--------+-------------------------------------+
2477                   | **5**  | auto-commit timeout in milliseconds |
2478                   +--------+-------------------------------------+
2479                   | **6**  | session timeout in milliseconds     |
2480                   +--------+-------------------------------------+
2481                   | **7**  | consumer poll time in milliseconds  |
2482                   +--------+-------------------------------------+
2483                   | **8**  | consumer topic list                 |
2484                   +--------+-------------------------------------+
2485                   | **9**  | key for the Kafka de-serializer     |
2486                   +--------+-------------------------------------+
2487                   | **10** | value for the Kafka de-serializer   |
2488                   +--------+-------------------------------------+
2489
2490 Kafka Output
2491 ============
2492                .. container:: paragraph
2493
2494                   APEX will send events to the Apache Kafka messaging
2495                   system. The output is uni-directional, an engine will
2496                   send events to the output but not receive any event
2497                   from the output.
2498
2499                .. container:: listingblock
2500
2501                   .. container:: content
2502
2503                      .. code::
2504
2505                         "carrierTechnologyParameters" : {
2506                           "carrierTechnology" : "KAFKA", (1)
2507                           "parameterClassName" :
2508                             "org.onap.policy.apex.plugins.event.carrier.kafka.KAFKACarrierTechnologyParameters",
2509                           "parameters" : {
2510                             "bootstrapServers"  : "localhost:49092", (2)
2511                             "acks"              : "all", (3)
2512                             "retries"           : 0, (4)
2513                             "batchSize"         : 16384, (5)
2514                             "lingerTime"        : 1, (6)
2515                             "bufferMemory"      : 33554432, (7)
2516                             "producerTopic"     : "apex-out", (8)
2517                             "keySerializer"     :
2518                                 "org.apache.kafka.common.serialization.StringSerializer", (9)
2519                             "valueSerializer"   :
2520                                 "org.apache.kafka.common.serialization.StringSerializer" (10)
2521                           }
2522                         }
2523
2524                .. container:: colist arabic
2525
2526                   +--------+---------------------------------+
2527                   | **1**  | set Kafka as carrier technology |
2528                   +--------+---------------------------------+
2529                   | **2**  | bootstrap server and port       |
2530                   +--------+---------------------------------+
2531                   | **3**  | acknowledgement strategy        |
2532                   +--------+---------------------------------+
2533                   | **4**  | number of retries               |
2534                   +--------+---------------------------------+
2535                   | **5**  | batch size                      |
2536                   +--------+---------------------------------+
2537                   | **6**  | time to linger in milliseconds  |
2538                   +--------+---------------------------------+
2539                   | **7**  | buffer memory in byte           |
2540                   +--------+---------------------------------+
2541                   | **8**  | producer topic                  |
2542                   +--------+---------------------------------+
2543                   | **9**  | key for the Kafka serializer    |
2544                   +--------+---------------------------------+
2545                   | **10** | value for the Kafka serializer  |
2546                   +--------+---------------------------------+
2547
2548 JMS IO
2549 #######
2550
2551             .. container:: paragraph
2552
2553                APEX supports the Java Messaging Service (JMS) as input
2554                as well as output. JMS IO is supported by the APEX JMS
2555                plugin. Input and output support an event encoding as
2556                text (JSON string) or object (serialized object). The
2557                input configuration is the same for both encodings, the
2558                output configuration differs.
2559
2560 JMS Input
2561 =========
2562                .. container:: paragraph
2563
2564                   APEX will receive events from a JMS messaging system.
2565                   The input is uni-directional, an engine will only
2566                   receive events from the input but not send any event
2567                   to the input.
2568
2569                .. container:: listingblock
2570
2571                   .. container:: content
2572
2573                      .. code::
2574
2575                         "carrierTechnologyParameters" : {
2576                           "carrierTechnology" : "JMS", (1)
2577                           "parameterClassName" :
2578                               "org.onap.policy.apex.plugins.event.carrier.jms.JMSCarrierTechnologyParameters",
2579                           "parameters" : { (2)
2580                             "initialContextFactory" :
2581                                 "org.jboss.naming.remote.client.InitialContextFactory", (3)
2582                             "connectionFactory" : "ConnectionFactory", (4)
2583                             "providerURL" : "remote://localhost:5445", (5)
2584                             "securityPrincipal" : "guest", (6)
2585                             "securityCredentials" : "IAmAGuest", (7)
2586                             "consumerTopic" : "jms/topic/apexIn" (8)
2587                           }
2588                         }
2589
2590                .. container:: colist arabic
2591
2592                   +-----------------------------------+-----------------------------------+
2593                   | **1**                             | set JMS as carrier technology     |
2594                   +-----------------------------------+-----------------------------------+
2595                   | **2**                             | set all JMS specific parameters   |
2596                   +-----------------------------------+-----------------------------------+
2597                   | **3**                             | the context factory, in this case |
2598                   |                                   | from JBOSS (it requires the       |
2599                   |                                   | dependency                        |
2600                   |                                   | org.jboss:jboss-remote-naming:2.0 |
2601                   |                                   | .4.Final                          |
2602                   |                                   | or a different version to be in   |
2603                   |                                   | the directory ``$APEX_HOME/lib``  |
2604                   |                                   | or ``%APEX_HOME%\lib``            |
2605                   +-----------------------------------+-----------------------------------+
2606                   | **4**                             | a connection factory for the JMS  |
2607                   |                                   | connection                        |
2608                   +-----------------------------------+-----------------------------------+
2609                   | **5**                             | URL with host and port of the JMS |
2610                   |                                   | provider                          |
2611                   +-----------------------------------+-----------------------------------+
2612                   | **6**                             | access credentials, user name     |
2613                   +-----------------------------------+-----------------------------------+
2614                   | **7**                             | access credentials, user password |
2615                   +-----------------------------------+-----------------------------------+
2616                   | **8**                             | the JMS topic to listen to        |
2617                   +-----------------------------------+-----------------------------------+
2618
2619 JMS Output with Text
2620 ====================
2621
2622                .. container:: paragraph
2623
2624                   APEX engine send events to a JMS messaging system. The
2625                   output is uni-directional, an engine will send events
2626                   to the output but not receive any event from output.
2627
2628                .. container:: listingblock
2629
2630                   .. container:: content
2631
2632                      .. code::
2633
2634                         "carrierTechnologyParameters" : {
2635                           "carrierTechnology" : "JMS", (1)
2636                           "parameterClassName" :
2637                               "org.onap.policy.apex.plugins.event.carrier.jms.JMSCarrierTechnologyParameters",
2638                           "parameters" : { (2)
2639                             "initialContextFactory" :
2640                                 "org.jboss.naming.remote.client.InitialContextFactory", (3)
2641                             "connectionFactory" : "ConnectionFactory", (4)
2642                             "providerURL" : "remote://localhost:5445", (5)
2643                             "securityPrincipal" : "guest", (6)
2644                             "securityCredentials" : "IAmAGuest", (7)
2645                             "producerTopic" : "jms/topic/apexOut", (8)
2646                             "objectMessageSending": "false" (9)
2647                           }
2648                         }
2649
2650                .. container:: colist arabic
2651
2652                   +-----------------------------------+-----------------------------------+
2653                   | **1**                             | set JMS as carrier technology     |
2654                   +-----------------------------------+-----------------------------------+
2655                   | **2**                             | set all JMS specific parameters   |
2656                   +-----------------------------------+-----------------------------------+
2657                   | **3**                             | the context factory, in this case |
2658                   |                                   | from JBOSS (it requires the       |
2659                   |                                   | dependency                        |
2660                   |                                   | org.jboss:jboss-remote-naming:2.0 |
2661                   |                                   | .4.Final                          |
2662                   |                                   | or a different version to be in   |
2663                   |                                   | the directory ``$APEX_HOME/lib``  |
2664                   |                                   | or ``%APEX_HOME%\lib``            |
2665                   +-----------------------------------+-----------------------------------+
2666                   | **4**                             | a connection factory for the JMS  |
2667                   |                                   | connection                        |
2668                   +-----------------------------------+-----------------------------------+
2669                   | **5**                             | URL with host and port of the JMS |
2670                   |                                   | provider                          |
2671                   +-----------------------------------+-----------------------------------+
2672                   | **6**                             | access credentials, user name     |
2673                   +-----------------------------------+-----------------------------------+
2674                   | **7**                             | access credentials, user password |
2675                   +-----------------------------------+-----------------------------------+
2676                   | **8**                             | the JMS topic to write to         |
2677                   +-----------------------------------+-----------------------------------+
2678                   | **9**                             | set object messaging to ``false`` |
2679                   |                                   | means it sends JSON text          |
2680                   +-----------------------------------+-----------------------------------+
2681
2682 JMS Output with Object
2683 ======================
2684
2685                .. container:: paragraph
2686
2687                   To configure APEX for JMS objects on the output
2688                   interface use the same configuration as above (for
2689                   output). Simply change the ``objectMessageSending``
2690                   parameter to ``true``.
2691
2692 Websocket (WS) IO
2693 ########################
2694
2695             .. container:: paragraph
2696
2697                APEX supports the Websockets as input as well as output.
2698                WS IO is supported by the APEX Websocket plugin. This
2699                carrier technology does only support uni-directional
2700                communication. APEX will not send events to a Websocket
2701                input and any event sent to a Websocket output will
2702                result in an error log.
2703
2704             .. container:: paragraph
2705
2706                The input can be configured as client (APEX connects to
2707                an existing Websocket server) or server (APEX starts a
2708                Websocket server). The same applies to the output. Input
2709                and output can both use a client or a server
2710                configuration, or separate configurations (input as
2711                client and output as server, input as server and output
2712                as client). Each configuration should use its own
2713                dedicated port to avoid any communication loops. The
2714                configuration of a Websocket client is the same for input
2715                and output. The configuration of a Websocket server is
2716                the same for input and output.
2717
2718 Websocket Client
2719 ================
2720
2721                .. container:: paragraph
2722
2723                   APEX will connect to a given Websocket server. As
2724                   input, it will receive events from the server but not
2725                   send any events. As output, it will send events to the
2726                   server and any event received from the server will
2727                   result in an error log.
2728
2729                .. container:: listingblock
2730
2731                   .. container:: content
2732
2733                      .. code::
2734
2735                         "carrierTechnologyParameters" : {
2736                           "carrierTechnology" : "WEBSOCKET", (1)
2737                           "parameterClassName" :
2738                           "org.onap.policy.apex.plugins.event.carrier.websocket.WEBSOCKETCarrierTechnologyParameters",
2739                           "parameters" : {
2740                             "host" : "localhost", (2)
2741                             "port" : 42451 (3)
2742                           }
2743                         }
2744
2745                .. container:: colist arabic
2746
2747                   +-------+------------------------------------------------------+
2748                   | **1** | set Websocket as carrier technology                  |
2749                   +-------+------------------------------------------------------+
2750                   | **2** | the host name on which a Websocket server is running |
2751                   +-------+------------------------------------------------------+
2752                   | **3** | the port of that Websocket server                    |
2753                   +-------+------------------------------------------------------+
2754
2755 Websocket Server
2756 ================
2757
2758                .. container:: paragraph
2759
2760                   APEX will start a Websocket server, which will accept
2761                   any Websocket clients to connect. As input, it will
2762                   receive events from the server but not send any
2763                   events. As output, it will send events to the server
2764                   and any event received from the server will result in
2765                   an error log.
2766
2767                .. container:: listingblock
2768
2769                   .. container:: content
2770
2771                      .. code::
2772
2773                         "carrierTechnologyParameters" : {
2774                           "carrierTechnology" : "WEBSOCKET", (1)
2775                           "parameterClassName" :
2776                           "org.onap.policy.apex.plugins.event.carrier.websocket.WEBSOCKETCarrierTechnologyParameters",
2777                           "parameters" : {
2778                             "wsClient" : false, (2)
2779                             "port"     : 42450 (3)
2780                           }
2781                         }
2782
2783                .. container:: colist arabic
2784
2785                   +-------+------------------------------------------------------------+
2786                   | **1** | set Websocket as carrier technology                        |
2787                   +-------+------------------------------------------------------------+
2788                   | **2** | disable client, so that APEX will start a Websocket server |
2789                   +-------+------------------------------------------------------------+
2790                   | **3** | the port for the Websocket server APEX will start          |
2791                   +-------+------------------------------------------------------------+
2792
2793 REST Client IO
2794 ##############
2795
2796             .. container:: paragraph
2797
2798                APEX can act as REST client on the input as well as on
2799                the output interface. The media type is
2800                ``application/json``, so this plugin does only work with
2801                the JSON Event protocol.
2802
2803 REST Client Input
2804 =================
2805
2806                .. container:: paragraph
2807
2808                   APEX will connect to a given URL to receive events,
2809                   but not send any events. The server is polled, i.e.
2810                   APEX will do an HTTP GET, take the result, and then do
2811                   the next GET. Any required timing needs to be handled
2812                   by the server configured via the URL. For instance,
2813                   the server could support a wait timeout via the URL as
2814                   ``?timeout=100ms``.
2815
2816                .. container:: listingblock
2817
2818                   .. container:: content
2819
2820                      .. code::
2821
2822                         "carrierTechnologyParameters" : {
2823                           "carrierTechnology" : "RESTCLIENT", (1)
2824                           "parameterClassName" :
2825                             "org.onap.policy.apex.plugins.event.carrier.restclient.RESTClientCarrierTechnologyParameters",
2826                           "parameters" : {
2827                             "url" : "http://example.org:8080/triggers/events", (2)
2828                           }
2829                         }
2830
2831                .. container:: colist arabic
2832
2833                   +-------+---------------------------------------+
2834                   | **1** | set REST client as carrier technology |
2835                   +-------+---------------------------------------+
2836                   | **2** | the URL of the HTTP server for events |
2837                   +-------+---------------------------------------+
2838
2839 REST Client Output
2840 ==================
2841
2842                .. container:: paragraph
2843
2844                   APEX will connect to a given URL to send events, but
2845                   not receive any events. The default HTTP operation is
2846                   POST (no configuration required). To change it to PUT
2847                   simply add the configuration parameter (as shown in
2848                   the example below).
2849                   The URL can be configured statically or tagged
2850                   as ``?example.{site}.org:8080/{trig}/events``,
2851                   all tags such as ``site`` and ``trig`` in the URL
2852                   need to be set  in the properties object available to the tasks.
2853                   In addition, the keys should exactly match with the tags defined in url.
2854                   The scope of the properties object is per HTTP call.
2855                   Hence, key/value pairs set in the properties object by task
2856                   is only available for that specific HTTP call.
2857
2858                .. container:: listingblock
2859
2860                   .. container:: content
2861
2862                      .. code::
2863
2864                         "carrierTechnologyParameters" : {
2865                           "carrierTechnology" : "RESTCLIENT", (1)
2866                           "parameterClassName" :
2867                             "org.onap.policy.apex.plugins.event.carrier.restclient.RESTClientCarrierTechnologyParameters",
2868                           "parameters" : {
2869                             "url" : "http://example.com:8888/actions/events", (2)
2870                             "url" : "http://example.{site}.com:8888/{trig}/events", (2')
2871                             "httpMethod" : "PUT" (3)
2872                           }
2873                         }
2874
2875                .. container:: colist arabic
2876
2877                   +-------+--------------------------------------------------+
2878                   | **1** | set REST client as carrier technology            |
2879                   +-------+--------------------------------------------------+
2880                   | **2** | the static URL of the HTTP server for events     |
2881                   +-------+--------------------------------------------------+
2882                   | **2'**| the tagged URL of the HTTP server for events     |
2883                   +-------+--------------------------------------------------+
2884                   | **3** | use HTTP PUT (remove this line to use HTTP POST) |
2885                   +-------+--------------------------------------------------+
2886
2887 REST Server IO
2888 ##############
2889
2890             .. container:: paragraph
2891
2892                APEX supports a REST server for input and output.
2893
2894             .. container:: paragraph
2895
2896                The REST server plugin always uses a synchronous mode. A
2897                client does a HTTP GET on the APEX REST server with the
2898                input event and receives the generated output event in
2899                the server reply. This means that for the REST server
2900                there has to always to be an input with an associated
2901                output. Input or output only are not permitted.
2902
2903             .. container:: paragraph
2904
2905                The plugin will start a Grizzly server as REST server for
2906                a normal APEX engine. If the APEX engine is executed as a
2907                servlet, for instance inside Tomcat, then Tomcat will be
2908                used as REST server (this case requires configuration on
2909                Tomcat as well).
2910
2911             .. container:: paragraph
2912
2913                Some configuration restrictions apply for all scenarios:
2914
2915             .. container:: ulist
2916
2917                -  Minimum port: 1024
2918
2919                -  Maximum port: 65535
2920
2921                -  The media type is ``application/json``, so this plugin
2922                   does only work with the JSON Event protocol.
2923
2924             .. container:: paragraph
2925
2926                The URL the client calls is created using
2927
2928             .. container:: ulist
2929
2930                -  the configured host and port, e.g.
2931                   ``http://localhost:12345``
2932
2933                -  the standard path, e.g. ``/apex/``
2934
2935                -  the name of the input/output, e.g. ``FirstConsumer/``
2936
2937                -  the input or output name, e.g. ``EventIn``.
2938
2939             .. container:: paragraph
2940
2941                The examples above lead to the URL
2942                ``http://localhost:12345/apex/FirstConsumer/EventIn``.
2943
2944             .. container:: paragraph
2945
2946                A client can also get status information of the REST
2947                server using ``/Status``, e.g.
2948                ``http://localhost:12345/apex/FirstConsumer/Status``.
2949
2950 REST Server Stand-alone
2951 =======================
2952
2953                .. container:: paragraph
2954
2955                   We need to configure a REST server input and a REST
2956                   server output. Input and output are associated with
2957                   each other via there name.
2958
2959                .. container:: paragraph
2960
2961                   Timeouts for REST calls need to be set carefully. If
2962                   they are too short, the call might timeout before a
2963                   policy finished creating an event.
2964
2965                .. container:: paragraph
2966
2967                   The following example configures the input named as
2968                   ``MyConsumer`` and associates an output named
2969                   ``MyProducer`` with it.
2970
2971                .. container:: listingblock
2972
2973                   .. container:: content
2974
2975                      .. code::
2976
2977                         "eventInputParameters": {
2978                           "MyConsumer": {
2979                             "carrierTechnologyParameters" : {
2980                               "carrierTechnology" : "RESTSERVER", (1)
2981                               "parameterClassName" :
2982                                 "org.onap.policy.apex.plugins.event.carrier.restserver.RESTServerCarrierTechnologyParameters",
2983                               "parameters" : {
2984                                 "standalone" : true, (2)
2985                                 "host" : "localhost", (3)
2986                                 "port" : 12345 (4)
2987                               }
2988                             },
2989                             "eventProtocolParameters":{
2990                               "eventProtocol" : "JSON" (5)
2991                             },
2992                             "synchronousMode"    : true, (6)
2993                             "synchronousPeer"    : "MyProducer", (7)
2994                             "synchronousTimeout" : 500 (8)
2995                           }
2996                         }
2997
2998                .. container:: colist arabic
2999
3000                   +-------+---------------------------------------+
3001                   | **1** | set REST server as carrier technology |
3002                   +-------+---------------------------------------+
3003                   | **2** | set the server as stand-alone         |
3004                   +-------+---------------------------------------+
3005                   | **3** | set the server host                   |
3006                   +-------+---------------------------------------+
3007                   | **4** | set the server listen port            |
3008                   +-------+---------------------------------------+
3009                   | **5** | use JSON event protocol               |
3010                   +-------+---------------------------------------+
3011                   | **6** | activate synchronous mode             |
3012                   +-------+---------------------------------------+
3013                   | **7** | associate an output ``MyProducer``    |
3014                   +-------+---------------------------------------+
3015                   | **8** | set a timeout of 500 milliseconds     |
3016                   +-------+---------------------------------------+
3017
3018                .. container:: paragraph
3019
3020                   The following example configures the output named as
3021                   ``MyProducer`` and associates the input ``MyConsumer``
3022                   with it. Note that for the output there are no more
3023                   paramters (such as host or port), since they are
3024                   already configured in the associated input
3025
3026                .. container:: listingblock
3027
3028                   .. container:: content
3029
3030                      .. code::
3031
3032                         "eventOutputParameters": {
3033                           "MyProducer": {
3034                             "carrierTechnologyParameters":{
3035                               "carrierTechnology" : "RESTSERVER",
3036                               "parameterClassName" :
3037                                 "org.onap.policy.apex.plugins.event.carrier.restserver.RESTServerCarrierTechnologyParameters"
3038                             },
3039                             "eventProtocolParameters":{
3040                               "eventProtocol" : "JSON"
3041                             },
3042                             "synchronousMode"    : true,
3043                             "synchronousPeer"    : "MyConsumer",
3044                             "synchronousTimeout" : 500
3045                           }
3046                         }
3047
3048 REST Server Stand-alone, multi input
3049 ====================================
3050
3051                .. container:: paragraph
3052
3053                   Any number of input/output pairs for REST servers can
3054                   be configured. For instance, we can configure an input
3055                   ``FirstConsumer`` with output ``FirstProducer`` and an
3056                   input ``SecondConsumer`` with output
3057                   ``SecondProducer``. Important is that there is always
3058                   one pair of input/output.
3059
3060 REST Server Stand-alone in Servlet
3061 ==================================
3062
3063                .. container:: paragraph
3064
3065                   If APEX is executed as a servlet, e.g. inside Tomcat,
3066                   the configuration becomes easier since the plugin can
3067                   now use Tomcat as the REST server. In this scenario,
3068                   there are not parameters (port, host, etc.) and the
3069                   key ``standalone`` must not be used (or set to false).
3070
3071                .. container:: paragraph
3072
3073                   For the Tomcat configuration, we need to add the REST
3074                   server plugin, e.g.
3075
3076                .. container:: listingblock
3077
3078                   .. container:: content
3079
3080                      .. code::
3081
3082                         <servlet>
3083                           ...
3084                           <init-param>
3085                             ...
3086                             <param-value>org.onap.policy.apex.plugins.event.carrier.restserver</param-value>
3087                           </init-param>
3088                           ...
3089                         </servlet>
3090
3091 REST Requestor IO
3092 ##################
3093
3094             .. container:: paragraph
3095
3096                APEX can act as REST requestor on the input as well as on
3097                the output interface. The media type is
3098                ``application/json``, so this plugin does only work with
3099                the JSON Event protocol.
3100
3101 REST Requestor Input
3102 ====================
3103
3104                .. container:: paragraph
3105
3106                   APEX will connect to a given URL to request an input.
3107                   The URL can be configured statically or tagged
3108                   as ``?example.{site}.org:8080/{trig}/events``,
3109                   all tags such as ``site`` and ``trig`` in the URL
3110                   need to be set  in the properties object available to the tasks.
3111                   In addition, the keys should exactly match with the tags defined in url.
3112                   The scope of the properties object is per HTTP call.
3113                   Hence, key/value pairs set in the properties object by task
3114                   is only available for that specific HTTP call.
3115
3116                .. container:: listingblock
3117
3118                   .. container:: content
3119
3120                      .. code::
3121
3122                         "carrierTechnologyParameters": {
3123                           "carrierTechnology": "RESTREQUESTOR", (1)
3124                           "parameterClassName": "org.onap.policy.apex.plugins.event.carrier.restrequestor.RESTRequestorCarrierTechnologyParameters",
3125                           "parameters": {
3126                             "url": "http://localhost:54321/some/path/to/rest/resource", (2)
3127                             "url": "http://localhost:54321/{site}/path/to/rest/{resValue}", (2')
3128                             "httpMethod": "POST", (3)
3129                             "restRequestTimeout": 2000 (4)
3130                           }
3131                         },
3132
3133                .. container:: colist arabic
3134
3135                   +-------+--------------------------------------------------+
3136                   | **1** | set REST requestor as carrier technology         |
3137                   +-------+--------------------------------------------------+
3138                   | **2** | the static URL of the HTTP server for events     |
3139                   +-------+--------------------------------------------------+
3140                   | **2'**| the tagged URL of the HTTP server for events     |
3141                   +-------+--------------------------------------------------+
3142                   | **3** | use HTTP PUT (remove this line to use HTTP POST) |
3143                   +-------+--------------------------------------------------+
3144                   | **4** | request timeout in milliseconds                  |
3145                   +-------+--------------------------------------------------+
3146
3147                .. container:: paragraph
3148
3149                   Further settings are required on the consumer to
3150                   define the event that is requested, for example:
3151
3152                .. container:: listingblock
3153
3154                   .. container:: content
3155
3156                      .. code::
3157
3158                         "eventName": "GuardResponseEvent", (1)
3159                         "eventNameFilter": "GuardResponseEvent", (2)
3160                         "requestorMode": true, (3)
3161                         "requestorPeer": "GuardRequestorProducer", (4)
3162                         "requestorTimeout": 500 (5)
3163
3164                .. container:: colist arabic
3165
3166                   +-------+---------------------------+
3167                   | **1** | the event name            |
3168                   +-------+---------------------------+
3169                   | **2** | a filter on the event     |
3170                   +-------+---------------------------+
3171                   | **3** | the mode of the requestor |
3172                   +-------+---------------------------+
3173                   | **4** | a peer for the requestor  |
3174                   +-------+---------------------------+
3175                   | **5** | a general request timeout |
3176                   +-------+---------------------------+
3177
3178 REST Requestor Output
3179 =====================
3180
3181                .. container:: paragraph
3182
3183                   APEX will connect to a given URL to send events, but
3184                   not receive any events.
3185
3186                .. container:: listingblock
3187
3188                   .. container:: content
3189
3190                      .. code::
3191
3192                         "carrierTechnologyParameters": {
3193                           "carrierTechnology": "RESTREQUESTOR", (1)
3194                           "parameterClassName": "org.onap.policy.apex.plugins.event.carrier.restrequestor.RESTRequestorCarrierTechnologyParameters"
3195                         },
3196
3197                .. container:: colist arabic
3198
3199                   +-------+------------------------------------------+
3200                   | **1** | set REST requestor as carrier technology |
3201                   +-------+------------------------------------------+
3202
3203                .. container:: paragraph
3204
3205                   Further settings are required on the consumer to
3206                   define the event that is requested, for example:
3207
3208                .. container:: listingblock
3209
3210                   .. container:: content
3211
3212                      .. code::
3213
3214                         "eventNameFilter": "GuardRequestEvent", (1)
3215                         "requestorMode": true, (2)
3216                         "requestorPeer": "GuardRequestorConsumer", (3)
3217                         "requestorTimeout": 500 (4)
3218
3219                .. container:: colist arabic
3220
3221                   +-------+---------------------------+
3222                   | **1** | a filter on the event     |
3223                   +-------+---------------------------+
3224                   | **2** | the mode of the requestor |
3225                   +-------+---------------------------+
3226                   | **3** | a peer for the requestor  |
3227                   +-------+---------------------------+
3228                   | **4** | a general request timeout |
3229                   +-------+---------------------------+
3230
3231 Event Protocols, Format and Encoding
3232 ------------------------------------
3233
3234          .. container:: paragraph
3235
3236             Event protocols define what event formats APEX can receive
3237             (input) and should send (output). They can be used in any
3238             combination for input and output, unless further restricted
3239             by a carrier technology plugin (for instance for JMS
3240             output). There can only be 1 event protocol per event
3241             plugin.
3242
3243          .. container:: paragraph
3244
3245             Supported *input* event protocols are:
3246
3247          .. container:: ulist
3248
3249             -  JSON, the event as a JSON string
3250
3251             -  APEX, an APEX event
3252
3253             -  JMS object, the event as a JMS object,
3254
3255             -  JMS text, the event as a JMS text,
3256
3257             -  XML, the event as an XML string,
3258
3259             -  YAML, the event as YAML text
3260
3261          .. container:: paragraph
3262
3263             Supported *output* event protocols are:
3264
3265          .. container:: ulist
3266
3267             -  JSON, the event as a JSON string
3268
3269             -  APEX, an APEX event
3270
3271             -  JMS object, the event as a JMS object,
3272
3273             -  JMS text, the event as a JMS text,
3274
3275             -  XML, the event as an XML string,
3276
3277             -  YAML, the event as YAML text
3278
3279          .. container:: paragraph
3280
3281             New event protocols can be added as plugins to APEX or
3282             developed outside APEX and added to an APEX deployment.
3283
3284 JSON Event
3285 ##########
3286
3287             .. container:: paragraph
3288
3289                The event protocol for JSON encoding does not require a
3290                specific plugin, it is supported by default. Furthermore,
3291                there is no difference in the configuration for the input
3292                and output interface.
3293
3294             .. container:: paragraph
3295
3296                For an input, APEX requires a well-formed JSON string.
3297                Well-formed here means according to the definitions of a
3298                policy. Any JSON string that is not defined as a trigger
3299                event (consume) will not be consumed (errors will be
3300                thrown). For output JSON events, APEX will always produce
3301                valid JSON strings according to the definition in the
3302                policy model.
3303
3304             .. container:: paragraph
3305
3306                The following JSON shows the configuration.
3307
3308             .. container:: listingblock
3309
3310                .. container:: content
3311
3312                   .. code::
3313
3314                      "eventProtocolParameters":{
3315                        "eventProtocol" : "JSON"
3316                      }
3317
3318             .. container:: paragraph
3319
3320                For JSON events, there are a few more optional
3321                parameters, which allow to define a mapping for standard
3322                event fields. An APEX event must have the fields
3323                ``name``, ``version``, ``source``, and ``target``
3324                defined. Sometimes it is not possible to configure a
3325                trigger or actioning system to use those fields. However,
3326                they might be in an event generated outside APEX (or used
3327                outside APEX) just with different names. To configure
3328                APEX to map between the different event names, simply add
3329                the following parameters to a JSON event:
3330
3331             .. container:: listingblock
3332
3333                .. container:: content
3334
3335                   .. code::
3336
3337                      "eventProtocolParameters":{
3338                        "eventProtocol" : "JSON",
3339                        "nameAlias"     : "policyName", (1)
3340                        "versionAlias"  : "policyVersion", (2)
3341                        "sourceAlias"   : "from", (3)
3342                        "targetAlias"   : "to", (4)
3343                        "nameSpaceAlias": "my.name.space" (5)
3344                      }
3345
3346             .. container:: colist arabic
3347
3348                +-----------------------------------+-----------------------------------+
3349                | **1**                             | mapping for the ``name`` field,   |
3350                |                                   | here from a field called          |
3351                |                                   | ``policyName``                    |
3352                +-----------------------------------+-----------------------------------+
3353                | **2**                             | mapping for the ``version``       |
3354                |                                   | field, here from a field called   |
3355                |                                   | ``policyVersion``                 |
3356                +-----------------------------------+-----------------------------------+
3357                | **3**                             | mapping for the ``source`` field, |
3358                |                                   | here from a field called ``from`` |
3359                |                                   | (only for an input event)         |
3360                +-----------------------------------+-----------------------------------+
3361                | **4**                             | mapping for the ``target`` field, |
3362                |                                   | here from a field called ``to``   |
3363                |                                   | (only for an output event)        |
3364                +-----------------------------------+-----------------------------------+
3365                | **5**                             | mapping for the ``nameSpace``     |
3366                |                                   | field, here from a field called   |
3367                |                                   | ``my.name.space``                 |
3368                +-----------------------------------+-----------------------------------+
3369
3370 APEX Event
3371 ##########
3372             .. container:: paragraph
3373
3374                The event protocol for APEX events does not require a
3375                specific plugin, it is supported by default. Furthermore,
3376                there is no difference in the configuration for the input
3377                and output interface.
3378
3379             .. container:: paragraph
3380
3381                For input and output APEX uses APEX events.
3382
3383             .. container:: paragraph
3384
3385                The following JSON shows the configuration.
3386
3387             .. container:: listingblock
3388
3389                .. container:: content
3390
3391                   .. code::
3392
3393                      "eventProtocolParameters":{
3394                        "eventProtocol" : "APEX"
3395                      }
3396
3397 JMS Event
3398 #########
3399
3400             .. container:: paragraph
3401
3402                The event protocol for JMS is provided by the APEX JMS
3403                plugin. The plugin supports encoding as JSON text or as
3404                object. There is no difference in the configuration for
3405                the input and output interface.
3406
3407 JMS Text
3408 ========
3409                .. container:: paragraph
3410
3411                   If used as input, APEX will take a JMS message and
3412                   extract a JSON string, then proceed as if a JSON event
3413                   was received. If used as output, APEX will take the
3414                   event produced by a policy, create a JSON string, and
3415                   then wrap it into a JMS message.
3416
3417                .. container:: paragraph
3418
3419                   The configuration for JMS text is as follows:
3420
3421                .. container:: listingblock
3422
3423                   .. container:: content
3424
3425                      .. code::
3426
3427                         "eventProtocolParameters":{
3428                           "eventProtocol" : "JMSTEXT",
3429                           "parameterClassName" :
3430                             "org.onap.policy.apex.plugins.event.protocol.jms.JMSTextEventProtocolParameters"
3431                         }
3432
3433 JMS Object
3434 ==========
3435                .. container:: paragraph
3436
3437                   If used as input, APEX will will take a JMS message,
3438                   extract a Java Bean from the ``ObjectMessage``
3439                   message, construct an APEX event and put the bean on
3440                   the APEX event as a parameter. If used as output, APEX
3441                   will take the event produced by a policy, create a
3442                   Java Bean and send it as a JMS message.
3443
3444                .. container:: paragraph
3445
3446                   The configuration for JMS object is as follows:
3447
3448                .. container:: listingblock
3449
3450                   .. container:: content
3451
3452                      .. code::
3453
3454                         "eventProtocolParameters":{
3455                           "eventProtocol" : "JMSOBJECT",
3456                           "parameterClassName" :
3457                             "org.onap.policy.apex.plugins.event.protocol.jms.JMSObjectEventProtocolParameters"
3458                         }
3459
3460 YAML Event
3461 ##########
3462
3463             .. container:: paragraph
3464
3465                The event protocol for YAML is provided by the APEX YAML
3466                plugin. There is no difference in the configuration for
3467                the input and output interface.
3468
3469             .. container:: paragraph
3470
3471                If used as input, APEX will consume events as YAML and
3472                map them to policy trigger events. Not well-formed YAML
3473                and not understood trigger events will be rejected. If
3474                used as output, APEX produce YAML encoded events from the
3475                event a policy produces. Those events will always be
3476                well-formed according to the definition in the policy
3477                model.
3478
3479             .. container:: paragraph
3480
3481                The following code shows the configuration.
3482
3483             .. container:: listingblock
3484
3485                .. container:: content
3486
3487                   .. code::
3488
3489                      "eventProtocolParameters":{
3490                        "eventProtocol" : "XML",
3491                        "parameterClassName" :
3492                            "org.onap.policy.apex.plugins.event.protocol.yaml.YamlEventProtocolParameters"
3493                      }
3494
3495 XML Event
3496 #########
3497             .. container:: paragraph
3498
3499                The event protocol for XML is provided by the APEX XML
3500                plugin. There is no difference in the configuration for
3501                the input and output interface.
3502
3503             .. container:: paragraph
3504
3505                If used as input, APEX will consume events as XML and map
3506                them to policy trigger events. Not well-formed XML and
3507                not understood trigger events will be rejected. If used
3508                as output, APEX produce XML encoded events from the event
3509                a policy produces. Those events will always be
3510                well-formed according to the definition in the policy
3511                model.
3512
3513             .. container:: paragraph
3514
3515                The following code shows the configuration.
3516
3517             .. container:: listingblock
3518
3519                .. container:: content
3520
3521                   .. code::
3522
3523                      "eventProtocolParameters":{
3524                        "eventProtocol" : "XML",
3525                        "parameterClassName" :
3526                            "org.onap.policy.apex.plugins.event.protocol.xml.XMLEventProtocolParameters"
3527                      }
3528
3529 A configuration example
3530 -----------------------
3531
3532          .. container:: paragraph
3533
3534             The following example loads all available plug-ins.
3535
3536          .. container:: paragraph
3537
3538             Events are consumed from a Websocket, APEX as client.
3539             Consumed event format is JSON.
3540
3541          .. container:: paragraph
3542
3543             Events are produced to Kafka. Produced event format is XML.
3544
3545          .. container:: listingblock
3546
3547             .. container:: content
3548
3549                .. code::
3550
3551                   {
3552                     "engineServiceParameters" : {
3553                       "name"          : "MyApexEngine",
3554                       "version"        : "0.0.1",
3555                       "id"             :  45,
3556                       "instanceCount"  : 4,
3557                       "deploymentPort" : 12345,
3558                       "policyModelFileName" : "examples/models/some-model.json",
3559                       "engineParameters"    : {
3560                         "executorParameters" : {
3561                           "JAVASCRIPT" : {
3562                             "parameterClassName" :
3563                                 "org.onap.policy.apex.plugins.executor.javascript.JavascriptExecutorParameters"
3564                           },
3565                           "JYTHON" : {
3566                             "parameterClassName" :
3567                                 "org.onap.policy.apex.plugins.executor.jython.JythonExecutorParameters"
3568                           },
3569                           "JRUBY" : {
3570                             "parameterClassName" :
3571                                 "org.onap.policy.apex.plugins.executor.jruby.JrubyExecutorParameters"
3572                           },
3573                           "JAVA" : {
3574                             "parameterClassName" :
3575                                 "org.onap.policy.apex.plugins.executor.java.JavaExecutorParameters"
3576                           },
3577                           "MVEL" : {
3578                             "parameterClassName" :
3579                                 "org.onap.policy.apex.plugins.executor.mvel.MVELExecutorParameters"
3580                           }
3581                         },
3582                         "contextParameters" : {
3583                           "parameterClassName" :
3584                               "org.onap.policy.apex.context.parameters.ContextParameters",
3585                           "schemaParameters" : {
3586                             "Avro":{
3587                                "parameterClassName" :
3588                                    "org.onap.policy.apex.plugins.context.schema.avro.AvroSchemaHelperParameters"
3589                             }
3590                           }
3591                         }
3592                       }
3593                     },
3594                     "producerCarrierTechnologyParameters" : {
3595                       "carrierTechnology" : "KAFKA",
3596                       "parameterClassName" :
3597                           "org.onap.policy.apex.plugins.event.carrier.kafka.KAFKACarrierTechnologyParameters",
3598                       "parameters" : {
3599                         "bootstrapServers"  : "localhost:49092",
3600                         "acks"              : "all",
3601                         "retries"           : 0,
3602                         "batchSize"         : 16384,
3603                         "lingerTime"        : 1,
3604                         "bufferMemory"      : 33554432,
3605                         "producerTopic"     : "apex-out",
3606                         "keySerializer"     : "org.apache.kafka.common.serialization.StringSerializer",
3607                         "valueSerializer"   : "org.apache.kafka.common.serialization.StringSerializer"
3608                       }
3609                     },
3610                     "producerEventProtocolParameters" : {
3611                       "eventProtocol" : "XML",
3612                            "parameterClassName" :
3613                                "org.onap.policy.apex.plugins.event.protocol.xml.XMLEventProtocolParameters"
3614                     },
3615                     "consumerCarrierTechnologyParameters" : {
3616                       "carrierTechnology" : "WEBSOCKET",
3617                       "parameterClassName" :
3618                           "org.onap.policy.apex.plugins.event.carrier.websocket.WEBSOCKETCarrierTechnologyParameters",
3619                       "parameters" : {
3620                         "host" : "localhost",
3621                         "port" : 88888
3622                       }
3623                     },
3624                     "consumerEventProtocolParameters" : {
3625                       "eventProtocol" : "JSON"
3626                     }
3627                   }
3628
3629 Engine and Applications of the APEX System
3630 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3631
3632 Introduction to APEX Engine and Applications
3633 --------------------------------------------
3634
3635          .. container:: paragraph
3636
3637             The core of APEX is the APEX Engine, also known as the APEX
3638             Policy Engine or the APEX PDP (since it is in fact a Policy
3639             Decision Point). Beside this engine, an APEX system comes
3640             with a few applications intended to help with policy
3641             authoring, deployment, and execution.
3642
3643          .. container:: paragraph
3644
3645             The engine itself and most applications are started from the
3646             command line with command line arguments. This is called a
3647             Command Line Interface (CLI). Some applications require an
3648             installation on a webserver, as for instance the REST
3649             Editor. Those applications can be accessed via a web
3650             browser.
3651
3652          .. container:: paragraph
3653
3654             You can also use the available APEX APIs and applications to
3655             develop other applications as required. This includes policy
3656             languages (and associated parsers and compilers /
3657             interpreters), GUIs to access APEX or to define policies,
3658             clients to connect to APEX, etc.
3659
3660          .. container:: paragraph
3661
3662             For this documentation, we assume an installation of APEX as
3663             a full system based on a current ONAP release.
3664
3665 CLI on Unix, Windows, and Cygwin
3666 --------------------------------
3667
3668          .. container:: paragraph
3669
3670             A note on APEX CLI applications: all applications and the
3671             engine itself have been deployed and tested on different
3672             operating systems: Red Hat, Ubuntu, Debian, Mac OSX,
3673             Windows, Cygwin. Each operating system comes with its own
3674             way of configuring and executing Java. The main items here
3675             are:
3676
3677          .. container:: ulist
3678
3679             -  For UNIX systems (RHL, Ubuntu, Debian, Mac OSX), the
3680                provided bash scripts work as expected with absolute
3681                paths (e.g.
3682                ``/opt/app/policy/apex-pdp/apex-pdp-2.0.0-SNAPSHOT/examples``),
3683                indirect and linked paths (e.g. ``../apex/apex``), and
3684                path substitutions using environment settings (e.g.
3685                ``$APEX_HOME/bin/``)
3686
3687             -  For Windows systems, the provided batch files (``.bat``)
3688                work as expected with with absolute paths (e.g.
3689                ``C:\apex\apex-2.0.0-SNAPSHOT\examples``), and path
3690                substitutions using environment settings (e.g.
3691                ``%APEX_HOME%\bin\``)
3692
3693             -  For Cygwin system we assume a standard Cygwin
3694                installation with standard tools (mainly bash) using a
3695                Windows Java installation. This means that the bash
3696                scripts can be used as in UNIX, however any argument
3697                pointing to files and directories need to use either a
3698                DOS path (e.g.
3699                ``C:\apex\apex-2.0.0-SNAPSHOT\examples\config...``) or
3700                the command ``cygpath`` with a mixed option. The reason
3701                for that is: Cygwin executes Java using UNIX paths but
3702                then runs Java as a DOS/WINDOWS process, which requires
3703                DOS paths for file access.
3704
3705 The APEX Engine
3706 ---------------
3707
3708          .. container:: paragraph
3709
3710             The APEX engine can be started in different ways, depending
3711             your requirements. All scripts are located in the APEX *bin*
3712             directory
3713
3714          .. container:: paragraph
3715
3716             On UNIX and Cygwin systems use:
3717
3718          .. container:: ulist
3719
3720             -  ``apexEngine.sh`` - this script will
3721
3722                .. container:: ulist
3723
3724                   -  Test if ``$APEX_USER`` is set and if the user
3725                      exists, terminate with an error otherwise
3726
3727                   -  Test if ``$APEX_HOME`` is set. If not set, it will
3728                      use the default setting as
3729                      ``/opt/app/policy/apex-pdp/apex-pdp``. Then the set
3730                      directory is tested to exist, the script will
3731                      terminate if not.
3732
3733                   -  When all tests are passed successfully, the script
3734                      will call ``apexApps.sh`` with arguments to start
3735                      the APEX engine.
3736
3737             -  ``apexApps.sh engine`` - this is the general APEX
3738                application launcher, which will
3739
3740                .. container:: ulist
3741
3742                   -  Start the engine with the argument ``engine``
3743
3744                   -  Test if ``$APEX_HOME`` is set and points to an
3745                      existing directory. If not set or directory does
3746                      not exist, script terminates.
3747
3748                   -  Not test for any settings of ``$APEX_USER``.
3749
3750          .. container:: paragraph
3751
3752             On Windows systems use ``apexEngine.bat`` and
3753             ``apexApps.bat engine`` respectively. Note: none of the
3754             windows batch files will test for ``%APEX_USER%``.
3755
3756          .. container:: paragraph
3757
3758             Summary of alternatives to start the APEX Engine:
3759
3760          +--------------------------------------------------------+----------------------------------------------------------+
3761          | Unix, Cygwin                                           | Windows                                                  |
3762          +========================================================+==========================================================+
3763          | .. container::                                         | .. container::                                           |
3764          |                                                        |                                                          |
3765          |    .. container:: listingblock                         |    .. container:: listingblock                           |
3766          |                                                        |                                                          |
3767          |       .. container:: content                           |       .. container:: content                             |
3768          |                                                        |                                                          |
3769          |          .. code::                                     |          .. code::                                       |
3770          |                                                        |                                                          |
3771          |             # $APEX_HOME/bin/apexEngine.sh [args]      |             > %APEX_HOME%\bin\apexEngine.bat [args]      |
3772          |             # $APEX_HOME/bin/apexApps.sh engine [args] |             > %APEX_HOME%\bin\apexApps.bat engine [args] |
3773          +--------------------------------------------------------+----------------------------------------------------------+
3774
3775          .. container:: paragraph
3776
3777             The APEX engine comes with a few CLI arguments for setting
3778             configuration and policy model. The configuration file is
3779             always required. The policy model file is only required if
3780             no model file is specified in the configuration, or if the
3781             specified model file should be over written. The option
3782             ``-h`` prints a help screen.
3783
3784          .. container:: listingblock
3785
3786             .. container:: content
3787
3788                .. code::
3789
3790                   usage: org.onap.policy.apex.service.engine.main.ApexMain [options...]
3791                   options
3792                   -c,--config-file <CONFIG_FILE>  the full path to the configuration file to use, the configuration file must be a Json file
3793                                                   containing the Apex configuration parameters
3794                   -h,--help                       outputs the usage of this command
3795                   -m,--model-file <MODEL_FILE>    the full path to the model file to use, if set it overrides the model file set in the
3796                                                   configuration file
3797                   -v,--version                    outputs the version of Apex
3798
3799 The APEX CLI Editor
3800 -------------------
3801
3802          .. container:: paragraph
3803
3804             The CLI Editor allows to define policies from the command
3805             line. The application uses a simple language and supports
3806             all elements of an APEX policy. It can be used in to
3807             different ways:
3808
3809          .. container:: ulist
3810
3811             -  non-interactive, specifying a file with the commands to
3812                create a policy
3813
3814             -  interactive, using the editors CLI to create a policy
3815
3816          .. container:: paragraph
3817
3818             When a policy is fully specified, the editor will generate
3819             the APEX core policy specification in JSON. This core
3820             specification is called the policy model in the APEX engine
3821             and can be used directly with the APEX engine.
3822
3823          .. container:: paragraph
3824
3825             On UNIX and Cygwin systems use:
3826
3827          .. container:: ulist
3828
3829             -  ``apexCLIEditor.sh`` - simply starts the CLI editor,
3830                arguments to the script determine the mode of the editor
3831
3832             -  ``apexApps.sh cli-editor`` - simply starts the CLI
3833                editor, arguments to the script determine the mode of the
3834                editor
3835
3836          .. container:: paragraph
3837
3838             On Windows systems use:
3839
3840          .. container:: ulist
3841
3842             -  ``apexCLIEditor.bat`` - simply starts the CLI editor,
3843                arguments to the script determine the mode of the editor
3844
3845             -  ``apexApps.bat cli-editor`` - simply starts the CLI
3846                editor, arguments to the script determine the mode of the
3847                editor
3848
3849          .. container:: paragraph
3850
3851             Summary of alternatives to start the APEX CLI Editor:
3852
3853          +------------------------------------------------------------+--------------------------------------------------------------+
3854          | Unix, Cygwin                                               | Windows                                                      |
3855          +============================================================+==============================================================+
3856          | .. container::                                             | .. container::                                               |
3857          |                                                            |                                                              |
3858          |    .. container:: listingblock                             |    .. container:: listingblock                               |
3859          |                                                            |                                                              |
3860          |       .. container:: content                               |       .. container:: content                                 |
3861          |                                                            |                                                              |
3862          |          .. code::                                         |          .. code::                                           |
3863          |                                                            |                                                              |
3864          |             # $APEX_HOME/bin/apexCLIEditor.sh.sh [args]    |             > %APEX_HOME%\bin\apexCLIEditor.bat [args]       |
3865          |             # $APEX_HOME/bin/apexApps.sh cli-editor [args] |             > %APEX_HOME%\bin\apexApps.bat cli-editor [args] |
3866          +------------------------------------------------------------+--------------------------------------------------------------+
3867
3868          .. container:: paragraph
3869
3870             The option ``-h`` provides a help screen with all command
3871             line arguments.
3872
3873          .. container:: listingblock
3874
3875             .. container:: content
3876
3877                .. code::
3878
3879                   usage: org.onap.policy.apex.auth.clieditor.ApexCLIEditorMain [options...]
3880                   options
3881                    -a,--model-props-file <MODEL_PROPS_FILE>       name of the apex model properties file to use
3882                    -c,--command-file <COMMAND_FILE>               name of a file containing editor commands to run into the editor
3883                    -h,--help                                      outputs the usage of this command
3884                    -i,--input-model-file <INPUT_MODEL_FILE>       name of a file that contains an input model for the editor
3885                    -if,--ignore-failures <IGNORE_FAILURES_FLAG>   true or false, ignore failures of commands in command files and continue
3886                                                                   executing the command file
3887                    -l,--log-file <LOG_FILE>                       name of a file that will contain command logs from the editor, will log
3888                                                                   to standard output if not specified or suppressed with "-nl" flag
3889                    -m,--metadata-file <CMD_METADATA_FILE>         name of the command metadata file to use
3890                    -nl,--no-log                                   if specified, no logging or output of commands to standard output or log
3891                                                                   file is carried out
3892                    -nm,--no-model-output                          if specified, no output of a model to standard output or model output
3893                                                                   file is carried out, the user can use the "save" command in a script to
3894                                                                   save a model
3895                    -o,--output-model-file <OUTPUT_MODEL_FILE>     name of a file that will contain the output model for the editor, will
3896                                                                   output model to standard output if not specified or suppressed with
3897                                                                   "-nm" flag
3898                    -wd,--working-directory <WORKING_DIRECTORY>    the working directory that is the root for the CLI editor and is the
3899                                                                   root from which to look for included macro files
3900
3901 The APEX REST Editor
3902 --------------------
3903
3904          .. container:: paragraph
3905
3906             The standard way to use the APEX REST Editor is via an
3907             installation of the *war* file on a webserver. However, the
3908             REST editor can also be started via command line. This will
3909             start a Grizzly webserver with the *war* deployed. Access to
3910             the REST Editor is then via the provided URL
3911
3912          .. container:: paragraph
3913
3914             On UNIX and Cygwin systems use:
3915
3916          .. container:: ulist
3917
3918             -  ``apexRESTEditor.sh`` - simply starts the webserver with
3919                the REST editor
3920
3921             -  ``apexApps.sh rest-editor`` - simply starts the webserver
3922                with the REST editor
3923
3924          .. container:: paragraph
3925
3926             On Windows systems use:
3927
3928          .. container:: ulist
3929
3930             -  ``apexRESTEditor.bat`` - simply starts the webserver with
3931                the REST editor
3932
3933             -  ``apexApps.bat rest-editor`` - simply starts the
3934                webserver with the REST editor
3935
3936          .. container:: paragraph
3937
3938             Summary of alternatives to start the APEX REST Editor:
3939
3940          +-------------------------------------------------------------+---------------------------------------------------------------+
3941          | Unix, Cygwin                                                | Windows                                                       |
3942          +=============================================================+===============================================================+
3943          | .. container::                                              | .. container::                                                |
3944          |                                                             |                                                               |
3945          |    .. container:: listingblock                              |    .. container:: listingblock                                |
3946          |                                                             |                                                               |
3947          |       .. container:: content                                |       .. container:: content                                  |
3948          |                                                             |                                                               |
3949          |          .. code::                                          |          .. code::                                            |
3950          |                                                             |                                                               |
3951          |             # $APEX_HOME/bin/apexRESTEditor.sh.sh [args]    |             > %APEX_HOME%\bin\apexRESTEditor.bat [args]       |
3952          |             # $APEX_HOME/bin/apexApps.sh rest-editor [args] |             > %APEX_HOME%\bin\apexApps.bat rest-editor [args] |
3953          +-------------------------------------------------------------+---------------------------------------------------------------+
3954
3955          .. container:: paragraph
3956
3957             The option ``-h`` provides a help screen with all command
3958             line arguments.
3959
3960          .. container:: listingblock
3961
3962             .. container:: content
3963
3964                .. code::
3965
3966                   usage: org.onap.policy.apex.client.editor.rest.ApexEditorMain [options...]
3967                   -h,--help                        outputs the usage of this command
3968                   -l,--listen <ADDRESS>            the IP address to listen on.  Default value is localhost to restrict access to the
3969                                                    local machine only.
3970                   -p,--port <PORT>                 port to use for the Apex RESTful editor REST calls.
3971                   -t,--time-to-live <TIME_TO_LIVE> the amount of time in seconds that the server will run for before terminating. Default
3972                                                    value is -1 to run indefinitely.
3973
3974          .. container:: paragraph
3975
3976             If the REST Editor is started without any arguments the
3977             final messages will look similar to this:
3978
3979          .. container:: listingblock
3980
3981             .. container:: content
3982
3983                .. code::
3984
3985                   Apex Editor REST endpoint (ApexEditorMain: Config=[ApexEditorParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=READY) starting at http://localhost:18989/apexservices/ . . .
3986                   Sep 05, 2018 11:24:30 PM org.glassfish.grizzly.http.server.NetworkListener start
3987                   INFO: Started listener bound to [localhost:18989]
3988                   Sep 05, 2018 11:24:30 PM org.glassfish.grizzly.http.server.HttpServer start
3989                   INFO: [HttpServer] Started.
3990                   Apex Editor REST endpoint (ApexEditorMain: Config=[ApexEditorParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=RUNNING) started at http://localhost:18989/apexservices/
3991
3992          .. container:: paragraph
3993
3994             The last line states the URL on which the REST Editor can be
3995             accessed. The example above stated
3996             ``http://0.0.0.0:18989/apex/``. In a web browser use the URL
3997             ``http://localhost:18989`` and the REST Editor will start.
3998
3999 The APEX Monitoring Client
4000 --------------------------
4001
4002          .. container:: paragraph
4003
4004             The standard way to use the APEX Monitoring Client is via an
4005             installation of the *war* file on a webserver. However, the
4006             Monitoring Client can also be started via command line. This
4007             will start a Grizzly webserver with the *war* deployed.
4008             Access to the Monitoring Client is then via the provided URL
4009
4010          .. container:: paragraph
4011
4012             On UNIX and Cygwin systems use:
4013
4014          .. container:: ulist
4015
4016             -  ``apexApps.sh eng-monitoring`` - simply starts the
4017                webserver with the Monitoring Client
4018
4019          .. container:: paragraph
4020
4021             On Windows systems use:
4022
4023          .. container:: ulist
4024
4025             -  ``apexApps.bat eng-monitoring`` - simply starts the
4026                webserver with the Monitoring Client
4027
4028          .. container:: paragraph
4029
4030             The option ``-h`` provides a help screen with all command
4031             line arguments.
4032
4033          .. container:: listingblock
4034
4035             .. container:: content
4036
4037                .. code::
4038
4039                   usage: org.onap.policy.apex.client.monitoring.rest.ApexMonitoringRestMain [options...]
4040                   -h,--help                        outputs the usage of this command
4041                   -p,--port <PORT>                 port to use for the Apex Services REST calls
4042                   -t,--time-to-live <TIME_TO_LIVE> the amount of time in seconds that the server will run for before terminating
4043
4044          .. container:: paragraph
4045
4046             If the Monitoring Client is started without any arguments
4047             the final messages will look similar to this:
4048
4049          .. container:: listingblock
4050
4051             .. container:: content
4052
4053                .. code::
4054
4055                   Apex Services REST endpoint (ApexMonitoringRestMain: Config=[ApexMonitoringRestParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=READY) starting at http://localhost:18989/apexservices/ . . .
4056                   Sep 05, 2018 11:26:20 PM org.glassfish.grizzly.http.server.NetworkListener start
4057                   INFO: Started listener bound to [localhost:18989]
4058                   Sep 05, 2018 11:26:20 PM org.glassfish.grizzly.http.server.HttpServer start
4059                   INFO: [HttpServer] Started.
4060                   Apex Services REST endpoint (ApexMonitoringRestMain: Config=[ApexMonitoringRestParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=RUNNING) started at http://localhost:18989/apexservices/
4061
4062          .. container:: paragraph
4063
4064             The last line states the URL on which the Monitoring Client
4065             can be accessed. The example above stated
4066             ``http://localhost:18989/apexservices``. In a web browser
4067             use the URL ``http://localhost:18989``.
4068
4069 The APEX Deployment Client
4070 --------------------------
4071
4072          .. container:: paragraph
4073
4074             The standard way to use the APEX Deployment Client is via an
4075             installation of the *war* file on a webserver. However, the
4076             Deployment Client can also be started via command line. This
4077             will start a Grizzly webserver with the *war* deployed.
4078             Access to the Deployment Client is then via the provided URL
4079
4080          .. container:: paragraph
4081
4082             On UNIX and Cygwin systems use:
4083
4084          .. container:: ulist
4085
4086             -  ``apexApps.sh eng-deployment`` - simply starts the
4087                webserver with the Deployment Client
4088
4089          .. container:: paragraph
4090
4091             On Windows systems use:
4092
4093          .. container:: ulist
4094
4095             -  ``apexApps.bat eng-deployment`` - simply starts the
4096                webserver with the Deployment Client
4097
4098          .. container:: paragraph
4099
4100             The option ``-h`` provides a help screen with all command
4101             line arguments.
4102
4103          .. container:: listingblock
4104
4105             .. container:: content
4106
4107                .. code::
4108
4109                   usage: org.onap.policy.apex.client.deployment.rest.ApexDeploymentRestMain [options...]
4110                   -h,--help                        outputs the usage of this command
4111                   -p,--port <PORT>                 port to use for the Apex Services REST calls
4112                   -t,--time-to-live <TIME_TO_LIVE> the amount of time in seconds that the server will run for before terminating
4113
4114          .. container:: paragraph
4115
4116             If the Deployment Client is started without any arguments
4117             the final messages will look similar to this:
4118
4119          .. container:: listingblock
4120
4121             .. container:: content
4122
4123                .. code::
4124
4125                   Apex Services REST endpoint (ApexDeploymentRestMain: Config=[ApexDeploymentRestParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=READY) starting at http://localhost:18989/apexservices/ . . .
4126                   Sep 05, 2018 11:27:09 PM org.glassfish.grizzly.http.server.NetworkListener start
4127                   INFO: Started listener bound to [localhost:18989]
4128                   Sep 05, 2018 11:27:09 PM org.glassfish.grizzly.http.server.HttpServer start
4129                   INFO: [HttpServer] Started.
4130                   Apex Services REST endpoint (ApexDeploymentRestMain: Config=[ApexDeploymentRestParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=RUNNING) started at http://localhost:18989/apexservices/
4131
4132          .. container:: paragraph
4133
4134             The last line states the URL on which the Deployment Client
4135             can be accessed. The example above stated
4136             ``http://localhost:18989/apexservices``. In a web browser
4137             use the URL ``http://localhost:18989``.
4138
4139 The APEX Full Client
4140 --------------------
4141
4142          .. container:: paragraph
4143
4144             The APEX Full Client combines the REST Editor, the
4145             Monitoring Client, and the Deployment Client into a single
4146             application. The standard way to use the APEX Full Client is
4147             via an installation of the *war* file on a webserver.
4148             However, the Full Client can also be started via command
4149             line. This will start a Grizzly webserver with the *war*
4150             deployed. Access to the Full Client is then via the provided
4151             URL
4152
4153          .. container:: paragraph
4154
4155             On UNIX and Cygwin systems use:
4156
4157          .. container:: ulist
4158
4159             -  ``apexApps.sh full-client`` - simply starts the webserver
4160                with the Full Client
4161
4162          .. container:: paragraph
4163
4164             On Windows systems use:
4165
4166          .. container:: ulist
4167
4168             -  ``apexApps.bat full-client`` - simply starts the
4169                webserver with the Full Client
4170
4171          .. container:: paragraph
4172
4173             The option ``-h`` provides a help screen with all command
4174             line arguments.
4175
4176          .. container:: listingblock
4177
4178             .. container:: content
4179
4180                .. code::
4181
4182                   usage: org.onap.policy.apex.client.full.rest.ApexServicesRestMain [options...]
4183                   -h,--help                        outputs the usage of this command
4184                   -p,--port <PORT>                 port to use for the Apex Services REST calls
4185                   -t,--time-to-live <TIME_TO_LIVE> the amount of time in seconds that the server will run for before terminating
4186
4187          .. container:: paragraph
4188
4189             If the Full Client is started without any arguments the
4190             final messages will look similar to this:
4191
4192          .. container:: listingblock
4193
4194             .. container:: content
4195
4196                .. code::
4197
4198                   Apex Editor REST endpoint (ApexServicesRestMain: Config=[ApexServicesRestParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=READY) starting at http://localhost:18989/apexservices/ . . .
4199                   Sep 05, 2018 11:28:28 PM org.glassfish.grizzly.http.server.NetworkListener start
4200                   INFO: Started listener bound to [localhost:18989]
4201                   Sep 05, 2018 11:28:28 PM org.glassfish.grizzly.http.server.HttpServer start
4202                   INFO: [HttpServer] Started.
4203                   Apex Editor REST endpoint (ApexServicesRestMain: Config=[ApexServicesRestParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=RUNNING) started at http://localhost:18989/apexservices/
4204
4205          .. container:: paragraph
4206
4207             The last line states the URL on which the Monitoring Client
4208             can be accessed. The example above stated
4209             ``http://localhost:18989/apexservices``. In a web browser
4210             use the URL ``http://localhost:18989``.
4211
4212  The APEX Application Launcher
4213 ------------------------------
4214
4215          .. container:: paragraph
4216
4217             The standard applications (Engine, CLI Editor, REST Editor)
4218             come with dedicated start scripts. For all other APEX
4219             applications, we provide an application launcher.
4220
4221          .. container:: paragraph
4222
4223             On UNIX and Cygwin systems use:
4224
4225          .. container:: ulist
4226
4227             -  apexApps.sh\` - simply starts the application launcher
4228
4229          .. container:: paragraph
4230
4231             On Windows systems use:
4232
4233          .. container:: ulist
4234
4235             -  ``apexApps.bat`` - simply starts the application launcher
4236
4237          .. container:: paragraph
4238
4239             Summary of alternatives to start the APEX application
4240             launcher:
4241
4242          +-------------------------------------------------+---------------------------------------------------+
4243          | Unix, Cygwin                                    | Windows                                           |
4244          +=================================================+===================================================+
4245          | .. container::                                  | .. container::                                    |
4246          |                                                 |                                                   |
4247          |    .. container:: listingblock                  |    .. container:: listingblock                    |
4248          |                                                 |                                                   |
4249          |       .. container:: content                    |       .. container:: content                      |
4250          |                                                 |                                                   |
4251          |          .. code::                              |          .. code::                                |
4252          |                                                 |                                                   |
4253          |             # $APEX_HOME/bin/apexApps.sh [args] |             > %APEX_HOME%\bin\apexApps.bat [args] |
4254          +-------------------------------------------------+---------------------------------------------------+
4255
4256          .. container:: paragraph
4257
4258             The option ``-h`` provides a help screen with all launcher
4259             command line arguments.
4260
4261          .. container:: listingblock
4262
4263             .. container:: content
4264
4265                .. code::
4266
4267                   apexApps.sh - runs APEX applications
4268
4269                          Usage:  apexApps.sh [options] | [<application> [<application options>]]
4270
4271                          Options
4272                            -d <app>    - describes an application
4273                            -l          - lists all applications supported by this script
4274                            -h          - this help screen
4275
4276          .. container:: paragraph
4277
4278             Using ``-l`` lists all known application the launcher can
4279             start.
4280
4281          .. container:: listingblock
4282
4283             .. container:: content
4284
4285                .. code::
4286
4287                   apexApps.sh: supported applications:
4288                    --> ws-echo engine eng-monitoring full-client eng-deployment tpl-event-json model-2-cli rest-editor cli-editor ws-console
4289
4290          .. container:: paragraph
4291
4292             Using the ``-d <name>`` option describes the named
4293             application, for instance for the ``ws-console``:
4294
4295          .. container:: listingblock
4296
4297             .. container:: content
4298
4299                .. code::
4300
4301                   apexApps.sh: application 'ws-console'
4302                    --> a simple console sending events to APEX, connect to APEX consumer port
4303
4304          .. container:: paragraph
4305
4306             Launching an application is done by calling the script with
4307             only the application name and any CLI arguments for the
4308             application. For instance, starting the ``ws-echo``
4309             application with port ``8888``:
4310
4311          .. container:: listingblock
4312
4313             .. container:: content
4314
4315                .. code::
4316
4317                   apexApps.sh ws-echo -p 8888
4318
4319 Application: Create Event Templates
4320 -----------------------------------
4321
4322          .. container:: paragraph
4323
4324             **Status: Experimental**
4325
4326          .. container:: paragraph
4327
4328             This application takes a policy model (JSON or XML encoded)
4329             and generates templates for events in JSON format. This can
4330             help when a policy defines rather complex trigger or action
4331             events or complex events between states. The application can
4332             produce events for the types: stimuli (policy trigger
4333             events), internal (events between policy states), and
4334             response (action events).
4335
4336          +----------------------------------------------------------------+------------------------------------------------------------------+
4337          | Unix, Cygwin                                                   | Windows                                                          |
4338          +================================================================+==================================================================+
4339          | .. container::                                                 | .. container::                                                   |
4340          |                                                                |                                                                  |
4341          |    .. container:: listingblock                                 |    .. container:: listingblock                                   |
4342          |                                                                |                                                                  |
4343          |       .. container:: content                                   |       .. container:: content                                     |
4344          |                                                                |                                                                  |
4345          |          .. code::                                             |          .. code::                                               |
4346          |                                                                |                                                                  |
4347          |             # $APEX_HOME/bin/apexApps.sh tpl-event-json [args] |             > %APEX_HOME%\bin\apexApps.bat tpl-event-json [args] |
4348          +----------------------------------------------------------------+------------------------------------------------------------------+
4349
4350          .. container:: paragraph
4351
4352             The option ``-h`` provides a help screen.
4353
4354          .. container:: listingblock
4355
4356             .. container:: content
4357
4358                .. code::
4359
4360                   gen-model2event v{release-version} - generates JSON templates for events generated from a policy model
4361                   usage: gen-model2event
4362                    -h,--help                 prints this help and usage screen
4363                    -m,--model <MODEL-FILE>   set the input policy model file
4364                    -t,--type <TYPE>          set the event type for generation, one of:
4365                                              stimuli (trigger events), response (action
4366                                              events), internal (events between states)
4367                    -v,--version              prints the application version
4368
4369          .. container:: paragraph
4370
4371             The created templates are not valid events, instead they use
4372             some markup for values one will need to change to actual
4373             values. For instance, running the tool with the *Sample
4374             Domain* policy model as:
4375
4376          .. container:: listingblock
4377
4378             .. container:: content
4379
4380                .. code::
4381
4382                   apexApps.sh tpl-event-json -m $APEX_HOME/examples/models/SampleDomain/SamplePolicyModelJAVA.json -t stimuli
4383
4384          .. container:: paragraph
4385
4386             will produce the following status messages:
4387
4388          .. container:: listingblock
4389
4390             .. container:: content
4391
4392                .. code::
4393
4394                   gen-model2event: starting Event generator
4395                    --> model file: examples/models/SampleDomain/SamplePolicyModelJAVA.json
4396                    --> type: stimuli
4397
4398          .. container:: paragraph
4399
4400             and then run the generator application producing two event
4401             templates. The first template is called ``Event0000``.
4402
4403          .. container:: listingblock
4404
4405             .. container:: content
4406
4407                .. code::
4408
4409                   {
4410                           "name" : "Event0000",
4411                           "nameSpace" : "org.onap.policy.apex.sample.events",
4412                           "version" : "0.0.1",
4413                           "source" : "Outside",
4414                           "target" : "Match",
4415                           "TestTemperature" : ###double: 0.0###,
4416                           "TestTimestamp" : ###long: 0###,
4417                           "TestMatchCase" : ###integer: 0###,
4418                           "TestSlogan" : "###string###"
4419                   }
4420
4421          .. container:: paragraph
4422
4423             The values for the keys are marked with ``#`` and the
4424             expected type of the value. To create an actual stimuli
4425             event, all these markers need to be change to actual values,
4426             for instance:
4427
4428          .. container:: listingblock
4429
4430             .. container:: content
4431
4432                .. code::
4433
4434                   {
4435                           "name" : "Event0000",
4436                           "nameSpace" : "org.onap.policy.apex.sample.events",
4437                           "version" : "0.0.1",
4438                           "source" : "Outside",
4439                           "target" : "Match",
4440                           "TestTemperature" : 25,
4441                           "TestTimestamp" : 123456789123456789,
4442                           "TestMatchCase" : 1,
4443                           "TestSlogan" : "Testing the Match Case with Temperature 25"
4444                   }
4445
4446 Application: Convert a Policy Model to CLI Editor Commands
4447 ----------------------------------------------------------
4448
4449          .. container:: paragraph
4450
4451             **Status: Experimental**
4452
4453          .. container:: paragraph
4454
4455             This application takes a policy model (JSON or XML encoded)
4456             and generates commands for the APEX CLI Editor. This
4457             effectively reverses a policy specification realized with
4458             the CLI Editor.
4459
4460          +-------------------------------------------------------------+---------------------------------------------------------------+
4461          | Unix, Cygwin                                                | Windows                                                       |
4462          +=============================================================+===============================================================+
4463          | .. container::                                              | .. container::                                                |
4464          |                                                             |                                                               |
4465          |    .. container:: listingblock                              |    .. container:: listingblock                                |
4466          |                                                             |                                                               |
4467          |       .. container:: content                                |       .. container:: content                                  |
4468          |                                                             |                                                               |
4469          |          .. code::                                          |          .. code::                                            |
4470          |                                                             |                                                               |
4471          |             # $APEX_HOME/bin/apexApps.sh model-2-cli [args] |             > %APEX_HOME%\bin\apexApps.bat model-2-cli [args] |
4472          +-------------------------------------------------------------+---------------------------------------------------------------+
4473
4474          .. container:: paragraph
4475
4476             The option ``-h`` provides a help screen.
4477
4478          .. container:: listingblock
4479
4480             .. container:: content
4481
4482                .. code::
4483
4484                   usage: gen-model2cli
4485                    -h,--help                 prints this help and usage screen
4486                    -m,--model <MODEL-FILE>   set the input policy model file
4487                    -sv,--skip-validation     switch of validation of the input file
4488                    -v,--version              prints the application version
4489
4490          .. container:: paragraph
4491
4492             For instance, running the tool with the *Sample Domain*
4493             policy model as:
4494
4495          .. container:: listingblock
4496
4497             .. container:: content
4498
4499                .. code::
4500
4501                   apexApps.sh model-2-cli -m $APEX_HOME/examples/models/SampleDomain/SamplePolicyModelJAVA.json
4502
4503          .. container:: paragraph
4504
4505             will produce the following status messages:
4506
4507          .. container:: listingblock
4508
4509             .. container:: content
4510
4511                .. code::
4512
4513                   gen-model2cli: starting CLI generator
4514                    --> model file: examples/models/SampleDomain/SamplePolicyModelJAVA.json
4515
4516          .. container:: paragraph
4517
4518             and then run the generator application producing all CLI
4519             Editor commands and printing them to standard out.
4520
4521 Application: Websocket Clients (Echo and Console)
4522 -------------------------------------------------
4523
4524          .. container:: paragraph
4525
4526             **Status: Production**
4527
4528          .. container:: paragraph
4529
4530             The application launcher also provides a Websocket echo
4531             client and a Websocket console client. The echo client
4532             connects to APEX and prints all events it receives from
4533             APEX. The console client connects to APEX, reads input from
4534             the command line, and sends this input as events to APEX.
4535
4536          +------------------------------------------------------------+--------------------------------------------------------------+
4537          | Unix, Cygwin                                               | Windows                                                      |
4538          +============================================================+==============================================================+
4539          | .. container::                                             | .. container::                                               |
4540          |                                                            |                                                              |
4541          |    .. container:: listingblock                             |    .. container:: listingblock                               |
4542          |                                                            |                                                              |
4543          |       .. container:: content                               |       .. container:: content                                 |
4544          |                                                            |                                                              |
4545          |          .. code::                                         |          .. code::                                           |
4546          |                                                            |                                                              |
4547          |             # $APEX_HOME/bin/apexApps.sh ws-echo [args]    |             > %APEX_HOME%\bin\apexApps.bat ws-echo [args]    |
4548          |             # $APEX_HOME/bin/apexApps.sh ws-console [args] |             > %APEX_HOME%\bin\apexApps.bat ws-console [args] |
4549          +------------------------------------------------------------+--------------------------------------------------------------+
4550
4551          .. container:: paragraph
4552
4553             The arguments are the same for both applications:
4554
4555          .. container:: ulist
4556
4557             -  ``-p`` defines the Websocket port to connect to (defaults
4558                to ``8887``)
4559
4560             -  ``-s`` defines the host on which a Websocket server is
4561                running (defaults to ``localhost``)
4562
4563          .. container:: paragraph
4564
4565             A discussion on how to use these two applications to build
4566             an APEX system is detailed HowTo-Websockets.
4567
4568 My First Policy
4569 ^^^^^^^^^^^^^^^
4570
4571 Introduction
4572 ------------
4573          .. container:: paragraph
4574
4575             Consider a scenario where a supermarket chain called
4576             *HyperM* controls how it sells items in a policy-based
4577             manner. Each time an item is processed by *HyperM*'s
4578             point-of-sale (PoS) system an event is generated and
4579             published about that item of stock being sold. This event
4580             can then be used to update stock levels, etc..
4581
4582          .. container:: paragraph
4583
4584             *HyperM* want to extend this approach to allow some checks
4585             to be performed before the sale can be completed. This can
4586             be achieved by requesting a policy-controlled decision as
4587             each item is processed by for sale by each PoS system. The
4588             decision process is integrated with *HyperM*'s other IT
4589             systems that manage stock control, sourcing and purchasing,
4590             personnel systems, etc.
4591
4592          .. container:: paragraph
4593
4594             In this document we will show how APEX and APEX Policies can
4595             be used to achieve this, starting with a simple policy,
4596             building up to more complicated policy that demonstrates the
4597             features of APEX.
4598
4599 Data Models
4600 -----------
4601
4602 Sales Input Event
4603 #################
4604
4605             .. container:: paragraph
4606
4607                Each time a PoS system processes a sales item an event
4608                with the following format is emitted:
4609
4610             .. table:: Table 1. Sale Input Event
4611
4612                +----------------------+----------------------+-----------------------+
4613                | Event                | Fields               | Description           |
4614                +======================+======================+=======================+
4615                | SALE_INPUT           | time, sale_ID,       | Event indicating a    |
4616                |                      | amount, item_ID,     | sale of an item is    |
4617                |                      | quantity,            | occurring             |
4618                |                      | assistant_ID,        |                       |
4619                |                      | branch_ID, notes, …​ |                       |
4620                +----------------------+----------------------+-----------------------+
4621
4622             .. container:: paragraph
4623
4624                In each ``SALE_INPUT`` event the ``sale_ID`` field is a
4625                unique ID generated by the PoS system. A timestamp for
4626                the event is stored in the ``time`` field. The ``amount``
4627                field refers to the value of the item(s) to be sold (in
4628                cents). The ``item_ID`` field is a unique identifier for
4629                each item type, and can be used to retrieve more
4630                information about the item from *HyperM*'s stock control
4631                system. The ``quantity`` field refers to the quantity of
4632                the item to be sold. The ``assistant_ID`` field is a
4633                unique identifier for the PoS operator, and can be used
4634                to retrieve more information about the operator from the
4635                *HyperM*'s personnel system. Since *HyperM* has many
4636                branches the ``branch_ID`` identifies the shop. The
4637                ``notes`` field contains arbitrary notes about the sale.
4638
4639 Sales Decision Event
4640 ####################
4641
4642             .. container:: paragraph
4643
4644                After a ``SALE_INPUT`` event is emitted by the PoS system
4645                *HyperM*'s policy-based controlled sales checking system
4646                emits a Sale Authorization Event indicating whether the
4647                sale is authorized or denied. The PoS system can then
4648                listen for this event before continuing with the sale.
4649
4650             .. table:: Table 2. Sale Authorisation Event
4651
4652                +----------------------+----------------------+-----------------------+
4653                | Event                | Fields               | Description           |
4654                +======================+======================+=======================+
4655                | SALE_AUTH            | sale_ID, time,       | Event indicating a    |
4656                |                      | authorized, amount,  | sale of an item is    |
4657                |                      | item_ID, quantity,   | authorized or denied  |
4658                |                      | assistant_ID,        |                       |
4659                |                      | branch_ID, notes,    |                       |
4660                |                      | message…​            |                       |
4661                +----------------------+----------------------+-----------------------+
4662
4663             .. container:: paragraph
4664
4665                In each ``SALE_AUTH`` event the ``sale_ID`` field is
4666                copied from the ``SALE_INPUT`` event that trigger the
4667                decision request. The ``SALE_AUTH`` event is also
4668                timestamped using the ``time`` field, and a field called
4669                ``authorised`` is set to ``true`` or ``false`` depending
4670                on whether the sale is authorized or denied. The
4671                ``message`` field carries an optional message about why a
4672                sale was not authorized. The other fields from the
4673                ``SALE_INPUT`` event are also included for completeness.
4674
4675 Stock Control: Items
4676 ####################
4677
4678             .. container:: paragraph
4679
4680                *HyperM* maintains information about each item for sale
4681                in a database table called ``ITEMS``.
4682
4683             .. table:: Table 3. Items Database
4684
4685                +----------------------+----------------------+-----------------------+
4686                | Table                | Fields               | Description           |
4687                +======================+======================+=======================+
4688                | ITEMS                | item_ID,             | Database table        |
4689                |                      | description,         | describing each item  |
4690                |                      | cost_price, barcode, | for sale              |
4691                |                      | supplier_ID,         |                       |
4692                |                      | category, …​         |                       |
4693                +----------------------+----------------------+-----------------------+
4694
4695             .. container:: paragraph
4696
4697                The database table ``ITEMS`` has a row for each items
4698                that *HyperM* sells. Each item is identified by an
4699                ``item_ID`` value. The ``description`` field stores a
4700                description of the item. The cost price of the item is
4701                given in ``cost_price``. The barcode of the item is
4702                encoded in ``barcode``, while the item supplier is
4703                identified by ``supplier_ID``. Items may also be
4704                classified into categories using the ``category`` field.
4705                Useful categories might include: ``soft drinks``,
4706                ``alcoholic drinks``, ``cigarettes``, ``knives``,
4707                ``confectionery``, ``bakery``, ``fruit&vegetables``,
4708                ``meat``, etc..
4709
4710 Personnel System: Assistants
4711 ############################
4712
4713             .. table:: Table 4. Assistants Database
4714
4715                +----------------------+----------------------+-----------------------+
4716                | Table                | Fields               | Description           |
4717                +======================+======================+=======================+
4718                | ASSISTANTS           | assistant_ID,        | Database table        |
4719                |                      | surname, firstname,  | describing each       |
4720                |                      | middlename, age,     | *HyperM* sales        |
4721                |                      | grade, phone_number, | assistant             |
4722                |                      | …​                   |                       |
4723                +----------------------+----------------------+-----------------------+
4724
4725             .. container:: paragraph
4726
4727                The database table ``ASSISTANTS`` has a row for each
4728                sales assistant employed by *HyperM*. Each assistant is
4729                identified by an ``assistant_ID`` value, with their name
4730                given in the ``firstname``, ``middlename`` and
4731                ``surname`` fields. The assistant’s age in years is given
4732                in ``age``, while their phone number is contained in the
4733                ``phone_number`` field. The assistant’s grade is encoded
4734                in ``grade``. Useful values for ``grade`` might include:
4735                ``trainee``, ``operator``, ``supervisor``, etc..
4736
4737 Locations: Branches
4738 ####################
4739
4740             .. table:: Table 5. Branches Database
4741
4742                +----------------------+----------------------+-----------------------+
4743                | Table                | Fields               | Description           |
4744                +======================+======================+=======================+
4745                | BRANCHES             | branch_ID,           | Database table        |
4746                |                      | branch_Name,         | describing each       |
4747                |                      | category, street,    | *HyperM* branch       |
4748                |                      | city, country,       |                       |
4749                |                      | postcode, …​         |                       |
4750                +----------------------+----------------------+-----------------------+
4751
4752             .. container:: paragraph
4753
4754                *HyperM* operates a number of branches. Each branch is
4755                described in the ``BRANCHES`` database table. Each branch
4756                is identified by a ``branch_ID``, with a branch name
4757                given in ``branch_Name``. The address for the branch is
4758                encoded in ``street``, ``city``, ``country`` and
4759                ``postcode``. The branch category is given in the
4760                ``category`` field. Useful values for ``category`` might
4761                include: ``Small``, ``Large``, ``Super``, ``Hyper``,
4762                etc..
4763
4764 Policy Step 1
4765 -------------
4766
4767 Scenario
4768 #########
4769             .. container:: paragraph
4770
4771                For the first version of our policy, let’s start with
4772                something simple. Let us assume that there exists some
4773                restriction that alcohol products cannot be sold before
4774                11:30am. In this section we will go through the necessary
4775                steps to define a policy that can enforce this for
4776                *HyperM*.
4777
4778             .. container:: ulist
4779
4780                -  Alcohol cannot be sold before 11:30am.
4781
4782 Create the an new empty Policy Model ``MyFirstPolicyModel``
4783 ###########################################################
4784
4785             .. container:: paragraph
4786
4787                Since an organisation like *HyperM* may have many
4788                policies covering many different domains, policies should
4789                be grouped into policy sets. In order to edit or deploy a
4790                policy, or policy set, the definition of the policy(ies)
4791                and all required events, tasks, states, etc., are grouped
4792                together into a 'Policy Model'. An organization might
4793                define many Policy Models, each containing a different
4794                set of policies.
4795
4796             .. container:: paragraph
4797
4798                So the first step is to create a new empty Policy Model
4799                called ``MyFirstPolicyModel``. Using the APEX Policy
4800                Editor, click on the 'File' menus and select 'New'. Then
4801                define our new policy model called
4802                ``MyFirstPolicyModel``. Use the 'Generate UUID' button to
4803                create a new unique ID for the policy model, and fill in
4804                a description for the policy model. Press the ``Submit``
4805                button to save your changes.
4806
4807             .. container:: imageblock
4808
4809                .. container:: content
4810
4811                   |File > New to create a new Policy Model|
4812
4813                .. container:: title
4814
4815                   Figure 4. Create a new Policy Model 1/2
4816
4817             .. container:: imageblock
4818
4819                .. container:: content
4820
4821                   |Create a new Policy Model|
4822
4823                .. container:: title
4824
4825                   Figure 5. Create a new Policy Model 2/2
4826
4827 Create the input event ``SALE_INPUT`` and the output event ``SALE_AUTH``
4828 ########################################################################
4829
4830             .. container:: paragraph
4831
4832                Using the APEX Policy Editor, click on the 'Events' tab.
4833                In the 'Events' pane, right click and select 'New':
4834
4835             .. container:: imageblock
4836
4837                .. container:: content
4838
4839                   |Right click to create a new event|
4840
4841                .. container:: title
4842
4843                   Figure 6. Create a new Event type
4844
4845             .. container:: paragraph
4846
4847                Create a new event type called ``SALE_INPUT``. Use the
4848                'Generate UUID' button to create a new unique ID for the
4849                event type, and fill in a description for the event. Add
4850                a namespace, e.g. ``com.hyperm``. We can add hard-coded
4851                strings for the ``Source`` and ``Target``, e.g. ``POS``
4852                and ``APEX``. At this stage we will not add any parameter
4853                fields, we will leave this until later. Use the
4854                ``Submit`` button to create the event.
4855
4856             .. container:: imageblock
4857
4858                .. container:: content
4859
4860                   |Fill in the necessary information for the
4861                   'SALE_INPUT' event and click 'Submit'|
4862
4863                .. container:: title
4864
4865                   Figure 7. Populate the ``SALE_INPUT`` event
4866
4867             .. container:: paragraph
4868
4869                Repeat the same steps for a new event type called
4870                ``SALE_AUTH``. Just use ``APEX`` as source and ``POS`` as
4871                target, since this is the output event coming from APEX
4872                going to the sales point.
4873
4874             .. container:: paragraph
4875
4876                Before we can add parameter fields to an event we must
4877                first define APEX Context Item Schemas that can be used
4878                by those fields.
4879
4880             .. container:: paragraph
4881
4882                To create new item schemas, click on the 'Context Item
4883                Schemas' tab. In that 'Context Item Schemas' pane, right
4884                click and select 'Create new ContextSchema'.
4885
4886             .. container:: imageblock
4887
4888                .. container:: content
4889
4890                   |Right click to create a new Item Schema|
4891
4892                .. container:: title
4893
4894                   Figure 8. Create new Data Types
4895
4896             .. container:: paragraph
4897
4898                Create item schemas with the following characteristics,
4899                each with its own unique UUID:
4900
4901             .. table:: Table 6. Item Schemas
4902
4903                +-------------------+-----------------+-----------------+----------------------+
4904                | Name              | Schema Flavour  | Schema          | Description          |
4905                |                   |                 | Definition      |                      |
4906                +===================+=================+=================+======================+
4907                | timestamp_type    | Java            | java.lang.Long  | A type for           |
4908                |                   |                 |                 | ``time`` values      |
4909                +-------------------+-----------------+-----------------+----------------------+
4910                | sale_ID_type      | Java            | java.lang.Long  | A type for           |
4911                |                   |                 |                 | ``sale_ID``          |
4912                |                   |                 |                 | values               |
4913                +-------------------+-----------------+-----------------+----------------------+
4914                | price_type        | Java            | java.lang.Long  | A type for           |
4915                |                   |                 |                 | ``amount``/``price`` |
4916                |                   |                 |                 | values               |
4917                +-------------------+-----------------+-----------------+----------------------+
4918                | item_ID_type      | Java            | java.lang.Long  | A type for           |
4919                |                   |                 |                 | ``item_ID``          |
4920                |                   |                 |                 | values               |
4921                +-------------------+-----------------+-----------------+----------------------+
4922                | assistant_ID_type | Java            | java.lang.Long  | A type for           |
4923                |                   |                 |                 | ``assistant_ID``     |
4924                |                   |                 |                 | values               |
4925                +-------------------+-----------------+-----------------+----------------------+
4926                | quantity_type     | Java            | java.lang.Integ | A type for           |
4927                |                   |                 | er              | ``quantity``         |
4928                |                   |                 |                 | values               |
4929                +-------------------+-----------------+-----------------+----------------------+
4930                | branch_ID_type    | Java            | java.lang.Long  | A type for           |
4931                |                   |                 |                 | ``branch_ID``        |
4932                |                   |                 |                 | values               |
4933                +-------------------+-----------------+-----------------+----------------------+
4934                | notes_type        | Java            | java.lang.Strin | A type for           |
4935                |                   |                 | g               | ``notes``            |
4936                |                   |                 |                 | values               |
4937                +-------------------+-----------------+-----------------+----------------------+
4938                | authorised_type   | Java            | java.lang.Boole | A type for           |
4939                |                   |                 | an              | ``authorised``       |
4940                |                   |                 |                 | values               |
4941                +-------------------+-----------------+-----------------+----------------------+
4942                | message_type      | Java            | java.lang.Strin | A type for           |
4943                |                   |                 | g               | ``message``          |
4944                |                   |                 |                 | values               |
4945                +-------------------+-----------------+-----------------+----------------------+
4946
4947             .. container:: imageblock
4948
4949                .. container:: content
4950
4951                   |Create a new Item Schema|
4952
4953                .. container:: title
4954
4955                   Figure 9. Create new Item Schemas
4956
4957             .. container:: paragraph
4958
4959                The item schemas can now be seen on the 'Context Item
4960                Schemas' tab, and can be updated at any time by
4961                right-clicking on the item schemas on the 'Context Item
4962                Schemas' tab. Now we can go back to the event definitions
4963                for ``SALE_INPUT`` and ``SALE_AUTH`` and add some
4964                parameter fields.
4965
4966             .. tip
4967
4968                .. container:: title
4969
4970                   Field Schema types       
4971
4972                .. container:: paragraph
4973
4974                   APEX natively supports schema definitions in ``Java`` and ``Avro``.
4975                                                                             
4976                .. container:: paragraph
4977
4978                   ``Java`` schema definitions are simply the name of a Java Class. There are some restrictions:
4979
4980                .. container:: ulist
4981
4982                   -  the class must be instantiatable, i.e. not an Java interface or abstract class
4983
4984                   -  primitive types are not supported, i.e. use ``java.lang.Integer`` instead of ``int``, etc.
4985
4986                   -  it must be possible to find the class, i.e. the class must be contained in the Java classpath.
4987
4988                .. container:: paragraph
4989
4990                   ``Avro`` schema definitions can be any valid `Avro <https://avro.apache.org/docs/current/spec.html>`__
4991                   schema. For events using fields defined with ``Avro`` schemas, any incoming event containing that field must
4992                   contain a value that conforms to the Avro schema.
4993
4994             .. container:: paragraph
4995
4996                Click on the 'Events' tab, then right click the
4997                ``SALE_INPUT`` row and select 'Edit Event
4998                :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`
4999                event add the following event parameters:
5000
5001             .. table:: Table 7. Event Parameter Fields for the ``SALE_INPUT`` Event
5002
5003                +----------------------+----------------------+-----------------------+
5004                | Parameter Name       | Parameter Type       | Optional              |
5005                +======================+======================+=======================+
5006                | time                 | timestamp_type       | no                    |
5007                +----------------------+----------------------+-----------------------+
5008                | sale_ID              | sale_ID_type         | no                    |
5009                +----------------------+----------------------+-----------------------+
5010                | amount               | price_type           | no                    |
5011                +----------------------+----------------------+-----------------------+
5012                | item_ID              | item_ID_type         | no                    |
5013                +----------------------+----------------------+-----------------------+
5014                | quantity             | quantity_type        | no                    |
5015                +----------------------+----------------------+-----------------------+
5016                | assistant_ID         | assistant_ID_type    | no                    |
5017                +----------------------+----------------------+-----------------------+
5018                | branch_ID            | branch_ID_type       | no                    |
5019                +----------------------+----------------------+-----------------------+
5020                | notes                | notes_type           | *yes*                 |
5021                +----------------------+----------------------+-----------------------+
5022
5023             .. container:: paragraph
5024
5025                Remember to click the 'Submit' button at the bottom of
5026                the event definition pane.
5027
5028             .. tip::
5029                Optional Fields in APEX Events
5030                Parameter fields can be *optional* in events. If a parameter is not marked as *optional* then by default it
5031                is *mandatory*, so it must appear in any input event passed to APEX. If an *optional* field is not set
5032                for an output event then value will be set to ``null``.
5033
5034             .. container:: imageblock
5035
5036                .. container:: content
5037
5038                   |Add new event parameters to an event|
5039
5040                .. container:: title
5041
5042                   Figure 10. Add typed parameter fields to an event
5043
5044             .. container:: paragraph
5045
5046                Select the ``SALE_AUTH`` event and add the following
5047                event parameters:
5048
5049             .. table:: Table 8. Event Parameter Fields for the ``SALE_AUTH`` Event
5050
5051                +----------------------+----------------------+-----------------------+
5052                | Parameter Name       | Parameter Type       | no                    |
5053                +======================+======================+=======================+
5054                | sale_ID              | sale_ID_type         | no                    |
5055                +----------------------+----------------------+-----------------------+
5056                | time                 | timestamp_type       | no                    |
5057                +----------------------+----------------------+-----------------------+
5058                | authorised           | authorised_type      | no                    |
5059                +----------------------+----------------------+-----------------------+
5060                | message              | message_type         | *yes*                 |
5061                +----------------------+----------------------+-----------------------+
5062                | amount               | price_type           | no                    |
5063                +----------------------+----------------------+-----------------------+
5064                | item_ID              | item_ID_type         | no                    |
5065                +----------------------+----------------------+-----------------------+
5066                | assistant_ID         | assistant_ID_type    | no                    |
5067                +----------------------+----------------------+-----------------------+
5068                | quantity             | quantity_type        | no                    |
5069                +----------------------+----------------------+-----------------------+
5070                | branch_ID            | branch_ID_type       | no                    |
5071                +----------------------+----------------------+-----------------------+
5072                | notes                | notes_type           | *yes*                 |
5073                +----------------------+----------------------+-----------------------+
5074
5075             .. container:: paragraph
5076
5077                Remember to click the 'Submit' button at the bottom of
5078                the event definition pane.
5079
5080             .. container:: paragraph
5081
5082                The events for our policy are now defined.
5083
5084 Create a new Policy and add the *"No Booze before 11:30"* check
5085 ###############################################################
5086
5087             .. container:: paragraph
5088
5089                APEX policies are defined using a state-machine model.
5090                Each policy comprises one or more *states* that can be
5091                individually executed. Where there is more than one
5092                *state* the states are chained together to form a
5093                `Directed Acyclic Graph
5094                (DAG) <https://en.wikipedia.org/wiki/Directed_acyclic_graph>`__
5095                of states. A *state* is triggered by passing it a single
5096                input (or 'trigger') event and once executed each state
5097                then emits an output event. For each *state* the logic
5098                for the *state* is embedded in one or more *tasks*. Each
5099                *task* contains specific *task logic* that is executed by
5100                the APEX execution environment each time the *task* is
5101                invoked. Where there is more than one *task* in a *state*
5102                then the *state* also defines some *task selection logic*
5103                to select an appropriate task each time the *state* is
5104                executed.
5105
5106             .. container:: paragraph
5107
5108                Therefore, to create a new policy we must first define
5109                one or more tasks.
5110
5111             .. container:: paragraph
5112
5113                To create a new Task click on the 'Tasks' tab. In the
5114                'Tasks' pane, right click and select 'Create new Task'.
5115                Create a new Task called ``MorningBoozeCheck``. Use the
5116                'Generate UUID' button to create a new unique ID for the
5117                task, and fill in a description for the task.
5118
5119             .. container:: imageblock
5120
5121                .. container:: content
5122
5123                   |Right click to create a new task|
5124
5125                .. container:: title
5126
5127                   Figure 11. Create a new Task
5128
5129             .. container:: paragraph
5130
5131                Tasks are configured with a set of *input fields* and a
5132                set of *output fields*. To add new input/output fields
5133                for a task use the 'Add Task Input Field' and 'Add Task
5134                Output Field' button. The list of input and out fields to
5135                add for the ``MorningBoozeCheck`` task are given below.
5136                The input fields are drawn from the parameters in the
5137                state’s input event, and the task’s output fields are
5138                used to populate the state’s output event. The task’s
5139                input and output fields must be a subset of the event
5140                parameters defined for the input and output events for
5141                any state that uses that task. (You may have noticed that
5142                the input and output fields for the ``MorningBoozeCheck``
5143                task have the exact same names and reuse the item schemas
5144                that we used for the parameters in the ``SALE_INPUT`` and
5145                ``SALE_AUTH`` events respectively).
5146
5147             .. table:: Table 9. Input fields for ``MorningBoozeCheck`` task
5148
5149                +-----------------------------------+-----------------------------------+
5150                | Parameter Name                    | Parameter Type                    |
5151                +===================================+===================================+
5152                | time                              | timestamp_type                    |
5153                +-----------------------------------+-----------------------------------+
5154                | sale_ID                           | sale_ID_type                      |
5155                +-----------------------------------+-----------------------------------+
5156                | amount                            | price_type                        |
5157                +-----------------------------------+-----------------------------------+
5158                | item_ID                           | item_ID_type                      |
5159                +-----------------------------------+-----------------------------------+
5160                | quantity                          | quantity_type                     |
5161                +-----------------------------------+-----------------------------------+
5162                | assistant_ID                      | assistant_ID_type                 |
5163                +-----------------------------------+-----------------------------------+
5164                | branch_ID                         | branch_ID_type                    |
5165                +-----------------------------------+-----------------------------------+
5166                | notes                             | notes_type                        |
5167                +-----------------------------------+-----------------------------------+
5168
5169             .. table:: Table 10. Output fields for ``MorningBoozeCheck`` task
5170
5171                +-----------------------------------+-----------------------------------+
5172                | Parameter Name                    | Parameter Type                    |
5173                +===================================+===================================+
5174                | sale_ID                           | sale_ID_type                      |
5175                +-----------------------------------+-----------------------------------+
5176                | time                              | timestamp_type                    |
5177                +-----------------------------------+-----------------------------------+
5178                | authorised                        | authorised_type                   |
5179                +-----------------------------------+-----------------------------------+
5180                | message                           | message_type                      |
5181                +-----------------------------------+-----------------------------------+
5182                | amount                            | price_type                        |
5183                +-----------------------------------+-----------------------------------+
5184                | item_ID                           | item_ID_type                      |
5185                +-----------------------------------+-----------------------------------+
5186                | assistant_ID                      | assistant_ID_type                 |
5187                +-----------------------------------+-----------------------------------+
5188                | quantity                          | quantity_type                     |
5189                +-----------------------------------+-----------------------------------+
5190                | branch_ID                         | branch_ID_type                    |
5191                +-----------------------------------+-----------------------------------+
5192                | notes                             | notes_type                        |
5193                +-----------------------------------+-----------------------------------+
5194
5195             .. container:: imageblock
5196
5197                .. container:: content
5198
5199                   |Add input and out fields for the task|
5200
5201                .. container:: title
5202
5203                   Figure 12. Add input and out fields for the Task
5204
5205             .. container:: paragraph
5206
5207                Each task must include some 'Task Logic' that implements
5208                the behaviour for the task. Task logic can be defined in
5209                a number of different ways using a choice of languages.
5210                For this task we will author the logic using the
5211                Java-like scripting language called
5212                ```MVEL`` <https://en.wikipedia.org/wiki/MVEL>`__.
5213
5214             .. container:: paragraph
5215
5216                For simplicity use the following code for the task logic.
5217                Paste the script text into the 'Task Logic' box, and use
5218                "MVEL" as the 'Task Logic Type / Flavour'.
5219
5220             .. container:: paragraph
5221
5222                This logic assumes that all items with ``item_ID``
5223                between 1000 and 2000 contain alcohol, which is not very
5224                realistic, but we will see a better approach for this
5225                later. It also uses the standard ``Java`` time utilities
5226                to check if the current time is between ``00:00:00 GMT``
5227                and ``11:30:00 GMT``. For a detailed guide to how to
5228                write your own logic in
5229                ```JavaScript`` <https://en.wikipedia.org/wiki/JavaScript>`__,
5230                ```MVEL`` <https://en.wikipedia.org/wiki/MVEL>`__ or one
5231                of the other supported languages please refer to APEX
5232                Programmers Guide.
5233
5234             .. container:: listingblock
5235
5236                .. container:: title
5237
5238                   MVEL code for the ``MorningBoozeCheck`` task
5239
5240                .. container:: content
5241
5242                   .. code::
5243
5244                      /*
5245                       * ============LICENSE_START=======================================================
5246                       *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
5247                       * ================================================================================
5248                       * Licensed under the Apache License, Version 2.0 (the "License");
5249                       * you may not use this file except in compliance with the License.
5250                       * You may obtain a copy of the License at
5251                       *
5252                       *      http://www.apache.org/licenses/LICENSE-2.0
5253                       *
5254                       * Unless required by applicable law or agreed to in writing, software
5255                       * distributed under the License is distributed on an "AS IS" BASIS,
5256                       * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5257                       * See the License for the specific language governing permissions and
5258                       * limitations under the License.
5259                       *
5260                       * SPDX-License-Identifier: Apache-2.0
5261                       * ============LICENSE_END=========================================================
5262                       */
5263                      import java.util.Date;
5264                      import java.util.Calendar;
5265                      import java.util.TimeZone;
5266                      import java.text.SimpleDateFormat;
5267
5268                      logger.info("Task Execution: '"+subject.id+"'. Input Fields: '"+inFields+"'");
5269
5270                      outFields.put("amount"      , inFields.get("amount"));
5271                      outFields.put("assistant_ID", inFields.get("assistant_ID"));
5272                      outFields.put("notes"       , inFields.get("notes"));
5273                      outFields.put("quantity"    , inFields.get("quantity"));
5274                      outFields.put("branch_ID"   , inFields.get("branch_ID"));
5275                      outFields.put("item_ID"     , inFields.get("item_ID"));
5276                      outFields.put("time"        , inFields.get("time"));
5277                      outFields.put("sale_ID"     , inFields.get("sale_ID"));
5278
5279                      item_id = inFields.get("item_ID");
5280
5281                      //The events used later to test this task use GMT timezone!
5282                      gmt = TimeZone.getTimeZone("GMT");
5283                      timenow = Calendar.getInstance(gmt);
5284                      df = new SimpleDateFormat("HH:mm:ss z");
5285                      df.setTimeZone(gmt);
5286                      timenow.setTimeInMillis(inFields.get("time"));
5287
5288                      midnight = timenow.clone();
5289                      midnight.set(
5290                          timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH),
5291                          timenow.get(Calendar.DATE),0,0,0);
5292                      eleven30 = timenow.clone();
5293                      eleven30.set(
5294                          timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH),
5295                          timenow.get(Calendar.DATE),11,30,0);
5296
5297                      itemisalcohol = false;
5298                      if(item_id != null && item_id >=1000 && item_id < 2000)
5299                          itemisalcohol = true;
5300
5301                      if( itemisalcohol
5302                          && timenow.after(midnight) && timenow.before(eleven30)){
5303                        outFields.put("authorised", false);
5304                        outFields.put("message", "Sale not authorised by policy task "+subject.taskName+
5305                          " for time "+df.format(timenow.getTime())+
5306                          ". Alcohol can not be sold between "+df.format(midnight.getTime())+
5307                          " and "+df.format(eleven30.getTime()));
5308                        return true;
5309                      }
5310                      else{
5311                        outFields.put("authorised", true);
5312                        outFields.put("message", "Sale authorised by policy task "+subject.taskName+
5313                          " for time "+df.format(timenow.getTime()));
5314                        return true;
5315                      }
5316
5317                      /*
5318                      This task checks if a sale request is for an item that is an alcoholic drink.
5319                      If the local time is between 00:00:00 GMT and 11:30:00 GMT then the sale is not
5320                      authorised. Otherwise the sale is authorised.
5321                      In this implementation we assume that items with item_ID value between 1000 and
5322                      2000 are all alcoholic drinks :-)
5323                      */
5324
5325             .. container:: imageblock
5326
5327                .. container:: content
5328
5329                   |Add task logic the task|
5330
5331                .. container:: title
5332
5333                   Figure 13. Add Task Logic the Task
5334
5335             .. container:: paragraph
5336
5337                An alternative version of the same logic is available in
5338                JavaScript. Just use "JAVASCRIPT" as the 'Task Logic Type
5339                / Flavour' instead.
5340
5341             .. container:: listingblock
5342
5343                .. container:: title
5344
5345                   Javascript alternative for the ``MorningBoozeCheck``
5346                   task
5347
5348                .. container:: content
5349
5350                   .. code::
5351
5352                      /*
5353                       * ============LICENSE_START=======================================================
5354                       *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
5355                       * ================================================================================
5356                       * Licensed under the Apache License, Version 2.0 (the "License");
5357                       * you may not use this file except in compliance with the License.
5358                       * You may obtain a copy of the License at
5359                       *
5360                       *      http://www.apache.org/licenses/LICENSE-2.0
5361                       *
5362                       * Unless required by applicable law or agreed to in writing, software
5363                       * distributed under the License is distributed on an "AS IS" BASIS,
5364                       * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5365                       * See the License for the specific language governing permissions and
5366                       * limitations under the License.
5367                       *
5368                       * SPDX-License-Identifier: Apache-2.0
5369                       * ============LICENSE_END=========================================================
5370                       */
5371
5372                      var returnValueType = Java.type("java.lang.Boolean");
5373                      var returnValue = new returnValueType(true);
5374
5375                      // Load compatibility script for imports etc
5376                      load("nashorn:mozilla_compat.js");
5377                      importPackage(java.text);
5378                      importClass(java.text.SimpleDateFormat);
5379
5380                      executor.logger.info("Task Execution: '"+executor.subject.id+"'. Input Fields: '"+executor.inFields+"'");
5381
5382                      executor.outFields.put("amount"      , executor.inFields.get("amount"));
5383                      executor.outFields.put("assistant_ID", executor.inFields.get("assistant_ID"));
5384                      executor.outFields.put("notes"       , executor.inFields.get("notes"));
5385                      executor.outFields.put("quantity"    , executor.inFields.get("quantity"));
5386                      executor.outFields.put("branch_ID"   , executor.inFields.get("branch_ID"));
5387                      executor.outFields.put("item_ID"     , executor.inFields.get("item_ID"));
5388                      executor.outFields.put("time"        , executor.inFields.get("time"));
5389                      executor.outFields.put("sale_ID"     , executor.inFields.get("sale_ID"));
5390
5391                      item_id = executor.inFields.get("item_ID");
5392
5393                      //All times in this script are in GMT/UTC since the policy and events assume time is in GMT.
5394                      var timenow_gmt =  new Date(Number(executor.inFields.get("time")));
5395
5396                      var midnight_gmt = new Date(Number(executor.inFields.get("time")));
5397                      midnight_gmt.setUTCHours(0,0,0,0);
5398
5399                      var eleven30_gmt = new Date(Number(executor.inFields.get("time")));
5400                      eleven30_gmt.setUTCHours(11,30,0,0);
5401
5402                      var timeformatter = new java.text.SimpleDateFormat("HH:mm:ss z");
5403
5404                      var itemisalcohol = false;
5405                      if(item_id != null && item_id >=1000 && item_id < 2000)
5406                          itemisalcohol = true;
5407
5408                      if( itemisalcohol
5409                          && timenow_gmt.getTime() >= midnight_gmt.getTime()
5410                          && timenow_gmt.getTime() <  eleven30_gmt.getTime()) {
5411
5412                        executor.outFields.put("authorised", false);
5413                        executor.outFields.put("message", "Sale not authorised by policy task " +
5414                          executor.subject.taskName+ " for time " + timeformatter.format(timenow_gmt.getTime()) +
5415                          ". Alcohol can not be sold between " + timeformatter.format(midnight_gmt.getTime()) +
5416                          " and " + timeformatter.format(eleven30_gmt.getTime()));
5417                      }
5418                      else{
5419                        executor.outFields.put("authorised", true);
5420                        executor.outFields.put("message", "Sale authorised by policy task " +
5421                          executor.subject.taskName + " for time "+timeformatter.format(timenow_gmt.getTime()));
5422                      }
5423
5424                      /*
5425                      This task checks if a sale request is for an item that is an alcoholic drink.
5426                      If the local time is between 00:00:00 GMT and 11:30:00 GMT then the sale is not
5427                      authorised. Otherwise the sale is authorised.
5428                      In this implementation we assume that items with item_ID value between 1000 and
5429                      2000 are all alcoholic drinks :-)
5430                      */
5431
5432             .. container:: paragraph
5433
5434                The task definition is now complete so click the 'Submit'
5435                button to save the task. The task can now be seen on the
5436                'Tasks' tab, and can be updated at any time by
5437                right-clicking on the task on the 'Task' tab. Now that we
5438                have created our task, we can can create a policy that
5439                uses that task.
5440
5441             .. container:: paragraph
5442
5443                To create a new Policy click on the 'Policies' tab. In
5444                the 'Policies' pane, right click and select 'Create new
5445                Policy':
5446
5447             .. container:: paragraph
5448
5449                Create a new Policy called ``MyFirstPolicy``. Use the
5450                'Generate UUID' button to create a new unique ID for the
5451                policy, and fill in a description for the policy. Use
5452                'FREEFORM' as the 'Policy Flavour'.
5453
5454             .. container:: paragraph
5455
5456                Each policy must have at least one state. Since this is
5457                'freeform' policy we can add as many states as we wish.
5458                Let’s start with one state. Add a new state called
5459                ``BoozeAuthDecide`` to this ``MyFirstPolicy`` policy
5460                using the 'Add new State' button after filling in the
5461                name of our new state.
5462
5463             .. container:: imageblock
5464
5465                .. container:: content
5466
5467                   |Create a new policy|
5468
5469                .. container:: title
5470
5471                   Figure 14. Create a new Policy
5472
5473             .. container:: paragraph
5474
5475                Each state must uses one input event type. For this new
5476                state select the ``SALE_INPUT`` event as the input event.
5477
5478             .. container:: paragraph
5479
5480                Each policy must define a 'First State' and a 'Policy
5481                Trigger Event'. The 'Policy Trigger Event' is the input
5482                event for the policy as a whole. This event is then
5483                passed to the first state in the chain of states in the
5484                policy, therefore the 'Policy Trigger Event' will be the
5485                input event for the first state. Each policy can only
5486                have one 'First State'. For our ``MyFirstPolicy`` policy,
5487                select ``BoozeAuthDecide`` as the 'First State'. This
5488                will automatically select ``SALE_INPUT`` as the 'Policy
5489                Trigger Event' for our policy.
5490
5491             .. container:: imageblock
5492
5493                .. container:: content
5494
5495                   |Create a state|
5496
5497                .. container:: title
5498
5499                   Figure 15. Create a new State
5500
5501             .. container:: paragraph
5502
5503                In this case we will create a reference the pre-existing
5504                ``MorningBoozeCheck`` task that we defined above using
5505                the 'Add New Task' button. Select the
5506                ``MorningBoozeCheck`` task, and use the name of the task
5507                as the 'Local Name' for the task.
5508
5509             .. container:: paragraph
5510
5511                in the case where a state references more than one task,
5512                a 'Default Task' must be selected for the state and some
5513                logic ('Task Selection Logic') must be specified to
5514                select the appropriate task at execution time. Since our
5515                new state ``BoozeAuthDecide`` only has one task the
5516                default task is automatically selected and no 'Task
5517                Selection Logic' is required.
5518
5519             .. note::
5520                .. container:: title
5521
5522                   State Output Mappings
5523
5524                .. container:: paragraph
5525
5526                   In a 'Policy' 'State' a 'State Output Mapping' has 3 roles:
5527                   1) Select which 'State' should be executed next, 2) Select
5528                   the type of the state’s 'Outgoing Event', and 3)
5529                   Populate the state’s 'Outgoing Event'. This is how states are
5530                   chained together to form a (`Directed Acyclic Graph
5531                   (DAG) <https://en.wikipedia.org/wiki/Directed_acyclic_graph>`__ )
5532                   of states. The final state(s) of a policy are those that do
5533                   not select any 'next' state. Since a 'State' can only
5534                   accept a single type of event, the type of the event emitted
5535                   by a previous 'State' must be match the incoming event type
5536                   of the next 'State'. This is also how the last state(s) in
5537                   a policy can emit events of different types. The 'State
5538                   Output Mapping' is also responsible for taking the
5539                   fields that are output by the task executed in the state and
5540                   populating the state’s output event before it is emitted.
5541
5542                .. container:: paragraph
5543
5544                   Each 'Task' referenced in 'State' must have a defined
5545                   'Output Mapping' to take the output of the task, select an
5546                   'Outgoing Event' type for the state, populate the state’s
5547                   outgoing event, and then select the next state to be
5548                   executed (if any).
5549
5550                .. container:: paragraph
5551
5552                There are 2 basic types of output mappings:
5553
5554                .. container:: olist arabic
5555
5556                #. **Direct Output Mappings** have a single value for
5557                   'Next State' and a single value for 'State Output
5558                   Event'. The outgoing event for the state is
5559                   automatically created, any outgoing event parameters
5560                   that were present in the incoming event are copied
5561                   into the outgoing event, then any task output fields
5562                   that have the same name and type as parameters in the
5563                   outgoing event are automatically copied into
5564                   the outgoing event.
5565
5566                #. **Logic-based State Output Mappings / Finalizers**
5567                   have some logic defined that dynamically selects
5568                   and creates the 'State Outgoing Event', manages
5569                   the population of the outgoing event parameters
5570                   (perhaps changing or adding to the outputs from the
5571                   task), and then dynamically selects the next state to
5572                   be executed (if any).
5573
5574             .. container:: paragraph
5575
5576                Each task reference must also have an associated 'Output
5577                State Mapping' so we need an 'Output State Mapping' for
5578                the ``BoozeAuthDecide`` state to use when the
5579                ``MorningBoozeCheck`` task is executed. The simplest type
5580                of output mapping is a 'Direct Output Mapping'.
5581
5582             .. container:: paragraph
5583
5584                Create a new 'Direct Output Mapping' for the state called
5585                ``MorningBoozeCheck_Output_Direct`` using the 'Add New
5586                Direct State Output Mapping' button. Select ``SALE_AUTH``
5587                as the output event and select ``None`` for the next
5588                state value. We can then select this output mapping for
5589                use when the the ``MorningBoozeCheck`` task is executed.
5590                Since there is only state, and only one task for that
5591                state, this output mapping ensures that the
5592                ``BoozeAuthDecide`` state is the only state executed and
5593                the state (and the policy) can only emit events of type
5594                ``SALE_AUTH``. (You may remember that the output fields
5595                for the ``MorningBoozeCheck`` task have the exact same
5596                names and reuse the item schemas that we used for the
5597                parameters in ``SALE_AUTH`` event. The
5598                ``MorningBoozeCheck_Output_Direct`` direct output mapping
5599                can now automatically copy the values from the
5600                ``MorningBoozeCheck`` task directly into outgoing
5601                ``SALE_AUTH`` events.)
5602
5603             .. container:: imageblock
5604
5605                .. container:: content
5606
5607                   |Add a Task and Output Mapping|
5608
5609                .. container:: title
5610
5611                   Figure 16. Add a Task and Output Mapping
5612
5613             .. container:: paragraph
5614
5615                Click the 'Submit' button to complete the definition of
5616                our ``MyFirstPolicy`` policy. The policy
5617                ``MyFirstPolicy`` can now be seen in the list of policies
5618                on the 'Policies' tab, and can be updated at any time by
5619                right-clicking on the policy on the 'Policies' tab.
5620
5621             .. container:: paragraph
5622
5623                The ``MyFirstPolicyModel``, including our
5624                ``MyFirstPolicy`` policy can now be checked for errors.
5625                Click on the 'Model' menu and select 'Validate'. The
5626                model should validate without any 'Warning' or 'Error'
5627                messages. If you see any 'Error' or 'Warning' messages,
5628                carefully read the message as a hint to find where you
5629                might have made a mistake when defining some aspect of
5630                your policy model.
5631
5632             .. container:: imageblock
5633
5634                .. container:: content
5635
5636                   |Validate the policy model for error using the 'Model'
5637                   > 'Validate' menu item|
5638
5639                .. container:: title
5640
5641                   Figure 17. Validate a Policy Model
5642
5643             .. container:: paragraph
5644
5645                Congratulations, you have now completed your first APEX
5646                policy. The policy model containing our new policy can
5647                now be exported from the editor and saved. Click on the
5648                'File' menu and select 'Download' to save the policy
5649                model in JSON format. The exported policy model is then
5650                available in the directory you selected, for instance
5651                ``$APEX_HOME/examples/models/MyFirstPolicy/1/MyFirstPolicyModel_0.0.1.json``.
5652                The exported policy can now be loaded into the APEX
5653                Policy Engine, or can be re-loaded and edited by the APEX
5654                Policy Editor.
5655
5656             .. container:: imageblock
5657
5658                .. container:: content
5659
5660                   |Download the completed policy model using the 'File'
5661                   > 'Download' menu item|
5662
5663                .. container:: title
5664
5665                   Figure 18. Export a Policy Model
5666
5667 Test Policy Step 1
5668 ##################
5669
5670             .. container:: paragraph
5671
5672                To start a new APEX Engine you can use the following
5673                configuration. In a full APEX installation you can find
5674                this configuration in
5675                ``$APEX_HOME/examples/config/MyFirstPolicy/1/MyFirstPolicyConfigStdin2StdoutJsonEvent.json``.
5676                This configuration expects incoming events to be in
5677                ``JSON`` format and to be passed into the APEX Engine
5678                from ``stdin``, and result events will be printed in
5679                ``JSON`` format to ``stdout``. This configuration loads
5680                the policy model stored in the file
5681                'MyFirstPolicyModel_0.0.1.json' as exported from the APEX
5682                Editor. Note, you may need to edit this file to provide
5683                the full path to wherever you stored the exported policy
5684                model file.
5685
5686             .. container:: listingblock
5687
5688                .. container:: title
5689
5690                   JSON to load and execute *My First Policy*, read input
5691                   JSON events from ``stdin``, and emit output events to
5692                   ``stdout``
5693
5694                .. container:: content
5695
5696                   .. code::
5697
5698                      {
5699                          "engineServiceParameters" : {
5700                              "name"                : "MyFirstPolicyApexEngine",
5701                              "version"             : "0.0.1",
5702                              "id"                  : 101,
5703                              "instanceCount"       : 4,
5704                              "deploymentPort"      : 12345,
5705                              "policyModelFileName" : "examples/models/MyFirstPolicy/1/MyFirstPolicyModel_0.0.1.json",
5706                              "engineParameters"    : {
5707                                  "executorParameters" : {
5708                                      "MVEL" : {
5709                                          "parameterClassName" : "org.onap.policy.apex.plugins.executor.mvel.MVELExecutorParameters"
5710                                      },
5711                                      "JAVASCRIPT" : {
5712                                          "parameterClassName" : "org.onap.policy.apex.plugins.executor.javascript.JavascriptExecutorParameters"
5713                                      }
5714                                  }
5715                              }
5716                          },
5717                          "eventOutputParameters": {
5718                              "FirstProducer": {
5719                                  "carrierTechnologyParameters" : {
5720                                      "carrierTechnology" : "FILE",
5721                                      "parameters" : {
5722                                          "standardIO" : true
5723                                      }
5724                                  },
5725                                  "eventProtocolParameters" : {
5726                                      "eventProtocol" : "JSON"
5727                                  }
5728                              }
5729                          },
5730                          "eventInputParameters": {
5731                              "FirstConsumer": {
5732                                  "carrierTechnologyParameters" : {
5733                                      "carrierTechnology" : "FILE",
5734                                      "parameters" : {
5735                                          "standardIO" : true
5736                                      }
5737                                  },
5738                                  "eventProtocolParameters" : {
5739                                      "eventProtocol" : "JSON"
5740                                  }
5741                              }
5742                          }
5743                      }
5744
5745             .. container:: paragraph
5746
5747                To test the policy try paste the following events into
5748                the console as the APEX engine executes:
5749
5750             .. table:: Table 11. Inputs and Outputs when testing *My First Policy*
5751
5752                +------------------------------------------+-------------------------------------------+-----------+
5753                | Input Event (JSON)                       | Output Event (JSON)                       | comment   |
5754                +==========================================+===========================================+===========+
5755                | .. container::                           | .. container::                            | Request   |
5756                |                                          |                                           | to buy a  |
5757                |    .. container:: listingblock           |    .. container:: listingblock            | non-alcoh |
5758                |                                          |                                           | olic      |
5759                |                                          |       .. container:: content              | item      |
5760                |       .. container:: content             |                                           | (``item_I |
5761                |                                          |          .. code::                        | D=5123``) |
5762                |                                          |                                           | at        |
5763                |          .. code::                       |             {                             | *10:13:09 |
5764                |                                          |               "name": "SALE_AUTH",        | *         |
5765                |                                          |                                           | on        |
5766                |             {                            |               "version": "0.0.1",         | *Tuesday, |
5767                |               "nameSpace": "com.hyperm", |               "nameSpace": "com.hyperm",  | 10        |
5768                |               "name" : "SALE_INPUT",     |               "source": "",               | January   |
5769                |               "version": "0.0.1",        |               "target": "",               | 2017*.    |
5770                |               "time" : 1483351989000,    |               "amount": 299,              | Sale is   |
5771                |               "sale_ID": 99999991,       |               "assistant_ID": 23,         | authorize |
5772                |               "amount": 299,             |               "authorised": true,         | d.        |
5773                |               "item_ID": 5123,           |               "branch_ID": 1,             |           |
5774                |               "quantity": 1,             |               "item_ID": 5123,            |           |
5775                |               "assistant_ID": 23,        |               "message": "Sale authorised |           |
5776                |               "branch_ID": 1,            |                by policy task MorningBo   |           |
5777                |               "notes": "Special Offer!!" |                ozeCheck for time 10:13:09 |           |
5778                |              }                           |                GMT",                      |           |
5779                |                                          |               "notes": "Special Offer!!", |           |
5780                |                                          |               "quantity": 1,              |           |
5781                |                                          |               "sale_ID": 99999991,        |           |
5782                |                                          |               "time": 1483351989000       |           |
5783                |                                          |             }                             |           |
5784                |                                          |                                           |           |
5785                |                                          |                                           |           |
5786                |                                          |                                           |           |
5787                +------------------------------------------+-------------------------------------------+-----------+
5788                | .. container::                           | .. container::                            | Request   |
5789                |                                          |                                           | to buy    |
5790                |    .. container:: listingblock           |    .. container:: listingblock            | alcohol   |
5791                |                                          |                                           | item      |
5792                |       .. container:: content             |       .. container:: content              | (``item_I |
5793                |                                          |                                           | D=1249``) |
5794                |          .. code::                       |          .. code::                        | at        |
5795                |                                          |                                           | *08:41:06 |
5796                |             {                            |             {                             | *         |
5797                |               "nameSpace": "com.hyperm", |               "nameSpace": "com.hyperm",  | on        |
5798                |               "name": "SALE_INPUT",      |               "name": "SALE_AUTH",        | *Monday,  |
5799                |               "version": "0.0.1",        |               "source": "",               | 02        |
5800                |                "time": 1483346466000,    |               "target": "",               | January   |
5801                |               "sale_ID": 99999992,       |               "amount": 1249,             | 2017*.    |
5802                |               "version": "0.0.1",        |               "assistant_ID": 12,         |           |
5803                |               "amount": 1249,            |               "authorised": false,        | Sale is   |
5804                |               "item_ID": 1012,           |               "branch_ID": 2,             | not       |
5805                |               "quantity": 1,             |               "item_ID": 1012,            | authorize |
5806                |               "assistant_ID": 12,        |               "message": "Sale not        | d.        |
5807                |               "branch_ID": 2             |                authorised by policy task  |           |
5808                |             }                            |                MorningBoozeCheck for time |           |
5809                |                                          |                08:41:06 GMT. Alcohol can  |           |
5810                |                                          |                not be sold between        |           |
5811                |                                          |                00:00:00 GMT and 11:30:00  |           |
5812                |                                          |                GMT",                      |           |
5813                |                                          |               "notes": null,              |           |
5814                |                                          |               "quantity": 1,              |           |
5815                |                                          |               "sale_ID": 99999992,        |           |
5816                |                                          |               "time": 1483346466000       |           |
5817                |                                          |             }                             |           |
5818                +------------------------------------------+-------------------------------------------+-----------+
5819                | .. container::                           | .. container::                            | Request   |
5820                |                                          |                                           | to buy    |
5821                |    .. container:: listingblock           |    .. container:: listingblock            | alcohol   |
5822                |                                          |                                           | (``item_I |
5823                |                                          |       .. container:: content              | D=1943``) |
5824                |       .. container:: content             |                                           | at        |
5825                |                                          |          .. code::                        | *20:17:13 |
5826                |                                          |                                           | *         |
5827                |          .. code::                       |             {                             | on        |
5828                |                                          |               "name": "SALE_AUTH",        | *Tuesday, |
5829                |             {                            |               "version": "0.0.1",         | 20        |
5830                |               "nameSpace": "com.hyperm", |               "nameSpace": "com.hyperm",  | December  |
5831                |               "name" : "SALE_INPUT",     |               "source": "",               | 2016*.    |
5832                |               "version": "0.0.1",        |               "target": "",               |           |
5833                |               "time" : 1482265033000,    |               "amount": 4799,             | Sale is   |
5834                |               "sale_ID": 99999993,       |               "assistant_ID": 9,          | authorize |
5835                |               "amount": 4799,            |               "authorised": true,         | d.        |
5836                |               "item_ID": 1943,           |               "branch_ID": 3,             |           |
5837                |               "quantity": 2,             |               "item_ID": 1943,            |           |
5838                |               "assistant_ID": 9,         |               "message": "Sale authorised |           |
5839                |               "branch_ID": 3             |                by policy task MorningBo   |           |
5840                |             }                            |                ozeCheck for time 20:17:13 |           |
5841                |                                          |                GMT",                      |           |
5842                |                                          |                "notes": null,             |           |
5843                |                                          |                "quantity": 2,             |           |
5844                |                                          |                "sale_ID": 99999993,       |           |
5845                |                                          |                "time": 1482265033000      |           |
5846                |                                          |             }                             |           |
5847                +------------------------------------------+-------------------------------------------+-----------+
5848
5849 4.3.6. Policy 1 in CLI Editor
5850 #############################
5851
5852             .. container:: paragraph
5853
5854                An equivalent version of the ``MyFirstPolicyModel``
5855                policy model can again be generated using the APEX CLI
5856                editor. A sample APEX CLI script is shown below:
5857
5858             .. container:: listingblock
5859
5860                .. container:: title
5861
5862                   APEX CLI Editor code for Policy 1
5863
5864                .. container:: content
5865
5866                   .. code::
5867
5868                      #-------------------------------------------------------------------------------
5869                      # ============LICENSE_START=======================================================
5870                      #  Copyright (C) 2016-2018 Ericsson. All rights reserved.
5871                      # ================================================================================
5872                      # Licensed under the Apache License, Version 2.0 (the "License");
5873                      # you may not use this file except in compliance with the License.
5874                      # You may obtain a copy of the License at
5875                      #
5876                      #      http://www.apache.org/licenses/LICENSE-2.0
5877                      #
5878                      # Unless required by applicable law or agreed to in writing, software
5879                      # distributed under the License is distributed on an "AS IS" BASIS,
5880                      # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5881                      # See the License for the specific language governing permissions and
5882                      # limitations under the License.
5883                      #
5884                      # SPDX-License-Identifier: Apache-2.0
5885                      # ============LICENSE_END=========================================================
5886                      #-------------------------------------------------------------------------------
5887
5888                      model create name=MyFirstPolicyModel version=0.0.1 uuid=540226fb-55ee-4f0e-a444-983a0494818e description="This is my first Apex Policy Model."
5889
5890                      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
5891
5892                      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
5893
5894                      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
5895
5896                      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
5897
5898                      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
5899
5900                      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
5901
5902                      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
5903
5904                      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
5905
5906                      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
5907
5908                      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
5909
5910                      task create name=MorningBoozeCheck version=0.0.1 uuid=3351b0f4-cf06-4fa2-8823-edf67bd30223 description=LS
5911                      This task checks if the sales request is for an item that contains alcohol.
5912                      If the local time is between 00:00:00 and 11:30:00 then the sale is not authorised. Otherwise the sale is authorised.
5913                      In this implementation we assume that all items with item_ID values between 1000 and 2000 contain alcohol :-)
5914                      LE
5915                      task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1
5916                      task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=amount schemaName=price_type schemaVersion=0.0.1
5917                      task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1
5918                      task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true
5919                      task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=quantity schemaName=quantity_type schemaVersion=0.0.1
5920                      task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1
5921                      task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=item_ID schemaName=item_ID_type schemaVersion=0.0.1
5922                      task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=time schemaName=timestamp_type schemaVersion=0.0.1
5923                      task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1
5924                      task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=amount schemaName=price_type schemaVersion=0.0.1
5925                      task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1
5926                      task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true
5927                      task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=quantity schemaName=quantity_type schemaVersion=0.0.1
5928                      task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1
5929                      task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=item_ID schemaName=item_ID_type schemaVersion=0.0.1
5930                      task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=authorised schemaName=authorised_type schemaVersion=0.0.1
5931                      task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=time schemaName=timestamp_type schemaVersion=0.0.1
5932                      task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=message schemaName=message_type schemaVersion=0.0.1 optional=true
5933                      task logic create name=MorningBoozeCheck version=0.0.1 logicFlavour=MVEL logic=LS
5934                      /*
5935                       * ============LICENSE_START=======================================================
5936                       *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
5937                       * ================================================================================
5938                       * Licensed under the Apache License, Version 2.0 (the "License");
5939                       * you may not use this file except in compliance with the License.
5940                       * You may obtain a copy of the License at
5941                       *
5942                       *      http://www.apache.org/licenses/LICENSE-2.0
5943                       *
5944                       * Unless required by applicable law or agreed to in writing, software
5945                       * distributed under the License is distributed on an "AS IS" BASIS,
5946                       * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5947                       * See the License for the specific language governing permissions and
5948                       * limitations under the License.
5949                       *
5950                       * SPDX-License-Identifier: Apache-2.0
5951                       * ============LICENSE_END=========================================================
5952                       */
5953                      import java.util.Date;
5954                      import java.util.Calendar;
5955                      import java.util.TimeZone;
5956                      import java.text.SimpleDateFormat;
5957
5958                      logger.info("Task Execution: '"+subject.id+"'. Input Fields: '"+inFields+"'");
5959
5960                      outFields.put("amount"      , inFields.get("amount"));
5961                      outFields.put("assistant_ID", inFields.get("assistant_ID"));
5962                      outFields.put("notes"       , inFields.get("notes"));
5963                      outFields.put("quantity"    , inFields.get("quantity"));
5964                      outFields.put("branch_ID"   , inFields.get("branch_ID"));
5965                      outFields.put("item_ID"     , inFields.get("item_ID"));
5966                      outFields.put("time"        , inFields.get("time"));
5967                      outFields.put("sale_ID"     , inFields.get("sale_ID"));
5968
5969                      item_id = inFields.get("item_ID");
5970
5971                      //The events used later to test this task use GMT timezone!
5972                      gmt = TimeZone.getTimeZone("GMT");
5973                      timenow = Calendar.getInstance(gmt);
5974                      df = new SimpleDateFormat("HH:mm:ss z");
5975                      df.setTimeZone(gmt);
5976                      timenow.setTimeInMillis(inFields.get("time"));
5977
5978                      midnight = timenow.clone();
5979                      midnight.set(
5980                          timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH),
5981                          timenow.get(Calendar.DATE),0,0,0);
5982                      eleven30 = timenow.clone();
5983                      eleven30.set(
5984                          timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH),
5985                          timenow.get(Calendar.DATE),11,30,0);
5986
5987                      itemisalcohol = false;
5988                      if(item_id != null && item_id >=1000 && item_id < 2000)
5989                          itemisalcohol = true;
5990
5991                      if( itemisalcohol
5992                          && timenow.after(midnight) && timenow.before(eleven30)){
5993                        outFields.put("authorised", false);
5994                        outFields.put("message", "Sale not authorised by policy task "+subject.taskName+
5995                          " for time "+df.format(timenow.getTime())+
5996                          ". Alcohol can not be sold between "+df.format(midnight.getTime())+
5997                          " and "+df.format(eleven30.getTime()));
5998                        return true;
5999                      }
6000                      else{
6001                        outFields.put("authorised", true);
6002                        outFields.put("message", "Sale authorised by policy task "+subject.taskName+
6003                          " for time "+df.format(timenow.getTime()));
6004                        return true;
6005                      }
6006
6007                      /*
6008                      This task checks if a sale request is for an item that is an alcoholic drink.
6009                      If the local time is between 00:00:00 GMT and 11:30:00 GMT then the sale is not
6010                      authorised. Otherwise the sale is authorised.
6011                      In this implementation we assume that items with item_ID value between 1000 and
6012                      2000 are all alcoholic drinks :-)
6013                      */
6014                      LE
6015
6016                      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"
6017                      event parameter create name=SALE_AUTH version=0.0.1 parName=amount schemaName=price_type schemaVersion=0.0.1
6018                      event parameter create name=SALE_AUTH version=0.0.1 parName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1
6019                      event parameter create name=SALE_AUTH version=0.0.1 parName=authorised schemaName=authorised_type schemaVersion=0.0.1
6020                      event parameter create name=SALE_AUTH version=0.0.1 parName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1
6021                      event parameter create name=SALE_AUTH version=0.0.1 parName=item_ID schemaName=item_ID_type schemaVersion=0.0.1
6022                      event parameter create name=SALE_AUTH version=0.0.1 parName=message schemaName=message_type schemaVersion=0.0.1 optional=true
6023                      event parameter create name=SALE_AUTH version=0.0.1 parName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true
6024                      event parameter create name=SALE_AUTH version=0.0.1 parName=quantity schemaName=quantity_type schemaVersion=0.0.1
6025                      event parameter create name=SALE_AUTH version=0.0.1 parName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1
6026                      event parameter create name=SALE_AUTH version=0.0.1 parName=time schemaName=timestamp_type schemaVersion=0.0.1
6027
6028                      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"
6029                      event parameter create name=SALE_INPUT version=0.0.1 parName=amount schemaName=price_type schemaVersion=0.0.1
6030                      event parameter create name=SALE_INPUT version=0.0.1 parName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1
6031                      event parameter create name=SALE_INPUT version=0.0.1 parName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1
6032                      event parameter create name=SALE_INPUT version=0.0.1 parName=item_ID schemaName=item_ID_type schemaVersion=0.0.1
6033                      event parameter create name=SALE_INPUT version=0.0.1 parName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true
6034                      event parameter create name=SALE_INPUT version=0.0.1 parName=quantity schemaName=quantity_type schemaVersion=0.0.1
6035                      event parameter create name=SALE_INPUT version=0.0.1 parName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1
6036                      event parameter create name=SALE_INPUT version=0.0.1 parName=time schemaName=timestamp_type schemaVersion=0.0.1
6037
6038
6039                      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
6040                      policy state create name=MyFirstPolicy version=0.0.1 stateName=BoozeAuthDecide triggerName=SALE_INPUT triggerVersion=0.0.1 defaultTaskName=MorningBoozeCheck defaultTaskVersion=0.0.1
6041                      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
6042                      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
6043
6044 Policy Step 2
6045 -------------
6046
6047 Scenario
6048 #########
6049             .. container:: paragraph
6050
6051                *HyperM* have just opened a new branch in a different
6052                country, but that country has different rules about when
6053                alcohol can be sold! In this section we will go through
6054                the necessary steps to extend our policy to enforce this
6055                for *HyperM*.
6056
6057             .. container:: ulist
6058
6059                -  In some branches alcohol cannot be sold before 1pm,
6060                   and not at all on Sundays.
6061
6062             .. container:: paragraph
6063
6064                Although there are a number of ways to accomplish this
6065                the easiest approach for us is to define another task and
6066                then select which task is appropriate at runtime
6067                depending on the branch identifier in the incoming event.
6068
6069 Extend the Policy with the new Scenario
6070 #######################################
6071
6072             .. container:: paragraph
6073
6074                To create a new Task click on the 'Tasks' tab. In the
6075                'Tasks' pane, right click and select 'Create new Task':
6076
6077             .. container:: paragraph
6078
6079                Create a new Task called ``MorningBoozeCheckAlt1``. Use
6080                the 'Generate UUID' button to create a new unique ID for
6081                the task, and fill in a description for the task. Select
6082                the same input and output fields that we used earlier
6083                when we defined the ``MorningBoozeCheck`` task earlier.
6084
6085             .. table:: Table 12. Input fields for ``MorningBoozeCheckAlt1`` task
6086
6087                +-----------------------------------+-----------------------------------+
6088                | Parameter Name                    | Parameter Type                    |
6089                +===================================+===================================+
6090                | time                              | timestamp_type                    |
6091                +-----------------------------------+-----------------------------------+
6092                | sale_ID                           | sale_ID_type                      |
6093                +-----------------------------------+-----------------------------------+
6094                | amount                            | price_type                        |
6095                +-----------------------------------+-----------------------------------+
6096                | item_ID                           | item_ID_type                      |
6097                +-----------------------------------+-----------------------------------+
6098                | quantity                          | quantity_type                     |
6099                +-----------------------------------+-----------------------------------+
6100                | assistant_ID                      | assistant_ID_type                 |
6101                +-----------------------------------+-----------------------------------+
6102                | branch_ID                         | branch_ID_type                    |
6103                +-----------------------------------+-----------------------------------+
6104                | notes                             | notes_type                        |
6105                +-----------------------------------+-----------------------------------+
6106
6107             .. table:: Table 13. Output fields for ``MorningBoozeCheckAlt1`` task
6108
6109                +-----------------------------------+-----------------------------------+
6110                | Parameter Name                    | Parameter Type                    |
6111                +===================================+===================================+
6112                | sale_ID                           | sale_ID_type                      |
6113                +-----------------------------------+-----------------------------------+
6114                | time                              | timestamp_type                    |
6115                +-----------------------------------+-----------------------------------+
6116                | authorised                        | authorised_type                   |
6117                +-----------------------------------+-----------------------------------+
6118                | message                           | message_type                      |
6119                +-----------------------------------+-----------------------------------+
6120                | amount                            | price_type                        |
6121                +-----------------------------------+-----------------------------------+
6122                | item_ID                           | item_ID_type                      |
6123                +-----------------------------------+-----------------------------------+
6124                | assistant_ID                      | assistant_ID_type                 |
6125                +-----------------------------------+-----------------------------------+
6126                | quantity                          | quantity_type                     |
6127                +-----------------------------------+-----------------------------------+
6128                | branch_ID                         | branch_ID_type                    |
6129                +-----------------------------------+-----------------------------------+
6130                | notes                             | notes_type                        |
6131                +-----------------------------------+-----------------------------------+
6132
6133             .. container:: paragraph
6134
6135                This task also requires some 'Task Logic' to implement
6136                the new behaviour for this task.
6137
6138             .. container:: paragraph
6139
6140                For simplicity use the following code for the task logic.
6141                It again assumes that all items with ``item_ID`` between
6142                1000 and 2000 contain alcohol. We again use the standard
6143                ``Java`` time utilities to check if the current time is
6144                between ``00:00:00 CET`` and ``13:00:00 CET`` or if it is
6145                ``Sunday``.
6146
6147             .. container:: paragraph
6148
6149                For this task we will again author the logic using the
6150                ```MVEL`` <https://en.wikipedia.org/wiki/MVEL>`__
6151                scripting language. Sample task logic code (specified in
6152                ```MVEL`` <https://en.wikipedia.org/wiki/MVEL>`__) is
6153                given below. For a detailed guide to how to write your
6154                own logic in
6155                ```JavaScript`` <https://en.wikipedia.org/wiki/JavaScript>`__,
6156                ```MVEL`` <https://en.wikipedia.org/wiki/MVEL>`__ or one
6157                of the other supported languages please refer to APEX
6158                Programmers Guide.
6159
6160             .. container:: listingblock
6161
6162                .. container:: title
6163
6164                   MVEL code for the ``MorningBoozeCheckAlt1`` task
6165
6166                .. container:: content
6167
6168                   .. code::
6169
6170                      /*
6171                       * ============LICENSE_START=======================================================
6172                       *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
6173                       * ================================================================================
6174                       * Licensed under the Apache License, Version 2.0 (the "License");
6175                       * you may not use this file except in compliance with the License.
6176                       * You may obtain a copy of the License at
6177                       *
6178                       *      http://www.apache.org/licenses/LICENSE-2.0
6179                       *
6180                       * Unless required by applicable law or agreed to in writing, software
6181                       * distributed under the License is distributed on an "AS IS" BASIS,
6182                       * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6183                       * See the License for the specific language governing permissions and
6184                       * limitations under the License.
6185                       *
6186                       * SPDX-License-Identifier: Apache-2.0
6187                       * ============LICENSE_END=========================================================
6188                       */
6189                      import java.util.Date;
6190                      import java.util.Calendar;
6191                      import java.util.TimeZone;
6192                      import java.text.SimpleDateFormat;
6193
6194                      logger.info("Task Execution: '"+subject.id+"'. Input Event: '"+inFields+"'");
6195
6196                      outFields.put("amount"      , inFields.get("amount"));
6197                      outFields.put("assistant_ID", inFields.get("assistant_ID"));
6198                      outFields.put("notes"       , inFields.get("notes"));
6199                      outFields.put("quantity"    , inFields.get("quantity"));
6200                      outFields.put("branch_ID"   , inFields.get("branch_ID"));
6201                      outFields.put("item_ID"     , inFields.get("item_ID"));
6202                      outFields.put("time"        , inFields.get("time"));
6203                      outFields.put("sale_ID"     , inFields.get("sale_ID"));
6204
6205                      item_id = inFields.get("item_ID");
6206
6207                      //The events used later to test this task use CET timezone!
6208                      cet = TimeZone.getTimeZone("CET");
6209                      timenow = Calendar.getInstance(cet);
6210                      df = new SimpleDateFormat("HH:mm:ss z");
6211                      df.setTimeZone(cet);
6212                      timenow.setTimeInMillis(inFields.get("time"));
6213
6214                      midnight = timenow.clone();
6215                      midnight.set(
6216                          timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH),
6217                          timenow.get(Calendar.DATE),0,0,0);
6218                      onepm = timenow.clone();
6219                      onepm.set(
6220                          timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH),
6221                          timenow.get(Calendar.DATE),13,0,0);
6222
6223                      itemisalcohol = false;
6224                      if(item_id != null && item_id >=1000 && item_id < 2000)
6225                          itemisalcohol = true;
6226
6227                      if( itemisalcohol &&
6228                          ( (timenow.after(midnight) && timenow.before(onepm))
6229                            ||
6230                            (timenow.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY)
6231                          )){
6232                        outFields.put("authorised", false);
6233                        outFields.put("message", "Sale not authorised by policy task "+subject.taskName+
6234                          " for time "+df.format(timenow.getTime())+
6235                          ". Alcohol can not be sold between "+df.format(midnight.getTime())+
6236                          " and "+df.format(onepm.getTime()) +" or on Sunday");
6237                        return true;
6238                      }
6239                      else{
6240                        outFields.put("authorised", true);
6241                        outFields.put("message", "Sale authorised by policy task "+subject.taskName+
6242                          " for time "+df.format(timenow.getTime()));
6243                        return true;
6244                      }
6245
6246                      /*
6247                      This task checks if a sale request is for an item that is an alcoholic drink.
6248                      If the local time is between 00:00:00 CET and 13:00:00 CET then the sale is not authorised.
6249                      Also alcohol sales are not allowed on Sundays. Otherwise the sale is authorised.
6250                      In this implementation we assume that items with item_ID between 1000 and 2000 are all alcoholic drinks :-)
6251                      */
6252
6253             .. container:: imageblock
6254
6255                .. container:: content
6256
6257                   |Create a new alternative task MorningBoozeCheckAlt1|
6258
6259                .. container:: title
6260
6261                   Figure 19. Create a new Task
6262
6263             .. container:: paragraph
6264
6265                The task definition is now complete so click the 'Submit'
6266                button to save the task. Now that we have created our
6267                task, we can can add this task to the single pre-existing
6268                state (``BoozeAuthDecide``) in our policy.
6269
6270             .. container:: paragraph
6271
6272                To edit the ``BoozeAuthDecide`` state in our policy click
6273                on the 'Policies' tab. In the 'Policies' pane, right
6274                click on our ``MyFirstPolicy`` policy and select 'Edit'.
6275                Navigate to the ``BoozeAuthDecide`` state in the 'states'
6276                section at the bottom of the policy definition pane.
6277
6278             .. container:: imageblock
6279
6280                .. container:: content
6281
6282                   |Right click to edit a policy|
6283
6284                .. container:: title
6285
6286                   Figure 20. Edit a Policy
6287
6288             .. container:: paragraph
6289
6290                To add our new task ``MorningBoozeCheckAlt1``, scroll
6291                down to the ``BoozeAuthDecide`` state in the 'States'
6292                section. In the 'State Tasks' section for
6293                ``BoozeAuthDecide`` use the 'Add new task' button. Select
6294                our new ``MorningBoozeCheckAlt1`` task, and use the name
6295                of the task as the 'Local Name' for the task. The
6296                ``MorningBoozeCheckAlt1`` task can reuse the same
6297                ``MorningBoozeCheck_Output_Direct`` 'Direct State Output
6298                Mapping' that we used for the ``MorningBoozeCheck`` task.
6299                (Recall that the role of the 'State Output Mapping' is to
6300                select the output event for the state, and select the
6301                next state to be executed. These both remain the same as
6302                before.)
6303
6304             .. container:: paragraph
6305
6306                Since our state has more than one task we must define
6307                some logic to determine which task should be used each
6308                time the state is executed. This *task selection logic*
6309                is defined in the state definition. For our
6310                ``BoozeAuthDecide`` state we want the choice of which
6311                task to use to be based on the ``branch_ID`` from which
6312                the ``SALE_INPUT`` event originated. For simplicity sake
6313                let us assume that branches with ``branch_ID`` between
6314                ``0`` and ``999`` should use the ``MorningBoozeCheck``
6315                task, and the branches with with ``branch_ID`` between
6316                ``1000`` and ``1999`` should use the
6317                ``MorningBoozeCheckAlt1`` task.
6318
6319             .. container:: paragraph
6320
6321                This time, for variety, we will author the task selection
6322                logic using the
6323                ```JavaScript`` <https://en.wikipedia.org/wiki/JavaScript>`__
6324                scripting language. Sample task selection logic code
6325                (specified in
6326                ```JavaScript`` <https://en.wikipedia.org/wiki/JavaScript>`__)
6327                is given below. Paste the script text into the 'Task
6328                Selection Logic' box, and use "JAVASCRIPT" as the 'Task
6329                Selection Logic Type / Flavour'. It is necessary to mark
6330                one of the tasks as the 'Default Task' so that the task
6331                selection logic always has a fallback default option in
6332                cases where a particular task cannot be selected. In this
6333                case the ``MorningBoozeCheck`` task can be the default
6334                task.
6335
6336             .. container:: listingblock
6337
6338                .. container:: title
6339
6340                   JavaScript code for the ``BoozeAuthDecide`` task
6341                   selection logic
6342
6343                .. container:: content
6344
6345                   .. code::
6346
6347                      /*
6348                       * ============LICENSE_START=======================================================
6349                       *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
6350                       * ================================================================================
6351                       * Licensed under the Apache License, Version 2.0 (the "License");
6352                       * you may not use this file except in compliance with the License.
6353                       * You may obtain a copy of the License at
6354                       *
6355                       *      http://www.apache.org/licenses/LICENSE-2.0
6356                       *
6357                       * Unless required by applicable law or agreed to in writing, software
6358                       * distributed under the License is distributed on an "AS IS" BASIS,
6359                       * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6360                       * See the License for the specific language governing permissions and
6361                       * limitations under the License.
6362                       *
6363                       * SPDX-License-Identifier: Apache-2.0
6364                       * ============LICENSE_END=========================================================
6365                       */
6366
6367
6368                      var returnValueType = Java.type("java.lang.Boolean");
6369                      var returnValue = new returnValueType(true);
6370
6371                      executor.logger.info("Task Selection Execution: '"+executor.subject.id+
6372                          "'. Input Event: '"+executor.inFields+"'");
6373
6374                      branchid = executor.inFields.get("branch_ID");
6375                      taskorig = executor.subject.getTaskKey("MorningBoozeCheck");
6376                      taskalt = executor.subject.getTaskKey("MorningBoozeCheckAlt1");
6377                      taskdef = executor.subject.getDefaultTaskKey();
6378
6379                      if(branchid >=0 && branchid <1000){
6380                        taskorig.copyTo(executor.selectedTask);
6381                      }
6382                      else if (branchid >=1000 && branchid <2000){
6383                        taskalt.copyTo(executor.selectedTask);
6384                      }
6385                      else{
6386                        taskdef.copyTo(executor.selectedTask);
6387                      }
6388
6389                      /*
6390                      This task selection logic selects task "MorningBoozeCheck" for branches with
6391                      0<=branch_ID<1000 and selects task "MorningBoozeCheckAlt1" for branches with
6392                      1000<=branch_ID<2000. Otherwise the default task is selected.
6393                      In this case the default task is also "MorningBoozeCheck"
6394                      */
6395
6396             .. container:: imageblock
6397
6398                .. container:: content
6399
6400                   |State definition with 2 Tasks and Task Selection
6401                   Logic|
6402
6403                .. container:: title
6404
6405                   Figure 21. State definition with 2 Tasks and Task
6406                   Selection Logic
6407
6408             .. container:: paragraph
6409
6410                When complete don’t forget to click the 'Submit' button
6411                at the bottom of 'Policies' pane for our
6412                ``MyFirstPolicy`` policy after updating the
6413                ``BoozeAuthDecide`` state.
6414
6415             .. container:: paragraph
6416
6417                Congratulations, you have now completed the second step
6418                towards your first APEX policy. The policy model
6419                containing our new policy can again be validated and
6420                exported from the editor and saved as shown in Step 1.
6421
6422             .. container:: paragraph
6423
6424                The exported policy model is then available in the
6425                directory you selected, as
6426                `MyFirstPolicyModel_0.0.1.json <files/mfp-files/2/MyFirstPolicyModel_0.0.1.json>`__.
6427                The exported policy can now be loaded into the APEX
6428                Policy Engine, or can be re-loaded and edited by the APEX
6429                Policy Editor.
6430
6431 Test Policy Step 2
6432 ##################
6433
6434             .. container:: paragraph
6435
6436                To start a new APEX Engine you can use the following
6437                configuration. In a full APEX installation you can find
6438                this configuration in
6439                ``$APEX_HOME/examples/config/MyFirstPolicy/2/MyFirstPolicyConfigStdin2StdoutJsonEvent.json``.
6440                Note, this has changed from the configuration file in
6441                Step 1 to enable the ``JAVASCRIPT`` executor for our new
6442                'Task Selection Logic'.
6443
6444             .. container:: listingblock
6445
6446                .. container:: title
6447
6448                   JSON to load and execute *My First Policy*, read input
6449                   JSON events from ``stdin``, and emit output events to
6450                   ``stdout``
6451
6452                .. container:: content
6453
6454                   .. code::
6455
6456                      {
6457                          "engineServiceParameters" : {
6458                              "name"                : "MyFirstPolicyApexEngine",
6459                              "version"             : "0.0.1",
6460                              "id"                  : 102,
6461                              "instanceCount"       : 4,
6462                              "deploymentPort"      : 12345,
6463                              "policyModelFileName" : "examples/models/MyFirstPolicy/2/MyFirstPolicyModel_0.0.1.json",
6464                              "engineParameters"    : {
6465                                  "executorParameters" : {
6466                                      "MVEL" : {
6467                                          "parameterClassName" : "org.onap.policy.apex.plugins.executor.mvel.MVELExecutorParameters"
6468                                      },
6469                                      "JAVASCRIPT" : {
6470                                          "parameterClassName" : "org.onap.policy.apex.plugins.executor.javascript.JavascriptExecutorParameters"
6471                                      }
6472                                  }
6473                              }
6474                          },
6475                          "eventOutputParameters": {
6476                              "FirstProducer": {
6477                                  "carrierTechnologyParameters" : {
6478                                      "carrierTechnology" : "FILE",
6479                                      "parameters" : {
6480                                          "standardIO" : true
6481                                      }
6482                                  },
6483                                  "eventProtocolParameters" : {
6484                                      "eventProtocol" : "JSON"
6485                                  }
6486                              }
6487                          },
6488                          "eventInputParameters": {
6489                              "FirstConsumer": {
6490                                  "carrierTechnologyParameters" : {
6491                                      "carrierTechnology" : "FILE",
6492                                      "parameters" : {
6493                                          "standardIO" : true
6494                                      }
6495                                  },
6496                                  "eventProtocolParameters" : {
6497                                      "eventProtocol" : "JSON"
6498                                  }
6499                              }
6500                          }
6501                      }
6502
6503             .. container:: paragraph
6504
6505                To test the policy try paste the following events into
6506                the console as the APEX engine executes. Note, all tests
6507                from Step 1 will still work perfectly since none of those
6508                events originate from a branch with ``branch_ID`` between
6509                ``1000`` and ``2000``. The 'Task Selection Logic' will
6510                therefore pick the ``MorningBoozeCheck`` task as
6511                expected, and will therefore give the same results.
6512
6513             .. table:: Table 14. Inputs and Outputs when testing *My First Policy*
6514
6515                +----------------------------------------------+------------------------------------------------------------+---------------------------+
6516                | Input Event (JSON)                           | Output Event (JSON)                                        | comment                   |
6517                +==============================================+============================================================+===========================+
6518                | .. container::                               | .. container::                                             | Request to buy            |
6519                |                                              |                                                            | alcohol item              |
6520                |    .. container:: listingblock               |    .. container:: listingblock                             | (``item_ID=1249``)        |
6521                |                                              |                                                            |                           |
6522                |                                              |                                                            | at *08:41:06              |
6523                |                                              |       .. container:: content                               | GMT* on *Monday,          |
6524                |       .. container:: content                 |                                                            | 02 January                |        
6525                |                                              |          .. code::                                         | 2017*.                    |
6526                |                                              |                                                            |                           |
6527                |                                              |             {                                              | Sale is not               |    
6528                |          .. code::                           |               "nameSpace": "com.hyperm",                   | authorized. Uses          |
6529                |                                              |               "name": "SALE_AUTH",                         | the                       |
6530                |                                              |               "version": "0.0.1",                          | ``MorningBoozeCheck``     |
6531                |             {                                |               "source": "",                                |                           |
6532                |               "nameSpace": "com.hyperm",     |               "target": "",                                | task.                     |     
6533                |               "name": "SALE_INPUT",          |               "amount": 1249,                              |                           |
6534                |                "version": "0.0.1",           |               "assistant_ID":12,                           | Note this test            |
6535                |               "time": 1483346466000,         |               "authorised": false,                         | is copied from            |
6536                |               "sale_ID": 99999992,           |               "branch_ID": 2,                              | Step 1 above,             |
6537                |               "amount": 1249,                |               "item_ID": 1012,                             | and demonstrates          |    
6538                |               "item_ID": 1012,               |               "message": "Sale not authorised by policy ta | that the                  |
6539                |               "quantity": 1,                 |                sk MorningBoozeCheck for time 08:41:06  GMT.| original                  |
6540                |               "assistant_ID": 12,            |                Alcohol can not be sold between 00:00:00    | ``MorningBoozeCheck``     |
6541                |               "branch_ID": 2                 |                GMT and 11:30:00 GMT",                      |                           |
6542                |              }                               |               "notes": null,                               | task is                   |
6543                |                                              |               "quantity": 1,                               | executed.                 |    
6544                |                                              |               "sale_ID": 99999992,                         |                           |
6545                |                                              |               "time": 1483346466000                        |                           |
6546                |                                              |             }                                              |                           |
6547                +----------------------------------------------+------------------------------------------------------------+---------------------------+
6548                | .. container::                               | .. container::                                             | Request to buy            |
6549                |                                              |                                                            | alcohol                   |
6550                |    .. container:: listingblock               |    .. container:: listingblock                             | (``item_ID=1047``)        |
6551                |                                              |                                                            |                           |
6552                |                                              |                                                            | at *10:14:33* on          |
6553                |                                              |       .. container:: content                               | *Thursday, 22             |
6554                |       .. container:: content                 |                                                            | December 2016*.           |
6555                |                                              |          .. code::                                         |                           |
6556                |                                              |                                                            | Sale is not               |
6557                |                                              |             {                                              | authorized. Uses          |
6558                |          .. code::                           |               "nameSpace" : "com.hyperm",                  | the                       |
6559                |                                              |               "name" : "SALE_AUTH",                        | ``MorningBoozeCheckAlt1`` |
6560                |                                              |               "version" : "0.0.1",                         | task.                     |
6561                |             {                                |               "source" : "",                               |                           |
6562                |                                              |               "target" : "",                               |                           |
6563                |               "nameSpace": "com.hyperm",     |               "sale_ID" : 99999981,                        |                           |
6564                |               "name": "SALE_INPUT",          |               "amount" : 299,                              |                           |
6565                |               "version": "0.0.1",            |               "assistant_ID": 1212,                        |                           |
6566                |               "time": 1482398073000,         |               "notes" : null,                              |                           |
6567                |               "sale_ID": 99999981,           |               "quantity" : 1,                              |                           |
6568                |               "amount": 299,                 |               "branch_ID" : 1002,                          |                           |
6569                |               "item_ID": 1047,               |               "item_ID" : 1047,                            |                           |
6570                |               "quantity": 1,                 |               "authorised" : false,                        |                           |
6571                |               "assistant_ID": 1212,          |               "time" : 1482398073000,                      |                           |
6572                |               "branch_ID": 1002              |               "message" : "Sale not authorised by policy t |                           |
6573                |             }                                |                ask MorningBoozeCheckAlt1 fortime           |                           |
6574                |                                              |                10:14:33 CET. Alcohol can not be sold       |                           |
6575                |                                              |                between 00:00:00 CET and 13:00:00 CET or on |                           |
6576                |                                              |                Sunday"                                     |                           |
6577                |                                              |             }                                              |                           |
6578                +----------------------------------------------+------------------------------------------------------------+---------------------------+
6579                | .. container::                               | .. container::                                             | Request to buy            |
6580                |                                              |                                                            | alcohol                   |
6581                |    .. container:: listingblock               |    .. container:: listingblock                             | (``item_ID=1443``)        |
6582                |                                              |                                                            |                           |
6583                |                                              |                                                            | at *17:19:37* on          |
6584                |                                              |       .. container:: content                               | *Sunday, 18               |
6585                |       .. container:: content                 |                                                            | December 2016*.           |
6586                |                                              |          .. code::                                         |                           |
6587                |                                              |                                                            | Sale is not               |
6588                |                                              |             {                                              | authorized. Uses          |
6589                |          .. code::                           |               "nameSpace" : "com.hyperm",                  | the                       |
6590                |                                              |                                                            | ``MorningBoozeCheckAlt1`` |
6591                |                                              |               "name" : "SALE_AUTH",                        | task.                     |
6592                |             {                                |                                                            |                           |
6593                |               "nameSpace": "com.hyperm",     |               "version" : "0.0.1",                         |                           |
6594                |               "name": "SALE_INPUT",          |               "source" : "",                               |                           |
6595                |               "version": "0.0.1",            |               "target" : "",                               |                           |
6596                |               "time": 1482077977000,         |               "sale_ID" : 99999982,                        |                           |
6597                |               "sale_ID": 99999982,           |               "amount" : 2199,                             |                           |
6598                |               "amount": 2199,                |               "assistant_ID" : 94,                         |                           |
6599                |               "item_ID": 1443,               |               "notes" : "Buy 3, get 1 free!!",             |                           |
6600                |               "quantity": 12,                |               "quantity" : 12,                             |                           |
6601                |               "assistant_ID": 94,            |               "branch_ID" : 1003,                          |                           |
6602                |               "branch_ID": 1003,             |               "item_ID" : 1443,                            |                           |
6603                |               "notes": "Buy 3, get 1 free!!" |               "authorised" : false,                        |                           |
6604                |             }                                |               "time" : 1482077977000,                      |                           |
6605                |                                              |               "message" : "Sale not authorised by policy t |                           |
6606                |                                              |                ask MorningBoozeCheckAlt1 for               |                           |
6607                |                                              |                time 17:19:37 CET. Alcohol c                |                           |
6608                |                                              |                an not be sold between 00:00:               |                           |
6609                |                                              |                00 CET and 13:00:00 CET or on               |                           |
6610                |                                              |                Sunday"                                     |                           |
6611                +----------------------------------------------+------------------------------------------------------------+---------------------------+
6612                | .. container::                               | .. container::                                             | Request to buy            |
6613                |                                              |                                                            | non-alcoholic             |
6614                |    .. container:: listingblock               |    .. container:: listingblock                             | item                      |
6615                |                                              |                                                            | (``item_ID=5321``)        |
6616                |                                              |                                                            |                           |
6617                |                                              |       .. container:: content                               | at *11:13:09* on          |
6618                |       .. container:: content                 |                                                            | *Monday, 2                |
6619                |                                              |          .. code::                                         | January 2017*.            |
6620                |                                              |                                                            |                           |
6621                |                                              |             {                                              | Sale is                   |
6622                |          .. code::                           |               "nameSpace" : "com.hyperm",                  | authorized. Uses          |
6623                |                                              |               "name" : "SALE_AUTH",                        | the                       |
6624                |             {                                |               "version" : "0.0.1",                         | ``MorningBoozeCheckAlt1`` |
6625                |                "nameSpace": "com.hyperm",    |               "source" : "",                               | task.                     |
6626                |                "name": "SALE_INPUT",         |               "target" : "",                               |                           |
6627                |                "version": "0.0.1",           |               "sale_ID" : 99999983,                        |                           |
6628                |                "time": 1483351989000,        |               "amount" : 699,                              |                           |
6629                |                "sale_ID": 99999983,          |               "assistant_ID" : 2323,                       |                           |
6630                |                "amount": 699,                |               "notes" : "",                                |                           |
6631                |                "item_ID": 5321,              |               "quantity" : 1,                              |                           |
6632                |                 "quantity": 1,               |               "branch_ID" : 1001,                          |                           |
6633                |                 "assistant_ID": 2323,        |               "item_ID" : 5321,                            |                           |
6634                |                 "branch_ID": 1001,           |               "authorised" : true,                         |                           |
6635                |                 "notes": ""                  |               "time" : 1483351989000,                      |                           |
6636                |              }                               |               "message" : "Sale authorised by policy task  |                           |
6637                |                                              |                MorningBoozeCheckAlt1 for time 11:13:09 CET"|                           |
6638                |                                              |             }                                              |                           |
6639                +----------------------------------------------+------------------------------------------------------------+---------------------------+
6640
6641 Policy 2 in CLI Editor
6642 ######################
6643
6644             .. container:: paragraph
6645
6646                An equivalent version of the ``MyFirstPolicyModel``
6647                policy model can again be generated using the APEX CLI
6648                editor. A sample APEX CLI script is shown below:
6649
6650             .. container:: listingblock
6651
6652                .. container:: title
6653
6654                   APEX CLI Editor code for Policy 2
6655
6656                .. container:: content
6657
6658                   .. code::
6659
6660                      #-------------------------------------------------------------------------------
6661                      # ============LICENSE_START=======================================================
6662                      #  Copyright (C) 2016-2018 Ericsson. All rights reserved.
6663                      # ================================================================================
6664                      # Licensed under the Apache License, Version 2.0 (the "License");
6665                      # you may not use this file except in compliance with the License.
6666                      # You may obtain a copy of the License at
6667                      #
6668                      #      http://www.apache.org/licenses/LICENSE-2.0
6669                      #
6670                      # Unless required by applicable law or agreed to in writing, software
6671                      # distributed under the License is distributed on an "AS IS" BASIS,
6672                      # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6673                      # See the License for the specific language governing permissions and
6674                      # limitations under the License.
6675                      #
6676                      # SPDX-License-Identifier: Apache-2.0
6677                      # ============LICENSE_END=========================================================
6678                      #-------------------------------------------------------------------------------
6679
6680                      model create name=MyFirstPolicyModel version=0.0.1 uuid=540226fb-55ee-4f0e-a444-983a0494818e description="This is my first Apex Policy Model."
6681
6682                      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
6683
6684                      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
6685
6686                      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
6687
6688                      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
6689
6690                      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
6691
6692                      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
6693
6694                      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
6695
6696                      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
6697
6698                      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
6699
6700                      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
6701
6702                      task create name=MorningBoozeCheck version=0.0.1 uuid=3351b0f4-cf06-4fa2-8823-edf67bd30223 description=LS
6703                      This task checks if the sales request is for an item that contains alcohol.
6704                      If the local time is between 00:00:00 and 11:30:00 then the sale is not authorised. Otherwise the sale is authorised.
6705                      In this implementation we assume that all items with item_ID values between 1000 and 2000 contain alcohol :-)
6706                      LE
6707                      task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1
6708                      task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=amount schemaName=price_type schemaVersion=0.0.1
6709                      task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1
6710                      task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true
6711                      task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=quantity schemaName=quantity_type schemaVersion=0.0.1
6712                      task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1
6713                      task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=item_ID schemaName=item_ID_type schemaVersion=0.0.1
6714                      task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=time schemaName=timestamp_type schemaVersion=0.0.1
6715                      task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1
6716                      task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=amount schemaName=price_type schemaVersion=0.0.1
6717                      task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1
6718                      task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true
6719                      task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=quantity schemaName=quantity_type schemaVersion=0.0.1
6720                      task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1
6721                      task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=item_ID schemaName=item_ID_type schemaVersion=0.0.1
6722                      task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=authorised schemaName=authorised_type schemaVersion=0.0.1
6723                      task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=time schemaName=timestamp_type schemaVersion=0.0.1
6724                      task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=message schemaName=message_type schemaVersion=0.0.1 optional=true
6725                      task logic create name=MorningBoozeCheck version=0.0.1 logicFlavour=MVEL logic=LS
6726                      /*
6727                       * ============LICENSE_START=======================================================
6728                       *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
6729                       * ================================================================================
6730                       * Licensed under the Apache License, Version 2.0 (the "License");
6731                       * you may not use this file except in compliance with the License.
6732                       * You may obtain a copy of the License at
6733                       *
6734                       *      http://www.apache.org/licenses/LICENSE-2.0
6735                       *
6736                       * Unless required by applicable law or agreed to in writing, software
6737                       * distributed under the License is distributed on an "AS IS" BASIS,
6738                       * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6739                       * See the License for the specific language governing permissions and
6740                       * limitations under the License.
6741                       *
6742                       * SPDX-License-Identifier: Apache-2.0
6743                       * ============LICENSE_END=========================================================
6744                       */
6745                      import java.util.Date;
6746                      import java.util.Calendar;
6747                      import java.util.TimeZone;
6748                      import java.text.SimpleDateFormat;
6749
6750                      logger.info("Task Execution: '"+subject.id+"'. Input Fields: '"+inFields+"'");
6751
6752                      outFields.put("amount"      , inFields.get("amount"));
6753                      outFields.put("assistant_ID", inFields.get("assistant_ID"));
6754                      outFields.put("notes"       , inFields.get("notes"));
6755                      outFields.put("quantity"    , inFields.get("quantity"));
6756                      outFields.put("branch_ID"   , inFields.get("branch_ID"));
6757                      outFields.put("item_ID"     , inFields.get("item_ID"));
6758                      outFields.put("time"        , inFields.get("time"));
6759                      outFields.put("sale_ID"     , inFields.get("sale_ID"));
6760
6761                      item_id = inFields.get("item_ID");
6762
6763                      //The events used later to test this task use GMT timezone!
6764                      gmt = TimeZone.getTimeZone("GMT");
6765                      timenow = Calendar.getInstance(gmt);
6766                      df = new SimpleDateFormat("HH:mm:ss z");
6767                      df.setTimeZone(gmt);
6768                      timenow.setTimeInMillis(inFields.get("time"));
6769
6770                      midnight = timenow.clone();
6771                      midnight.set(
6772                          timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH),
6773                          timenow.get(Calendar.DATE),0,0,0);
6774                      eleven30 = timenow.clone();
6775                      eleven30.set(
6776                          timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH),
6777                          timenow.get(Calendar.DATE),11,30,0);
6778
6779                      itemisalcohol = false;
6780                      if(item_id != null && item_id >=1000 && item_id < 2000)
6781                          itemisalcohol = true;
6782
6783                      if( itemisalcohol
6784                          && timenow.after(midnight) && timenow.before(eleven30)){
6785                        outFields.put("authorised", false);
6786                        outFields.put("message", "Sale not authorised by policy task "+subject.taskName+
6787                          " for time "+df.format(timenow.getTime())+
6788                          ". Alcohol can not be sold between "+df.format(midnight.getTime())+
6789                          " and "+df.format(eleven30.getTime()));
6790                        return true;
6791                      }
6792                      else{
6793                        outFields.put("authorised", true);
6794                        outFields.put("message", "Sale authorised by policy task "+subject.taskName+
6795                          " for time "+df.format(timenow.getTime()));
6796                        return true;
6797                      }
6798
6799                      /*
6800                      This task checks if a sale request is for an item that is an alcoholic drink.
6801                      If the local time is between 00:00:00 GMT and 11:30:00 GMT then the sale is not
6802                      authorised. Otherwise the sale is authorised.
6803                      In this implementation we assume that items with item_ID value between 1000 and
6804                      2000 are all alcoholic drinks :-)
6805                      */
6806                      LE
6807
6808                      task create name=MorningBoozeCheckAlt1 version=0.0.1 uuid=bc6d90c9-c902-4686-afd3-925b30e39990 description=LS
6809                      This task checks if a sale request is for an item that is an alcoholic drink.
6810                      If the local time is between 00:00:00 CET and 13:00:00 CET then the sale is not authorised.
6811                      Also alcohol sales are not allowed on Sundays. Otherwise the sale is authorised.
6812                      In this implementation we assume that items with item_ID between 1000 and 2000 are all alcoholic drinks
6813                      LE
6814                      task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1
6815                      task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=amount schemaName=price_type schemaVersion=0.0.1
6816                      task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1
6817                      task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true
6818                      task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=quantity schemaName=quantity_type schemaVersion=0.0.1
6819                      task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1
6820                      task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=item_ID schemaName=item_ID_type schemaVersion=0.0.1
6821                      task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=time schemaName=timestamp_type schemaVersion=0.0.1
6822                      task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1
6823                      task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=amount schemaName=price_type schemaVersion=0.0.1
6824                      task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1
6825                      task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true
6826                      task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=quantity schemaName=quantity_type schemaVersion=0.0.1
6827                      task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1
6828                      task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=item_ID schemaName=item_ID_type schemaVersion=0.0.1
6829                      task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=authorised schemaName=authorised_type schemaVersion=0.0.1
6830                      task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=time schemaName=timestamp_type schemaVersion=0.0.1
6831                      task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=message schemaName=message_type schemaVersion=0.0.1 optional=true
6832                      task logic create name=MorningBoozeCheckAlt1 version=0.0.1 logicFlavour=MVEL logic=LS
6833                      /*
6834                       * ============LICENSE_START=======================================================
6835                       *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
6836                       * ================================================================================
6837                       * Licensed under the Apache License, Version 2.0 (the "License");
6838                       * you may not use this file except in compliance with the License.
6839                       * You may obtain a copy of the License at
6840                       *
6841                       *      http://www.apache.org/licenses/LICENSE-2.0
6842                       *
6843                       * Unless required by applicable law or agreed to in writing, software
6844                       * distributed under the License is distributed on an "AS IS" BASIS,
6845                       * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6846                       * See the License for the specific language governing permissions and
6847                       * limitations under the License.
6848                       *
6849                       * SPDX-License-Identifier: Apache-2.0
6850                       * ============LICENSE_END=========================================================
6851                       */
6852                      import java.util.Date;
6853                      import java.util.Calendar;
6854                      import java.util.TimeZone;
6855                      import java.text.SimpleDateFormat;
6856
6857                      logger.info("Task Execution: '"+subject.id+"'. Input Event: '"+inFields+"'");
6858
6859                      outFields.put("amount"      , inFields.get("amount"));
6860                      outFields.put("assistant_ID", inFields.get("assistant_ID"));
6861                      outFields.put("notes"       , inFields.get("notes"));
6862                      outFields.put("quantity"    , inFields.get("quantity"));
6863                      outFields.put("branch_ID"   , inFields.get("branch_ID"));
6864                      outFields.put("item_ID"     , inFields.get("item_ID"));
6865                      outFields.put("time"        , inFields.get("time"));
6866                      outFields.put("sale_ID"     , inFields.get("sale_ID"));
6867
6868                      item_id = inFields.get("item_ID");
6869
6870                      //The events used later to test this task use CET timezone!
6871                      cet = TimeZone.getTimeZone("CET");
6872                      timenow = Calendar.getInstance(cet);
6873                      df = new SimpleDateFormat("HH:mm:ss z");
6874                      df.setTimeZone(cet);
6875                      timenow.setTimeInMillis(inFields.get("time"));
6876
6877                      midnight = timenow.clone();
6878                      midnight.set(
6879                          timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH),
6880                          timenow.get(Calendar.DATE),0,0,0);
6881                      onepm = timenow.clone();
6882                      onepm.set(
6883                          timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH),
6884                          timenow.get(Calendar.DATE),13,0,0);
6885
6886                      itemisalcohol = false;
6887                      if(item_id != null && item_id >=1000 && item_id < 2000)
6888                          itemisalcohol = true;
6889
6890                      if( itemisalcohol &&
6891                          ( (timenow.after(midnight) && timenow.before(onepm))
6892                            ||
6893                            (timenow.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY)
6894                          )){
6895                        outFields.put("authorised", false);
6896                        outFields.put("message", "Sale not authorised by policy task "+subject.taskName+
6897                          " for time "+df.format(timenow.getTime())+
6898                          ". Alcohol can not be sold between "+df.format(midnight.getTime())+
6899                          " and "+df.format(onepm.getTime()) +" or on Sunday");
6900                        return true;
6901                      }
6902                      else{
6903                        outFields.put("authorised", true);
6904                        outFields.put("message", "Sale authorised by policy task "+subject.taskName+
6905                          " for time "+df.format(timenow.getTime()));
6906                        return true;
6907                      }
6908
6909                      /*
6910                      This task checks if a sale request is for an item that is an alcoholic drink.
6911                      If the local time is between 00:00:00 CET and 13:00:00 CET then the sale is not authorised.
6912                      Also alcohol sales are not allowed on Sundays. Otherwise the sale is authorised.
6913                      In this implementation we assume that items with item_ID between 1000 and 2000 are all alcoholic drinks :-)
6914                      */
6915                      LE
6916
6917                      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"
6918                      event parameter create name=SALE_AUTH version=0.0.1 parName=amount schemaName=price_type schemaVersion=0.0.1
6919                      event parameter create name=SALE_AUTH version=0.0.1 parName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1
6920                      event parameter create name=SALE_AUTH version=0.0.1 parName=authorised schemaName=authorised_type schemaVersion=0.0.1
6921                      event parameter create name=SALE_AUTH version=0.0.1 parName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1
6922                      event parameter create name=SALE_AUTH version=0.0.1 parName=item_ID schemaName=item_ID_type schemaVersion=0.0.1
6923                      event parameter create name=SALE_AUTH version=0.0.1 parName=message schemaName=message_type schemaVersion=0.0.1 optional=true
6924                      event parameter create name=SALE_AUTH version=0.0.1 parName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true
6925                      event parameter create name=SALE_AUTH version=0.0.1 parName=quantity schemaName=quantity_type schemaVersion=0.0.1
6926                      event parameter create name=SALE_AUTH version=0.0.1 parName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1
6927                      event parameter create name=SALE_AUTH version=0.0.1 parName=time schemaName=timestamp_type schemaVersion=0.0.1
6928
6929                      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"
6930                      event parameter create name=SALE_INPUT version=0.0.1 parName=amount schemaName=price_type schemaVersion=0.0.1
6931                      event parameter create name=SALE_INPUT version=0.0.1 parName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1
6932                      event parameter create name=SALE_INPUT version=0.0.1 parName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1
6933                      event parameter create name=SALE_INPUT version=0.0.1 parName=item_ID schemaName=item_ID_type schemaVersion=0.0.1
6934                      event parameter create name=SALE_INPUT version=0.0.1 parName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true
6935                      event parameter create name=SALE_INPUT version=0.0.1 parName=quantity schemaName=quantity_type schemaVersion=0.0.1
6936                      event parameter create name=SALE_INPUT version=0.0.1 parName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1
6937                      event parameter create name=SALE_INPUT version=0.0.1 parName=time schemaName=timestamp_type schemaVersion=0.0.1
6938
6939
6940                      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
6941                      policy state create name=MyFirstPolicy version=0.0.1 stateName=BoozeAuthDecide triggerName=SALE_INPUT triggerVersion=0.0.1 defaultTaskName=MorningBoozeCheck defaultTaskVersion=0.0.1
6942                      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
6943                      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
6944                      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
6945                      policy state selecttasklogic create name=MyFirstPolicy version=0.0.1 stateName=BoozeAuthDecide logicFlavour=JAVASCRIPT logic=LS
6946                      /*
6947                       * ============LICENSE_START=======================================================
6948                       *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
6949                       * ================================================================================
6950                       * Licensed under the Apache License, Version 2.0 (the "License");
6951                       * you may not use this file except in compliance with the License.
6952                       * You may obtain a copy of the License at
6953                       *
6954                       *      http://www.apache.org/licenses/LICENSE-2.0
6955                       *
6956                       * Unless required by applicable law or agreed to in writing, software
6957                       * distributed under the License is distributed on an "AS IS" BASIS,
6958                       * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6959                       * See the License for the specific language governing permissions and
6960                       * limitations under the License.
6961                       *
6962                       * SPDX-License-Identifier: Apache-2.0
6963                       * ============LICENSE_END=========================================================
6964                       */
6965
6966                      var returnValueType = Java.type("java.lang.Boolean");
6967                      var returnValue = new returnValueType(true);
6968
6969                      executor.logger.info("Task Selection Execution: '"+executor.subject.id+"'. Input Event: '"+executor.inFields+"'");
6970
6971                      branchid = executor.inFields.get("branch_ID");
6972                      taskorig = executor.subject.getTaskKey("MorningBoozeCheck");
6973                      taskalt = executor.subject.getTaskKey("MorningBoozeCheckAlt1");
6974                      taskdef = executor.subject.getDefaultTaskKey();
6975
6976                      if(branchid >=0 && branchid <1000){
6977                        taskorig.copyTo(executor.selectedTask);
6978                      }
6979                      else if (branchid >=1000 && branchid <2000){
6980                        taskalt.copyTo(executor.selectedTask);
6981                      }
6982                      else{
6983                        taskdef.copyTo(executor.selectedTask);
6984                      }
6985
6986                      /*
6987                      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"
6988                      */
6989                      LE
6990
6991 APEX Logging
6992 ^^^^^^^^^^^^
6993
6994 Introduction to APEX Logging
6995 ----------------------------
6996
6997          .. container:: paragraph
6998
6999             All APEX components make extensive use of logging using the
7000             logging façade `SLF4J <https://www.slf4j.org/>`__ with the
7001             backend `Logback <https://logback.qos.ch/>`__. Both are used
7002             off-the-shelve, so the standard documentation and
7003             configuration apply to APEX logging. For details on how to
7004             work with logback please see the `logback
7005             manual <https://logback.qos.ch/manual/index.html>`__.
7006
7007          .. container:: paragraph
7008
7009             The APEX applications is the logback configuration file
7010             ``$APEX_HOME/etc/logback.xml`` (Windows:
7011             ``%APEX_HOME%\etc\logback.xml``). The logging backend is set
7012             to no debug, i.e. logs from the logging framework should be
7013             hidden at runtime.
7014
7015          .. container:: paragraph
7016
7017             The configurable log levels work as expected:
7018
7019          .. container:: ulist
7020
7021             -  *error* (or *ERROR*) is used for serious errors in the
7022                APEX runtime engine
7023
7024             -  *warn* (or *WARN*) is used for warnings, which in general
7025                can be ignored but might indicate some deeper problems
7026
7027             -  *info* (or *INFO*) is used to provide generally
7028                interesting messages for startup and policy execution
7029
7030             -  *debug* (or *DEBUG*) provides more details on startup and
7031                policy execution
7032
7033             -  *trace* (or *TRACE*) gives full details on every aspect
7034                of the APEX engine from start to end
7035
7036          .. container:: paragraph
7037
7038             The loggers can also be configured as expected. The standard
7039             configuration (after installing APEX) uses log level *info*
7040             on all APEX classes (components).
7041
7042          .. container:: paragraph
7043
7044             The applications and scripts in ``$APEX_HOME/bin`` (Windows:
7045             ``%APEX_HOME\bin``) are configured to use the logback
7046             configuration ``$APEX_HOME/etc/logback.xml`` (Windows:
7047             ``%APEX_HOME\etc\logback.xml``). There are multiple ways to
7048             use different logback configurations, for instance:
7049
7050          .. container:: ulist
7051
7052             -  Maintain multiple configurations in ``etc``, for instance
7053                a ``logback-debug.xml`` for deep debugging and a
7054                ``logback-production.xml`` for APEX in production mode,
7055                then copy the required configuration file to the used
7056                ``logback.xml`` prior starting APEX
7057
7058             -  Edit the scripts in ``bin`` to use a different logback
7059                configuration file (only recommended if you are familiar
7060                with editing bash scripts or windows batch files)
7061
7062 Standard Logging Configuration
7063 ------------------------------
7064
7065          .. container:: paragraph
7066
7067             The standard logging configuration defines a context *APEX*,
7068             which is used in the standard output pattern. The location
7069             for log files is defined in the property ``VAR_LOG`` and set
7070             to ``/var/log/onap/policy/apex-pdp``. The standard status
7071             listener is set to *NOP* and the overall logback
7072             configuration is set to no debug.
7073
7074          .. container:: listingblock
7075
7076             .. container:: content
7077
7078                .. code::
7079                  :number-lines:
7080
7081                  <configuration debug="false">
7082                    <statusListener class="ch.qos.logback.core.status.NopStatusListener" />
7083
7084                     <contextName>Apex</contextName>
7085                     <property name="VAR_LOG" value="/var/log/onap/policy/apex-pdp/" />
7086
7087                    ...appenders
7088                    ...loggers
7089                  </configuration>
7090
7091 .. container:: paragraph
7092
7093    The first appender defined is called ``STDOUT`` for logs to standard
7094    out.
7095
7096 .. container:: listingblock
7097
7098    .. container:: content
7099
7100       .. code::
7101         :number-lines:
7102
7103         <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
7104          <encoder>
7105             <Pattern>%d %contextName [%t] %level %logger{36} - %msg%n</Pattern>
7106           </encoder>
7107         </appender>
7108
7109 .. container:: paragraph
7110
7111    The root level logger then is set to the level *info* using the
7112    standard out appender.
7113
7114 .. container:: listingblock
7115
7116    .. container:: content
7117
7118       .. code::
7119         :number-lines:
7120
7121         <root level="info">
7122           <appender-ref ref="STDOUT" />
7123         </root>
7124
7125 .. container:: paragraph
7126
7127    The second appender is called ``FILE``. It writes logs to a file
7128    ``apex.log``.
7129
7130 .. container:: listingblock
7131
7132    .. container:: content
7133
7134       .. code::
7135         :number-lines:
7136
7137         <appender name="FILE" class="ch.qos.logback.core.FileAppender">
7138           <file>${VAR_LOG}/apex.log</file>
7139           <encoder>
7140             <pattern>%d %-5relative [procId=${processId}] [%thread] %-5level %logger{26} - %msg %n %ex{full}</pattern>
7141           </encoder>
7142         </appender>
7143
7144 .. container:: paragraph
7145
7146    The third appender is called ``CTXT_FILE``. It writes logs to a file
7147    ``apex_ctxt.log``.
7148
7149 .. container:: listingblock
7150
7151    .. container:: content
7152
7153       .. code::
7154         :number-lines:
7155
7156         <appender name="CTXT_FILE" class="ch.qos.logback.core.FileAppender">
7157           <file>${VAR_LOG}/apex_ctxt.log</file>
7158           <encoder>
7159             <pattern>%d %-5relative [procId=${processId}] [%thread] %-5level %logger{26} - %msg %n %ex{full}</pattern>
7160           </encoder>
7161         </appender>
7162
7163 .. container:: paragraph
7164
7165    The last definitions are for specific loggers. The first logger
7166    captures all standard APEX classes. It is configured for log level
7167    *info* and uses the standard output and file appenders. The second
7168    logger captures APEX context classes responsible for context
7169    monitoring. It is configured for log level *trace* and uses the
7170    context file appender.
7171
7172 .. container:: listingblock
7173
7174    .. container:: content
7175
7176       .. code::
7177         :number-lines:
7178
7179
7180         <logger name="org.onap.policy.apex" level="info" additivity="false">
7181           <appender-ref ref="STDOUT" />
7182           <appender-ref ref="FILE" />
7183         </logger>
7184
7185         <logger name="org.onap.policy.apex.core.context.monitoring" level="TRACE" additivity="false">
7186           <appender-ref ref="CTXT_FILE" />
7187         </logger>
7188
7189 Adding Logback Status and Debug
7190 -------------------------------
7191
7192    .. container:: paragraph
7193
7194       To activate logback status messages change the status listener
7195       from 'NOP' to for instance console.
7196
7197    .. container:: listingblock
7198
7199       .. container:: content
7200
7201          .. code::
7202
7203             <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
7204
7205    .. container:: paragraph
7206
7207       To activate all logback debugging, for instance to debug a new
7208       logback configuration, activate the debug attribute in the
7209       configuration.
7210
7211    .. container:: listingblock
7212
7213       .. container:: content
7214
7215          .. code::
7216
7217             <configuration debug="true">
7218             ...
7219             </configuration>
7220
7221 Logging External Components
7222 ---------------------------
7223
7224    .. container:: paragraph
7225
7226       Logback can also be configured to log any other, external
7227       components APEX is using, if they are using the common logging
7228       framework.
7229
7230    .. container:: paragraph
7231
7232       For instance, the context component of APEX is using *Infinispan*
7233       and one can add a logger for this external component. The
7234       following example adds a logger for *Infinispan* using the
7235       standard output appender.
7236
7237    .. container:: listingblock
7238
7239       .. container:: content
7240
7241          .. code::
7242
7243             <logger name="org.infinispan" level="INFO" additivity="false">
7244               <appender-ref ref="STDOUT" />
7245             </logger>
7246
7247    .. container:: paragraph
7248
7249       Another example is Apache Zookeeper. The following example adds a
7250       logger for Zookeeper using the standard outout appender.
7251
7252    .. container:: listingblock
7253
7254       .. container:: content
7255
7256          .. code::
7257
7258             <logger name="org.apache.zookeeper.ClientCnxn" level="INFO" additivity="false">
7259               <appender-ref ref="STDOUT" />
7260             </logger>
7261
7262 Configuring loggers for Policy Logic
7263 ------------------------------------
7264
7265    .. container:: paragraph
7266
7267       The logging for the logic inside a policy (task logic, task
7268       selection logic, state finalizer logic) can be configured separate
7269       from standard logging. The logger for policy logic is
7270       ``org.onap.policy.apex.executionlogging``. The following example
7271       defines
7272
7273    .. container:: ulist
7274
7275       -  a new appender for standard out using a very simple pattern
7276          (simply the actual message)
7277
7278       -  a logger for policy logic to standard out using the new
7279          appender and the already described file appender.
7280
7281    .. container:: listingblock
7282
7283       .. container:: content
7284
7285          .. code::
7286
7287             <appender name="POLICY_APPENDER_STDOUT" class="ch.qos.logback.core.ConsoleAppender">
7288               <encoder>
7289                 <pattern>policy: %msg\n</pattern>
7290               </encoder>
7291             </appender>
7292
7293             <logger name="org.onap.policy.apex.executionlogging" level="info" additivity="false">
7294               <appender-ref ref="POLICY_APPENDER_STDOUT" />
7295               <appender-ref ref="FILE" />
7296             </logger>
7297
7298    .. container:: paragraph
7299
7300       It is also possible to use specific logging for parts of policy
7301       logic. The following example defines a logger for task logic.
7302
7303    .. container:: listingblock
7304
7305       .. container:: content
7306
7307          .. code::
7308
7309             <logger name="org.onap.policy.apex.executionlogging.TaskExecutionLogging" level="TRACE" additivity="false">
7310               <appender-ref ref="POLICY_APPENDER_STDOUT" />
7311             </logger>
7312
7313 Rolling File Appenders
7314 ----------------------
7315
7316    .. container:: paragraph
7317
7318       Rolling file appenders are a good option for more complex logging
7319       of a production or complex testing APEX installation. The standard
7320       logback configuration can be used for these use cases. This
7321       section gives two examples for the standard logging and for
7322       context logging.
7323
7324    .. container:: paragraph
7325
7326       First the standard logging. The following example defines a
7327       rolling file appender. The appender rolls over on a daily basis.
7328       It allows for a file size of 100 MB.
7329
7330    .. container:: listingblock
7331
7332       .. container:: content
7333
7334          .. code::
7335
7336             <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
7337               <file>${VAR_LOG}/apex.log</file>
7338               <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
7339                 <!-- rollover daily -->
7340                 <!-- <fileNamePattern>xstream-%d{yyyy-MM-dd}.%i.txt</fileNamePattern> -->
7341                 <fileNamePattern>${VAR_LOG}/apex_%d{yyyy-MM-dd}.%i.log.gz
7342                 </fileNamePattern>
7343                 <maxHistory>4</maxHistory>
7344                 <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
7345                   <!-- or whenever the file size reaches 100MB -->
7346                   <maxFileSize>100MB</maxFileSize>
7347                 </timeBasedFileNamingAndTriggeringPolicy>
7348               </rollingPolicy>
7349               <encoder>
7350                 <pattern>
7351                   %d %-5relative [procId=${processId}] [%thread] %-5level %logger{26} - %msg %ex{full} %n
7352                 </pattern>
7353               </encoder>
7354             </appender>
7355
7356    .. container:: paragraph
7357
7358       A very similar configuration can be used for a rolling file
7359       appender logging APEX context.
7360
7361    .. container:: listingblock
7362
7363       .. container:: content
7364
7365          .. code::
7366
7367             <appender name="CTXT-FILE"
7368                   class="ch.qos.logback.core.rolling.RollingFileAppender">
7369               <file>${VAR_LOG}/apex_ctxt.log</file>
7370               <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
7371                 <fileNamePattern>${VAR_LOG}/apex_ctxt_%d{yyyy-MM-dd}.%i.log.gz
7372                 </fileNamePattern>
7373                 <maxHistory>4</maxHistory>
7374                 <timeBasedFileNamingAndTriggeringPolicy
7375                     class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
7376                   <maxFileSize>100MB</maxFileSize>
7377                 </timeBasedFileNamingAndTriggeringPolicy>
7378               </rollingPolicy>
7379               <encoder>
7380                 <pattern>
7381                   %d %-5relative [procId=${processId}] [%thread] %-5level %logger{26} - %msg %ex{full} %n
7382                 </pattern>
7383               </encoder>
7384             </appender>
7385
7386 Example Configuration for Logging Logic
7387 ---------------------------------------
7388
7389    .. container:: paragraph
7390
7391       The following example shows a configuration that logs policy logic
7392       to standard out and a file (*info*). All other APEX components are
7393       logging to a file (*debug*).. This configuration an be used in a
7394       pre-production phase with the APEX engine still running in a
7395       separate terminal to monitor policy execution. This logback
7396       configuration is in the APEX installation as
7397       ``etc/logback-logic.xml``.
7398
7399    .. container:: listingblock
7400
7401       .. container:: content
7402
7403          .. code::
7404
7405             <configuration debug="false">
7406                 <statusListener class="ch.qos.logback.core.status.NopStatusListener" />
7407
7408                 <contextName>Apex</contextName>
7409                 <property name="VAR_LOG" value="/var/log/onap/policy/apex-pdp/" />
7410
7411                 <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
7412                     <encoder>
7413                         <Pattern>%d %contextName [%t] %level %logger{36} - %msg%n</Pattern>
7414                     </encoder>
7415                 </appender>
7416
7417                 <appender name="FILE" class="ch.qos.logback.core.FileAppender">
7418                     <file>${VAR_LOG}/apex.log</file>
7419                     <encoder>
7420                         <pattern>
7421                             %d %-5relative [procId=${processId}] [%thread] %-5level%logger{26} - %msg %n %ex{full}
7422                         </pattern>
7423                     </encoder>
7424                 </appender>
7425
7426                 <appender name="POLICY_APPENDER_STDOUT" class="ch.qos.logback.core.ConsoleAppender">
7427                     <encoder>
7428                         <pattern>policy: %msg\n</pattern>
7429                     </encoder>
7430                 </appender>
7431
7432                 <root level="error">
7433                     <appender-ref ref="STDOUT" />
7434                 </root>
7435
7436                 <logger name="org.onap.policy.apex" level="debug" additivity="false">
7437                     <appender-ref ref="FILE" />
7438                 </logger>
7439
7440                 <logger name="org.onap.policy.apex.executionlogging" level="info" additivity="false">
7441                     <appender-ref ref="POLICY_APPENDER_STDOUT" />
7442                     <appender-ref ref="FILE" />
7443                 </logger>
7444             </configuration>
7445
7446 Example Configuration for a Production Server
7447 ---------------------------------------------
7448
7449    .. container:: paragraph
7450
7451       The following example shows a configuration that logs all APEX
7452       components, including policy logic, to a file (*debug*). This
7453       configuration an be used in a production phase with the APEX
7454       engine being executed as a service on a system without console
7455       output. This logback configuration is in the APEX installation as
7456       ``logback-server.xml``
7457
7458    .. container:: listingblock
7459
7460       .. container:: content
7461
7462          .. code::
7463
7464             <configuration debug="false">
7465                 <statusListener class="ch.qos.logback.core.status.NopStatusListener" />
7466
7467                 <contextName>Apex</contextName>
7468                 <property name="VAR_LOG" value="/var/log/onap/policy/apex-pdp/" />
7469
7470                 <appender name="FILE" class="ch.qos.logback.core.FileAppender">
7471                     <file>${VAR_LOG}/apex.log</file>
7472                     <encoder>
7473                         <pattern>
7474                             %d %-5relative [procId=${processId}] [%thread] %-5level%logger{26} - %msg %n %ex{full}
7475                         </pattern>
7476                     </encoder>
7477                 </appender>
7478
7479                 <root level="debug">
7480                     <appender-ref ref="FILE" />
7481                 </root>
7482
7483                 <logger name="org.onap.policy.apex.executionlogging" level="debug" additivity="false">
7484                     <appender-ref ref="FILE" />
7485                 </logger>
7486             </configuration>
7487
7488 Building a System with Websocket Backend
7489 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7490
7491 Websockets
7492 ----------
7493
7494          .. container:: paragraph
7495
7496             Websocket is a protocol to run sockets of HTTP. Since it in
7497             essence a socket, the connection is realized between a
7498             server (waiting for connections) and a client (connecting to
7499             a server). Server/client separation is only important for
7500             connection establishment, once connected, everyone can
7501             send/receive on the same socket (as any standard socket
7502             would allow).
7503
7504          .. container:: paragraph
7505
7506             Standard Websocket implementations are simple, no
7507             publish/subscribe and no special event handling. Most
7508             servers simply send all incoming messages to all
7509             connections. There is a PubSub definition on top of
7510             Websocket called `WAMP <http://wamp-proto.org/>`__. APEX
7511             does not support WAMP at the moment.
7512
7513 Websocket in Java
7514 -----------------
7515
7516          .. container:: paragraph
7517
7518             In Java, `JSR
7519             356 <http://www.oracle.com/technetwork/articles/java/jsr356-1937161.html>`__
7520             defines the standard Websocket API. This JSR is part of Jave
7521             EE 7 standard. For Java SE, several implementations exist in
7522             open source. Since Websockets are a stable standard and
7523             simple, most implementations are stable and ready to use. A
7524             lot of products support Websockets, like Spring, JBoss,
7525             Netty, … there are also Kafka extensions for Websockets.
7526
7527 Websocket Example Code for Websocket clients (FOSS)
7528 ---------------------------------------------------
7529
7530          .. container:: paragraph
7531
7532             There are a lot of implementations and examples available on
7533             Github for Websocket clients. If one is using Java EE 7,
7534             then one can also use the native Websocket implementation.
7535             Good examples for clients using simply Java SE are here:
7536
7537          .. container:: ulist
7538
7539             -  `Websocket
7540                implementation <https://github.com/TooTallNate/Java-WebSocket>`__
7541
7542             -  `Websocket sending client example, using
7543                AWT <https://github.com/TooTallNate/Java-WebSocket/blob/master/src/main/example/ChatClient.java>`__
7544
7545             -  `Websocket receiving client example (simple echo
7546                client) <https://github.com/TooTallNate/Java-WebSocket/blob/master/src/main/example/ExampleClient.java>`__
7547
7548          .. container:: paragraph
7549
7550             For Java EE, the native Websocket API is explained here:
7551
7552          .. container:: ulist
7553
7554             -  `Oracle
7555                docs <http://www.oracle.com/technetwork/articles/java/jsr356-1937161.html>`__
7556
7557             -  link: `An
7558                example <http://www.programmingforliving.com/2013/08/jsr-356-java-api-for-websocket-client-api.html>`__
7559
7560 BCP: Websocket Configuration
7561 ----------------------------
7562
7563          .. container:: paragraph
7564
7565             The probably best is to configure APEX for Websocket servers
7566             for input (ingress, consume) and output (egress, produce)
7567             interfaces. This means that APEX will start Websocket
7568             servers on named ports and wait for clients to connect.
7569             Advantage: once APEX is running all connectivity
7570             infrastructure is running as well. Consequence: if APEX is
7571             not running, everyone else is in the dark, too.
7572
7573          .. container:: paragraph
7574
7575             The best protocol to be used is JSON string. Each event on
7576             any interface is then a string with a JSON encoding. JSON
7577             string is a little bit slower than byte code, but we doubt
7578             that this will be noticeable. A further advantage of JSON
7579             strings over Websockets with APEX starting the servers: it
7580             is very easy to connect web browsers to such a system.
7581             Simple connect the web browser to the APEX sockets and
7582             send/read JSON strings.
7583
7584          .. container:: paragraph
7585
7586             Once APEX is started you simply connect Websocket clients to
7587             it, and send/receive event. When APEX is terminated, the
7588             Websocket servers go down, and the clients will be
7589             disconnected. APEX does not (yet) support auto-client
7590             reconnect nor WAMP, so clients might need to be restarted or
7591             reconnected manually after an APEX boot.
7592
7593 Demo with VPN Policy Model
7594 --------------------------
7595
7596          .. container:: paragraph
7597
7598             We assume that you have an APEX installation using the full
7599             package, i.e. APEX with all examples, of version ``0.5.6``
7600             or higher. We will use the VPN policy from the APEX examples
7601             here.
7602
7603          .. container:: paragraph
7604
7605             Now, have the following ready to start the demo:
7606
7607          .. container:: ulist
7608
7609             -  3 terminals on the host where APEX is running (we need 1
7610                for APEX and 1 for each client)
7611
7612             -  the events in the file
7613                ``$APEX_HOME/examples/events/VPN/SetupEvents.json`` open
7614                in an editor (we need to send those events to APEX)
7615
7616             -  the events in the file
7617                ``$APEX_HOME/examples/events/VPN/Link09Events.json`` open
7618                in an editor (we need to send those events to APEX)
7619
7620 A Websocket Configuration for the VPN Domain
7621 ############################################
7622
7623             .. container:: paragraph
7624
7625                Create a new APEX configuration using the VPN policy
7626                model and configuring APEX as discussed above for
7627                Websockets. Copy the following configuration into
7628                ``$APEX_HOME/examples/config/VPN/Ws2WsServerAvroContextJsonEvent.json``
7629                (for Windows use
7630                ``%APEX_HOME%\examples\config\VPN\Ws2WsServerAvroContextJsonEvent.json``):
7631
7632             .. container:: listingblock
7633
7634                .. container:: content
7635
7636                   .. code::
7637                     :number-lines:
7638
7639                     {
7640                       "engineServiceParameters" : {
7641                         "name"          : "VPNApexEngine",
7642                         "version"        : "0.0.1",
7643                         "id"             :  45,
7644                         "instanceCount"  : 1,
7645                         "deploymentPort" : 12345,
7646                         "policyModelFileName" : "examples/models/VPN/VPNPolicyModelAvro.json",
7647                         "engineParameters"    : {
7648                           "executorParameters" : {
7649                             "MVEL" : {
7650                               "parameterClassName" : "org.onap.policy.apex.plugins.executor.mvel.MVELExecutorParameters"
7651                             }
7652                           },
7653                           "contextParameters" : {
7654                             "parameterClassName" : "org.onap.policy.apex.context.parameters.ContextParameters",
7655                             "schemaParameters":{
7656                               "Avro":{
7657                                 "parameterClassName" : "org.onap.policy.apex.plugins.context.schema.avro.AvroSchemaHelperParameters"
7658                               }
7659                             }
7660                           }
7661                         }
7662                       },
7663                       "producerCarrierTechnologyParameters" : {
7664                         "carrierTechnology" : "WEBSOCKET",
7665                         "parameterClassName" : "org.onap.policy.apex.plugins.event.carrier.websocket.WEBSOCKETCarrierTechnologyParameters",
7666                         "parameters" : {
7667                           "wsClient" : false,
7668                           "port"     : 42452
7669                         }
7670                       },
7671                       "producerEventProtocolParameters" : {
7672                         "eventProtocol" : "JSON"
7673                       },
7674                       "consumerCarrierTechnologyParameters" : {
7675                         "carrierTechnology" : "WEBSOCKET",
7676                         "parameterClassName" : "org.onap.policy.apex.plugins.event.carrier.websocket.WEBSOCKETCarrierTechnologyParameters",
7677                         "parameters" : {
7678                          "wsClient" : false,
7679                           "port"     : 42450
7680                         }
7681                       },
7682                       "consumerEventProtocolParameters" : {
7683                         "eventProtocol" : "JSON"
7684                       }
7685                     }
7686
7687 Start APEX Engine
7688 #################
7689
7690    .. container:: paragraph
7691
7692       In a new terminal, start APEX with the new configuration for
7693       Websocket-Server ingress/egress:
7694
7695    .. container:: listingblock
7696
7697       .. container:: content
7698
7699          .. code::
7700             :number-lines:
7701
7702             #: $APEX_HOME/bin/apexEngine.sh -c $APEX_HOME/examples/config/VPN/Ws2WsServerAvroContextJsonEvent.json
7703
7704 .. container:: listingblock
7705
7706    .. container:: content
7707
7708       .. code::
7709         :number-lines:
7710
7711         #: %APEX_HOME%\bin\apexEngine.bat -c %APEX_HOME%\examples\config\VPN\Ws2WsServerAvroContextJsonEvent.json
7712
7713 .. container:: paragraph
7714
7715    Wait for APEX to start, it takes a while to create all Websocket
7716    servers (about 8 seconds on a standard laptop without cached
7717    binaries). depending on your log messages, you will see no (some, a
7718    lot) log messages. If APEX starts correctly, the last few messages
7719    you should see are:
7720
7721 .. container:: listingblock
7722
7723    .. container:: content
7724
7725       .. code::
7726         :number-lines:
7727
7728          2017-07-28 13:17:20,834 Apex [main] INFO c.e.a.s.engine.runtime.EngineService - engine model VPNPolicyModelAvro:0.0.1 added to the engine-AxArtifactKey:(name=VPNApexEngine-0,version=0.0.1)
7729          2017-07-28 13:17:21,057 Apex [Apex-apex-engine-service-0:0] INFO c.e.a.s.engine.runtime.EngineService - Engine AxArtifactKey:(name=VPNApexEngine-0,version=0.0.1) processing ...
7730          2017-07-28 13:17:21,296 Apex [main] INFO c.e.a.s.e.r.impl.EngineServiceImpl - Added the action listener to the engine
7731          Started Apex service
7732
7733 .. container:: paragraph
7734
7735    APEX is running in the new terminal and will produce output when the
7736    policy is triggered/executed.
7737
7738 Run the Websocket Echo Client
7739 #############################
7740
7741    .. container:: paragraph
7742
7743       The echo client is included in an APEX full installation. To run
7744       the client, open a new shell (Unix, Cygwin) or command prompt
7745       (``cmd`` on Windows). Then use the APEX application launcher to
7746       start the client.
7747
7748    .. important::  
7749       APEX engine needs to run first
7750       The example assumes that an APEX engine configured for *produce* carrier technology Websocket and *JSON* event protocol is executed first.
7751
7752    +---------------------------------------------------------+-----------------------------------------------------------+
7753    | Unix, Cygwin                                            | Windows                                                   |
7754    +=========================================================+===========================================================+
7755    | .. container::                                          | .. container::                                            |
7756    |                                                         |                                                           |
7757    |    .. container:: listingblock                          |    .. container:: listingblock                            |
7758    |                                                         |                                                           |
7759    |       .. container:: content                            |       .. container:: content                              |
7760    |                                                         |                                                           |
7761    |          .. code::                                      |          .. code::                                        |
7762    |                                                         |                                                           |
7763    |             # $APEX_HOME/bin/apexApps.sh ws-echo [args] |             > %APEX_HOME%\bin\apexApps.bat ws-echo [args] |
7764    +---------------------------------------------------------+-----------------------------------------------------------+
7765
7766    .. container:: paragraph
7767
7768       Use the following command line arguments for server and port of
7769       the Websocket server. The port should be the same as configured in
7770       the APEX engine. The server host should be the host on which the
7771       APEX engine is running
7772
7773    .. container:: ulist
7774
7775       -  ``-p`` defines the Websocket port to connect to (defaults to
7776          ``8887``)
7777
7778       -  ``-s`` defines the host on which a Websocket server is running
7779          (defaults to ``localhost``)
7780
7781    .. container:: paragraph
7782
7783       Let’s assume that there is an APEX engine running, configured for
7784       produce Websocket carrier technology, as server, for port 42452,
7785       with produce event protocol JSON,. If we start the console client
7786       on the same host, we can omit the ``-s`` options. We start the
7787       console client as:
7788
7789    .. container:: listingblock
7790
7791       .. container:: content
7792
7793          .. code::
7794
7795             # $APEX_HOME/bin/apexApps.sh ws-echo -p 42452 (1)
7796             > %APEX_HOME%\bin\apexApps.bat ws-echo -p 42452 (2)
7797
7798    .. container:: colist arabic
7799
7800       +-------+--------------------------------+
7801       | **1** | Start client on Unix or Cygwin |
7802       +-------+--------------------------------+
7803       | **2** | Start client on Windows        |
7804       +-------+--------------------------------+
7805
7806    .. container:: paragraph
7807
7808       Once started successfully, the client will produce the following
7809       messages (assuming we used ``-p 42452`` and an APEX engine is
7810       running on ``localhost`` with the same port:
7811
7812    .. container:: listingblock
7813
7814       .. container:: content
7815
7816          .. code::
7817
7818             ws-simple-echo: starting simple event echo
7819              --> server: localhost
7820              --> port: 42452
7821
7822             Once started, the application will simply print out all received events to standard out.
7823             Each received event will be prefixed by '---' and suffixed by '===='
7824
7825
7826             ws-simple-echo: opened connection to APEX (Web Socket Protocol Handshake)
7827
7828 Run the Websocket Console Client
7829 ################################
7830
7831    .. container:: paragraph
7832
7833       The console client is included in an APEX full installation. To
7834       run the client, open a new shell (Unix, Cygwin) or command prompt
7835       (``cmd`` on Windows). Then use the APEX application launcher to
7836       start the client.
7837
7838    .. important::  
7839       APEX engine needs to run first
7840       The example assumes that an APEX engine configured for *consume* carrier technology Websocket and *JSON* event
7841       protocol is executed first.
7842
7843    +------------------------------------------------------------+--------------------------------------------------------------+
7844    | Unix, Cygwin                                               | Windows                                                      |
7845    +============================================================+==============================================================+
7846    | .. container::                                             | .. container::                                               |
7847    |                                                            |                                                              |
7848    |    .. container:: listingblock                             |    .. container:: listingblock                               |
7849    |                                                            |                                                              |
7850    |       .. container:: content                               |       .. container:: content                                 |
7851    |                                                            |                                                              |
7852    |          .. code::                                         |          .. code::                                           |
7853    |                                                            |                                                              |
7854    |             # $APEX_HOME/bin/apexApps.sh ws-console [args] |             > %APEX_HOME%\bin\apexApps.bat ws-console [args] |
7855    +------------------------------------------------------------+--------------------------------------------------------------+
7856
7857    .. container:: paragraph
7858
7859       Use the following command line arguments for server and port of
7860       the Websocket server. The port should be the same as configured in
7861       the APEX engine. The server host should be the host on which the
7862       APEX engine is running
7863
7864    .. container:: ulist
7865
7866       -  ``-p`` defines the Websocket port to connect to (defaults to
7867          ``8887``)
7868
7869       -  ``-s`` defines the host on which a Websocket server is running
7870          (defaults to ``localhost``)
7871
7872    .. container:: paragraph
7873
7874       Let’s assume that there is an APEX engine running, configured for
7875       consume Websocket carrier technology, as server, for port 42450,
7876       with consume event protocol JSON,. If we start the console client
7877       on the same host, we can omit the ``-s`` options. We start the
7878       console client as:
7879
7880    .. container:: listingblock
7881
7882       .. container:: content
7883
7884          .. code::
7885
7886             # $APEX_HOME/bin/apexApps.sh ws-console -p 42450 (1)
7887             > %APEX_HOME%\bin\apexApps.sh ws-console -p 42450 (2)
7888
7889    .. container:: colist arabic
7890
7891       +-------+--------------------------------+
7892       | **1** | Start client on Unix or Cygwin |
7893       +-------+--------------------------------+
7894       | **2** | Start client on Windows        |
7895       +-------+--------------------------------+
7896
7897    .. container:: paragraph
7898
7899       Once started successfully, the client will produce the following
7900       messages (assuming we used ``-p 42450`` and an APEX engine is
7901       running on ``localhost`` with the same port:
7902
7903    .. container:: listingblock
7904
7905       .. container:: content
7906
7907          .. code::
7908
7909             ws-simple-console: starting simple event console
7910              --> server: localhost
7911              --> port: 42450
7912
7913              - terminate the application typing 'exit<enter>' or using 'CTRL+C'
7914              - events are created by a non-blank starting line and terminated by a blank line
7915
7916
7917             ws-simple-console: opened connection to APEX (Web Socket Protocol Handshake)
7918
7919 Send Events
7920 ###########
7921
7922    .. container:: paragraph
7923
7924       Now you have the full system up and running:
7925
7926    .. container:: ulist
7927
7928       -  Terminal 1: APEX ready and loaded
7929
7930       -  Terminal 2: an echo client, printing received messages produced
7931          by the VPN policy
7932
7933       -  Terminal 2: a console client, waiting for input on the console
7934          (standard in) and sending text to APEX
7935
7936    .. container:: paragraph
7937
7938       We started the engine with the VPN policy example. So all the
7939       events we are using now are located in files in the following
7940       example directory:
7941
7942    .. container:: listingblock
7943
7944       .. container:: content
7945
7946          .. code::
7947            :number-lines:
7948
7949            #: $APEX_HOME/examples/events/VPN
7950            > %APEX_HOME%\examples\events\VPN
7951
7952 .. container:: paragraph
7953
7954    To sends events, simply copy the content of the event files into
7955    Terminal 3 (the console client). It will read multi-line JSON text
7956    and send the events. So copy the content of ``SetupEvents.json`` into
7957    the client. APEX will trigger a policy and produce some output, the
7958    echo client will also print some events created in the policy. In
7959    Terminal 1 (APEX) you’ll see some status messages from the policy as:
7960
7961 .. container:: listingblock
7962
7963    .. container:: content
7964
7965       .. code::
7966         :number-lines:
7967
7968         {Link=L09, LinkUp=true}
7969         L09     true
7970         outFields: {Link=L09, LinkUp=true}
7971         {Link=L10, LinkUp=true}
7972         L09     true
7973         L10     true
7974         outFields: {Link=L10, LinkUp=true}
7975         {CustomerName=C, LinkList=L09 L10, SlaDT=300, YtdDT=300}
7976         *** Customers ***
7977         C       300     300     [L09, L10]
7978         outFields: {CustomerName=C, LinkList=L09 L10, SlaDT=300, YtdDT=300}
7979         {CustomerName=A, LinkList=L09 L10, SlaDT=300, YtdDT=50}
7980         *** Customers ***
7981         A       300     50      [L09, L10]
7982         C       300     300     [L09, L10]
7983         outFields: {CustomerName=A, LinkList=L09 L10, SlaDT=300, YtdDT=50}
7984         {CustomerName=D, LinkList=L09 L10, SlaDT=300, YtdDT=400}
7985         *** Customers ***
7986         A       300     50      [L09, L10]
7987         C       300     300     [L09, L10]
7988         D       300     400     [L09, L10]
7989         outFields: {CustomerName=D, LinkList=L09 L10, SlaDT=300, YtdDT=400}
7990         {CustomerName=B, LinkList=L09 L10, SlaDT=300, YtdDT=299}
7991         *** Customers ***
7992         A       300     50      [L09, L10]
7993         B       300     299     [L09, L10]
7994         C       300     300     [L09, L10]
7995         D       300     400     [L09, L10]
7996         outFields: {CustomerName=B, LinkList=L09 L10, SlaDT=300, YtdDT=299}
7997
7998 .. container:: paragraph
7999
8000    In Terminal 2 (echo-client) you see the received events, the last two
8001    should look like:
8002
8003 .. container:: listingblock
8004
8005    .. container:: content
8006
8007       .. code::
8008         :number-lines:
8009
8010         ws-simple-echo: received
8011         ---------------------------------
8012         {
8013           "name": "VPNCustomerCtxtActEvent",
8014           "version": "0.0.1",
8015           "nameSpace": "org.onap.policy.apex.domains.vpn.events",
8016           "source": "Source",
8017           "target": "Target",
8018           "CustomerName": "C",
8019           "LinkList": "L09 L10",
8020           "SlaDT": 300,
8021           "YtdDT": 300
8022         }
8023         =================================
8024
8025         ws-simple-echo: received
8026         ---------------------------------
8027         {
8028           "name": "VPNCustomerCtxtActEvent",
8029           "version": "0.0.1",
8030           "nameSpace": "org.onap.policy.apex.domains.vpn.events",
8031           "source": "Source",
8032           "target": "Target",
8033           "CustomerName": "D",
8034           "LinkList": "L09 L10",
8035           "SlaDT": 300,
8036           "YtdDT": 400
8037         }
8038         =================================
8039
8040 .. container:: paragraph
8041
8042    Congratulations, you have triggered a policy in APEX using
8043    Websockets, the policy did run through, created events, picked up by
8044    the echo-client.
8045
8046 .. container:: paragraph
8047
8048    Now you can send the Link 09 and Link 10 events, they will trigger
8049    the actual VPN policy and some calculations are made. Let’s take the
8050    Link 09 events from ``Link09Events.json``, copy them all into
8051    Terminal 3 (the console). APEX will run the policy (with some status
8052    output), and the echo client will receive and print events.
8053
8054 .. container:: paragraph
8055
8056    To terminate the applications, simply press ``CTRL+C`` in Terminal 1
8057    (APEX). This will also terminate the echo-client in Terminal 2. Then
8058    type ``exit<enter>`` in Terminal 3 (or ``CTRL+C``) to terminate the
8059    console-client.
8060
8061 .. container::
8062    :name: footer
8063
8064    .. container::
8065       :name: footer-text
8066
8067       2.0.0-SNAPSHOT
8068       Last updated 2018-09-10 15:38:16 IST
8069
8070 .. |Extract the TAR archive| image:: images/install-guide/win-extract-tar-gz.png
8071 .. |Extract the APEX distribution| image:: images/install-guide/win-extract-tar.png
8072 .. |REST Editor Start Screen| image:: images/install-guide/rest-start.png
8073 .. |REST Editor with loaded SampleDomain Policy Model| image:: images/install-guide/rest-loaded.png
8074 .. |APEX Configuration Matrix| image:: images/apex-intro/ApexEngineConfig.png
8075 .. |File > New to create a new Policy Model| image:: images/mfp/MyFirstPolicy_P1_newPolicyModel1.png
8076 .. |Create a new Policy Model| image:: images/mfp/MyFirstPolicy_P1_newPolicyModel2.png
8077 .. |Right click to create a new event| image:: images/mfp/MyFirstPolicy_P1_newEvent1.png
8078 .. |Fill in the necessary information for the 'SALE_INPUT' event and click 'Submit'| image:: images/mfp/MyFirstPolicy_P1_newEvent2.png
8079 .. |Right click to create a new Item Schema| image:: images/mfp/MyFirstPolicy_P1_newItemSchema1.png
8080 .. |Create a new Item Schema| image:: images/mfp/MyFirstPolicy_P1_newItemSchema2.png
8081 .. |Add new event parameters to an event| image:: images/mfp/MyFirstPolicy_P1_newEvent3.png
8082 .. |Right click to create a new task| image:: images/mfp/MyFirstPolicy_P1_newTask1.png
8083 .. |Add input and out fields for the task| image:: images/mfp/MyFirstPolicy_P1_newTask2.png
8084 .. |Add task logic the task| image:: images/mfp/MyFirstPolicy_P1_newTask3.png
8085 .. |Create a new policy| image:: images/mfp/MyFirstPolicy_P1_newPolicy1.png
8086 .. |Create a state| image:: images/mfp/MyFirstPolicy_P1_newState1.png
8087 .. |Add a Task and Output Mapping| image:: images/mfp/MyFirstPolicy_P1_newState2.png
8088 .. |Validate the policy model for error using the 'Model' > 'Validate' menu item| image:: images/mfp/MyFirstPolicy_P1_validatePolicyModel.png
8089 .. |Download the completed policy model using the 'File' > 'Download' menu item| image:: images/mfp/MyFirstPolicy_P1_exportPolicyModel1.png
8090 .. |Create a new alternative task MorningBoozeCheckAlt1| image:: images/mfp/MyFirstPolicy_P2_newTask1.png
8091 .. |Right click to edit a policy| image:: images/mfp/MyFirstPolicy_P2_editPolicy1.png
8092 .. |State definition with 2 Tasks and Task Selection Logic| image:: images/mfp/MyFirstPolicy_P2_editState1.png
8093