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