ramverma | 3b71c97 | 2019-07-10 11:25:37 +0000 | [diff] [blame^] | 1 | .. This work is licensed under a Creative Commons Attribution 4.0 International License. |
| 2 | .. http://creativecommons.org/licenses/by/4.0 |
| 3 | |
| 4 | |
| 5 | APEX User Manual |
| 6 | **************** |
| 7 | |
| 8 | .. contents:: |
| 9 | :depth: 3 |
| 10 | |
| 11 | Installation |
| 12 | ^^^^^^^^^^^^ |
| 13 | |
| 14 | Requirements |
| 15 | ------------ |
| 16 | |
| 17 | .. container:: paragraph |
| 18 | |
| 19 | APEX is 100% written in Java and runs on any platform |
| 20 | that supports a JVM, e.g. Windows, Unix, Cygwin. Some |
| 21 | APEX applications (such as the monitoring application) |
| 22 | come as web archives, they do require a war-capable web |
| 23 | server installed. |
| 24 | |
| 25 | Installation Requirements |
| 26 | ######################### |
| 27 | |
| 28 | .. container:: ulist |
| 29 | |
| 30 | - Downloaded distribution: JAVA runtime environment |
| 31 | (JRE, Java 8 or later, APEX is tested with the |
| 32 | Oracle Java) |
| 33 | |
| 34 | - Building from source: JAVA development kit (JDK, |
| 35 | Java 8 or later, APEX is tested with the Oracle |
| 36 | Java) |
| 37 | |
| 38 | - A web archive capable webserver, for instance for |
| 39 | the monitoring application |
| 40 | |
| 41 | .. container:: ulist |
| 42 | |
| 43 | - for instance `Apache |
| 44 | Tomcat <https://tomcat.apache.org/>`__ |
| 45 | |
| 46 | - Sufficient rights to install APEX on the system |
| 47 | |
| 48 | - Installation tools depending on the installation |
| 49 | method used: |
| 50 | |
| 51 | .. container:: ulist |
| 52 | |
| 53 | - ZIP to extract from a ZIP distribution |
| 54 | |
| 55 | .. container:: ulist |
| 56 | |
| 57 | - Windows for instance |
| 58 | `7Zip <http://www.7-zip.org/>`__ |
| 59 | |
| 60 | - TAR and GZ to extract from that TAR.GZ |
| 61 | distribution |
| 62 | |
| 63 | .. container:: ulist |
| 64 | |
| 65 | - Windows for instance |
| 66 | `7Zip <http://www.7-zip.org/>`__ |
| 67 | |
| 68 | - RPM to install from the RPM distribution |
| 69 | |
| 70 | .. container:: ulist |
| 71 | |
| 72 | - Install: ``sudo apt-get install rpm`` |
| 73 | |
| 74 | - DPKG to install from the DEB distribution |
| 75 | |
| 76 | .. container:: ulist |
| 77 | |
| 78 | - Install: ``sudo apt-get install dpkg`` |
| 79 | |
| 80 | Feature Requirements |
| 81 | #################### |
| 82 | |
| 83 | .. container:: paragraph |
| 84 | |
| 85 | APEX supports a number of features that require extra |
| 86 | software being installed. |
| 87 | |
| 88 | .. container:: ulist |
| 89 | |
| 90 | - `Apache Kafka <https://kafka.apache.org/>`__ to |
| 91 | connect APEX to a Kafka message bus |
| 92 | |
| 93 | - `Hazelcast <https://hazelcast.com/>`__ to use |
| 94 | distributed hash maps for context |
| 95 | |
| 96 | - `Infinispan <http://infinispan.org/>`__ for |
| 97 | distributed context and persistence |
| 98 | |
| 99 | - `Docker <https://www.docker.com/>`__ to run APEX |
| 100 | inside a Docker container |
| 101 | |
| 102 | Build (Install from Source) Requirements |
| 103 | ######################################## |
| 104 | |
| 105 | .. container:: paragraph |
| 106 | |
| 107 | Installation from source requires a few development |
| 108 | tools |
| 109 | |
| 110 | .. container:: ulist |
| 111 | |
| 112 | - GIT to retrieve the source code |
| 113 | |
| 114 | - Java SDK, Java version 8 or later |
| 115 | |
| 116 | - Apache Maven 3 (the APEX build environment) |
| 117 | |
| 118 | Get the APEX Source Code |
| 119 | ------------------------ |
| 120 | |
| 121 | .. container:: paragraph |
| 122 | |
| 123 | The first APEX source code was hosted on Github in |
| 124 | January 2018. By the end of 2018, APEX was added as a |
| 125 | project in the ONAP Policy Framework, released later in |
| 126 | the ONAP Casablanca release. |
| 127 | |
| 128 | .. container:: paragraph |
| 129 | |
| 130 | The APEX source code is hosted in ONAP as project APEX. |
| 131 | The current stable version is in the master branch. |
| 132 | Simply clone the master branch from ONAP using HTTPS. |
| 133 | |
| 134 | .. container:: listingblock |
| 135 | |
| 136 | .. container:: content |
| 137 | |
| 138 | .. code:: |
| 139 | :number-lines: |
| 140 | |
| 141 | git clone https://gerrit.onap.org/r/policy/apex-pdp |
| 142 | |
| 143 | Build APEX |
| 144 | ---------- |
| 145 | |
| 146 | .. container:: paragraph |
| 147 | |
| 148 | The examples in this document assume that the APEX source |
| 149 | repositories are cloned to: |
| 150 | |
| 151 | .. container:: ulist |
| 152 | |
| 153 | - Unix, Cygwin: ``/usr/local/src/apex-pdp`` |
| 154 | |
| 155 | - Windows: ``C:\dev\apex-pdp`` |
| 156 | |
| 157 | - Cygwin: ``/cygdrive/c/dev/apex-pdp`` |
| 158 | |
| 159 | .. important:: |
| 160 | A Build requires ONAP Nexus |
| 161 | APEX has a dependency to ONAP parent projects. You might need to adjust your Maven M2 settings. The most current |
| 162 | settings can be found in the ONAP oparent repo: `Settings <https://git.onap.org/oparent/plain/settings.xml>`__. |
| 163 | |
| 164 | .. important:: |
| 165 | A Build needs Space |
| 166 | Building APEX requires approximately 2-3 GB of hard disc space, 1 GB for the actual build with full |
| 167 | distribution and 1-2 GB for the downloaded dependencies |
| 168 | |
| 169 | .. important:: |
| 170 | A Build requires Internet (for first build) |
| 171 | During the build, several (a lot) of Maven dependencies will be downloaded and stored in the configured local Maven |
| 172 | repository. The first standard build (and any first specific build) requires Internet access to download those |
| 173 | dependencies. |
| 174 | |
| 175 | .. important:: |
| 176 | Building RPM distributions |
| 177 | RPM images are only build if the ``rpm`` package is installed (Unix). To install ``rpm`` run ``sudo apt-get install rpm``, |
| 178 | then build APEX. |
| 179 | |
| 180 | .. container:: paragraph |
| 181 | |
| 182 | Use Maven to for a standard build without any tests. |
| 183 | |
| 184 | +-------------------------------------------------------+--------------------------------------------------------+ |
| 185 | | Unix, Cygwin | Windows | |
| 186 | +=======================================================+========================================================+ |
| 187 | | .. container:: | .. container:: | |
| 188 | | | | |
| 189 | | .. container:: content | .. container:: content | |
| 190 | | | | |
| 191 | | .. code:: | .. code:: | |
| 192 | | :number-lines: | :number-lines: | |
| 193 | | | | |
| 194 | | # cd /usr/local/src/apex-pdp | >c: | |
| 195 | | # mvn clean install -DskipTest | >cd \dev\apex | |
| 196 | | | >mvn clean install -DskipTests | |
| 197 | +-------------------------------------------------------+--------------------------------------------------------+ |
| 198 | |
| 199 | .. container:: paragraph |
| 200 | |
| 201 | The build takes 2-3 minutes on a standard development laptop. It |
| 202 | should run through without errors, but with a lot of messages from |
| 203 | the build process. |
| 204 | |
| 205 | .. container:: paragraph |
| 206 | |
| 207 | When Maven is finished with the build, the final screen should look |
| 208 | similar to this (omitting some ``success`` lines): |
| 209 | |
| 210 | .. container:: listingblock |
| 211 | |
| 212 | .. container:: content |
| 213 | |
| 214 | .. code:: |
| 215 | :number-lines: |
| 216 | |
| 217 | [INFO] tools .............................................. SUCCESS [ 0.248 s] |
| 218 | [INFO] tools-common ....................................... SUCCESS [ 0.784 s] |
| 219 | [INFO] simple-wsclient .................................... SUCCESS [ 3.303 s] |
| 220 | [INFO] model-generator .................................... SUCCESS [ 0.644 s] |
| 221 | [INFO] packages ........................................... SUCCESS [ 0.336 s] |
| 222 | [INFO] apex-pdp-package-full .............................. SUCCESS [01:10 min] |
| 223 | [INFO] Policy APEX PDP - Docker build 2.0.0-SNAPSHOT ...... SUCCESS [ 10.307 s] |
| 224 | [INFO] ------------------------------------------------------------------------ |
| 225 | [INFO] BUILD SUCCESS |
| 226 | [INFO] ------------------------------------------------------------------------ |
| 227 | [INFO] Total time: 03:43 min |
| 228 | [INFO] Finished at: 2018-09-03T11:56:01+01:00 |
| 229 | [INFO] ------------------------------------------------------------------------ |
| 230 | |
| 231 | .. container:: paragraph |
| 232 | |
| 233 | The build will have created all artifacts required for an APEX |
| 234 | installation. The following example show how to change to the target |
| 235 | directory and how it should look like. |
| 236 | |
| 237 | +----------------------------------------------------------------------------------------------------------------------------+ |
| 238 | | Unix, Cygwin | |
| 239 | +============================================================================================================================+ |
| 240 | | .. container:: | |
| 241 | | | |
| 242 | | .. container:: listingblock | |
| 243 | | | |
| 244 | | .. container:: content | |
| 245 | | | |
| 246 | | .. code:: | |
| 247 | | :number-lines: | |
| 248 | | | |
| 249 | | -rwxrwx---+ 1 esvevan Domain Users 772 Sep 3 11:55 apex-pdp-package-full_2.0.0~SNAPSHOT_all.changes* | |
| 250 | | -rwxrwx---+ 1 esvevan Domain Users 146328082 Sep 3 11:55 apex-pdp-package-full-2.0.0-SNAPSHOT.deb* | |
| 251 | | -rwxrwx---+ 1 esvevan Domain Users 15633 Sep 3 11:54 apex-pdp-package-full-2.0.0-SNAPSHOT.jar* | |
| 252 | | -rwxrwx---+ 1 esvevan Domain Users 146296819 Sep 3 11:55 apex-pdp-package-full-2.0.0-SNAPSHOT-tarball.tar.gz* | |
| 253 | | drwxrwx---+ 1 esvevan Domain Users 0 Sep 3 11:54 archive-tmp/ | |
| 254 | | -rwxrwx---+ 1 esvevan Domain Users 89 Sep 3 11:54 checkstyle-cachefile* | |
| 255 | | -rwxrwx---+ 1 esvevan Domain Users 10621 Sep 3 11:54 checkstyle-checker.xml* | |
| 256 | | -rwxrwx---+ 1 esvevan Domain Users 584 Sep 3 11:54 checkstyle-header.txt* | |
| 257 | | -rwxrwx---+ 1 esvevan Domain Users 86 Sep 3 11:54 checkstyle-result.xml* | |
| 258 | | drwxrwx---+ 1 esvevan Domain Users 0 Sep 3 11:54 classes/ | |
| 259 | | drwxrwx---+ 1 esvevan Domain Users 0 Sep 3 11:54 dependency-maven-plugin-markers/ | |
| 260 | | drwxrwx---+ 1 esvevan Domain Users 0 Sep 3 11:54 etc/ | |
| 261 | | drwxrwx---+ 1 esvevan Domain Users 0 Sep 3 11:54 examples/ | |
| 262 | | drwxrwx---+ 1 esvevan Domain Users 0 Sep 3 11:55 install_hierarchy/ | |
| 263 | | drwxrwx---+ 1 esvevan Domain Users 0 Sep 3 11:54 maven-archiver/ | |
| 264 | +----------------------------------------------------------------------------------------------------------------------------+ |
| 265 | |
| 266 | +--------------------------------------------------------------------------------------------------------+ |
| 267 | | Windows | |
| 268 | +========================================================================================================+ |
| 269 | | .. container:: | |
| 270 | | | |
| 271 | | .. container:: listingblock | |
| 272 | | | |
| 273 | | .. container:: content | |
| 274 | | | |
| 275 | | .. code:: | |
| 276 | | :number-lines: | |
| 277 | | | |
| 278 | | 03/09/2018 11:55 <DIR> . | |
| 279 | | 03/09/2018 11:55 <DIR> .. | |
| 280 | | 03/09/2018 11:55 146,296,819 apex-pdp-package-full-2.0.0-SNAPSHOT-tarball.tar.gz | |
| 281 | | 03/09/2018 11:55 146,328,082 apex-pdp-package-full-2.0.0-SNAPSHOT.deb | |
| 282 | | 03/09/2018 11:54 15,633 apex-pdp-package-full-2.0.0-SNAPSHOT.jar | |
| 283 | | 03/09/2018 11:55 772 apex-pdp-package-full_2.0.0~SNAPSHOT_all.changes | |
| 284 | | 03/09/2018 11:54 <DIR> archive-tmp | |
| 285 | | 03/09/2018 11:54 89 checkstyle-cachefile | |
| 286 | | 03/09/2018 11:54 10,621 checkstyle-checker.xml | |
| 287 | | 03/09/2018 11:54 584 checkstyle-header.txt | |
| 288 | | 03/09/2018 11:54 86 checkstyle-result.xml | |
| 289 | | 03/09/2018 11:54 <DIR> classes | |
| 290 | | 03/09/2018 11:54 <DIR> dependency-maven-plugin-markers | |
| 291 | | 03/09/2018 11:54 <DIR> etc | |
| 292 | | 03/09/2018 11:54 <DIR> examples | |
| 293 | | 03/09/2018 11:55 <DIR> install_hierarchy | |
| 294 | | 03/09/2018 11:54 <DIR> maven-archiver | |
| 295 | | 8 File(s) 292,652,686 bytes | |
| 296 | | 9 Dir(s) 14,138,720,256 bytes free | |
| 297 | +--------------------------------------------------------------------------------------------------------+ |
| 298 | |
| 299 | Install APEX |
| 300 | ------------ |
| 301 | |
| 302 | .. container:: paragraph |
| 303 | |
| 304 | APEX can be installed in different ways: |
| 305 | |
| 306 | .. container:: ulist |
| 307 | |
| 308 | - Unix: automatically using ``rpm`` or ``dpkg`` from ``.rpm`` or |
| 309 | ``.deb`` archive |
| 310 | |
| 311 | - Windows, Unix, Cygwin: manually from a ``.tar.gz`` archive |
| 312 | |
| 313 | - Windows, Unix, Cygwin: build from source using Maven, then |
| 314 | install manually |
| 315 | |
| 316 | Install with RPM and DPKG |
| 317 | ######################### |
| 318 | |
| 319 | .. container:: paragraph |
| 320 | |
| 321 | The install distributions of APEX automatically install the |
| 322 | system. The installation directory is |
| 323 | ``/opt/app/policy/apex-pdp``. Log files are located in |
| 324 | ``/var/log/onap/policy/apex-pdp``. The latest APEX version will |
| 325 | be available as ``/opt/app/policy/apex-pdp/apex-pdp``. |
| 326 | |
| 327 | .. container:: paragraph |
| 328 | |
| 329 | For the installation, a new user ``apexuser`` and a new group |
| 330 | ``apexuser`` will be created. This user owns the installation |
| 331 | directories and the log file location. The user is also used by |
| 332 | the standard APEX start scripts to run APEX with this user’s |
| 333 | permissions. |
| 334 | |
| 335 | +-----------------------------------------------------------------------+ |
| 336 | | RPM Installation | |
| 337 | +=======================================================================+ |
| 338 | | .. container:: | |
| 339 | | | |
| 340 | | .. container:: listingblock | |
| 341 | | | |
| 342 | | .. container:: content | |
| 343 | | | |
| 344 | | .. code:: | |
| 345 | | :number-lines: | |
| 346 | | | |
| 347 | | # sudo rpm -i apex-pdp-package-full-2.0.0-SNAPSHOT.rpm | |
| 348 | | ********************preinst******************* | |
| 349 | | arguments 1 | |
| 350 | | ********************************************** | |
| 351 | | creating group apexuser . . . | |
| 352 | | creating user apexuser . . . | |
| 353 | | ********************postinst**************** | |
| 354 | | arguments 1 | |
| 355 | | *********************************************** | |
| 356 | +-----------------------------------------------------------------------+ |
| 357 | |
| 358 | +--------------------------------------------------------------------------------------+ |
| 359 | | DPKG Installation | |
| 360 | +======================================================================================+ |
| 361 | | .. container:: | |
| 362 | | | |
| 363 | | .. container:: listingblock | |
| 364 | | | |
| 365 | | .. container:: content | |
| 366 | | | |
| 367 | | .. code:: | |
| 368 | | :number-lines: | |
| 369 | | | |
| 370 | | # sudo dpkg -i apex-pdp-package-full-2.0.0-SNAPSHOT.deb | |
| 371 | | Selecting previously unselected package apex-uservice. | |
| 372 | | (Reading database ... 288458 files and directories currently installed.) | |
| 373 | | Preparing to unpack apex-pdp-package-full-2.0.0-SNAPSHOT.deb ... | |
| 374 | | ********************preinst******************* | |
| 375 | | arguments install | |
| 376 | | ********************************************** | |
| 377 | | creating group apexuser . . . | |
| 378 | | creating user apexuser . . . | |
| 379 | | Unpacking apex-uservice (2.0.0-SNAPSHOT) ... | |
| 380 | | Setting up apex-uservice (2.0.0-SNAPSHOT) ... | |
| 381 | | ********************postinst**************** | |
| 382 | | arguments configure | |
| 383 | | *********************************************** | |
| 384 | +--------------------------------------------------------------------------------------+ |
| 385 | |
| 386 | .. container:: paragraph |
| 387 | |
| 388 | Once the installation is finished, APEX is fully installed and ready |
| 389 | to run. |
| 390 | |
| 391 | Install Manually from Archive (Unix, Cygwin) |
| 392 | ############################################ |
| 393 | |
| 394 | .. container:: paragraph |
| 395 | |
| 396 | Download a ``tar.gz`` archive. Create a directory where APEX |
| 397 | should be installed. Extract the ``tar`` archive. The following |
| 398 | example shows how to install APEX in ``/opt/apex`` and create a |
| 399 | link to ``/opt/apex/apex`` for the most recent installation. |
| 400 | |
| 401 | .. container:: listingblock |
| 402 | |
| 403 | .. container:: content |
| 404 | |
| 405 | .. code:: |
| 406 | :number-lines: |
| 407 | |
| 408 | # cd /opt |
| 409 | # mkdir apex |
| 410 | # cd apex |
| 411 | # mkdir apex-full-2.0.0-SNAPSHOT |
| 412 | # tar xvfz ~/Downloads/apex-pdp-package-full-2.0.0-SNAPSHOT.tar.gz -C apex-full-2.0.0-SNAPSHOT |
| 413 | # ln -s apex apex-pdp-package-full-2.0.0-SNAPSHOT |
| 414 | |
| 415 | Install Manually from Archive (Windows, 7Zip, GUI) |
| 416 | ################################################## |
| 417 | |
| 418 | .. container:: paragraph |
| 419 | |
| 420 | Download a ``tar.gz`` archive and copy the file into the install |
| 421 | folder (in this example ``C:\apex``). Assuming you are using 7Zip, |
| 422 | right click on the file and extract the ``tar`` archive. Note: the |
| 423 | screenshots might show an older version than you have. |
| 424 | |
| 425 | .. container:: imageblock |
| 426 | |
| 427 | .. container:: content |
| 428 | |
| 429 | |Extract the TAR archive| |
| 430 | |
| 431 | .. container:: paragraph |
| 432 | |
| 433 | The right-click on the new created TAR file and extract the actual |
| 434 | APEX distribution. |
| 435 | |
| 436 | .. container:: imageblock |
| 437 | |
| 438 | .. container:: content |
| 439 | |
| 440 | |Extract the APEX distribution| |
| 441 | |
| 442 | .. container:: paragraph |
| 443 | |
| 444 | Inside the new APEX folder you see the main directories: ``bin``, |
| 445 | ``etc``, ``examples``, ``lib``, and ``war`` |
| 446 | |
| 447 | .. container:: paragraph |
| 448 | |
| 449 | Once extracted, please rename the created folder to |
| 450 | ``apex-full-2.0.0-SNAPSHOT``. This will keep the directory name in |
| 451 | line with the rest of this documentation. |
| 452 | |
| 453 | Install Manually from Archive (Windows, 7Zip, CMD) |
| 454 | ################################################## |
| 455 | |
| 456 | .. container:: paragraph |
| 457 | |
| 458 | Download a ``tar.gz`` archive and copy the file into the install |
| 459 | folder (in this example ``C:\apex``). Start ``cmd``, for instance |
| 460 | typing ``Windows+R`` and then ``cmd`` in the dialog. Assuming |
| 461 | ``7Zip`` is installed in the standard folder, simply run the |
| 462 | following commands (for APEX version 2.0.0-SNAPSHOT full |
| 463 | distribution) |
| 464 | |
| 465 | .. container:: listingblock |
| 466 | |
| 467 | .. container:: content |
| 468 | |
| 469 | .. code:: |
| 470 | :number-lines: |
| 471 | |
| 472 | >c: |
| 473 | >cd \apex |
| 474 | >"\Program Files\7-Zip\7z.exe" x apex-pdp-package-full-2.0.0-SNAPSHOT.tar.gz -so | "\Program Files\7-Zip\7z.exe" x -aoa -si -ttar -o"apex-full-2.0.0-SNAPSHOT" |
| 475 | |
| 476 | .. container:: paragraph |
| 477 | |
| 478 | APEX is now installed in the folder |
| 479 | ``C:\apex\apex-full-2.0.0-SNAPSHOT``. |
| 480 | |
| 481 | Build from Source |
| 482 | ----------------- |
| 483 | |
| 484 | Build and Install Manually (Unix, Windows, Cygwin) |
| 485 | ################################################## |
| 486 | |
| 487 | .. container:: paragraph |
| 488 | |
| 489 | Clone the APEX GIT repositories into a directory. Go to that |
| 490 | directory. Use Maven to build APEX (all details on building |
| 491 | APEX from source can be found in *APEX HowTo: Build*). Install |
| 492 | from the created artifacts (``rpm``, ``deb``, ``tar.gz``, or |
| 493 | copying manually). |
| 494 | |
| 495 | .. important:: |
| 496 | Building RPM distributions |
| 497 | RPM images are only build if the ``rpm`` package is installed (Unix). To install ``rpm`` run |
| 498 | ``sudo apt-get install rpm``, then build APEX. |
| 499 | |
| 500 | .. container:: paragraph |
| 501 | |
| 502 | The following example shows how to build the APEX system, |
| 503 | without tests (``-DskipTests``) to safe some time. It assumes |
| 504 | that the APX GIT repositories are cloned to: |
| 505 | |
| 506 | .. container:: ulist |
| 507 | |
| 508 | - Unix, Cygwin: ``/usr/local/src/apex`` |
| 509 | |
| 510 | - Windows: ``C:\dev\apex`` |
| 511 | |
| 512 | +-------------------------------------------------------+--------------------------------------------------------+ |
| 513 | | Unix, Cygwin | Windows | |
| 514 | +=======================================================+========================================================+ |
| 515 | | .. container:: | .. container:: | |
| 516 | | | | |
| 517 | | .. container:: content | .. container:: content | |
| 518 | | | | |
| 519 | | .. code:: | .. code:: | |
| 520 | | :number-lines: | :number-lines: | |
| 521 | | | | |
| 522 | | # cd /usr/local/src/apex | >c: | |
| 523 | | # mvn clean install -DskipTests | >cd \dev\apex | |
| 524 | | | >mvn clean install -DskipTests | |
| 525 | +-------------------------------------------------------+--------------------------------------------------------+ |
| 526 | |
| 527 | .. container:: paragraph |
| 528 | |
| 529 | The build takes about 2 minutes without test and about 4-5 minutes |
| 530 | with tests on a standard development laptop. It should run through |
| 531 | without errors, but with a lot of messages from the build process. If |
| 532 | build with tests (i.e. without ``-DskipTests``), there will be error |
| 533 | messages and stack trace prints from some tests. This is normal, as |
| 534 | long as the build finishes successful. |
| 535 | |
| 536 | .. container:: paragraph |
| 537 | |
| 538 | When Maven is finished with the build, the final screen should look |
| 539 | similar to this (omitting some ``success`` lines): |
| 540 | |
| 541 | .. container:: listingblock |
| 542 | |
| 543 | .. container:: content |
| 544 | |
| 545 | .. code:: |
| 546 | :number-lines: |
| 547 | |
| 548 | [INFO] tools .............................................. SUCCESS [ 0.248 s] |
| 549 | [INFO] tools-common ....................................... SUCCESS [ 0.784 s] |
| 550 | [INFO] simple-wsclient .................................... SUCCESS [ 3.303 s] |
| 551 | [INFO] model-generator .................................... SUCCESS [ 0.644 s] |
| 552 | [INFO] packages ........................................... SUCCESS [ 0.336 s] |
| 553 | [INFO] apex-pdp-package-full .............................. SUCCESS [01:10 min] |
| 554 | [INFO] Policy APEX PDP - Docker build 2.0.0-SNAPSHOT ...... SUCCESS [ 10.307 s] |
| 555 | [INFO] ------------------------------------------------------------------------ |
| 556 | [INFO] BUILD SUCCESS |
| 557 | [INFO] ------------------------------------------------------------------------ |
| 558 | [INFO] Total time: 03:43 min |
| 559 | [INFO] Finished at: 2018-09-03T11:56:01+01:00 |
| 560 | [INFO] ------------------------------------------------------------------------ |
| 561 | |
| 562 | .. container:: paragraph |
| 563 | |
| 564 | The build will have created all artifacts required for an APEX |
| 565 | installation. The following example show how to change to the target |
| 566 | directory and how it should look like. |
| 567 | |
| 568 | +-----------------------------------------------------------------------------------------------------------------------------+ |
| 569 | | Unix, Cygwin | |
| 570 | +=============================================================================================================================+ |
| 571 | | .. container:: | |
| 572 | | | |
| 573 | | .. container:: listingblock | |
| 574 | | | |
| 575 | | .. code:: | |
| 576 | | :number-lines: | |
| 577 | | | |
| 578 | | # cd packages/apex-pdp-package-full/target | |
| 579 | | # ls -l | |
| 580 | | -rwxrwx---+ 1 esvevan Domain Users 772 Sep 3 11:55 apex-pdp-package-full_2.0.0~SNAPSHOT_all.changes* | |
| 581 | | -rwxrwx---+ 1 esvevan Domain Users 146328082 Sep 3 11:55 apex-pdp-package-full-2.0.0-SNAPSHOT.deb* | |
| 582 | | -rwxrwx---+ 1 esvevan Domain Users 15633 Sep 3 11:54 apex-pdp-package-full-2.0.0-SNAPSHOT.jar* | |
| 583 | | -rwxrwx---+ 1 esvevan Domain Users 146296819 Sep 3 11:55 apex-pdp-package-full-2.0.0-SNAPSHOT-tarball.tar.gz* | |
| 584 | | drwxrwx---+ 1 esvevan Domain Users 0 Sep 3 11:54 archive-tmp/ | |
| 585 | | -rwxrwx---+ 1 esvevan Domain Users 89 Sep 3 11:54 checkstyle-cachefile* | |
| 586 | | -rwxrwx---+ 1 esvevan Domain Users 10621 Sep 3 11:54 checkstyle-checker.xml* | |
| 587 | | -rwxrwx---+ 1 esvevan Domain Users 584 Sep 3 11:54 checkstyle-header.txt* | |
| 588 | | -rwxrwx---+ 1 esvevan Domain Users 86 Sep 3 11:54 checkstyle-result.xml* | |
| 589 | | drwxrwx---+ 1 esvevan Domain Users 0 Sep 3 11:54 classes/ | |
| 590 | | drwxrwx---+ 1 esvevan Domain Users 0 Sep 3 11:54 dependency-maven-plugin-markers/ | |
| 591 | | drwxrwx---+ 1 esvevan Domain Users 0 Sep 3 11:54 etc/ | |
| 592 | | drwxrwx---+ 1 esvevan Domain Users 0 Sep 3 11:54 examples/ | |
| 593 | | drwxrwx---+ 1 esvevan Domain Users 0 Sep 3 11:55 install_hierarchy/ | |
| 594 | | drwxrwx---+ 1 esvevan Domain Users 0 Sep 3 11:54 maven-archiver/ | |
| 595 | +-----------------------------------------------------------------------------------------------------------------------------+ |
| 596 | |
| 597 | +-----------------------------------------------------------------------------------------------------------------------------+ |
| 598 | | Windows | |
| 599 | +=============================================================================================================================+ |
| 600 | | .. container:: | |
| 601 | | | |
| 602 | | .. container:: listingblock | |
| 603 | | | |
| 604 | | .. code:: | |
| 605 | | :number-lines: | |
| 606 | | | |
| 607 | | >cd packages\apex-pdp-package-full\target | |
| 608 | | >dir | |
| 609 | | 03/09/2018 11:55 <DIR> . | |
| 610 | | 03/09/2018 11:55 <DIR> .. | |
| 611 | | 03/09/2018 11:55 146,296,819 apex-pdp-package-full-2.0.0-SNAPSHOT-tarball.tar.gz | |
| 612 | | 03/09/2018 11:55 146,328,082 apex-pdp-package-full-2.0.0-SNAPSHOT.deb | |
| 613 | | 03/09/2018 11:54 15,633 apex-pdp-package-full-2.0.0-SNAPSHOT.jar | |
| 614 | | 03/09/2018 11:55 772 apex-pdp-package-full_2.0.0~SNAPSHOT_all.changes | |
| 615 | | 03/09/2018 11:54 <DIR> archive-tmp | |
| 616 | | 03/09/2018 11:54 89 checkstyle-cachefile | |
| 617 | | 03/09/2018 11:54 10,621 checkstyle-checker.xml | |
| 618 | | 03/09/2018 11:54 584 checkstyle-header.txt | |
| 619 | | 03/09/2018 11:54 86 checkstyle-result.xml | |
| 620 | | 03/09/2018 11:54 <DIR> classes | |
| 621 | | 03/09/2018 11:54 <DIR> dependency-maven-plugin-markers | |
| 622 | | 03/09/2018 11:54 <DIR> etc | |
| 623 | | 03/09/2018 11:54 <DIR> examples | |
| 624 | | 03/09/2018 11:55 <DIR> install_hierarchy | |
| 625 | | 03/09/2018 11:54 <DIR> maven-archiver | |
| 626 | | 8 File(s) 292,652,686 bytes | |
| 627 | | 9 Dir(s) 14,138,720,256 bytes free | |
| 628 | +-----------------------------------------------------------------------------------------------------------------------------+ |
| 629 | |
| 630 | .. container:: paragraph |
| 631 | |
| 632 | Now, take the ``.deb`` or the ``.tar.gz`` file and install APEX. |
| 633 | Alternatively, copy the content of the folder ``install_hierarchy`` |
| 634 | to your APEX directory. |
| 635 | |
| 636 | Installation Layout |
| 637 | ------------------- |
| 638 | |
| 639 | .. container:: paragraph |
| 640 | |
| 641 | A full installation of APEX comes with the following layout. |
| 642 | |
| 643 | .. container:: listingblock |
| 644 | |
| 645 | .. container:: content |
| 646 | |
| 647 | :: |
| 648 | |
| 649 | $APEX_HOME |
| 650 | ├───bin (1) |
| 651 | ├───etc (2) |
| 652 | │ ├───editor |
| 653 | │ ├───hazelcast |
| 654 | │ ├───infinispan |
| 655 | │ └───META-INF |
| 656 | ├───examples (3) |
| 657 | │ ├───config (4) |
| 658 | │ ├───docker (5) |
| 659 | │ ├───events (6) |
| 660 | │ ├───html (7) |
| 661 | │ ├───models (8) |
| 662 | │ └───scripts (9) |
| 663 | ├───lib (10) |
| 664 | │ └───applications (11) |
| 665 | └───war (12) |
| 666 | |
| 667 | .. container:: colist arabic |
| 668 | |
| 669 | +-----------------------------------+-----------------------------------+ |
| 670 | | **1** | binaries, mainly scripts (bash | |
| 671 | | | and bat) to start the APEX engine | |
| 672 | | | and applications | |
| 673 | +-----------------------------------+-----------------------------------+ |
| 674 | | **2** | configuration files, such as | |
| 675 | | | logback (logging) and third party | |
| 676 | | | library configurations | |
| 677 | +-----------------------------------+-----------------------------------+ |
| 678 | | **3** | example policy models to get | |
| 679 | | | started | |
| 680 | +-----------------------------------+-----------------------------------+ |
| 681 | | **4** | configurations for the examples | |
| 682 | | | (with sub directories for | |
| 683 | | | individual examples) | |
| 684 | +-----------------------------------+-----------------------------------+ |
| 685 | | **5** | Docker files and additional | |
| 686 | | | Docker instructions for the | |
| 687 | | | exampples | |
| 688 | +-----------------------------------+-----------------------------------+ |
| 689 | | **6** | example events for the examples | |
| 690 | | | (with sub directories for | |
| 691 | | | individual examples) | |
| 692 | +-----------------------------------+-----------------------------------+ |
| 693 | | **7** | HTML files for some examples, | |
| 694 | | | e.g. the Decisionmaker example | |
| 695 | +-----------------------------------+-----------------------------------+ |
| 696 | | **8** | the policy models, generated for | |
| 697 | | | each example (with sub | |
| 698 | | | directories for individual | |
| 699 | | | examples) | |
| 700 | +-----------------------------------+-----------------------------------+ |
| 701 | | **9** | additional scripts for the | |
| 702 | | | examples (with sub directories | |
| 703 | | | for individual examples) | |
| 704 | +-----------------------------------+-----------------------------------+ |
| 705 | | **10** | the library folder with all Java | |
| 706 | | | JAR files | |
| 707 | +-----------------------------------+-----------------------------------+ |
| 708 | | **11** | applications, also known as jar | |
| 709 | | | with dependencies (or fat jars), | |
| 710 | | | individually deployable | |
| 711 | +-----------------------------------+-----------------------------------+ |
| 712 | | **12** | WAR files for web applications | |
| 713 | +-----------------------------------+-----------------------------------+ |
| 714 | |
| 715 | System Configuration |
| 716 | -------------------- |
| 717 | |
| 718 | .. container:: paragraph |
| 719 | |
| 720 | Once APEX is installed, a few configurations need to be done: |
| 721 | |
| 722 | .. container:: ulist |
| 723 | |
| 724 | - Create an APEX user and an APEX group (optional, if not |
| 725 | installed using RPM and DPKG) |
| 726 | |
| 727 | - Create environment settings for ``APEX_HOME`` and |
| 728 | ``APEX_USER``, required by the start scripts |
| 729 | |
| 730 | - Change settings of the logging framework (optional) |
| 731 | |
| 732 | - Create directories for logging, required (execution might fail |
| 733 | if directories do not exist or cannot be created) |
| 734 | |
| 735 | APEX User and Group |
| 736 | ################### |
| 737 | |
| 738 | .. container:: paragraph |
| 739 | |
| 740 | On smaller installations and test systems, APEX can run as any |
| 741 | user or group. |
| 742 | |
| 743 | .. container:: paragraph |
| 744 | |
| 745 | However, if APEX is installed in production, we strongly |
| 746 | recommend you set up a dedicated user for running APEX. This |
| 747 | will isolate the execution of APEX to that user. We recommend |
| 748 | you use the userid ``apexuser`` but you may use any user you |
| 749 | choose. |
| 750 | |
| 751 | .. container:: paragraph |
| 752 | |
| 753 | The following example, for UNIX, creates a group called |
| 754 | ``apexuser``, an APEX user called ``apexuser``, adds the group |
| 755 | to the user, and changes ownership of the APEX installation to |
| 756 | the user. Substitute ``<apex-dir>`` with the directory where |
| 757 | APEX is installed. |
| 758 | |
| 759 | .. container:: listingblock |
| 760 | |
| 761 | .. container:: content |
| 762 | |
| 763 | .. code:: |
| 764 | :number-lines: |
| 765 | |
| 766 | # sudo groupadd apexuser |
| 767 | # sudo useradd -g apexuser apexuser |
| 768 | # sudo chown -R apexuser:apexuser <apex-dir> |
| 769 | |
| 770 | .. container:: paragraph |
| 771 | |
| 772 | For other operating systems please consult your manual or system |
| 773 | administrator. |
| 774 | |
| 775 | Environment Settings: APEX_HOME and APEX_USER |
| 776 | ############################################# |
| 777 | |
| 778 | .. container:: paragraph |
| 779 | |
| 780 | The provided start scripts for APEX require two environment |
| 781 | variables being set: |
| 782 | |
| 783 | .. container:: ulist |
| 784 | |
| 785 | - ``APEX_USER`` with the user under whos name and permission APEX |
| 786 | should be started (Unix only) |
| 787 | |
| 788 | - ``APEX_HOME`` with the directory where APEX is installed (Unix, |
| 789 | Windows, Cygwin) |
| 790 | |
| 791 | .. container:: paragraph |
| 792 | |
| 793 | The first row in the following table shows how to set these |
| 794 | environment variables temporary (assuming the user is |
| 795 | ``apexuser``). The second row shows how to verify the settings. |
| 796 | The last row explains how to set those variables permanently. |
| 797 | |
| 798 | +------------------------------------------------+---------------------------------------------------------+ |
| 799 | | Unix, Cygwin (bash/tcsh) | Windows | |
| 800 | +================================================+=========================================================+ |
| 801 | | .. container:: | .. container:: | |
| 802 | | | | |
| 803 | | .. container:: content | .. container:: content | |
| 804 | | | | |
| 805 | | .. code:: | .. code:: | |
| 806 | | :number-lines: | :number-lines: | |
| 807 | | | | |
| 808 | | # export APEX_USER=apexuser | >set APEX_HOME=C:\apex\apex-full-2.0.0-SNAPSHOT | |
| 809 | | # cd /opt/app/policy/apex-pdp | | |
| 810 | | # export APEX_HOME=`pwd` | | |
| 811 | | | | |
| 812 | +------------------------------------------------+ | |
| 813 | | .. container:: | | |
| 814 | | | | |
| 815 | | .. container:: content | | |
| 816 | | | | |
| 817 | | .. code:: tcsh | | |
| 818 | | :number-lines: | | |
| 819 | | | | |
| 820 | | # setenv APEX_USER apexuser | | |
| 821 | | # cd /opt/app/policy/apex-pdp | | |
| 822 | | # setenv APEX_HOME `pwd` | | |
| 823 | | | | |
| 824 | +------------------------------------------------+---------------------------------------------------------+ |
| 825 | | .. container:: | .. container:: | |
| 826 | | | | |
| 827 | | .. container:: content | .. container:: content | |
| 828 | | | | |
| 829 | | .. code:: | .. code:: | |
| 830 | | :number-lines: | :number-lines: | |
| 831 | | | | |
| 832 | | # env | grep APEX | >set APEX_HOME | |
| 833 | | # APEX_USER=apexuser | APEX_HOME=\apex\apex-full-2.0.0-SNAPSHOT | |
| 834 | | # APEX_HOME=/opt/app/policy/apex-pdp | | |
| 835 | | | | |
| 836 | +------------------------------------------------+---------------------------------------------------------+ |
| 837 | |
| 838 | Making Environment Settings Permanent (Unix, Cygwin) |
| 839 | ==================================================== |
| 840 | |
| 841 | .. container:: paragraph |
| 842 | |
| 843 | For a per-user setting, edit the a user’s ``bash`` or ``tcsh`` |
| 844 | settings in ``~/.bashrc`` or ``~/.tcshrc``. For system-wide |
| 845 | settings, edit ``/etc/profiles`` (requires permissions). |
| 846 | |
| 847 | Making Environment Settings Permanent (Windows) |
| 848 | =============================================== |
| 849 | |
| 850 | .. container:: paragraph |
| 851 | |
| 852 | On Windows 7 do |
| 853 | |
| 854 | .. container:: ulist |
| 855 | |
| 856 | - Click on the **Start** Menu |
| 857 | |
| 858 | - Right click on **Computer** |
| 859 | |
| 860 | - Select **Properties** |
| 861 | |
| 862 | .. container:: paragraph |
| 863 | |
| 864 | On Windows 8/10 do |
| 865 | |
| 866 | .. container:: ulist |
| 867 | |
| 868 | - Click on the **Start** Menu |
| 869 | |
| 870 | - Select **System** |
| 871 | |
| 872 | .. container:: paragraph |
| 873 | |
| 874 | Then do the following |
| 875 | |
| 876 | .. container:: ulist |
| 877 | |
| 878 | - Select **Advanced System Settings** |
| 879 | |
| 880 | - On the **Advanced** tab, click the **Environment Variables** |
| 881 | button |
| 882 | |
| 883 | - Edit an existing variable, or create a new System variable: |
| 884 | 'Variable name'="APEX_HOME", 'Variable |
| 885 | value'="C:\apex\apex-full-2.0.0-SNAPSHOT" |
| 886 | |
| 887 | .. container:: paragraph |
| 888 | |
| 889 | For the settings to take effect, an application needs to be |
| 890 | restarted (e.g. any open ``cmd`` window). |
| 891 | |
| 892 | Edit the APEX Logging Settings |
| 893 | ############################## |
| 894 | |
| 895 | .. container:: paragraph |
| 896 | |
| 897 | Configure the APEX logging settings to your requirements, for |
| 898 | instance: |
| 899 | |
| 900 | .. container:: ulist |
| 901 | |
| 902 | - change the directory where logs are written to, or |
| 903 | |
| 904 | - change the log levels |
| 905 | |
| 906 | .. container:: paragraph |
| 907 | |
| 908 | Edit the file ``$APEX_HOME/etc/logback.xml`` for any required |
| 909 | changes. To change the log directory change the line |
| 910 | |
| 911 | .. container:: paragraph |
| 912 | |
| 913 | ``<property name="VAR_LOG" value="/var/log/onap/policy/apex-pdp/" />`` |
| 914 | |
| 915 | .. container:: paragraph |
| 916 | |
| 917 | to |
| 918 | |
| 919 | .. container:: paragraph |
| 920 | |
| 921 | ``<property name="VAR_LOG" value="/PATH/TO/LOG/DIRECTORY/" />`` |
| 922 | |
| 923 | .. container:: paragraph |
| 924 | |
| 925 | On Windows, it is recommended to change the log directory to: |
| 926 | |
| 927 | .. container:: paragraph |
| 928 | |
| 929 | ``<property name="VAR_LOG" value="C:/apex/apex-full-2.0.0-SNAPSHOT/logs" />`` |
| 930 | |
| 931 | .. container:: paragraph |
| 932 | |
| 933 | Note: Be careful about when to use ``\`` vs. ``/`` as the path |
| 934 | separator! |
| 935 | |
| 936 | Create Directories for Logging |
| 937 | ############################## |
| 938 | |
| 939 | .. container:: paragraph |
| 940 | |
| 941 | Make sure that the log directory exists. This is important when |
| 942 | APEX was installed manually or when the log directory was changed |
| 943 | in the settings (see above). |
| 944 | |
| 945 | +------------------------------------------------------------------+-------------------------------------------------------+ |
| 946 | | Unix, Cygwin | Windows | |
| 947 | +==================================================================+=======================================================+ |
| 948 | | .. container:: | .. container:: | |
| 949 | | | | |
| 950 | | .. container:: content | .. container:: content | |
| 951 | | | | |
| 952 | | .. code:: | .. code:: | |
| 953 | | :number-lines: | :number-lines: | |
| 954 | | | | |
| 955 | | mkdir -p /var/log/onap/policy/apex-pdp | >mkdir C:\apex\apex-full-2.0.0-SNAPSHOT\logs | |
| 956 | | chown -R apexuser:apexuser /var/log/onap/policy/apex-pdp | | |
| 957 | +------------------------------------------------------------------+-------------------------------------------------------+ |
| 958 | |
| 959 | Verify the APEX Installation |
| 960 | ---------------------------- |
| 961 | |
| 962 | .. container:: paragraph |
| 963 | |
| 964 | When APEX is installed and all settings are realized, the |
| 965 | installation can be verified. |
| 966 | |
| 967 | Verify Installation - run Engine |
| 968 | ################################ |
| 969 | |
| 970 | .. container:: paragraph |
| 971 | |
| 972 | A simple verification of an APEX installation can be done by |
| 973 | simply starting the APEX engine without any configuration. On |
| 974 | Unix (or Cygwin) start the engine using |
| 975 | ``$APEX_HOME/bin/apexEngine.sh``. On Windows start the engine |
| 976 | using ``%APEX_HOME%\bin\apexEngine.bat``. The engine will fail |
| 977 | to fully start. However, if the output looks similar to the |
| 978 | following line, the APEX installation is realized. |
| 979 | |
| 980 | .. container:: listingblock |
| 981 | |
| 982 | .. container:: content |
| 983 | |
| 984 | .. code:: |
| 985 | :number-lines: |
| 986 | |
| 987 | Starting Apex service with parameters [] . . . |
| 988 | start of Apex service failed: Apex configuration file was not specified as an argument |
| 989 | 2018-09-03 13:11:33,914 Apex [main] ERROR o.o.p.a.service.engine.main.ApexMain - start of Apex service failed |
| 990 | org.onap.policy.apex.model.basicmodel.concepts.ApexException: Apex configuration file was not specified as an argument |
| 991 | at org.onap.policy.apex.service.engine.main.ApexCommandLineArguments.validateReadableFile(ApexCommandLineArguments.java:267) |
| 992 | at org.onap.policy.apex.service.engine.main.ApexCommandLineArguments.validate(ApexCommandLineArguments.java:161) |
| 993 | at org.onap.policy.apex.service.engine.main.ApexMain.<init>(ApexMain.java:68) |
| 994 | at org.onap.policy.apex.service.engine.main.ApexMain.main(ApexMain.java:165) |
| 995 | usage: org.onap.policy.apex.service.engine.main.ApexMain [options...] |
| 996 | options |
| 997 | -c,--config-file <CONFIG_FILE>the full path to the configuration file to use, the configuration file must be a Json file |
| 998 | containing the Apex configuration parameters |
| 999 | -h,--help outputs the usage of this command |
| 1000 | -m,--model-file <MODEL_FILE> the full path to the model file to use, if set it overrides the model file set in the |
| 1001 | configuration file |
| 1002 | -v,--version outputs the version of Apex |
| 1003 | |
| 1004 | Verify Installation - run an Example |
| 1005 | #################################### |
| 1006 | |
| 1007 | .. container:: paragraph |
| 1008 | |
| 1009 | A full APEX installation comes with several examples. Here, we can |
| 1010 | fully verify the installation by running one of the examples. |
| 1011 | |
| 1012 | .. container:: paragraph |
| 1013 | |
| 1014 | We use the example called *SampleDomain* and configure the engine |
| 1015 | to use standard in and standard out for events. Run the engine |
| 1016 | with the provided configuration. Note: Cygwin executes scripts as |
| 1017 | Unix scripts but runs Java as a Windows application, thus the |
| 1018 | configuration file must be given as a Windows path. |
| 1019 | |
| 1020 | .. container:: listingblock |
| 1021 | |
| 1022 | .. container:: content |
| 1023 | |
| 1024 | .. code:: |
| 1025 | :number-lines: |
| 1026 | |
| 1027 | # $APEX_HOME/bin/apexEngine.sh -c $APEX_HOME/examples/config/SampleDomain/Stdin2StdoutJsonEventJava.json (1) |
| 1028 | # $APEX_HOME/bin/apexEngine.sh -c C:/apex/apex-full-2.0.0-SNAPSHOT/examples/config/SampleDomain/Stdin2StdoutJsonEventJava.json (2) |
| 1029 | >%APEX_HOME%\bin\apexEngine.bat -c %APEX_HOME%\examples\config\SampleDomain\Stdin2StdoutJsonEventJava.json :: (3) |
| 1030 | |
| 1031 | .. container:: colist arabic |
| 1032 | |
| 1033 | +-------+---------+ |
| 1034 | | **1** | UNIX | |
| 1035 | +-------+---------+ |
| 1036 | | **2** | Cygwin | |
| 1037 | +-------+---------+ |
| 1038 | | **3** | Windows | |
| 1039 | +-------+---------+ |
| 1040 | |
| 1041 | .. container:: paragraph |
| 1042 | |
| 1043 | The engine should start successfully. Assuming the logging levels are |
| 1044 | not change (default level is ``info``), the output should look |
| 1045 | similar to this (last few lines) |
| 1046 | |
| 1047 | .. container:: listingblock |
| 1048 | |
| 1049 | .. container:: content |
| 1050 | |
| 1051 | .. code:: |
| 1052 | :number-lines: |
| 1053 | |
| 1054 | Starting Apex service with parameters [-c, v:/dev/ericsson/apex/onap/apex-pdp/packages/apex-pdp-package-full/target/install_hierarchy/examples/config/SampleDomain/Stdin2StdoutJsonEventJava.json] . . . |
| 1055 | 2018-09-05 15:16:42,800 Apex [main] INFO o.o.p.a.s.e.r.impl.EngineServiceImpl - Created apex engine MyApexEngine-0:0.0.1 . |
| 1056 | 2018-09-05 15:16:42,804 Apex [main] INFO o.o.p.a.s.e.r.impl.EngineServiceImpl - Created apex engine MyApexEngine-1:0.0.1 . |
| 1057 | 2018-09-05 15:16:42,804 Apex [main] INFO o.o.p.a.s.e.r.impl.EngineServiceImpl - Created apex engine MyApexEngine-2:0.0.1 . |
| 1058 | 2018-09-05 15:16:42,805 Apex [main] INFO o.o.p.a.s.e.r.impl.EngineServiceImpl - Created apex engine MyApexEngine-3:0.0.1 . |
| 1059 | 2018-09-05 15:16:42,805 Apex [main] INFO o.o.p.a.s.e.r.impl.EngineServiceImpl - APEX service created. |
| 1060 | 2018-09-05 15:16:43,962 Apex [main] INFO o.o.p.a.s.e.e.EngDepMessagingService - engine<-->deployment messaging starting . . . |
| 1061 | 2018-09-05 15:16:43,963 Apex [main] INFO o.o.p.a.s.e.e.EngDepMessagingService - engine<-->deployment messaging started |
| 1062 | 2018-09-05 15:16:44,987 Apex [main] INFO o.o.p.a.s.e.r.impl.EngineServiceImpl - Registering apex model on engine MyApexEngine-0:0.0.1 |
| 1063 | 2018-09-05 15:16:45,112 Apex [main] INFO o.o.p.a.s.e.r.impl.EngineServiceImpl - Registering apex model on engine MyApexEngine-1:0.0.1 |
| 1064 | 2018-09-05 15:16:45,113 Apex [main] INFO o.o.p.a.s.e.r.impl.EngineServiceImpl - Registering apex model on engine MyApexEngine-2:0.0.1 |
| 1065 | 2018-09-05 15:16:45,113 Apex [main] INFO o.o.p.a.s.e.r.impl.EngineServiceImpl - Registering apex model on engine MyApexEngine-3:0.0.1 |
| 1066 | 2018-09-05 15:16:45,120 Apex [main] INFO o.o.p.a.s.e.r.impl.EngineServiceImpl - Added the action listener to the engine |
| 1067 | Started Apex service |
| 1068 | |
| 1069 | .. container:: paragraph |
| 1070 | |
| 1071 | Important are the last two line, stating that APEX has added the |
| 1072 | final action listener to the engine and that the engine is started. |
| 1073 | |
| 1074 | .. container:: paragraph |
| 1075 | |
| 1076 | The engine is configured to read events from standard input and write |
| 1077 | produced events to standard output. The policy model is a very simple |
| 1078 | policy. |
| 1079 | |
| 1080 | .. container:: paragraph |
| 1081 | |
| 1082 | The following table shows an input event in the left column and an |
| 1083 | output event in the right column. Past the input event into the |
| 1084 | console where APEX is running, and the output event should appear in |
| 1085 | the console. Pasting the input event multiple times will produce |
| 1086 | output events with different values. |
| 1087 | |
| 1088 | +-------------------------------------------------------------+-------------------------------------------------------------+ |
| 1089 | | Input Event | Example Output Event | |
| 1090 | +=============================================================+=============================================================+ |
| 1091 | | .. container:: | .. container:: | |
| 1092 | | | | |
| 1093 | | .. container:: content | .. container:: content | |
| 1094 | | | | |
| 1095 | | .. code:: | .. code:: | |
| 1096 | | :number-lines: | :number-lines: | |
| 1097 | | | | |
| 1098 | | { | { | |
| 1099 | | "nameSpace": "org.onap.policy.apex.sample.events", | "name": "Event0004", | |
| 1100 | | "name": "Event0000", | "version": "0.0.1", | |
| 1101 | | "version": "0.0.1", | "nameSpace": "org.onap.policy.apex.sample.events", | |
| 1102 | | "source": "test", | "source": "Act", | |
| 1103 | | "target": "apex", | "target": "Outside", | |
| 1104 | | "TestSlogan": "Test slogan for External Event0", | "TestActCaseSelected": 2, | |
| 1105 | | "TestMatchCase": 0, | "TestActStateTime": 1536157104627, | |
| 1106 | | "TestTimestamp": 1469781869269, | "TestDecideCaseSelected": 0, | |
| 1107 | | "TestTemperature": 9080.866 | "TestDecideStateTime": 1536157104625, | |
| 1108 | | } | "TestEstablishCaseSelected": 0, | |
| 1109 | | | "TestEstablishStateTime": 1536157104623, | |
| 1110 | | | "TestMatchCase": 0, | |
| 1111 | | | "TestMatchCaseSelected": 1, | |
| 1112 | | | "TestMatchStateTime": 1536157104620, | |
| 1113 | | | "TestSlogan": "Test slogan for External Event0", | |
| 1114 | | | "TestTemperature": 9080.866, | |
| 1115 | | | "TestTimestamp": 1469781869269 | |
| 1116 | | | } | |
| 1117 | +-------------------------------------------------------------+-------------------------------------------------------------+ |
| 1118 | |
| 1119 | .. container:: paragraph |
| 1120 | |
| 1121 | Terminate APEX by simply using ``CTRL+C`` in the console. |
| 1122 | |
| 1123 | Verify a Full Installation - REST Editor |
| 1124 | ######################################## |
| 1125 | |
| 1126 | .. container:: paragraph |
| 1127 | |
| 1128 | APEX has a REST application for viewing policy models. The |
| 1129 | application can also be used to create new policy models close to |
| 1130 | the engine native policy language. Start the REST editor as |
| 1131 | follows. |
| 1132 | |
| 1133 | .. container:: listingblock |
| 1134 | |
| 1135 | .. container:: content |
| 1136 | |
| 1137 | .. code:: |
| 1138 | :number-lines: |
| 1139 | |
| 1140 | # $APEX_HOME/bin/apexApps.sh rest-editor |
| 1141 | |
| 1142 | .. container:: listingblock |
| 1143 | |
| 1144 | .. container:: content |
| 1145 | |
| 1146 | .. code:: |
| 1147 | :number-lines: |
| 1148 | |
| 1149 | >%APEX_HOME%\bin\apexApps.bat rest-editor |
| 1150 | |
| 1151 | .. container:: paragraph |
| 1152 | |
| 1153 | The script will start a simple web server |
| 1154 | (`Grizzly <https://javaee.github.io/grizzly/>`__) and deploy a |
| 1155 | ``war`` web archive in it. Once the editor is started, it will be |
| 1156 | available on ``localhost:18989``. The last few line of the messages |
| 1157 | should be: |
| 1158 | |
| 1159 | .. container:: listingblock |
| 1160 | |
| 1161 | .. container:: content |
| 1162 | |
| 1163 | .. code:: |
| 1164 | :number-lines: |
| 1165 | |
| 1166 | Apex Editor REST endpoint (ApexEditorMain: Config=[ApexEditorParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=READY) starting at http://localhost:18989/apexservices/ . . . |
| 1167 | Sep 05, 2018 10:35:57 PM org.glassfish.grizzly.http.server.NetworkListener start |
| 1168 | INFO: Started listener bound to [localhost:18989] |
| 1169 | Sep 05, 2018 10:35:57 PM org.glassfish.grizzly.http.server.HttpServer start |
| 1170 | INFO: [HttpServer] Started. |
| 1171 | Apex Editor REST endpoint (ApexEditorMain: Config=[ApexEditorParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=RUNNING) started at http://localhost:18989/apexservices/ |
| 1172 | |
| 1173 | .. container:: paragraph |
| 1174 | |
| 1175 | Now open a browser (Firefox, Chrome, Opera, Internet Explorer) and |
| 1176 | use the URL ``http://localhost:18989/``. This will connect the |
| 1177 | browser to the started REST editor. The start screen should be as |
| 1178 | follows. |
| 1179 | |
| 1180 | .. container:: imageblock |
| 1181 | |
| 1182 | .. container:: content |
| 1183 | |
| 1184 | |REST Editor Start Screen| |
| 1185 | |
| 1186 | .. container:: title |
| 1187 | |
| 1188 | Figure 1. REST Editor Start Screen |
| 1189 | |
| 1190 | .. container:: paragraph |
| 1191 | |
| 1192 | Now load a policy model by clicking the menu ``File`` and then |
| 1193 | ``Open``. In the opened dialog, go to the directory where APEX is |
| 1194 | installed, then ``examples``, ``models``, ``SampleDomain``, and there |
| 1195 | select the file ``SamplePolicyModelJAVA.json``. This will load the |
| 1196 | policy model used to verify the policy engine (see above). Once |
| 1197 | loaded, the screen should look as follows. |
| 1198 | |
| 1199 | .. container:: imageblock |
| 1200 | |
| 1201 | .. container:: content |
| 1202 | |
| 1203 | |REST Editor with loaded SampleDomain Policy Model| |
| 1204 | |
| 1205 | .. container:: title |
| 1206 | |
| 1207 | Figure 2. REST Editor with loaded SampleDomain Policy Model |
| 1208 | |
| 1209 | .. container:: paragraph |
| 1210 | |
| 1211 | Now you can use the REST editor. To finish this verification, simply |
| 1212 | terminate your browser (or the tab), and then use ``CTRL+C`` in the |
| 1213 | console where you started the REST editor. |
| 1214 | |
| 1215 | Installing WAR Applications |
| 1216 | --------------------------- |
| 1217 | |
| 1218 | .. container:: paragraph |
| 1219 | |
| 1220 | APEX comes with a set of WAR files. These are complete |
| 1221 | applications that can be installed and run in an application |
| 1222 | server. All of these applications are realized as servlets. You |
| 1223 | can find the WAR applications in ``$APEX_HOME/war`` (UNIX, Cygwin) |
| 1224 | or ``%APEX_HOME%\war`` (Windows). |
| 1225 | |
| 1226 | .. container:: paragraph |
| 1227 | |
| 1228 | Installing and using the WAR applications requires a web server |
| 1229 | that can execute ``war`` web archives. We recommend to use `Apache |
| 1230 | Tomcat <https://tomcat.apache.org/>`__, however other web servers |
| 1231 | can be used as well. |
| 1232 | |
| 1233 | .. container:: paragraph |
| 1234 | |
| 1235 | Install Apache Tomcat including the ``Manager App``, see `V9.0 |
| 1236 | Docs <https://tomcat.apache.org/tomcat-9.0-doc/manager-howto.html#Configuring_Manager_Application_Access>`__ |
| 1237 | for details. Start the Tomcat service, or make sure that Tomcat is |
| 1238 | running. |
| 1239 | |
| 1240 | .. container:: paragraph |
| 1241 | |
| 1242 | There are multiple ways to install the APEX WAR applications: |
| 1243 | |
| 1244 | .. container:: ulist |
| 1245 | |
| 1246 | - copy the ``.war`` file into the Tomcat ``webapps`` folder |
| 1247 | |
| 1248 | - use the Tomcat ``Manager App`` to deploy via the web interface |
| 1249 | |
| 1250 | - deploy using a REST call to Tomcat |
| 1251 | |
| 1252 | .. container:: paragraph |
| 1253 | |
| 1254 | For details on how to install ``war`` files please consult the |
| 1255 | `Tomcat |
| 1256 | Documentation <https://tomcat.apache.org/tomcat-9.0-doc/index.html>`__ |
| 1257 | or the `Manager App |
| 1258 | HOW-TO <https://tomcat.apache.org/tomcat-9.0-doc/manager-howto.html>`__. |
| 1259 | Once you installed an APEX WAR application (and wait for |
| 1260 | sufficient time for Tomcat to finalize the installation), open the |
| 1261 | ``Manager App`` in Tomcat. You should see the APEX WAR application |
| 1262 | being installed and running. |
| 1263 | |
| 1264 | .. container:: paragraph |
| 1265 | |
| 1266 | In case of errors, examine the log files in the Tomcat log |
| 1267 | directory. In a conventional install, those log files are in the |
| 1268 | logs directory where Tomcat is installed. |
| 1269 | |
| 1270 | .. container:: paragraph |
| 1271 | |
| 1272 | The current APEX version provides the following WAR applications: |
| 1273 | |
| 1274 | .. container:: ulist |
| 1275 | |
| 1276 | - client-deployment-2.0.0-SNAPSHOT.war - a client to deploy new |
| 1277 | policy models to a running engine |
| 1278 | |
| 1279 | - client-editor-2.0.0-SNAPSHOT.war - the standard policy REST |
| 1280 | editor GUI |
| 1281 | |
| 1282 | - client-monitoring-2.0.0-SNAPSHOT.war - a client for monitoring |
| 1283 | a running APEX engine |
| 1284 | |
| 1285 | - client-full-2.0.0-SNAPSHOT.war - a full client with a |
| 1286 | one-stop-access to deployment, monitoring, and REST editor |
| 1287 | |
| 1288 | - examples-servlet-2.0.0-SNAPSHOT.war - an example APEX servlet |
| 1289 | |
| 1290 | Running APEX in Docker |
| 1291 | ---------------------- |
| 1292 | |
| 1293 | .. container:: paragraph |
| 1294 | |
| 1295 | Since APEX is in ONAP, we provide a full virtualization |
| 1296 | environment for the engine. |
| 1297 | |
| 1298 | Run in ONAP |
| 1299 | ########### |
| 1300 | |
| 1301 | .. container:: paragraph |
| 1302 | |
| 1303 | Running APEX from the ONAP docker repository only requires 2 |
| 1304 | commands: |
| 1305 | |
| 1306 | .. container:: olist arabic |
| 1307 | |
| 1308 | #. Log into the ONAP docker repo |
| 1309 | |
| 1310 | .. container:: listingblock |
| 1311 | |
| 1312 | .. container:: content |
| 1313 | |
| 1314 | :: |
| 1315 | |
| 1316 | docker login -u docker -p docker nexus3.onap.org:10003 |
| 1317 | |
| 1318 | .. container:: olist arabic |
| 1319 | |
| 1320 | #. Run the APEX docker image |
| 1321 | |
| 1322 | .. container:: listingblock |
| 1323 | |
| 1324 | .. container:: content |
| 1325 | |
| 1326 | :: |
| 1327 | |
| 1328 | docker run -it --rm nexus3.onap.org:10003/onap/policy-apex-pdp:latest |
| 1329 | |
| 1330 | Build a Docker Image |
| 1331 | #################### |
| 1332 | |
| 1333 | .. container:: paragraph |
| 1334 | |
| 1335 | Alternatively, one can use the Dockerfile defined in the Docker |
| 1336 | package to build an image. |
| 1337 | |
| 1338 | .. container:: listingblock |
| 1339 | |
| 1340 | .. container:: title |
| 1341 | |
| 1342 | APEX Dockerfile |
| 1343 | |
| 1344 | .. container:: content |
| 1345 | |
| 1346 | .. code:: |
| 1347 | :number-lines: |
| 1348 | |
| 1349 | # |
| 1350 | # Docker file to build an image that runs APEX on Java 8 in Ubuntu |
| 1351 | # |
| 1352 | FROM ubuntu:16.04 |
| 1353 | |
| 1354 | RUN apt-get update && \ |
| 1355 | apt-get upgrade -y && \ |
| 1356 | apt-get install -y software-properties-common && \ |
| 1357 | add-apt-repository ppa:openjdk-r/ppa -y && \ |
| 1358 | apt-get update && \ |
| 1359 | apt-get install -y openjdk-8-jdk |
| 1360 | |
| 1361 | # Create apex user and group |
| 1362 | RUN groupadd apexuser |
| 1363 | RUN useradd --create-home -g apexuser apexuser |
| 1364 | |
| 1365 | # Add Apex-specific directories and set ownership as the Apex admin user |
| 1366 | RUN mkdir -p /opt/app/policy/apex-pdp |
| 1367 | RUN mkdir -p /var/log/onap/policy/apex-pdp |
| 1368 | RUN chown -R apexuser:apexuser /var/log/onap/policy/apex-pdp |
| 1369 | |
| 1370 | # Unpack the tarball |
| 1371 | RUN mkdir /packages |
| 1372 | COPY apex-pdp-package-full.tar.gz /packages |
| 1373 | RUN tar xvfz /packages/apex-pdp-package-full.tar.gz --directory /opt/app/policy/apex-pdp |
| 1374 | RUN rm /packages/apex-pdp-package-full.tar.gz |
| 1375 | |
| 1376 | # Ensure everything has the correct permissions |
| 1377 | RUN find /opt/app -type d -perm 755 |
| 1378 | RUN find /opt/app -type f -perm 644 |
| 1379 | RUN chmod a+x /opt/app/policy/apex-pdp/bin/* |
| 1380 | |
| 1381 | # Copy examples to Apex user area |
| 1382 | RUN cp -pr /opt/app/policy/apex-pdp/examples /home/apexuser |
| 1383 | |
| 1384 | RUN apt-get clean |
| 1385 | |
| 1386 | RUN chown -R apexuser:apexuser /home/apexuser/* |
| 1387 | |
| 1388 | USER apexuser |
| 1389 | ENV PATH /opt/app/policy/apex-pdp/bin:$PATH |
| 1390 | WORKDIR /home/apexuser |
| 1391 | |
| 1392 | APEX Configurations Explained |
| 1393 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 1394 | |
| 1395 | Introduction to APEX Configuration |
| 1396 | ---------------------------------- |
| 1397 | |
| 1398 | .. container:: paragraph |
| 1399 | |
| 1400 | An APEX engine can be configured to use various combinations |
| 1401 | of event input handlers, event output handlers, event |
| 1402 | protocols, context handlers, and logic executors. The system |
| 1403 | is build using a plugin architecture. Each configuration |
| 1404 | option is realized by a plugin, which can be loaded and |
| 1405 | configured when the engine is started. New plugins can be |
| 1406 | added to the system at any time, though to benefit from a |
| 1407 | new plugin an engine will need to be restarted. |
| 1408 | |
| 1409 | .. container:: imageblock |
| 1410 | |
| 1411 | .. container:: content |
| 1412 | |
| 1413 | |APEX Configuration Matrix| |
| 1414 | |
| 1415 | .. container:: title |
| 1416 | |
| 1417 | Figure 3. APEX Configuration Matrix |
| 1418 | |
| 1419 | .. container:: paragraph |
| 1420 | |
| 1421 | The APEX distribution already comes with a number of |
| 1422 | plugins. The figure above shows the provided plugins. Any |
| 1423 | combination of input, output, event protocol, context |
| 1424 | handlers, and executors is possible. |
| 1425 | |
| 1426 | General Configuration Format |
| 1427 | ---------------------------- |
| 1428 | |
| 1429 | .. container:: paragraph |
| 1430 | |
| 1431 | The APEX configuration file is a JSON file containing a few |
| 1432 | main blocks for different parts of the configuration. Each |
| 1433 | block then holds the configuration details. The following |
| 1434 | code shows the main blocks: |
| 1435 | |
| 1436 | .. container:: listingblock |
| 1437 | |
| 1438 | .. container:: content |
| 1439 | |
| 1440 | .. code:: |
| 1441 | |
| 1442 | { |
| 1443 | "engineServiceParameters":{ |
| 1444 | ... (1) |
| 1445 | "engineParameters":{ (2) |
| 1446 | "engineParameters":{...}, (3) |
| 1447 | "contextParameters":{...} (4) |
| 1448 | } |
| 1449 | }, |
| 1450 | "eventInputParameters":{ (5) |
| 1451 | "input1":{ (6) |
| 1452 | "carrierTechnologyParameters":{...}, |
| 1453 | "eventProtocolParameters":{...} |
| 1454 | }, |
| 1455 | "input2":{...}, (7) |
| 1456 | "carrierTechnologyParameters":{...}, |
| 1457 | "eventProtocolParameters":{...} |
| 1458 | }, |
| 1459 | ... (8) |
| 1460 | }, |
| 1461 | "eventOutputParameters":{ (9) |
| 1462 | "output1":{ (10) |
| 1463 | "carrierTechnologyParameters":{...}, |
| 1464 | "eventProtocolParameters":{...} |
| 1465 | }, |
| 1466 | "output2":{ (11) |
| 1467 | "carrierTechnologyParameters":{...}, |
| 1468 | "eventProtocolParameters":{...} |
| 1469 | }, |
| 1470 | ... (12) |
| 1471 | } |
| 1472 | } |
| 1473 | |
| 1474 | .. container:: colist arabic |
| 1475 | |
| 1476 | +-----------------------------------+-----------------------------------+ |
| 1477 | | **1** | main engine configuration | |
| 1478 | +-----------------------------------+-----------------------------------+ |
| 1479 | | **2** | engine parameters for plugin | |
| 1480 | | | configurations (execution | |
| 1481 | | | environments and context | |
| 1482 | | | handling) | |
| 1483 | +-----------------------------------+-----------------------------------+ |
| 1484 | | **3** | engine specific parameters, | |
| 1485 | | | mainly for executor plugins | |
| 1486 | +-----------------------------------+-----------------------------------+ |
| 1487 | | **4** | context specific parameters, e.g. | |
| 1488 | | | for context schemas, persistence, | |
| 1489 | | | etc. | |
| 1490 | +-----------------------------------+-----------------------------------+ |
| 1491 | | **5** | configuration of the input | |
| 1492 | | | interface | |
| 1493 | +-----------------------------------+-----------------------------------+ |
| 1494 | | **6** | an example input called | |
| 1495 | | | ``input1`` with carrier | |
| 1496 | | | technology and event protocol | |
| 1497 | +-----------------------------------+-----------------------------------+ |
| 1498 | | **7** | an example input called | |
| 1499 | | | ``input2`` with carrier | |
| 1500 | | | technology and event protocol | |
| 1501 | +-----------------------------------+-----------------------------------+ |
| 1502 | | **8** | any further input configuration | |
| 1503 | +-----------------------------------+-----------------------------------+ |
| 1504 | | **9** | configuration of the output | |
| 1505 | | | interface | |
| 1506 | +-----------------------------------+-----------------------------------+ |
| 1507 | | **10** | an example output called | |
| 1508 | | | ``output1`` with carrier | |
| 1509 | | | technology and event protocol | |
| 1510 | +-----------------------------------+-----------------------------------+ |
| 1511 | | **11** | an example output called | |
| 1512 | | | ``output2`` with carrier | |
| 1513 | | | technology and event protocol | |
| 1514 | +-----------------------------------+-----------------------------------+ |
| 1515 | | **12** | any further output configuration | |
| 1516 | +-----------------------------------+-----------------------------------+ |
| 1517 | |
| 1518 | Engine Service Parameters |
| 1519 | ------------------------- |
| 1520 | |
| 1521 | .. container:: paragraph |
| 1522 | |
| 1523 | The configuration provides a number of parameters to |
| 1524 | configure the engine. An example configuration with |
| 1525 | explanations of all options is shown below. |
| 1526 | |
| 1527 | .. container:: listingblock |
| 1528 | |
| 1529 | .. container:: content |
| 1530 | |
| 1531 | .. code:: |
| 1532 | |
| 1533 | "engineServiceParameters" : { |
| 1534 | "name" : "AADMApexEngine", (1) |
| 1535 | "version" : "0.0.1", (2) |
| 1536 | "id" : 45, (3) |
| 1537 | "instanceCount" : 4, (4) |
| 1538 | "deploymentPort" : 12345, (5) |
| 1539 | "policyModelFileName" : "examples/models/VPN/VPNPolicyModelJava.json", (6) |
| 1540 | "periodicEventPeriod": 1000, (7) |
| 1541 | "engineParameters":{ (8) |
| 1542 | "engineParameters":{...}, (9) |
| 1543 | "contextParameters":{...} (10) |
| 1544 | } |
| 1545 | } |
| 1546 | |
| 1547 | .. container:: colist arabic |
| 1548 | |
| 1549 | +-----------------------------------+-----------------------------------+ |
| 1550 | | **1** | a name for the engine. The engine | |
| 1551 | | | name is used to create a key in a | |
| 1552 | | | runtime engine. An name matching | |
| 1553 | | | the following regular expression | |
| 1554 | | | can be used here: | |
| 1555 | | | ``[A-Za-z0-9\\-_\\.]+`` | |
| 1556 | +-----------------------------------+-----------------------------------+ |
| 1557 | | **2** | a version of the engine, use | |
| 1558 | | | semantic versioning as explained | |
| 1559 | | | here: `Semantic | |
| 1560 | | | Versioning <http://semver.org/>`_ | |
| 1561 | | | _. | |
| 1562 | | | This version is used in a runtime | |
| 1563 | | | engine to create a version of the | |
| 1564 | | | engine. For that reason, the | |
| 1565 | | | version must match the following | |
| 1566 | | | regular expression ``[A-Z0-9.]+`` | |
| 1567 | +-----------------------------------+-----------------------------------+ |
| 1568 | | **3** | a numeric identifier for the | |
| 1569 | | | engine | |
| 1570 | +-----------------------------------+-----------------------------------+ |
| 1571 | | **4** | the number of threads (policy | |
| 1572 | | | instances executed in parallel) | |
| 1573 | | | the engine should use, use ``1`` | |
| 1574 | | | for single threaded engines | |
| 1575 | +-----------------------------------+-----------------------------------+ |
| 1576 | | **5** | the port for the deployment | |
| 1577 | | | Websocket connection to the | |
| 1578 | | | engine | |
| 1579 | +-----------------------------------+-----------------------------------+ |
| 1580 | | **6** | the model file to load into the | |
| 1581 | | | engine on startup (optional) | |
| 1582 | +-----------------------------------+-----------------------------------+ |
| 1583 | | **7** | an optional timer for periodic | |
| 1584 | | | policies, in milliseconds (a | |
| 1585 | | | defined periodic policy will be | |
| 1586 | | | executed every ``X`` | |
| 1587 | | | milliseconds), not used of not | |
| 1588 | | | set or ``0`` | |
| 1589 | +-----------------------------------+-----------------------------------+ |
| 1590 | | **8** | engine parameters for plugin | |
| 1591 | | | configurations (execution | |
| 1592 | | | environments and context | |
| 1593 | | | handling) | |
| 1594 | +-----------------------------------+-----------------------------------+ |
| 1595 | | **9** | engine specific parameters, | |
| 1596 | | | mainly for executor plugins | |
| 1597 | +-----------------------------------+-----------------------------------+ |
| 1598 | | **10** | context specific parameters, e.g. | |
| 1599 | | | for context schemas, persistence, | |
| 1600 | | | etc. | |
| 1601 | +-----------------------------------+-----------------------------------+ |
| 1602 | |
| 1603 | .. container:: paragraph |
| 1604 | |
| 1605 | The model file is optional, it can also be specified via |
| 1606 | command line. In any case, make sure all execution and other |
| 1607 | required plug-ins for the loaded model are loaded as |
| 1608 | required. |
| 1609 | |
| 1610 | Input and Output Interfaces |
| 1611 | --------------------------- |
| 1612 | |
| 1613 | .. container:: paragraph |
| 1614 | |
| 1615 | An APEX engine has two main interfaces: |
| 1616 | |
| 1617 | .. container:: ulist |
| 1618 | |
| 1619 | - An *input* interface to receive events: also known as |
| 1620 | ingress interface or consumer, receiving (consuming) |
| 1621 | events commonly named triggers, and |
| 1622 | |
| 1623 | - An *output* interface to publish produced events: also |
| 1624 | known as egress interface or producer, sending |
| 1625 | (publishing) events commonly named actions or action |
| 1626 | events. |
| 1627 | |
| 1628 | .. container:: paragraph |
| 1629 | |
| 1630 | The input and output interface is configured in terms of |
| 1631 | inputs and outputs, respectively. Each input and output is a |
| 1632 | combination of a carrier technology and an event protocol. |
| 1633 | Carrier technologies and event protocols are provided by |
| 1634 | plugins, each with its own specific configuration. Most |
| 1635 | carrier technologies can be configured for input as well as |
| 1636 | output. Most event protocols can be used for all carrier |
| 1637 | technologies. One exception is the JMS object event |
| 1638 | protocol, which can only be used for the JMS carrier |
| 1639 | technology. Some further restrictions apply (for instance |
| 1640 | for carrier technologies using bi- or uni-directional |
| 1641 | modes). |
| 1642 | |
| 1643 | .. container:: paragraph |
| 1644 | |
| 1645 | Input and output interface can be configured separately, in |
| 1646 | isolation, with any number of carrier technologies. The |
| 1647 | resulting general configuration options are: |
| 1648 | |
| 1649 | .. container:: ulist |
| 1650 | |
| 1651 | - Input interface with one or more inputs |
| 1652 | |
| 1653 | .. container:: ulist |
| 1654 | |
| 1655 | - each input with a carrier technology and an event |
| 1656 | protocol |
| 1657 | |
| 1658 | - some inputs with optional synchronous mode |
| 1659 | |
| 1660 | - some event protocols with additional parameters |
| 1661 | |
| 1662 | - Output interface with one or more outputs |
| 1663 | |
| 1664 | .. container:: ulist |
| 1665 | |
| 1666 | - each output with a carrier technology and an event |
| 1667 | encoding |
| 1668 | |
| 1669 | - some outputs with optional synchronous mode |
| 1670 | |
| 1671 | - some event protocols with additional parameters |
| 1672 | |
| 1673 | .. container:: paragraph |
| 1674 | |
| 1675 | The configuration for input and output is contained in |
| 1676 | ``eventInputParameters`` and ``eventOutputParameters``, |
| 1677 | respectively. Inside here, one can configure any number of |
| 1678 | inputs and outputs. Each of them needs to have a unique |
| 1679 | identifier (name), the content of the name is free form. The |
| 1680 | example below shows a configuration for two inputs and two |
| 1681 | outputs. |
| 1682 | |
| 1683 | .. container:: listingblock |
| 1684 | |
| 1685 | .. container:: content |
| 1686 | |
| 1687 | .. code:: |
| 1688 | |
| 1689 | "eventInputParameters": { (1) |
| 1690 | "FirstConsumer": { (2) |
| 1691 | "carrierTechnologyParameters" : {...}, (3) |
| 1692 | "eventProtocolParameters":{...}, (4) |
| 1693 | ... (5) |
| 1694 | }, |
| 1695 | "SecondConsumer": { (6) |
| 1696 | "carrierTechnologyParameters" : {...}, (7) |
| 1697 | "eventProtocolParameters":{...}, (8) |
| 1698 | ... (9) |
| 1699 | }, |
| 1700 | }, |
| 1701 | "eventOutputParameters": { (10) |
| 1702 | "FirstProducer": { (11) |
| 1703 | "carrierTechnologyParameters":{...}, (12) |
| 1704 | "eventProtocolParameters":{...}, (13) |
| 1705 | ... (14) |
| 1706 | }, |
| 1707 | "SecondProducer": { (15) |
| 1708 | "carrierTechnologyParameters":{...}, (16) |
| 1709 | "eventProtocolParameters":{...}, (17) |
| 1710 | ... (18) |
| 1711 | } |
| 1712 | } |
| 1713 | |
| 1714 | .. container:: colist arabic |
| 1715 | |
| 1716 | +--------+--------------------------------------------------------------------+ |
| 1717 | | **1** | input interface configuration, APEX input plugins | |
| 1718 | +--------+--------------------------------------------------------------------+ |
| 1719 | | **2** | first input called ``FirstConsumer`` | |
| 1720 | +--------+--------------------------------------------------------------------+ |
| 1721 | | **3** | carrier technology for plugin | |
| 1722 | +--------+--------------------------------------------------------------------+ |
| 1723 | | **4** | event protocol for plugin | |
| 1724 | +--------+--------------------------------------------------------------------+ |
| 1725 | | **5** | any other input configuration (e.g. event name filter, see below) | |
| 1726 | +--------+--------------------------------------------------------------------+ |
| 1727 | | **6** | second input called ``SecondConsumer`` | |
| 1728 | +--------+--------------------------------------------------------------------+ |
| 1729 | | **7** | carrier technology for plugin | |
| 1730 | +--------+--------------------------------------------------------------------+ |
| 1731 | | **8** | event protocol for plugin | |
| 1732 | +--------+--------------------------------------------------------------------+ |
| 1733 | | **9** | any other plugin configuration | |
| 1734 | +--------+--------------------------------------------------------------------+ |
| 1735 | | **10** | output interface configuration, APEX output plugins | |
| 1736 | +--------+--------------------------------------------------------------------+ |
| 1737 | | **11** | first output called ``FirstProducer`` | |
| 1738 | +--------+--------------------------------------------------------------------+ |
| 1739 | | **12** | carrier technology for plugin | |
| 1740 | +--------+--------------------------------------------------------------------+ |
| 1741 | | **13** | event protocol for plugin | |
| 1742 | +--------+--------------------------------------------------------------------+ |
| 1743 | | **14** | any other plugin configuration | |
| 1744 | +--------+--------------------------------------------------------------------+ |
| 1745 | | **15** | second output called ``SecondProducer`` | |
| 1746 | +--------+--------------------------------------------------------------------+ |
| 1747 | | **16** | carrier technology for plugin | |
| 1748 | +--------+--------------------------------------------------------------------+ |
| 1749 | | **17** | event protocol for plugin | |
| 1750 | +--------+--------------------------------------------------------------------+ |
| 1751 | | **18** | any other output configuration (e.g. event name filter, see below) | |
| 1752 | +--------+--------------------------------------------------------------------+ |
| 1753 | |
| 1754 | Event Filters |
| 1755 | ############# |
| 1756 | |
| 1757 | .. container:: paragraph |
| 1758 | |
| 1759 | APEX will always send an event after a policy execution |
| 1760 | is finished. For a successful execution, the event sent |
| 1761 | is the output event created by the policy. In case the |
| 1762 | policy does not create an output event, APEX will create |
| 1763 | a new event with all input event fields plus an |
| 1764 | additional field ``exceptionMessage`` with an exception |
| 1765 | message. |
| 1766 | |
| 1767 | .. container:: paragraph |
| 1768 | |
| 1769 | There are situations in which this auto-generated error |
| 1770 | event might not be required or wanted: |
| 1771 | |
| 1772 | .. container:: ulist |
| 1773 | |
| 1774 | - when a policy failing should not result in an event |
| 1775 | send out via an output interface |
| 1776 | |
| 1777 | - when the auto-generated event goes back in an APEX |
| 1778 | engine (or the same APEX engine), this can create |
| 1779 | endless loops |
| 1780 | |
| 1781 | - the auto-generated event should go to a special output |
| 1782 | interface or channel |
| 1783 | |
| 1784 | .. container:: paragraph |
| 1785 | |
| 1786 | All of these situations are supported by a filter option |
| 1787 | using a wildecard (regular expression) configuration on |
| 1788 | APEX I/O interfaces. The parameter is called |
| 1789 | ``eventNameFilter`` and the value are `Java regular |
| 1790 | expressions <https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html>`__ |
| 1791 | (a |
| 1792 | `tutorial <http://www.vogella.com/tutorials/JavaRegularExpressions/article.html>`__). |
| 1793 | The following code shows some examples: |
| 1794 | |
| 1795 | .. container:: listingblock |
| 1796 | |
| 1797 | .. container:: content |
| 1798 | |
| 1799 | .. code:: |
| 1800 | |
| 1801 | "eventInputParameters": { |
| 1802 | "Input1": { |
| 1803 | "carrierTechnologyParameters" : {...}, |
| 1804 | "eventProtocolParameters":{...}, |
| 1805 | "eventNameFilter" : "^E[Vv][Ee][Nn][Tt][0-9]004$" (1) |
| 1806 | } |
| 1807 | }, |
| 1808 | "eventOutputParameters": { |
| 1809 | "Output1": { |
| 1810 | "carrierTechnologyParameters":{...}, |
| 1811 | "eventProtocolParameters":{...}, |
| 1812 | "eventNameFilter" : "^E[Vv][Ee][Nn][Tt][0-9]104$" (2) |
| 1813 | } |
| 1814 | } |
| 1815 | |
| 1816 | Executors |
| 1817 | --------- |
| 1818 | |
| 1819 | .. container:: paragraph |
| 1820 | |
| 1821 | Executors are plugins that realize the execution of logic |
| 1822 | contained in a policy model. Logic can be in a task |
| 1823 | selector, a task, and a state finalizer. Using plugins for |
| 1824 | execution environments makes APEX very flexible to support |
| 1825 | virtually any executable logic expressions. |
| 1826 | |
| 1827 | .. container:: paragraph |
| 1828 | |
| 1829 | APEX 2.0.0-SNAPSHOT supports the following executors: |
| 1830 | |
| 1831 | .. container:: ulist |
| 1832 | |
| 1833 | - Java, for Java implemented logic |
| 1834 | |
| 1835 | .. container:: ulist |
| 1836 | |
| 1837 | - This executor requires logic implemented using the |
| 1838 | APEX Java interfaces. |
| 1839 | |
| 1840 | - Generated JAR files must be in the classpath of the |
| 1841 | APEX engine at start time. |
| 1842 | |
| 1843 | - Javascript |
| 1844 | |
| 1845 | - JRuby, |
| 1846 | |
| 1847 | - Jython, |
| 1848 | |
| 1849 | - MVEL |
| 1850 | |
| 1851 | .. container:: ulist |
| 1852 | |
| 1853 | - This executor uses the latest version of the MVEL |
| 1854 | engine, which can be very hard to debug and can |
| 1855 | produce unwanted side effects during execution |
| 1856 | |
| 1857 | Configure the Javascript Executor |
| 1858 | ################################# |
| 1859 | |
| 1860 | .. container:: paragraph |
| 1861 | |
| 1862 | The Javascript executor is added to the configuration as |
| 1863 | follows: |
| 1864 | |
| 1865 | .. container:: listingblock |
| 1866 | |
| 1867 | .. container:: content |
| 1868 | |
| 1869 | .. code:: |
| 1870 | |
| 1871 | "engineServiceParameters":{ |
| 1872 | "engineParameters":{ |
| 1873 | "executorParameters":{ |
| 1874 | "JAVASCRIPT":{ |
| 1875 | "parameterClassName" : |
| 1876 | "org.onap.policy.apex.plugins.executor.javascript.JavascriptExecutorParameters" |
| 1877 | } |
| 1878 | } |
| 1879 | } |
| 1880 | } |
| 1881 | |
| 1882 | Configure the Jython Executor |
| 1883 | ############################# |
| 1884 | |
| 1885 | .. container:: paragraph |
| 1886 | |
| 1887 | The Jython executor is added to the configuration as |
| 1888 | follows: |
| 1889 | |
| 1890 | .. container:: listingblock |
| 1891 | |
| 1892 | .. container:: content |
| 1893 | |
| 1894 | .. code:: |
| 1895 | |
| 1896 | "engineServiceParameters":{ |
| 1897 | "engineParameters":{ |
| 1898 | "executorParameters":{ |
| 1899 | "JYTHON":{ |
| 1900 | "parameterClassName" : |
| 1901 | "org.onap.policy.apex.plugins.executor.jython.JythonExecutorParameters" |
| 1902 | } |
| 1903 | } |
| 1904 | } |
| 1905 | } |
| 1906 | |
| 1907 | Configure the JRuby Executor |
| 1908 | ############################ |
| 1909 | |
| 1910 | .. container:: paragraph |
| 1911 | |
| 1912 | The JRuby executor is added to the configuration as |
| 1913 | follows: |
| 1914 | |
| 1915 | .. container:: listingblock |
| 1916 | |
| 1917 | .. container:: content |
| 1918 | |
| 1919 | .. code:: |
| 1920 | |
| 1921 | "engineServiceParameters":{ |
| 1922 | "engineParameters":{ |
| 1923 | "executorParameters":{ |
| 1924 | "JRUBY":{ |
| 1925 | "parameterClassName" : |
| 1926 | "org.onap.policy.apex.plugins.executor.jruby.JrubyExecutorParameters" |
| 1927 | } |
| 1928 | } |
| 1929 | } |
| 1930 | } |
| 1931 | |
| 1932 | Configure the Java Executor |
| 1933 | ########################### |
| 1934 | |
| 1935 | .. container:: paragraph |
| 1936 | |
| 1937 | The Java executor is added to the configuration as |
| 1938 | follows: |
| 1939 | |
| 1940 | .. container:: listingblock |
| 1941 | |
| 1942 | .. container:: content |
| 1943 | |
| 1944 | .. code:: |
| 1945 | |
| 1946 | "engineServiceParameters":{ |
| 1947 | "engineParameters":{ |
| 1948 | "executorParameters":{ |
| 1949 | "JAVA":{ |
| 1950 | "parameterClassName" : |
| 1951 | "org.onap.policy.apex.plugins.executor.java.JavaExecutorParameters" |
| 1952 | } |
| 1953 | } |
| 1954 | } |
| 1955 | } |
| 1956 | |
| 1957 | Configure the MVEL Executor |
| 1958 | ########################### |
| 1959 | |
| 1960 | .. container:: paragraph |
| 1961 | |
| 1962 | The MVEL executor is added to the configuration as |
| 1963 | follows: |
| 1964 | |
| 1965 | .. container:: listingblock |
| 1966 | |
| 1967 | .. container:: content |
| 1968 | |
| 1969 | .. code:: |
| 1970 | |
| 1971 | "engineServiceParameters":{ |
| 1972 | "engineParameters":{ |
| 1973 | "executorParameters":{ |
| 1974 | "MVEL":{ |
| 1975 | "parameterClassName" : |
| 1976 | "org.onap.policy.apex.plugins.executor.mvel.MVELExecutorParameters" |
| 1977 | } |
| 1978 | } |
| 1979 | } |
| 1980 | } |
| 1981 | |
| 1982 | Context Handlers |
| 1983 | ---------------- |
| 1984 | |
| 1985 | .. container:: paragraph |
| 1986 | |
| 1987 | Context handlers are responsible for all context processing. |
| 1988 | There are the following main areas: |
| 1989 | |
| 1990 | .. container:: ulist |
| 1991 | |
| 1992 | - Context schema: use schema handlers other than Java class |
| 1993 | (supported by default without configuration) |
| 1994 | |
| 1995 | - Context distribution: distribute context across multiple |
| 1996 | APEX engines |
| 1997 | |
| 1998 | - Context locking: mechanisms to lock context elements for |
| 1999 | read/write |
| 2000 | |
| 2001 | - Context persistence: mechanisms to persist context |
| 2002 | |
| 2003 | .. container:: paragraph |
| 2004 | |
| 2005 | APEX provides plugins for each of the main areas. |
| 2006 | |
| 2007 | Configure AVRO Schema Handler |
| 2008 | ############################# |
| 2009 | |
| 2010 | .. container:: paragraph |
| 2011 | |
| 2012 | The AVRO schema handler is added to the configuration as |
| 2013 | follows: |
| 2014 | |
| 2015 | .. container:: listingblock |
| 2016 | |
| 2017 | .. container:: content |
| 2018 | |
| 2019 | .. code:: |
| 2020 | |
| 2021 | "engineServiceParameters":{ |
| 2022 | "engineParameters":{ |
| 2023 | "contextParameters":{ |
| 2024 | "parameterClassName" : "org.onap.policy.apex.context.parameters.ContextParameters", |
| 2025 | "schemaParameters":{ |
| 2026 | "Avro":{ |
| 2027 | "parameterClassName" : |
| 2028 | "org.onap.policy.apex.plugins.context.schema.avro.AvroSchemaHelperParameters" |
| 2029 | } |
| 2030 | } |
| 2031 | } |
| 2032 | } |
| 2033 | } |
| 2034 | |
| 2035 | .. container:: paragraph |
| 2036 | |
| 2037 | Using the AVRO schema handler has one limitation: AVRO |
| 2038 | only supports field names that represent valid Java class |
| 2039 | names. This means only letters and the character ``_`` |
| 2040 | are supported. Characters commonly used in field names, |
| 2041 | such as ``.`` and ``-``, are not supported by AVRO. for |
| 2042 | more information see `Avro Spec: |
| 2043 | Names <https://avro.apache.org/docs/1.8.1/spec.html#names>`__. |
| 2044 | |
| 2045 | .. container:: paragraph |
| 2046 | |
| 2047 | To work with this limitation, the APEX Avro plugin will |
| 2048 | parse a given AVRO definition and replace *all* |
| 2049 | occurrences of ``.`` and ``-`` with a ``_``. This means |
| 2050 | that |
| 2051 | |
| 2052 | .. container:: ulist |
| 2053 | |
| 2054 | - In a policy model, if the AVRO schema defined a field |
| 2055 | as ``my-name`` the policy logic should access it as |
| 2056 | ``my_name`` |
| 2057 | |
| 2058 | - In a policy model, if the AVRO schema defined a field |
| 2059 | as ``my.name`` the policy logic should access it as |
| 2060 | ``my_name`` |
| 2061 | |
| 2062 | - There should be no field names that convert to the |
| 2063 | same internal name |
| 2064 | |
| 2065 | .. container:: ulist |
| 2066 | |
| 2067 | - For instance the simultaneous use of |
| 2068 | ``my_name``, ``my.name``, and ``my-name`` should |
| 2069 | be avoided |
| 2070 | |
| 2071 | - If not avoided, the event processing might |
| 2072 | create unwanted side effects |
| 2073 | |
| 2074 | - If field names use any other not-supported character, |
| 2075 | the AVRO plugin will reject it |
| 2076 | |
| 2077 | .. container:: ulist |
| 2078 | |
| 2079 | - Since AVRO uses lazy initialization, this |
| 2080 | rejection might only become visible at runtime |
| 2081 | |
| 2082 | Carrier Technologies |
| 2083 | -------------------- |
| 2084 | |
| 2085 | .. container:: paragraph |
| 2086 | |
| 2087 | Carrier technologies define how APEX receives (input) and |
| 2088 | sends (output) events. They can be used in any combination, |
| 2089 | using asynchronous or synchronous mode. There can also be |
| 2090 | any number of carrier technologies for the input (consume) |
| 2091 | and the output (produce) interface. |
| 2092 | |
| 2093 | .. container:: paragraph |
| 2094 | |
| 2095 | Supported *input* technologies are: |
| 2096 | |
| 2097 | .. container:: ulist |
| 2098 | |
| 2099 | - Standard input, read events from the standard input |
| 2100 | (console), not suitable for APEX background servers |
| 2101 | |
| 2102 | - File input, read events from a file |
| 2103 | |
| 2104 | - Kafka, read events from a Kafka system |
| 2105 | |
| 2106 | - Websockets, read events from a Websocket |
| 2107 | |
| 2108 | - JMS, |
| 2109 | |
| 2110 | - REST (synchronous and asynchronous), additionally as |
| 2111 | client or server |
| 2112 | |
| 2113 | - Event Requestor, allows reading of events that have been |
| 2114 | looped back into APEX |
| 2115 | |
| 2116 | .. container:: paragraph |
| 2117 | |
| 2118 | Supported *output* technologies are: |
| 2119 | |
| 2120 | .. container:: ulist |
| 2121 | |
| 2122 | - Standard output, write events to the standard output |
| 2123 | (console), not suitable for APEX background servers |
| 2124 | |
| 2125 | - File output, write events to a file |
| 2126 | |
| 2127 | - Kafka, write events to a Kafka system |
| 2128 | |
| 2129 | - Websockets, write events to a Websocket |
| 2130 | |
| 2131 | - JMS |
| 2132 | |
| 2133 | - REST (synchronous and asynchronous), additionally as |
| 2134 | client or server |
| 2135 | |
| 2136 | - Event Requestor, allows events to be looped back into |
| 2137 | APEX |
| 2138 | |
| 2139 | .. container:: paragraph |
| 2140 | |
| 2141 | New carrier technologies can be added as plugins to APEX or |
| 2142 | developed outside APEX and added to an APEX deployment. |
| 2143 | |
| 2144 | Standard IO |
| 2145 | ########### |
| 2146 | |
| 2147 | .. container:: paragraph |
| 2148 | |
| 2149 | Standard IO does not require a specific plugin, it is |
| 2150 | supported be default. |
| 2151 | |
| 2152 | Standard Input |
| 2153 | ============== |
| 2154 | .. container:: paragraph |
| 2155 | |
| 2156 | APEX will take events from its standard input. This |
| 2157 | carrier is good for testing, but certainly not for a |
| 2158 | use case where APEX runs as a server. The |
| 2159 | configuration is as follows: |
| 2160 | |
| 2161 | .. container:: listingblock |
| 2162 | |
| 2163 | .. container:: content |
| 2164 | |
| 2165 | :: |
| 2166 | |
| 2167 | "carrierTechnologyParameters" : { |
| 2168 | "carrierTechnology" : "FILE", (1) |
| 2169 | "parameters" : { |
| 2170 | "standardIO" : true (2) |
| 2171 | } |
| 2172 | } |
| 2173 | |
| 2174 | .. container:: colist arabic |
| 2175 | |
| 2176 | +-------+---------------------------------------+ |
| 2177 | | **1** | standard input is considered a file | |
| 2178 | +-------+---------------------------------------+ |
| 2179 | | **2** | file descriptor set to standard input | |
| 2180 | +-------+---------------------------------------+ |
| 2181 | |
| 2182 | Standard Output |
| 2183 | =============== |
| 2184 | |
| 2185 | .. container:: paragraph |
| 2186 | |
| 2187 | APEX will send events to its standard output. This |
| 2188 | carrier is good for testing, but certainly not for a |
| 2189 | use case where APEX runs as a server. The |
| 2190 | configuration is as follows: |
| 2191 | |
| 2192 | .. container:: listingblock |
| 2193 | |
| 2194 | .. container:: content |
| 2195 | |
| 2196 | .. code:: |
| 2197 | |
| 2198 | "carrierTechnologyParameters" : { |
| 2199 | "carrierTechnology" : "FILE", (1) |
| 2200 | "parameters" : { |
| 2201 | "standardIO" : true (2) |
| 2202 | } |
| 2203 | } |
| 2204 | |
| 2205 | .. container:: colist arabic |
| 2206 | |
| 2207 | +-------+----------------------------------------+ |
| 2208 | | **1** | standard output is considered a file | |
| 2209 | +-------+----------------------------------------+ |
| 2210 | | **2** | file descriptor set to standard output | |
| 2211 | +-------+----------------------------------------+ |
| 2212 | |
| 2213 | 2.7.2. File IO |
| 2214 | ############## |
| 2215 | |
| 2216 | .. container:: paragraph |
| 2217 | |
| 2218 | File IO does not require a specific plugin, it is |
| 2219 | supported be default. |
| 2220 | |
| 2221 | File Input |
| 2222 | ========== |
| 2223 | |
| 2224 | .. container:: paragraph |
| 2225 | |
| 2226 | APEX will take events from a file. The same file |
| 2227 | should not be used as an output. The configuration is |
| 2228 | as follows: |
| 2229 | |
| 2230 | .. container:: listingblock |
| 2231 | |
| 2232 | .. container:: content |
| 2233 | |
| 2234 | .. code:: |
| 2235 | |
| 2236 | "carrierTechnologyParameters" : { |
| 2237 | "carrierTechnology" : "FILE", (1) |
| 2238 | "parameters" : { |
| 2239 | "fileName" : "examples/events/SampleDomain/EventsIn.xmlfile" (2) |
| 2240 | } |
| 2241 | } |
| 2242 | |
| 2243 | .. container:: colist arabic |
| 2244 | |
| 2245 | +-------+------------------------------------------+ |
| 2246 | | **1** | set file input | |
| 2247 | +-------+------------------------------------------+ |
| 2248 | | **2** | the name of the file to read events from | |
| 2249 | +-------+------------------------------------------+ |
| 2250 | |
| 2251 | File Output |
| 2252 | =========== |
| 2253 | .. container:: paragraph |
| 2254 | |
| 2255 | APEX will write events to a file. The same file should |
| 2256 | not be used as an input. The configuration is as |
| 2257 | follows: |
| 2258 | |
| 2259 | .. container:: listingblock |
| 2260 | |
| 2261 | .. container:: content |
| 2262 | |
| 2263 | .. code:: |
| 2264 | |
| 2265 | "carrierTechnologyParameters" : { |
| 2266 | "carrierTechnology" : "FILE", (1) |
| 2267 | "parameters" : { |
| 2268 | "fileName" : "examples/events/SampleDomain/EventsOut.xmlfile" (2) |
| 2269 | } |
| 2270 | } |
| 2271 | |
| 2272 | .. container:: colist arabic |
| 2273 | |
| 2274 | +-------+-----------------------------------------+ |
| 2275 | | **1** | set file output | |
| 2276 | +-------+-----------------------------------------+ |
| 2277 | | **2** | the name of the file to write events to | |
| 2278 | +-------+-----------------------------------------+ |
| 2279 | |
| 2280 | Event Requestor IO |
| 2281 | ################## |
| 2282 | |
| 2283 | .. container:: paragraph |
| 2284 | |
| 2285 | Event Requestor IO does not require a specific plugin, it |
| 2286 | is supported be default. It should only be used with the |
| 2287 | APEX event protocol. |
| 2288 | |
| 2289 | Event Requestor Input |
| 2290 | ===================== |
| 2291 | |
| 2292 | .. container:: paragraph |
| 2293 | |
| 2294 | APEX will take events from APEX. |
| 2295 | |
| 2296 | .. container:: listingblock |
| 2297 | |
| 2298 | .. container:: content |
| 2299 | |
| 2300 | .. code:: |
| 2301 | |
| 2302 | "carrierTechnologyParameters" : { |
| 2303 | "carrierTechnology": "EVENT_REQUESTOR" (1) |
| 2304 | } |
| 2305 | |
| 2306 | .. container:: colist arabic |
| 2307 | |
| 2308 | +-------+---------------------------+ |
| 2309 | | **1** | set event requestor input | |
| 2310 | +-------+---------------------------+ |
| 2311 | |
| 2312 | Event Requestor Output |
| 2313 | ====================== |
| 2314 | |
| 2315 | .. container:: paragraph |
| 2316 | |
| 2317 | APEX will write events to APEX. |
| 2318 | |
| 2319 | .. container:: listingblock |
| 2320 | |
| 2321 | .. container:: content |
| 2322 | |
| 2323 | .. code:: |
| 2324 | |
| 2325 | "carrierTechnologyParameters" : { |
| 2326 | "carrierTechnology": "EVENT_REQUESTOR" (1) |
| 2327 | } |
| 2328 | |
| 2329 | Peering Event Requestors |
| 2330 | ======================== |
| 2331 | |
| 2332 | .. container:: paragraph |
| 2333 | |
| 2334 | When using event requestors, they need to be peered. |
| 2335 | This means an event requestor output needs to be |
| 2336 | peered (associated) with an event requestor input. The |
| 2337 | following example shows the use of an event requestor |
| 2338 | with the APEX event protocol and the peering of output |
| 2339 | and input. |
| 2340 | |
| 2341 | .. container:: listingblock |
| 2342 | |
| 2343 | .. container:: content |
| 2344 | |
| 2345 | .. code:: |
| 2346 | |
| 2347 | "eventInputParameters": { |
| 2348 | "EventRequestorConsumer": { |
| 2349 | "carrierTechnologyParameters": { |
| 2350 | "carrierTechnology": "EVENT_REQUESTOR" (1) |
| 2351 | }, |
| 2352 | "eventProtocolParameters": { |
| 2353 | "eventProtocol": "APEX" (2) |
| 2354 | }, |
| 2355 | "eventNameFilter": "InputEvent", (3) |
| 2356 | "requestorMode": true, (4) |
| 2357 | "requestorPeer": "EventRequestorProducer", (5) |
| 2358 | "requestorTimeout": 500 (6) |
| 2359 | } |
| 2360 | }, |
| 2361 | "eventOutputParameters": { |
| 2362 | "EventRequestorProducer": { |
| 2363 | "carrierTechnologyParameters": { |
| 2364 | "carrierTechnology": "EVENT_REQUESTOR" (7) |
| 2365 | }, |
| 2366 | "eventProtocolParameters": { |
| 2367 | "eventProtocol": "APEX" (8) |
| 2368 | }, |
| 2369 | "eventNameFilter": "EventListEvent", (9) |
| 2370 | "requestorMode": true, (10) |
| 2371 | "requestorPeer": "EventRequestorConsumer", (11) |
| 2372 | "requestorTimeout": 500 (12) |
| 2373 | } |
| 2374 | } |
| 2375 | |
| 2376 | .. container:: colist arabic |
| 2377 | |
| 2378 | +-----------------------------------+-----------------------------------+ |
| 2379 | | **1** | event requestor on a consumer | |
| 2380 | +-----------------------------------+-----------------------------------+ |
| 2381 | | **2** | with APEX event protocol | |
| 2382 | +-----------------------------------+-----------------------------------+ |
| 2383 | | **3** | optional filter (best to use a | |
| 2384 | | | filter to prevent unwanted events | |
| 2385 | | | on the consumer side) | |
| 2386 | +-----------------------------------+-----------------------------------+ |
| 2387 | | **4** | activate requestor mode | |
| 2388 | +-----------------------------------+-----------------------------------+ |
| 2389 | | **5** | the peer to the output (must | |
| 2390 | | | match the output carrier) | |
| 2391 | +-----------------------------------+-----------------------------------+ |
| 2392 | | **6** | an optional timeout in | |
| 2393 | | | milliseconds | |
| 2394 | +-----------------------------------+-----------------------------------+ |
| 2395 | | **7** | event requestor on a producer | |
| 2396 | +-----------------------------------+-----------------------------------+ |
| 2397 | | **8** | with APEX event protocol | |
| 2398 | +-----------------------------------+-----------------------------------+ |
| 2399 | | **9** | optional filter (best to use a | |
| 2400 | | | filter to prevent unwanted events | |
| 2401 | | | on the consumer side) | |
| 2402 | +-----------------------------------+-----------------------------------+ |
| 2403 | | **10** | activate requestor mode | |
| 2404 | +-----------------------------------+-----------------------------------+ |
| 2405 | | **11** | the peer to the output (must | |
| 2406 | | | match the input carrier) | |
| 2407 | +-----------------------------------+-----------------------------------+ |
| 2408 | | **12** | an optional timeout in | |
| 2409 | | | milliseconds | |
| 2410 | +-----------------------------------+-----------------------------------+ |
| 2411 | |
| 2412 | Kafka IO |
| 2413 | ######## |
| 2414 | |
| 2415 | .. container:: paragraph |
| 2416 | |
| 2417 | Kafka IO is supported by the APEX Kafka plugin. The |
| 2418 | configurations below are examples. APEX will take any |
| 2419 | configuration inside the parameter object and forward it |
| 2420 | to Kafka. More information on Kafka specific |
| 2421 | configuration parameters can be found in the Kafka |
| 2422 | documentation: |
| 2423 | |
| 2424 | .. container:: ulist |
| 2425 | |
| 2426 | - `Kafka Consumer |
| 2427 | Class <https://kafka.apache.org/090/javadoc/org/apache/kafka/clients/consumer/KafkaConsumer.html>`__ |
| 2428 | |
| 2429 | - `Kafka Producer |
| 2430 | Class <https://kafka.apache.org/090/javadoc/org/apache/kafka/clients/producer/KafkaProducer.html>`__ |
| 2431 | |
| 2432 | Kafka Input |
| 2433 | =========== |
| 2434 | .. container:: paragraph |
| 2435 | |
| 2436 | APEX will receive events from the Apache Kafka |
| 2437 | messaging system. The input is uni-directional, an |
| 2438 | engine will only receive events from the input but not |
| 2439 | send any event to the input. |
| 2440 | |
| 2441 | .. container:: listingblock |
| 2442 | |
| 2443 | .. container:: content |
| 2444 | |
| 2445 | .. code:: |
| 2446 | |
| 2447 | "carrierTechnologyParameters" : { |
| 2448 | "carrierTechnology" : "KAFKA", (1) |
| 2449 | "parameterClassName" : |
| 2450 | "org.onap.policy.apex.plugins.event.carrier.kafka.KAFKACarrierTechnologyParameters", |
| 2451 | "parameters" : { |
| 2452 | "bootstrapServers" : "localhost:49092", (2) |
| 2453 | "groupId" : "apex-group-id", (3) |
| 2454 | "enableAutoCommit" : true, (4) |
| 2455 | "autoCommitTime" : 1000, (5) |
| 2456 | "sessionTimeout" : 30000, (6) |
| 2457 | "consumerPollTime" : 100, (7) |
| 2458 | "consumerTopicList" : ["apex-in-0", "apex-in-1"], (8) |
| 2459 | "keyDeserializer" : |
| 2460 | "org.apache.kafka.common.serialization.StringDeserializer", (9) |
| 2461 | "valueDeserializer" : |
| 2462 | "org.apache.kafka.common.serialization.StringDeserializer" (10) |
| 2463 | } |
| 2464 | } |
| 2465 | |
| 2466 | .. container:: colist arabic |
| 2467 | |
| 2468 | +--------+-------------------------------------+ |
| 2469 | | **1** | set Kafka as carrier technology | |
| 2470 | +--------+-------------------------------------+ |
| 2471 | | **2** | bootstrap server and port | |
| 2472 | +--------+-------------------------------------+ |
| 2473 | | **3** | a group identifier | |
| 2474 | +--------+-------------------------------------+ |
| 2475 | | **4** | flag for auto-commit | |
| 2476 | +--------+-------------------------------------+ |
| 2477 | | **5** | auto-commit timeout in milliseconds | |
| 2478 | +--------+-------------------------------------+ |
| 2479 | | **6** | session timeout in milliseconds | |
| 2480 | +--------+-------------------------------------+ |
| 2481 | | **7** | consumer poll time in milliseconds | |
| 2482 | +--------+-------------------------------------+ |
| 2483 | | **8** | consumer topic list | |
| 2484 | +--------+-------------------------------------+ |
| 2485 | | **9** | key for the Kafka de-serializer | |
| 2486 | +--------+-------------------------------------+ |
| 2487 | | **10** | value for the Kafka de-serializer | |
| 2488 | +--------+-------------------------------------+ |
| 2489 | |
| 2490 | Kafka Output |
| 2491 | ============ |
| 2492 | .. container:: paragraph |
| 2493 | |
| 2494 | APEX will send events to the Apache Kafka messaging |
| 2495 | system. The output is uni-directional, an engine will |
| 2496 | send events to the output but not receive any event |
| 2497 | from the output. |
| 2498 | |
| 2499 | .. container:: listingblock |
| 2500 | |
| 2501 | .. container:: content |
| 2502 | |
| 2503 | .. code:: |
| 2504 | |
| 2505 | "carrierTechnologyParameters" : { |
| 2506 | "carrierTechnology" : "KAFKA", (1) |
| 2507 | "parameterClassName" : |
| 2508 | "org.onap.policy.apex.plugins.event.carrier.kafka.KAFKACarrierTechnologyParameters", |
| 2509 | "parameters" : { |
| 2510 | "bootstrapServers" : "localhost:49092", (2) |
| 2511 | "acks" : "all", (3) |
| 2512 | "retries" : 0, (4) |
| 2513 | "batchSize" : 16384, (5) |
| 2514 | "lingerTime" : 1, (6) |
| 2515 | "bufferMemory" : 33554432, (7) |
| 2516 | "producerTopic" : "apex-out", (8) |
| 2517 | "keySerializer" : |
| 2518 | "org.apache.kafka.common.serialization.StringSerializer", (9) |
| 2519 | "valueSerializer" : |
| 2520 | "org.apache.kafka.common.serialization.StringSerializer" (10) |
| 2521 | } |
| 2522 | } |
| 2523 | |
| 2524 | .. container:: colist arabic |
| 2525 | |
| 2526 | +--------+---------------------------------+ |
| 2527 | | **1** | set Kafka as carrier technology | |
| 2528 | +--------+---------------------------------+ |
| 2529 | | **2** | bootstrap server and port | |
| 2530 | +--------+---------------------------------+ |
| 2531 | | **3** | acknowledgement strategy | |
| 2532 | +--------+---------------------------------+ |
| 2533 | | **4** | number of retries | |
| 2534 | +--------+---------------------------------+ |
| 2535 | | **5** | batch size | |
| 2536 | +--------+---------------------------------+ |
| 2537 | | **6** | time to linger in milliseconds | |
| 2538 | +--------+---------------------------------+ |
| 2539 | | **7** | buffer memory in byte | |
| 2540 | +--------+---------------------------------+ |
| 2541 | | **8** | producer topic | |
| 2542 | +--------+---------------------------------+ |
| 2543 | | **9** | key for the Kafka serializer | |
| 2544 | +--------+---------------------------------+ |
| 2545 | | **10** | value for the Kafka serializer | |
| 2546 | +--------+---------------------------------+ |
| 2547 | |
| 2548 | JMS IO |
| 2549 | ####### |
| 2550 | |
| 2551 | .. container:: paragraph |
| 2552 | |
| 2553 | APEX supports the Java Messaging Service (JMS) as input |
| 2554 | as well as output. JMS IO is supported by the APEX JMS |
| 2555 | plugin. Input and output support an event encoding as |
| 2556 | text (JSON string) or object (serialized object). The |
| 2557 | input configuration is the same for both encodings, the |
| 2558 | output configuration differs. |
| 2559 | |
| 2560 | JMS Input |
| 2561 | ========= |
| 2562 | .. container:: paragraph |
| 2563 | |
| 2564 | APEX will receive events from a JMS messaging system. |
| 2565 | The input is uni-directional, an engine will only |
| 2566 | receive events from the input but not send any event |
| 2567 | to the input. |
| 2568 | |
| 2569 | .. container:: listingblock |
| 2570 | |
| 2571 | .. container:: content |
| 2572 | |
| 2573 | .. code:: |
| 2574 | |
| 2575 | "carrierTechnologyParameters" : { |
| 2576 | "carrierTechnology" : "JMS", (1) |
| 2577 | "parameterClassName" : |
| 2578 | "org.onap.policy.apex.plugins.event.carrier.jms.JMSCarrierTechnologyParameters", |
| 2579 | "parameters" : { (2) |
| 2580 | "initialContextFactory" : |
| 2581 | "org.jboss.naming.remote.client.InitialContextFactory", (3) |
| 2582 | "connectionFactory" : "ConnectionFactory", (4) |
| 2583 | "providerURL" : "remote://localhost:5445", (5) |
| 2584 | "securityPrincipal" : "guest", (6) |
| 2585 | "securityCredentials" : "IAmAGuest", (7) |
| 2586 | "consumerTopic" : "jms/topic/apexIn" (8) |
| 2587 | } |
| 2588 | } |
| 2589 | |
| 2590 | .. container:: colist arabic |
| 2591 | |
| 2592 | +-----------------------------------+-----------------------------------+ |
| 2593 | | **1** | set JMS as carrier technology | |
| 2594 | +-----------------------------------+-----------------------------------+ |
| 2595 | | **2** | set all JMS specific parameters | |
| 2596 | +-----------------------------------+-----------------------------------+ |
| 2597 | | **3** | the context factory, in this case | |
| 2598 | | | from JBOSS (it requires the | |
| 2599 | | | dependency | |
| 2600 | | | org.jboss:jboss-remote-naming:2.0 | |
| 2601 | | | .4.Final | |
| 2602 | | | or a different version to be in | |
| 2603 | | | the directory ``$APEX_HOME/lib`` | |
| 2604 | | | or ``%APEX_HOME%\lib`` | |
| 2605 | +-----------------------------------+-----------------------------------+ |
| 2606 | | **4** | a connection factory for the JMS | |
| 2607 | | | connection | |
| 2608 | +-----------------------------------+-----------------------------------+ |
| 2609 | | **5** | URL with host and port of the JMS | |
| 2610 | | | provider | |
| 2611 | +-----------------------------------+-----------------------------------+ |
| 2612 | | **6** | access credentials, user name | |
| 2613 | +-----------------------------------+-----------------------------------+ |
| 2614 | | **7** | access credentials, user password | |
| 2615 | +-----------------------------------+-----------------------------------+ |
| 2616 | | **8** | the JMS topic to listen to | |
| 2617 | +-----------------------------------+-----------------------------------+ |
| 2618 | |
| 2619 | JMS Output with Text |
| 2620 | ==================== |
| 2621 | |
| 2622 | .. container:: paragraph |
| 2623 | |
| 2624 | APEX engine send events to a JMS messaging system. The |
| 2625 | output is uni-directional, an engine will send events |
| 2626 | to the output but not receive any event from output. |
| 2627 | |
| 2628 | .. container:: listingblock |
| 2629 | |
| 2630 | .. container:: content |
| 2631 | |
| 2632 | .. code:: |
| 2633 | |
| 2634 | "carrierTechnologyParameters" : { |
| 2635 | "carrierTechnology" : "JMS", (1) |
| 2636 | "parameterClassName" : |
| 2637 | "org.onap.policy.apex.plugins.event.carrier.jms.JMSCarrierTechnologyParameters", |
| 2638 | "parameters" : { (2) |
| 2639 | "initialContextFactory" : |
| 2640 | "org.jboss.naming.remote.client.InitialContextFactory", (3) |
| 2641 | "connectionFactory" : "ConnectionFactory", (4) |
| 2642 | "providerURL" : "remote://localhost:5445", (5) |
| 2643 | "securityPrincipal" : "guest", (6) |
| 2644 | "securityCredentials" : "IAmAGuest", (7) |
| 2645 | "producerTopic" : "jms/topic/apexOut", (8) |
| 2646 | "objectMessageSending": "false" (9) |
| 2647 | } |
| 2648 | } |
| 2649 | |
| 2650 | .. container:: colist arabic |
| 2651 | |
| 2652 | +-----------------------------------+-----------------------------------+ |
| 2653 | | **1** | set JMS as carrier technology | |
| 2654 | +-----------------------------------+-----------------------------------+ |
| 2655 | | **2** | set all JMS specific parameters | |
| 2656 | +-----------------------------------+-----------------------------------+ |
| 2657 | | **3** | the context factory, in this case | |
| 2658 | | | from JBOSS (it requires the | |
| 2659 | | | dependency | |
| 2660 | | | org.jboss:jboss-remote-naming:2.0 | |
| 2661 | | | .4.Final | |
| 2662 | | | or a different version to be in | |
| 2663 | | | the directory ``$APEX_HOME/lib`` | |
| 2664 | | | or ``%APEX_HOME%\lib`` | |
| 2665 | +-----------------------------------+-----------------------------------+ |
| 2666 | | **4** | a connection factory for the JMS | |
| 2667 | | | connection | |
| 2668 | +-----------------------------------+-----------------------------------+ |
| 2669 | | **5** | URL with host and port of the JMS | |
| 2670 | | | provider | |
| 2671 | +-----------------------------------+-----------------------------------+ |
| 2672 | | **6** | access credentials, user name | |
| 2673 | +-----------------------------------+-----------------------------------+ |
| 2674 | | **7** | access credentials, user password | |
| 2675 | +-----------------------------------+-----------------------------------+ |
| 2676 | | **8** | the JMS topic to write to | |
| 2677 | +-----------------------------------+-----------------------------------+ |
| 2678 | | **9** | set object messaging to ``false`` | |
| 2679 | | | means it sends JSON text | |
| 2680 | +-----------------------------------+-----------------------------------+ |
| 2681 | |
| 2682 | JMS Output with Object |
| 2683 | ====================== |
| 2684 | |
| 2685 | .. container:: paragraph |
| 2686 | |
| 2687 | To configure APEX for JMS objects on the output |
| 2688 | interface use the same configuration as above (for |
| 2689 | output). Simply change the ``objectMessageSending`` |
| 2690 | parameter to ``true``. |
| 2691 | |
| 2692 | Websocket (WS) IO |
| 2693 | ######################## |
| 2694 | |
| 2695 | .. container:: paragraph |
| 2696 | |
| 2697 | APEX supports the Websockets as input as well as output. |
| 2698 | WS IO is supported by the APEX Websocket plugin. This |
| 2699 | carrier technology does only support uni-directional |
| 2700 | communication. APEX will not send events to a Websocket |
| 2701 | input and any event sent to a Websocket output will |
| 2702 | result in an error log. |
| 2703 | |
| 2704 | .. container:: paragraph |
| 2705 | |
| 2706 | The input can be configured as client (APEX connects to |
| 2707 | an existing Websocket server) or server (APEX starts a |
| 2708 | Websocket server). The same applies to the output. Input |
| 2709 | and output can both use a client or a server |
| 2710 | configuration, or separate configurations (input as |
| 2711 | client and output as server, input as server and output |
| 2712 | as client). Each configuration should use its own |
| 2713 | dedicated port to avoid any communication loops. The |
| 2714 | configuration of a Websocket client is the same for input |
| 2715 | and output. The configuration of a Websocket server is |
| 2716 | the same for input and output. |
| 2717 | |
| 2718 | Websocket Client |
| 2719 | ================ |
| 2720 | |
| 2721 | .. container:: paragraph |
| 2722 | |
| 2723 | APEX will connect to a given Websocket server. As |
| 2724 | input, it will receive events from the server but not |
| 2725 | send any events. As output, it will send events to the |
| 2726 | server and any event received from the server will |
| 2727 | result in an error log. |
| 2728 | |
| 2729 | .. container:: listingblock |
| 2730 | |
| 2731 | .. container:: content |
| 2732 | |
| 2733 | .. code:: |
| 2734 | |
| 2735 | "carrierTechnologyParameters" : { |
| 2736 | "carrierTechnology" : "WEBSOCKET", (1) |
| 2737 | "parameterClassName" : |
| 2738 | "org.onap.policy.apex.plugins.event.carrier.websocket.WEBSOCKETCarrierTechnologyParameters", |
| 2739 | "parameters" : { |
| 2740 | "host" : "localhost", (2) |
| 2741 | "port" : 42451 (3) |
| 2742 | } |
| 2743 | } |
| 2744 | |
| 2745 | .. container:: colist arabic |
| 2746 | |
| 2747 | +-------+------------------------------------------------------+ |
| 2748 | | **1** | set Websocket as carrier technology | |
| 2749 | +-------+------------------------------------------------------+ |
| 2750 | | **2** | the host name on which a Websocket server is running | |
| 2751 | +-------+------------------------------------------------------+ |
| 2752 | | **3** | the port of that Websocket server | |
| 2753 | +-------+------------------------------------------------------+ |
| 2754 | |
| 2755 | Websocket Server |
| 2756 | ================ |
| 2757 | |
| 2758 | .. container:: paragraph |
| 2759 | |
| 2760 | APEX will start a Websocket server, which will accept |
| 2761 | any Websocket clients to connect. As input, it will |
| 2762 | receive events from the server but not send any |
| 2763 | events. As output, it will send events to the server |
| 2764 | and any event received from the server will result in |
| 2765 | an error log. |
| 2766 | |
| 2767 | .. container:: listingblock |
| 2768 | |
| 2769 | .. container:: content |
| 2770 | |
| 2771 | .. code:: |
| 2772 | |
| 2773 | "carrierTechnologyParameters" : { |
| 2774 | "carrierTechnology" : "WEBSOCKET", (1) |
| 2775 | "parameterClassName" : |
| 2776 | "org.onap.policy.apex.plugins.event.carrier.websocket.WEBSOCKETCarrierTechnologyParameters", |
| 2777 | "parameters" : { |
| 2778 | "wsClient" : false, (2) |
| 2779 | "port" : 42450 (3) |
| 2780 | } |
| 2781 | } |
| 2782 | |
| 2783 | .. container:: colist arabic |
| 2784 | |
| 2785 | +-------+------------------------------------------------------------+ |
| 2786 | | **1** | set Websocket as carrier technology | |
| 2787 | +-------+------------------------------------------------------------+ |
| 2788 | | **2** | disable client, so that APEX will start a Websocket server | |
| 2789 | +-------+------------------------------------------------------------+ |
| 2790 | | **3** | the port for the Websocket server APEX will start | |
| 2791 | +-------+------------------------------------------------------------+ |
| 2792 | |
| 2793 | REST Client IO |
| 2794 | ############## |
| 2795 | |
| 2796 | .. container:: paragraph |
| 2797 | |
| 2798 | APEX can act as REST client on the input as well as on |
| 2799 | the output interface. The media type is |
| 2800 | ``application/json``, so this plugin does only work with |
| 2801 | the JSON Event protocol. |
| 2802 | |
| 2803 | REST Client Input |
| 2804 | ================= |
| 2805 | |
| 2806 | .. container:: paragraph |
| 2807 | |
| 2808 | APEX will connect to a given URL to receive events, |
| 2809 | but not send any events. The server is polled, i.e. |
| 2810 | APEX will do an HTTP GET, take the result, and then do |
| 2811 | the next GET. Any required timing needs to be handled |
| 2812 | by the server configured via the URL. For instance, |
| 2813 | the server could support a wait timeout via the URL as |
| 2814 | ``?timeout=100ms``. |
| 2815 | |
| 2816 | .. container:: listingblock |
| 2817 | |
| 2818 | .. container:: content |
| 2819 | |
| 2820 | .. code:: |
| 2821 | |
| 2822 | "carrierTechnologyParameters" : { |
| 2823 | "carrierTechnology" : "RESTCLIENT", (1) |
| 2824 | "parameterClassName" : |
| 2825 | "org.onap.policy.apex.plugins.event.carrier.restclient.RESTClientCarrierTechnologyParameters", |
| 2826 | "parameters" : { |
| 2827 | "url" : "http://example.org:8080/triggers/events", (2) |
| 2828 | } |
| 2829 | } |
| 2830 | |
| 2831 | .. container:: colist arabic |
| 2832 | |
| 2833 | +-------+---------------------------------------+ |
| 2834 | | **1** | set REST client as carrier technology | |
| 2835 | +-------+---------------------------------------+ |
| 2836 | | **2** | the URL of the HTTP server for events | |
| 2837 | +-------+---------------------------------------+ |
| 2838 | |
| 2839 | REST Client Output |
| 2840 | ================== |
| 2841 | |
| 2842 | .. container:: paragraph |
| 2843 | |
| 2844 | APEX will connect to a given URL to send events, but |
| 2845 | not receive any events. The default HTTP operation is |
| 2846 | POST (no configuration required). To change it to PUT |
| 2847 | simply add the configuration parameter (as shown in |
| 2848 | the example below). |
| 2849 | |
| 2850 | .. container:: listingblock |
| 2851 | |
| 2852 | .. container:: content |
| 2853 | |
| 2854 | .. code:: |
| 2855 | |
| 2856 | "carrierTechnologyParameters" : { |
| 2857 | "carrierTechnology" : "RESTCLIENT", (1) |
| 2858 | "parameterClassName" : |
| 2859 | "org.onap.policy.apex.plugins.event.carrier.restclient.RESTClientCarrierTechnologyParameters", |
| 2860 | "parameters" : { |
| 2861 | "url" : "http://example.com:8888/actions/events", (2) |
| 2862 | "httpMethod" : "PUT" (3) |
| 2863 | } |
| 2864 | } |
| 2865 | |
| 2866 | .. container:: colist arabic |
| 2867 | |
| 2868 | +-------+--------------------------------------------------+ |
| 2869 | | **1** | set REST client as carrier technology | |
| 2870 | +-------+--------------------------------------------------+ |
| 2871 | | **2** | the URL of the HTTP server for events | |
| 2872 | +-------+--------------------------------------------------+ |
| 2873 | | **3** | use HTTP PUT (remove this line to use HTTP POST) | |
| 2874 | +-------+--------------------------------------------------+ |
| 2875 | |
| 2876 | REST Server IO |
| 2877 | ############## |
| 2878 | |
| 2879 | .. container:: paragraph |
| 2880 | |
| 2881 | APEX supports a REST server for input and output. |
| 2882 | |
| 2883 | .. container:: paragraph |
| 2884 | |
| 2885 | The REST server plugin always uses a synchronous mode. A |
| 2886 | client does a HTTP GET on the APEX REST server with the |
| 2887 | input event and receives the generated output event in |
| 2888 | the server reply. This means that for the REST server |
| 2889 | there has to always to be an input with an associated |
| 2890 | output. Input or output only are not permitted. |
| 2891 | |
| 2892 | .. container:: paragraph |
| 2893 | |
| 2894 | The plugin will start a Grizzly server as REST server for |
| 2895 | a normal APEX engine. If the APEX engine is executed as a |
| 2896 | servlet, for instance inside Tomcat, then Tomcat will be |
| 2897 | used as REST server (this case requires configuration on |
| 2898 | Tomcat as well). |
| 2899 | |
| 2900 | .. container:: paragraph |
| 2901 | |
| 2902 | Some configuration restrictions apply for all scenarios: |
| 2903 | |
| 2904 | .. container:: ulist |
| 2905 | |
| 2906 | - Minimum port: 1024 |
| 2907 | |
| 2908 | - Maximum port: 65535 |
| 2909 | |
| 2910 | - The media type is ``application/json``, so this plugin |
| 2911 | does only work with the JSON Event protocol. |
| 2912 | |
| 2913 | .. container:: paragraph |
| 2914 | |
| 2915 | The URL the client calls is created using |
| 2916 | |
| 2917 | .. container:: ulist |
| 2918 | |
| 2919 | - the configured host and port, e.g. |
| 2920 | ``http://localhost:12345`` |
| 2921 | |
| 2922 | - the standard path, e.g. ``/apex/`` |
| 2923 | |
| 2924 | - the name of the input/output, e.g. ``FirstConsumer/`` |
| 2925 | |
| 2926 | - the input or output name, e.g. ``EventIn``. |
| 2927 | |
| 2928 | .. container:: paragraph |
| 2929 | |
| 2930 | The examples above lead to the URL |
| 2931 | ``http://localhost:12345/apex/FirstConsumer/EventIn``. |
| 2932 | |
| 2933 | .. container:: paragraph |
| 2934 | |
| 2935 | A client can also get status information of the REST |
| 2936 | server using ``/Status``, e.g. |
| 2937 | ``http://localhost:12345/apex/FirstConsumer/Status``. |
| 2938 | |
| 2939 | REST Server Stand-alone |
| 2940 | ======================= |
| 2941 | |
| 2942 | .. container:: paragraph |
| 2943 | |
| 2944 | We need to configure a REST server input and a REST |
| 2945 | server output. Input and output are associated with |
| 2946 | each other via there name. |
| 2947 | |
| 2948 | .. container:: paragraph |
| 2949 | |
| 2950 | Timeouts for REST calls need to be set carefully. If |
| 2951 | they are too short, the call might timeout before a |
| 2952 | policy finished creating an event. |
| 2953 | |
| 2954 | .. container:: paragraph |
| 2955 | |
| 2956 | The following example configures the input named as |
| 2957 | ``MyConsumer`` and associates an output named |
| 2958 | ``MyProducer`` with it. |
| 2959 | |
| 2960 | .. container:: listingblock |
| 2961 | |
| 2962 | .. container:: content |
| 2963 | |
| 2964 | .. code:: |
| 2965 | |
| 2966 | "eventInputParameters": { |
| 2967 | "MyConsumer": { |
| 2968 | "carrierTechnologyParameters" : { |
| 2969 | "carrierTechnology" : "RESTSERVER", (1) |
| 2970 | "parameterClassName" : |
| 2971 | "org.onap.policy.apex.plugins.event.carrier.restserver.RESTServerCarrierTechnologyParameters", |
| 2972 | "parameters" : { |
| 2973 | "standalone" : true, (2) |
| 2974 | "host" : "localhost", (3) |
| 2975 | "port" : 12345 (4) |
| 2976 | } |
| 2977 | }, |
| 2978 | "eventProtocolParameters":{ |
| 2979 | "eventProtocol" : "JSON" (5) |
| 2980 | }, |
| 2981 | "synchronousMode" : true, (6) |
| 2982 | "synchronousPeer" : "MyProducer", (7) |
| 2983 | "synchronousTimeout" : 500 (8) |
| 2984 | } |
| 2985 | } |
| 2986 | |
| 2987 | .. container:: colist arabic |
| 2988 | |
| 2989 | +-------+---------------------------------------+ |
| 2990 | | **1** | set REST server as carrier technology | |
| 2991 | +-------+---------------------------------------+ |
| 2992 | | **2** | set the server as stand-alone | |
| 2993 | +-------+---------------------------------------+ |
| 2994 | | **3** | set the server host | |
| 2995 | +-------+---------------------------------------+ |
| 2996 | | **4** | set the server listen port | |
| 2997 | +-------+---------------------------------------+ |
| 2998 | | **5** | use JSON event protocol | |
| 2999 | +-------+---------------------------------------+ |
| 3000 | | **6** | activate synchronous mode | |
| 3001 | +-------+---------------------------------------+ |
| 3002 | | **7** | associate an output ``MyProducer`` | |
| 3003 | +-------+---------------------------------------+ |
| 3004 | | **8** | set a timeout of 500 milliseconds | |
| 3005 | +-------+---------------------------------------+ |
| 3006 | |
| 3007 | .. container:: paragraph |
| 3008 | |
| 3009 | The following example configures the output named as |
| 3010 | ``MyProducer`` and associates the input ``MyConsumer`` |
| 3011 | with it. Note that for the output there are no more |
| 3012 | paramters (such as host or port), since they are |
| 3013 | already configured in the associated input |
| 3014 | |
| 3015 | .. container:: listingblock |
| 3016 | |
| 3017 | .. container:: content |
| 3018 | |
| 3019 | .. code:: |
| 3020 | |
| 3021 | "eventOutputParameters": { |
| 3022 | "MyProducer": { |
| 3023 | "carrierTechnologyParameters":{ |
| 3024 | "carrierTechnology" : "RESTSERVER", |
| 3025 | "parameterClassName" : |
| 3026 | "org.onap.policy.apex.plugins.event.carrier.restserver.RESTServerCarrierTechnologyParameters" |
| 3027 | }, |
| 3028 | "eventProtocolParameters":{ |
| 3029 | "eventProtocol" : "JSON" |
| 3030 | }, |
| 3031 | "synchronousMode" : true, |
| 3032 | "synchronousPeer" : "MyConsumer", |
| 3033 | "synchronousTimeout" : 500 |
| 3034 | } |
| 3035 | } |
| 3036 | |
| 3037 | REST Server Stand-alone, multi input |
| 3038 | ==================================== |
| 3039 | |
| 3040 | .. container:: paragraph |
| 3041 | |
| 3042 | Any number of input/output pairs for REST servers can |
| 3043 | be configured. For instance, we can configure an input |
| 3044 | ``FirstConsumer`` with output ``FirstProducer`` and an |
| 3045 | input ``SecondConsumer`` with output |
| 3046 | ``SecondProducer``. Important is that there is always |
| 3047 | one pair of input/output. |
| 3048 | |
| 3049 | REST Server Stand-alone in Servlet |
| 3050 | ================================== |
| 3051 | |
| 3052 | .. container:: paragraph |
| 3053 | |
| 3054 | If APEX is executed as a servlet, e.g. inside Tomcat, |
| 3055 | the configuration becomes easier since the plugin can |
| 3056 | now use Tomcat as the REST server. In this scenario, |
| 3057 | there are not parameters (port, host, etc.) and the |
| 3058 | key ``standalone`` must not be used (or set to false). |
| 3059 | |
| 3060 | .. container:: paragraph |
| 3061 | |
| 3062 | For the Tomcat configuration, we need to add the REST |
| 3063 | server plugin, e.g. |
| 3064 | |
| 3065 | .. container:: listingblock |
| 3066 | |
| 3067 | .. container:: content |
| 3068 | |
| 3069 | .. code:: |
| 3070 | |
| 3071 | <servlet> |
| 3072 | ... |
| 3073 | <init-param> |
| 3074 | ... |
| 3075 | <param-value>org.onap.policy.apex.plugins.event.carrier.restserver</param-value> |
| 3076 | </init-param> |
| 3077 | ... |
| 3078 | </servlet> |
| 3079 | |
| 3080 | REST Requestor IO |
| 3081 | ################## |
| 3082 | |
| 3083 | .. container:: paragraph |
| 3084 | |
| 3085 | APEX can act as REST requestor on the input as well as on |
| 3086 | the output interface. The media type is |
| 3087 | ``application/json``, so this plugin does only work with |
| 3088 | the JSON Event protocol. |
| 3089 | |
| 3090 | REST Requestor Input |
| 3091 | ==================== |
| 3092 | |
| 3093 | .. container:: paragraph |
| 3094 | |
| 3095 | APEX will connect to a given URL to request an input. |
| 3096 | |
| 3097 | .. container:: listingblock |
| 3098 | |
| 3099 | .. container:: content |
| 3100 | |
| 3101 | .. code:: |
| 3102 | |
| 3103 | "carrierTechnologyParameters": { |
| 3104 | "carrierTechnology": "RESTREQUESTOR", (1) |
| 3105 | "parameterClassName": "org.onap.policy.apex.plugins.event.carrier.restrequestor.RESTRequestorCarrierTechnologyParameters", |
| 3106 | "parameters": { |
| 3107 | "url": "http://localhost:54321/some/path/to/rest/resource", (2) |
| 3108 | "httpMethod": "POST", (3) |
| 3109 | "restRequestTimeout": 2000 (4) |
| 3110 | } |
| 3111 | }, |
| 3112 | |
| 3113 | .. container:: colist arabic |
| 3114 | |
| 3115 | +-------+--------------------------------------------------+ |
| 3116 | | **1** | set REST requestor as carrier technology | |
| 3117 | +-------+--------------------------------------------------+ |
| 3118 | | **2** | the URL of the HTTP server for events | |
| 3119 | +-------+--------------------------------------------------+ |
| 3120 | | **3** | use HTTP PUT (remove this line to use HTTP POST) | |
| 3121 | +-------+--------------------------------------------------+ |
| 3122 | | **4** | request timeout in milliseconds | |
| 3123 | +-------+--------------------------------------------------+ |
| 3124 | |
| 3125 | .. container:: paragraph |
| 3126 | |
| 3127 | Further settings are required on the consumer to |
| 3128 | define the event that is requested, for example: |
| 3129 | |
| 3130 | .. container:: listingblock |
| 3131 | |
| 3132 | .. container:: content |
| 3133 | |
| 3134 | .. code:: |
| 3135 | |
| 3136 | "eventName": "GuardResponseEvent", (1) |
| 3137 | "eventNameFilter": "GuardResponseEvent", (2) |
| 3138 | "requestorMode": true, (3) |
| 3139 | "requestorPeer": "GuardRequestorProducer", (4) |
| 3140 | "requestorTimeout": 500 (5) |
| 3141 | |
| 3142 | .. container:: colist arabic |
| 3143 | |
| 3144 | +-------+---------------------------+ |
| 3145 | | **1** | the event name | |
| 3146 | +-------+---------------------------+ |
| 3147 | | **2** | a filter on the event | |
| 3148 | +-------+---------------------------+ |
| 3149 | | **3** | the mode of the requestor | |
| 3150 | +-------+---------------------------+ |
| 3151 | | **4** | a peer for the requestor | |
| 3152 | +-------+---------------------------+ |
| 3153 | | **5** | a general request timeout | |
| 3154 | +-------+---------------------------+ |
| 3155 | |
| 3156 | REST Requestor Output |
| 3157 | ===================== |
| 3158 | |
| 3159 | .. container:: paragraph |
| 3160 | |
| 3161 | APEX will connect to a given URL to send events, but |
| 3162 | not receive any events. |
| 3163 | |
| 3164 | .. container:: listingblock |
| 3165 | |
| 3166 | .. container:: content |
| 3167 | |
| 3168 | .. code:: |
| 3169 | |
| 3170 | "carrierTechnologyParameters": { |
| 3171 | "carrierTechnology": "RESTREQUESTOR", (1) |
| 3172 | "parameterClassName": "org.onap.policy.apex.plugins.event.carrier.restrequestor.RESTRequestorCarrierTechnologyParameters" |
| 3173 | }, |
| 3174 | |
| 3175 | .. container:: colist arabic |
| 3176 | |
| 3177 | +-------+------------------------------------------+ |
| 3178 | | **1** | set REST requestor as carrier technology | |
| 3179 | +-------+------------------------------------------+ |
| 3180 | |
| 3181 | .. container:: paragraph |
| 3182 | |
| 3183 | Further settings are required on the consumer to |
| 3184 | define the event that is requested, for example: |
| 3185 | |
| 3186 | .. container:: listingblock |
| 3187 | |
| 3188 | .. container:: content |
| 3189 | |
| 3190 | .. code:: |
| 3191 | |
| 3192 | "eventNameFilter": "GuardRequestEvent", (1) |
| 3193 | "requestorMode": true, (2) |
| 3194 | "requestorPeer": "GuardRequestorConsumer", (3) |
| 3195 | "requestorTimeout": 500 (4) |
| 3196 | |
| 3197 | .. container:: colist arabic |
| 3198 | |
| 3199 | +-------+---------------------------+ |
| 3200 | | **1** | a filter on the event | |
| 3201 | +-------+---------------------------+ |
| 3202 | | **2** | the mode of the requestor | |
| 3203 | +-------+---------------------------+ |
| 3204 | | **3** | a peer for the requestor | |
| 3205 | +-------+---------------------------+ |
| 3206 | | **4** | a general request timeout | |
| 3207 | +-------+---------------------------+ |
| 3208 | |
| 3209 | Event Protocols, Format and Encoding |
| 3210 | ------------------------------------ |
| 3211 | |
| 3212 | .. container:: paragraph |
| 3213 | |
| 3214 | Event protocols define what event formats APEX can receive |
| 3215 | (input) and should send (output). They can be used in any |
| 3216 | combination for input and output, unless further restricted |
| 3217 | by a carrier technology plugin (for instance for JMS |
| 3218 | output). There can only be 1 event protocol per event |
| 3219 | plugin. |
| 3220 | |
| 3221 | .. container:: paragraph |
| 3222 | |
| 3223 | Supported *input* event protocols are: |
| 3224 | |
| 3225 | .. container:: ulist |
| 3226 | |
| 3227 | - JSON, the event as a JSON string |
| 3228 | |
| 3229 | - APEX, an APEX event |
| 3230 | |
| 3231 | - JMS object, the event as a JMS object, |
| 3232 | |
| 3233 | - JMS text, the event as a JMS text, |
| 3234 | |
| 3235 | - XML, the event as an XML string, |
| 3236 | |
| 3237 | - YAML, the event as YAML text |
| 3238 | |
| 3239 | .. container:: paragraph |
| 3240 | |
| 3241 | Supported *output* event protocols are: |
| 3242 | |
| 3243 | .. container:: ulist |
| 3244 | |
| 3245 | - JSON, the event as a JSON string |
| 3246 | |
| 3247 | - APEX, an APEX event |
| 3248 | |
| 3249 | - JMS object, the event as a JMS object, |
| 3250 | |
| 3251 | - JMS text, the event as a JMS text, |
| 3252 | |
| 3253 | - XML, the event as an XML string, |
| 3254 | |
| 3255 | - YAML, the event as YAML text |
| 3256 | |
| 3257 | .. container:: paragraph |
| 3258 | |
| 3259 | New event protocols can be added as plugins to APEX or |
| 3260 | developed outside APEX and added to an APEX deployment. |
| 3261 | |
| 3262 | JSON Event |
| 3263 | ########## |
| 3264 | |
| 3265 | .. container:: paragraph |
| 3266 | |
| 3267 | The event protocol for JSON encoding does not require a |
| 3268 | specific plugin, it is supported by default. Furthermore, |
| 3269 | there is no difference in the configuration for the input |
| 3270 | and output interface. |
| 3271 | |
| 3272 | .. container:: paragraph |
| 3273 | |
| 3274 | For an input, APEX requires a well-formed JSON string. |
| 3275 | Well-formed here means according to the definitions of a |
| 3276 | policy. Any JSON string that is not defined as a trigger |
| 3277 | event (consume) will not be consumed (errors will be |
| 3278 | thrown). For output JSON events, APEX will always produce |
| 3279 | valid JSON strings according to the definition in the |
| 3280 | policy model. |
| 3281 | |
| 3282 | .. container:: paragraph |
| 3283 | |
| 3284 | The following JSON shows the configuration. |
| 3285 | |
| 3286 | .. container:: listingblock |
| 3287 | |
| 3288 | .. container:: content |
| 3289 | |
| 3290 | .. code:: |
| 3291 | |
| 3292 | "eventProtocolParameters":{ |
| 3293 | "eventProtocol" : "JSON" |
| 3294 | } |
| 3295 | |
| 3296 | .. container:: paragraph |
| 3297 | |
| 3298 | For JSON events, there are a few more optional |
| 3299 | parameters, which allow to define a mapping for standard |
| 3300 | event fields. An APEX event must have the fields |
| 3301 | ``name``, ``version``, ``source``, and ``target`` |
| 3302 | defined. Sometimes it is not possible to configure a |
| 3303 | trigger or actioning system to use those fields. However, |
| 3304 | they might be in an event generated outside APEX (or used |
| 3305 | outside APEX) just with different names. To configure |
| 3306 | APEX to map between the different event names, simply add |
| 3307 | the following parameters to a JSON event: |
| 3308 | |
| 3309 | .. container:: listingblock |
| 3310 | |
| 3311 | .. container:: content |
| 3312 | |
| 3313 | .. code:: |
| 3314 | |
| 3315 | "eventProtocolParameters":{ |
| 3316 | "eventProtocol" : "JSON", |
| 3317 | "nameAlias" : "policyName", (1) |
| 3318 | "versionAlias" : "policyVersion", (2) |
| 3319 | "sourceAlias" : "from", (3) |
| 3320 | "targetAlias" : "to", (4) |
| 3321 | "nameSpaceAlias": "my.name.space" (5) |
| 3322 | } |
| 3323 | |
| 3324 | .. container:: colist arabic |
| 3325 | |
| 3326 | +-----------------------------------+-----------------------------------+ |
| 3327 | | **1** | mapping for the ``name`` field, | |
| 3328 | | | here from a field called | |
| 3329 | | | ``policyName`` | |
| 3330 | +-----------------------------------+-----------------------------------+ |
| 3331 | | **2** | mapping for the ``version`` | |
| 3332 | | | field, here from a field called | |
| 3333 | | | ``policyVersion`` | |
| 3334 | +-----------------------------------+-----------------------------------+ |
| 3335 | | **3** | mapping for the ``source`` field, | |
| 3336 | | | here from a field called ``from`` | |
| 3337 | | | (only for an input event) | |
| 3338 | +-----------------------------------+-----------------------------------+ |
| 3339 | | **4** | mapping for the ``target`` field, | |
| 3340 | | | here from a field called ``to`` | |
| 3341 | | | (only for an output event) | |
| 3342 | +-----------------------------------+-----------------------------------+ |
| 3343 | | **5** | mapping for the ``nameSpace`` | |
| 3344 | | | field, here from a field called | |
| 3345 | | | ``my.name.space`` | |
| 3346 | +-----------------------------------+-----------------------------------+ |
| 3347 | |
| 3348 | APEX Event |
| 3349 | ########## |
| 3350 | .. container:: paragraph |
| 3351 | |
| 3352 | The event protocol for APEX events does not require a |
| 3353 | specific plugin, it is supported by default. Furthermore, |
| 3354 | there is no difference in the configuration for the input |
| 3355 | and output interface. |
| 3356 | |
| 3357 | .. container:: paragraph |
| 3358 | |
| 3359 | For input and output APEX uses APEX events. |
| 3360 | |
| 3361 | .. container:: paragraph |
| 3362 | |
| 3363 | The following JSON shows the configuration. |
| 3364 | |
| 3365 | .. container:: listingblock |
| 3366 | |
| 3367 | .. container:: content |
| 3368 | |
| 3369 | .. code:: |
| 3370 | |
| 3371 | "eventProtocolParameters":{ |
| 3372 | "eventProtocol" : "APEX" |
| 3373 | } |
| 3374 | |
| 3375 | JMS Event |
| 3376 | ######### |
| 3377 | |
| 3378 | .. container:: paragraph |
| 3379 | |
| 3380 | The event protocol for JMS is provided by the APEX JMS |
| 3381 | plugin. The plugin supports encoding as JSON text or as |
| 3382 | object. There is no difference in the configuration for |
| 3383 | the input and output interface. |
| 3384 | |
| 3385 | JMS Text |
| 3386 | ======== |
| 3387 | .. container:: paragraph |
| 3388 | |
| 3389 | If used as input, APEX will take a JMS message and |
| 3390 | extract a JSON string, then proceed as if a JSON event |
| 3391 | was received. If used as output, APEX will take the |
| 3392 | event produced by a policy, create a JSON string, and |
| 3393 | then wrap it into a JMS message. |
| 3394 | |
| 3395 | .. container:: paragraph |
| 3396 | |
| 3397 | The configuration for JMS text is as follows: |
| 3398 | |
| 3399 | .. container:: listingblock |
| 3400 | |
| 3401 | .. container:: content |
| 3402 | |
| 3403 | .. code:: |
| 3404 | |
| 3405 | "eventProtocolParameters":{ |
| 3406 | "eventProtocol" : "JMSTEXT", |
| 3407 | "parameterClassName" : |
| 3408 | "org.onap.policy.apex.plugins.event.protocol.jms.JMSTextEventProtocolParameters" |
| 3409 | } |
| 3410 | |
| 3411 | JMS Object |
| 3412 | ========== |
| 3413 | .. container:: paragraph |
| 3414 | |
| 3415 | If used as input, APEX will will take a JMS message, |
| 3416 | extract a Java Bean from the ``ObjectMessage`` |
| 3417 | message, construct an APEX event and put the bean on |
| 3418 | the APEX event as a parameter. If used as output, APEX |
| 3419 | will take the event produced by a policy, create a |
| 3420 | Java Bean and send it as a JMS message. |
| 3421 | |
| 3422 | .. container:: paragraph |
| 3423 | |
| 3424 | The configuration for JMS object is as follows: |
| 3425 | |
| 3426 | .. container:: listingblock |
| 3427 | |
| 3428 | .. container:: content |
| 3429 | |
| 3430 | .. code:: |
| 3431 | |
| 3432 | "eventProtocolParameters":{ |
| 3433 | "eventProtocol" : "JMSOBJECT", |
| 3434 | "parameterClassName" : |
| 3435 | "org.onap.policy.apex.plugins.event.protocol.jms.JMSObjectEventProtocolParameters" |
| 3436 | } |
| 3437 | |
| 3438 | YAML Event |
| 3439 | ########## |
| 3440 | |
| 3441 | .. container:: paragraph |
| 3442 | |
| 3443 | The event protocol for YAML is provided by the APEX YAML |
| 3444 | plugin. There is no difference in the configuration for |
| 3445 | the input and output interface. |
| 3446 | |
| 3447 | .. container:: paragraph |
| 3448 | |
| 3449 | If used as input, APEX will consume events as YAML and |
| 3450 | map them to policy trigger events. Not well-formed YAML |
| 3451 | and not understood trigger events will be rejected. If |
| 3452 | used as output, APEX produce YAML encoded events from the |
| 3453 | event a policy produces. Those events will always be |
| 3454 | well-formed according to the definition in the policy |
| 3455 | model. |
| 3456 | |
| 3457 | .. container:: paragraph |
| 3458 | |
| 3459 | The following code shows the configuration. |
| 3460 | |
| 3461 | .. container:: listingblock |
| 3462 | |
| 3463 | .. container:: content |
| 3464 | |
| 3465 | .. code:: |
| 3466 | |
| 3467 | "eventProtocolParameters":{ |
| 3468 | "eventProtocol" : "XML", |
| 3469 | "parameterClassName" : |
| 3470 | "org.onap.policy.apex.plugins.event.protocol.yaml.YamlEventProtocolParameters" |
| 3471 | } |
| 3472 | |
| 3473 | XML Event |
| 3474 | ######### |
| 3475 | .. container:: paragraph |
| 3476 | |
| 3477 | The event protocol for XML is provided by the APEX XML |
| 3478 | plugin. There is no difference in the configuration for |
| 3479 | the input and output interface. |
| 3480 | |
| 3481 | .. container:: paragraph |
| 3482 | |
| 3483 | If used as input, APEX will consume events as XML and map |
| 3484 | them to policy trigger events. Not well-formed XML and |
| 3485 | not understood trigger events will be rejected. If used |
| 3486 | as output, APEX produce XML encoded events from the event |
| 3487 | a policy produces. Those events will always be |
| 3488 | well-formed according to the definition in the policy |
| 3489 | model. |
| 3490 | |
| 3491 | .. container:: paragraph |
| 3492 | |
| 3493 | The following code shows the configuration. |
| 3494 | |
| 3495 | .. container:: listingblock |
| 3496 | |
| 3497 | .. container:: content |
| 3498 | |
| 3499 | .. code:: |
| 3500 | |
| 3501 | "eventProtocolParameters":{ |
| 3502 | "eventProtocol" : "XML", |
| 3503 | "parameterClassName" : |
| 3504 | "org.onap.policy.apex.plugins.event.protocol.xml.XMLEventProtocolParameters" |
| 3505 | } |
| 3506 | |
| 3507 | A configuration example |
| 3508 | ----------------------- |
| 3509 | |
| 3510 | .. container:: paragraph |
| 3511 | |
| 3512 | The following example loads all available plug-ins. |
| 3513 | |
| 3514 | .. container:: paragraph |
| 3515 | |
| 3516 | Events are consumed from a Websocket, APEX as client. |
| 3517 | Consumed event format is JSON. |
| 3518 | |
| 3519 | .. container:: paragraph |
| 3520 | |
| 3521 | Events are produced to Kafka. Produced event format is XML. |
| 3522 | |
| 3523 | .. container:: listingblock |
| 3524 | |
| 3525 | .. container:: content |
| 3526 | |
| 3527 | .. code:: |
| 3528 | |
| 3529 | { |
| 3530 | "engineServiceParameters" : { |
| 3531 | "name" : "MyApexEngine", |
| 3532 | "version" : "0.0.1", |
| 3533 | "id" : 45, |
| 3534 | "instanceCount" : 4, |
| 3535 | "deploymentPort" : 12345, |
| 3536 | "policyModelFileName" : "examples/models/some-model.json", |
| 3537 | "engineParameters" : { |
| 3538 | "executorParameters" : { |
| 3539 | "JAVASCRIPT" : { |
| 3540 | "parameterClassName" : |
| 3541 | "org.onap.policy.apex.plugins.executor.javascript.JavascriptExecutorParameters" |
| 3542 | }, |
| 3543 | "JYTHON" : { |
| 3544 | "parameterClassName" : |
| 3545 | "org.onap.policy.apex.plugins.executor.jython.JythonExecutorParameters" |
| 3546 | }, |
| 3547 | "JRUBY" : { |
| 3548 | "parameterClassName" : |
| 3549 | "org.onap.policy.apex.plugins.executor.jruby.JrubyExecutorParameters" |
| 3550 | }, |
| 3551 | "JAVA" : { |
| 3552 | "parameterClassName" : |
| 3553 | "org.onap.policy.apex.plugins.executor.java.JavaExecutorParameters" |
| 3554 | }, |
| 3555 | "MVEL" : { |
| 3556 | "parameterClassName" : |
| 3557 | "org.onap.policy.apex.plugins.executor.mvel.MVELExecutorParameters" |
| 3558 | } |
| 3559 | }, |
| 3560 | "contextParameters" : { |
| 3561 | "parameterClassName" : |
| 3562 | "org.onap.policy.apex.context.parameters.ContextParameters", |
| 3563 | "schemaParameters" : { |
| 3564 | "Avro":{ |
| 3565 | "parameterClassName" : |
| 3566 | "org.onap.policy.apex.plugins.context.schema.avro.AvroSchemaHelperParameters" |
| 3567 | } |
| 3568 | } |
| 3569 | } |
| 3570 | } |
| 3571 | }, |
| 3572 | "producerCarrierTechnologyParameters" : { |
| 3573 | "carrierTechnology" : "KAFKA", |
| 3574 | "parameterClassName" : |
| 3575 | "org.onap.policy.apex.plugins.event.carrier.kafka.KAFKACarrierTechnologyParameters", |
| 3576 | "parameters" : { |
| 3577 | "bootstrapServers" : "localhost:49092", |
| 3578 | "acks" : "all", |
| 3579 | "retries" : 0, |
| 3580 | "batchSize" : 16384, |
| 3581 | "lingerTime" : 1, |
| 3582 | "bufferMemory" : 33554432, |
| 3583 | "producerTopic" : "apex-out", |
| 3584 | "keySerializer" : "org.apache.kafka.common.serialization.StringSerializer", |
| 3585 | "valueSerializer" : "org.apache.kafka.common.serialization.StringSerializer" |
| 3586 | } |
| 3587 | }, |
| 3588 | "producerEventProtocolParameters" : { |
| 3589 | "eventProtocol" : "XML", |
| 3590 | "parameterClassName" : |
| 3591 | "org.onap.policy.apex.plugins.event.protocol.xml.XMLEventProtocolParameters" |
| 3592 | }, |
| 3593 | "consumerCarrierTechnologyParameters" : { |
| 3594 | "carrierTechnology" : "WEBSOCKET", |
| 3595 | "parameterClassName" : |
| 3596 | "org.onap.policy.apex.plugins.event.carrier.websocket.WEBSOCKETCarrierTechnologyParameters", |
| 3597 | "parameters" : { |
| 3598 | "host" : "localhost", |
| 3599 | "port" : 88888 |
| 3600 | } |
| 3601 | }, |
| 3602 | "consumerEventProtocolParameters" : { |
| 3603 | "eventProtocol" : "JSON" |
| 3604 | } |
| 3605 | } |
| 3606 | |
| 3607 | Engine and Applications of the APEX System |
| 3608 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 3609 | |
| 3610 | Introduction to APEX Engine and Applications |
| 3611 | -------------------------------------------- |
| 3612 | |
| 3613 | .. container:: paragraph |
| 3614 | |
| 3615 | The core of APEX is the APEX Engine, also known as the APEX |
| 3616 | Policy Engine or the APEX PDP (since it is in fact a Policy |
| 3617 | Decision Point). Beside this engine, an APEX system comes |
| 3618 | with a few applications intended to help with policy |
| 3619 | authoring, deployment, and execution. |
| 3620 | |
| 3621 | .. container:: paragraph |
| 3622 | |
| 3623 | The engine itself and most applications are started from the |
| 3624 | command line with command line arguments. This is called a |
| 3625 | Command Line Interface (CLI). Some applications require an |
| 3626 | installation on a webserver, as for instance the REST |
| 3627 | Editor. Those applications can be accessed via a web |
| 3628 | browser. |
| 3629 | |
| 3630 | .. container:: paragraph |
| 3631 | |
| 3632 | You can also use the available APEX APIs and applications to |
| 3633 | develop other applications as required. This includes policy |
| 3634 | languages (and associated parsers and compilers / |
| 3635 | interpreters), GUIs to access APEX or to define policies, |
| 3636 | clients to connect to APEX, etc. |
| 3637 | |
| 3638 | .. container:: paragraph |
| 3639 | |
| 3640 | For this documentation, we assume an installation of APEX as |
| 3641 | a full system based on a current ONAP release. |
| 3642 | |
| 3643 | CLI on Unix, Windows, and Cygwin |
| 3644 | -------------------------------- |
| 3645 | |
| 3646 | .. container:: paragraph |
| 3647 | |
| 3648 | A note on APEX CLI applications: all applications and the |
| 3649 | engine itself have been deployed and tested on different |
| 3650 | operating systems: Red Hat, Ubuntu, Debian, Mac OSX, |
| 3651 | Windows, Cygwin. Each operating system comes with its own |
| 3652 | way of configuring and executing Java. The main items here |
| 3653 | are: |
| 3654 | |
| 3655 | .. container:: ulist |
| 3656 | |
| 3657 | - For UNIX systems (RHL, Ubuntu, Debian, Mac OSX), the |
| 3658 | provided bash scripts work as expected with absolute |
| 3659 | paths (e.g. |
| 3660 | ``/opt/app/policy/apex-pdp/apex-pdp-2.0.0-SNAPSHOT/examples``), |
| 3661 | indirect and linked paths (e.g. ``../apex/apex``), and |
| 3662 | path substitutions using environment settings (e.g. |
| 3663 | ``$APEX_HOME/bin/``) |
| 3664 | |
| 3665 | - For Windows systems, the provided batch files (``.bat``) |
| 3666 | work as expected with with absolute paths (e.g. |
| 3667 | ``C:\apex\apex-2.0.0-SNAPSHOT\examples``), and path |
| 3668 | substitutions using environment settings (e.g. |
| 3669 | ``%APEX_HOME%\bin\``) |
| 3670 | |
| 3671 | - For Cygwin system we assume a standard Cygwin |
| 3672 | installation with standard tools (mainly bash) using a |
| 3673 | Windows Java installation. This means that the bash |
| 3674 | scripts can be used as in UNIX, however any argument |
| 3675 | pointing to files and directories need to use either a |
| 3676 | DOS path (e.g. |
| 3677 | ``C:\apex\apex-2.0.0-SNAPSHOT\examples\config...``) or |
| 3678 | the command ``cygpath`` with a mixed option. The reason |
| 3679 | for that is: Cygwin executes Java using UNIX paths but |
| 3680 | then runs Java as a DOS/WINDOWS process, which requires |
| 3681 | DOS paths for file access. |
| 3682 | |
| 3683 | The APEX Engine |
| 3684 | --------------- |
| 3685 | |
| 3686 | .. container:: paragraph |
| 3687 | |
| 3688 | The APEX engine can be started in different ways, depending |
| 3689 | your requirements. All scripts are located in the APEX *bin* |
| 3690 | directory |
| 3691 | |
| 3692 | .. container:: paragraph |
| 3693 | |
| 3694 | On UNIX and Cygwin systems use: |
| 3695 | |
| 3696 | .. container:: ulist |
| 3697 | |
| 3698 | - ``apexEngine.sh`` - this script will |
| 3699 | |
| 3700 | .. container:: ulist |
| 3701 | |
| 3702 | - Test if ``$APEX_USER`` is set and if the user |
| 3703 | exists, terminate with an error otherwise |
| 3704 | |
| 3705 | - Test if ``$APEX_HOME`` is set. If not set, it will |
| 3706 | use the default setting as |
| 3707 | ``/opt/app/policy/apex-pdp/apex-pdp``. Then the set |
| 3708 | directory is tested to exist, the script will |
| 3709 | terminate if not. |
| 3710 | |
| 3711 | - When all tests are passed successfully, the script |
| 3712 | will call ``apexApps.sh`` with arguments to start |
| 3713 | the APEX engine. |
| 3714 | |
| 3715 | - ``apexApps.sh engine`` - this is the general APEX |
| 3716 | application launcher, which will |
| 3717 | |
| 3718 | .. container:: ulist |
| 3719 | |
| 3720 | - Start the engine with the argument ``engine`` |
| 3721 | |
| 3722 | - Test if ``$APEX_HOME`` is set and points to an |
| 3723 | existing directory. If not set or directory does |
| 3724 | not exist, script terminates. |
| 3725 | |
| 3726 | - Not test for any settings of ``$APEX_USER``. |
| 3727 | |
| 3728 | .. container:: paragraph |
| 3729 | |
| 3730 | On Windows systems use ``apexEngine.bat`` and |
| 3731 | ``apexApps.bat engine`` respectively. Note: none of the |
| 3732 | windows batch files will test for ``%APEX_USER%``. |
| 3733 | |
| 3734 | .. container:: paragraph |
| 3735 | |
| 3736 | Summary of alternatives to start the APEX Engine: |
| 3737 | |
| 3738 | +--------------------------------------------------------+----------------------------------------------------------+ |
| 3739 | | Unix, Cygwin | Windows | |
| 3740 | +========================================================+==========================================================+ |
| 3741 | | .. container:: | .. container:: | |
| 3742 | | | | |
| 3743 | | .. container:: listingblock | .. container:: listingblock | |
| 3744 | | | | |
| 3745 | | .. container:: content | .. container:: content | |
| 3746 | | | | |
| 3747 | | .. code:: | .. code:: | |
| 3748 | | | | |
| 3749 | | # $APEX_HOME/bin/apexEngine.sh [args] | > %APEX_HOME%\bin\apexEngine.bat [args] | |
| 3750 | | # $APEX_HOME/bin/apexApps.sh engine [args] | > %APEX_HOME%\bin\apexApps.bat engine [args] | |
| 3751 | +--------------------------------------------------------+----------------------------------------------------------+ |
| 3752 | |
| 3753 | .. container:: paragraph |
| 3754 | |
| 3755 | The APEX engine comes with a few CLI arguments for setting |
| 3756 | configuration and policy model. The configuration file is |
| 3757 | always required. The policy model file is only required if |
| 3758 | no model file is specified in the configuration, or if the |
| 3759 | specified model file should be over written. The option |
| 3760 | ``-h`` prints a help screen. |
| 3761 | |
| 3762 | .. container:: listingblock |
| 3763 | |
| 3764 | .. container:: content |
| 3765 | |
| 3766 | .. code:: |
| 3767 | |
| 3768 | usage: org.onap.policy.apex.service.engine.main.ApexMain [options...] |
| 3769 | options |
| 3770 | -c,--config-file <CONFIG_FILE> the full path to the configuration file to use, the configuration file must be a Json file |
| 3771 | containing the Apex configuration parameters |
| 3772 | -h,--help outputs the usage of this command |
| 3773 | -m,--model-file <MODEL_FILE> the full path to the model file to use, if set it overrides the model file set in the |
| 3774 | configuration file |
| 3775 | -v,--version outputs the version of Apex |
| 3776 | |
| 3777 | The APEX CLI Editor |
| 3778 | ------------------- |
| 3779 | |
| 3780 | .. container:: paragraph |
| 3781 | |
| 3782 | The CLI Editor allows to define policies from the command |
| 3783 | line. The application uses a simple language and supports |
| 3784 | all elements of an APEX policy. It can be used in to |
| 3785 | different ways: |
| 3786 | |
| 3787 | .. container:: ulist |
| 3788 | |
| 3789 | - non-interactive, specifying a file with the commands to |
| 3790 | create a policy |
| 3791 | |
| 3792 | - interactive, using the editors CLI to create a policy |
| 3793 | |
| 3794 | .. container:: paragraph |
| 3795 | |
| 3796 | When a policy is fully specified, the editor will generate |
| 3797 | the APEX core policy specification in JSON. This core |
| 3798 | specification is called the policy model in the APEX engine |
| 3799 | and can be used directly with the APEX engine. |
| 3800 | |
| 3801 | .. container:: paragraph |
| 3802 | |
| 3803 | On UNIX and Cygwin systems use: |
| 3804 | |
| 3805 | .. container:: ulist |
| 3806 | |
| 3807 | - ``apexCLIEditor.sh`` - simply starts the CLI editor, |
| 3808 | arguments to the script determine the mode of the editor |
| 3809 | |
| 3810 | - ``apexApps.sh cli-editor`` - simply starts the CLI |
| 3811 | editor, arguments to the script determine the mode of the |
| 3812 | editor |
| 3813 | |
| 3814 | .. container:: paragraph |
| 3815 | |
| 3816 | On Windows systems use: |
| 3817 | |
| 3818 | .. container:: ulist |
| 3819 | |
| 3820 | - ``apexCLIEditor.bat`` - simply starts the CLI editor, |
| 3821 | arguments to the script determine the mode of the editor |
| 3822 | |
| 3823 | - ``apexApps.bat cli-editor`` - simply starts the CLI |
| 3824 | editor, arguments to the script determine the mode of the |
| 3825 | editor |
| 3826 | |
| 3827 | .. container:: paragraph |
| 3828 | |
| 3829 | Summary of alternatives to start the APEX CLI Editor: |
| 3830 | |
| 3831 | +------------------------------------------------------------+--------------------------------------------------------------+ |
| 3832 | | Unix, Cygwin | Windows | |
| 3833 | +============================================================+==============================================================+ |
| 3834 | | .. container:: | .. container:: | |
| 3835 | | | | |
| 3836 | | .. container:: listingblock | .. container:: listingblock | |
| 3837 | | | | |
| 3838 | | .. container:: content | .. container:: content | |
| 3839 | | | | |
| 3840 | | .. code:: | .. code:: | |
| 3841 | | | | |
| 3842 | | # $APEX_HOME/bin/apexCLIEditor.sh.sh [args] | > %APEX_HOME%\bin\apexCLIEditor.bat [args] | |
| 3843 | | # $APEX_HOME/bin/apexApps.sh cli-editor [args] | > %APEX_HOME%\bin\apexApps.bat cli-editor [args] | |
| 3844 | +------------------------------------------------------------+--------------------------------------------------------------+ |
| 3845 | |
| 3846 | .. container:: paragraph |
| 3847 | |
| 3848 | The option ``-h`` provides a help screen with all command |
| 3849 | line arguments. |
| 3850 | |
| 3851 | .. container:: listingblock |
| 3852 | |
| 3853 | .. container:: content |
| 3854 | |
| 3855 | .. code:: |
| 3856 | |
| 3857 | usage: org.onap.policy.apex.auth.clieditor.ApexCLIEditorMain [options...] |
| 3858 | options |
| 3859 | -a,--model-props-file <MODEL_PROPS_FILE> name of the apex model properties file to use |
| 3860 | -c,--command-file <COMMAND_FILE> name of a file containing editor commands to run into the editor |
| 3861 | -h,--help outputs the usage of this command |
| 3862 | -i,--input-model-file <INPUT_MODEL_FILE> name of a file that contains an input model for the editor |
| 3863 | -if,--ignore-failures <IGNORE_FAILURES_FLAG> true or false, ignore failures of commands in command files and continue |
| 3864 | executing the command file |
| 3865 | -l,--log-file <LOG_FILE> name of a file that will contain command logs from the editor, will log |
| 3866 | to standard output if not specified or suppressed with "-nl" flag |
| 3867 | -m,--metadata-file <CMD_METADATA_FILE> name of the command metadata file to use |
| 3868 | -nl,--no-log if specified, no logging or output of commands to standard output or log |
| 3869 | file is carried out |
| 3870 | -nm,--no-model-output if specified, no output of a model to standard output or model output |
| 3871 | file is carried out, the user can use the "save" command in a script to |
| 3872 | save a model |
| 3873 | -o,--output-model-file <OUTPUT_MODEL_FILE> name of a file that will contain the output model for the editor, will |
| 3874 | output model to standard output if not specified or suppressed with |
| 3875 | "-nm" flag |
| 3876 | -wd,--working-directory <WORKING_DIRECTORY> the working directory that is the root for the CLI editor and is the |
| 3877 | root from which to look for included macro files |
| 3878 | |
| 3879 | The APEX REST Editor |
| 3880 | -------------------- |
| 3881 | |
| 3882 | .. container:: paragraph |
| 3883 | |
| 3884 | The standard way to use the APEX REST Editor is via an |
| 3885 | installation of the *war* file on a webserver. However, the |
| 3886 | REST editor can also be started via command line. This will |
| 3887 | start a Grizzly webserver with the *war* deployed. Access to |
| 3888 | the REST Editor is then via the provided URL |
| 3889 | |
| 3890 | .. container:: paragraph |
| 3891 | |
| 3892 | On UNIX and Cygwin systems use: |
| 3893 | |
| 3894 | .. container:: ulist |
| 3895 | |
| 3896 | - ``apexRESTEditor.sh`` - simply starts the webserver with |
| 3897 | the REST editor |
| 3898 | |
| 3899 | - ``apexApps.sh rest-editor`` - simply starts the webserver |
| 3900 | with the REST editor |
| 3901 | |
| 3902 | .. container:: paragraph |
| 3903 | |
| 3904 | On Windows systems use: |
| 3905 | |
| 3906 | .. container:: ulist |
| 3907 | |
| 3908 | - ``apexRESTEditor.bat`` - simply starts the webserver with |
| 3909 | the REST editor |
| 3910 | |
| 3911 | - ``apexApps.bat rest-editor`` - simply starts the |
| 3912 | webserver with the REST editor |
| 3913 | |
| 3914 | .. container:: paragraph |
| 3915 | |
| 3916 | Summary of alternatives to start the APEX REST Editor: |
| 3917 | |
| 3918 | +-------------------------------------------------------------+---------------------------------------------------------------+ |
| 3919 | | Unix, Cygwin | Windows | |
| 3920 | +=============================================================+===============================================================+ |
| 3921 | | .. container:: | .. container:: | |
| 3922 | | | | |
| 3923 | | .. container:: listingblock | .. container:: listingblock | |
| 3924 | | | | |
| 3925 | | .. container:: content | .. container:: content | |
| 3926 | | | | |
| 3927 | | .. code:: | .. code:: | |
| 3928 | | | | |
| 3929 | | # $APEX_HOME/bin/apexRESTEditor.sh.sh [args] | > %APEX_HOME%\bin\apexRESTEditor.bat [args] | |
| 3930 | | # $APEX_HOME/bin/apexApps.sh rest-editor [args] | > %APEX_HOME%\bin\apexApps.bat rest-editor [args] | |
| 3931 | +-------------------------------------------------------------+---------------------------------------------------------------+ |
| 3932 | |
| 3933 | .. container:: paragraph |
| 3934 | |
| 3935 | The option ``-h`` provides a help screen with all command |
| 3936 | line arguments. |
| 3937 | |
| 3938 | .. container:: listingblock |
| 3939 | |
| 3940 | .. container:: content |
| 3941 | |
| 3942 | .. code:: |
| 3943 | |
| 3944 | usage: org.onap.policy.apex.client.editor.rest.ApexEditorMain [options...] |
| 3945 | -h,--help outputs the usage of this command |
| 3946 | -l,--listen <ADDRESS> the IP address to listen on. Default value is localhost to restrict access to the |
| 3947 | local machine only. |
| 3948 | -p,--port <PORT> port to use for the Apex RESTful editor REST calls. |
| 3949 | -t,--time-to-live <TIME_TO_LIVE> the amount of time in seconds that the server will run for before terminating. Default |
| 3950 | value is -1 to run indefinitely. |
| 3951 | |
| 3952 | .. container:: paragraph |
| 3953 | |
| 3954 | If the REST Editor is started without any arguments the |
| 3955 | final messages will look similar to this: |
| 3956 | |
| 3957 | .. container:: listingblock |
| 3958 | |
| 3959 | .. container:: content |
| 3960 | |
| 3961 | .. code:: |
| 3962 | |
| 3963 | Apex Editor REST endpoint (ApexEditorMain: Config=[ApexEditorParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=READY) starting at http://localhost:18989/apexservices/ . . . |
| 3964 | Sep 05, 2018 11:24:30 PM org.glassfish.grizzly.http.server.NetworkListener start |
| 3965 | INFO: Started listener bound to [localhost:18989] |
| 3966 | Sep 05, 2018 11:24:30 PM org.glassfish.grizzly.http.server.HttpServer start |
| 3967 | INFO: [HttpServer] Started. |
| 3968 | Apex Editor REST endpoint (ApexEditorMain: Config=[ApexEditorParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=RUNNING) started at http://localhost:18989/apexservices/ |
| 3969 | |
| 3970 | .. container:: paragraph |
| 3971 | |
| 3972 | The last line states the URL on which the REST Editor can be |
| 3973 | accessed. The example above stated |
| 3974 | ``http://0.0.0.0:18989/apex/``. In a web browser use the URL |
| 3975 | ``http://localhost:18989`` and the REST Editor will start. |
| 3976 | |
| 3977 | The APEX Monitoring Client |
| 3978 | -------------------------- |
| 3979 | |
| 3980 | .. container:: paragraph |
| 3981 | |
| 3982 | The standard way to use the APEX Monitoring Client is via an |
| 3983 | installation of the *war* file on a webserver. However, the |
| 3984 | Monitoring Client can also be started via command line. This |
| 3985 | will start a Grizzly webserver with the *war* deployed. |
| 3986 | Access to the Monitoring Client is then via the provided URL |
| 3987 | |
| 3988 | .. container:: paragraph |
| 3989 | |
| 3990 | On UNIX and Cygwin systems use: |
| 3991 | |
| 3992 | .. container:: ulist |
| 3993 | |
| 3994 | - ``apexApps.sh eng-monitoring`` - simply starts the |
| 3995 | webserver with the Monitoring Client |
| 3996 | |
| 3997 | .. container:: paragraph |
| 3998 | |
| 3999 | On Windows systems use: |
| 4000 | |
| 4001 | .. container:: ulist |
| 4002 | |
| 4003 | - ``apexApps.bat eng-monitoring`` - simply starts the |
| 4004 | webserver with the Monitoring Client |
| 4005 | |
| 4006 | .. container:: paragraph |
| 4007 | |
| 4008 | The option ``-h`` provides a help screen with all command |
| 4009 | line arguments. |
| 4010 | |
| 4011 | .. container:: listingblock |
| 4012 | |
| 4013 | .. container:: content |
| 4014 | |
| 4015 | .. code:: |
| 4016 | |
| 4017 | usage: org.onap.policy.apex.client.monitoring.rest.ApexMonitoringRestMain [options...] |
| 4018 | -h,--help outputs the usage of this command |
| 4019 | -p,--port <PORT> port to use for the Apex Services REST calls |
| 4020 | -t,--time-to-live <TIME_TO_LIVE> the amount of time in seconds that the server will run for before terminating |
| 4021 | |
| 4022 | .. container:: paragraph |
| 4023 | |
| 4024 | If the Monitoring Client is started without any arguments |
| 4025 | the final messages will look similar to this: |
| 4026 | |
| 4027 | .. container:: listingblock |
| 4028 | |
| 4029 | .. container:: content |
| 4030 | |
| 4031 | .. code:: |
| 4032 | |
| 4033 | Apex Services REST endpoint (ApexMonitoringRestMain: Config=[ApexMonitoringRestParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=READY) starting at http://localhost:18989/apexservices/ . . . |
| 4034 | Sep 05, 2018 11:26:20 PM org.glassfish.grizzly.http.server.NetworkListener start |
| 4035 | INFO: Started listener bound to [localhost:18989] |
| 4036 | Sep 05, 2018 11:26:20 PM org.glassfish.grizzly.http.server.HttpServer start |
| 4037 | INFO: [HttpServer] Started. |
| 4038 | Apex Services REST endpoint (ApexMonitoringRestMain: Config=[ApexMonitoringRestParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=RUNNING) started at http://localhost:18989/apexservices/ |
| 4039 | |
| 4040 | .. container:: paragraph |
| 4041 | |
| 4042 | The last line states the URL on which the Monitoring Client |
| 4043 | can be accessed. The example above stated |
| 4044 | ``http://localhost:18989/apexservices``. In a web browser |
| 4045 | use the URL ``http://localhost:18989``. |
| 4046 | |
| 4047 | The APEX Deployment Client |
| 4048 | -------------------------- |
| 4049 | |
| 4050 | .. container:: paragraph |
| 4051 | |
| 4052 | The standard way to use the APEX Deployment Client is via an |
| 4053 | installation of the *war* file on a webserver. However, the |
| 4054 | Deployment Client can also be started via command line. This |
| 4055 | will start a Grizzly webserver with the *war* deployed. |
| 4056 | Access to the Deployment Client is then via the provided URL |
| 4057 | |
| 4058 | .. container:: paragraph |
| 4059 | |
| 4060 | On UNIX and Cygwin systems use: |
| 4061 | |
| 4062 | .. container:: ulist |
| 4063 | |
| 4064 | - ``apexApps.sh eng-deployment`` - simply starts the |
| 4065 | webserver with the Deployment Client |
| 4066 | |
| 4067 | .. container:: paragraph |
| 4068 | |
| 4069 | On Windows systems use: |
| 4070 | |
| 4071 | .. container:: ulist |
| 4072 | |
| 4073 | - ``apexApps.bat eng-deployment`` - simply starts the |
| 4074 | webserver with the Deployment Client |
| 4075 | |
| 4076 | .. container:: paragraph |
| 4077 | |
| 4078 | The option ``-h`` provides a help screen with all command |
| 4079 | line arguments. |
| 4080 | |
| 4081 | .. container:: listingblock |
| 4082 | |
| 4083 | .. container:: content |
| 4084 | |
| 4085 | .. code:: |
| 4086 | |
| 4087 | usage: org.onap.policy.apex.client.deployment.rest.ApexDeploymentRestMain [options...] |
| 4088 | -h,--help outputs the usage of this command |
| 4089 | -p,--port <PORT> port to use for the Apex Services REST calls |
| 4090 | -t,--time-to-live <TIME_TO_LIVE> the amount of time in seconds that the server will run for before terminating |
| 4091 | |
| 4092 | .. container:: paragraph |
| 4093 | |
| 4094 | If the Deployment Client is started without any arguments |
| 4095 | the final messages will look similar to this: |
| 4096 | |
| 4097 | .. container:: listingblock |
| 4098 | |
| 4099 | .. container:: content |
| 4100 | |
| 4101 | .. code:: |
| 4102 | |
| 4103 | Apex Services REST endpoint (ApexDeploymentRestMain: Config=[ApexDeploymentRestParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=READY) starting at http://localhost:18989/apexservices/ . . . |
| 4104 | Sep 05, 2018 11:27:09 PM org.glassfish.grizzly.http.server.NetworkListener start |
| 4105 | INFO: Started listener bound to [localhost:18989] |
| 4106 | Sep 05, 2018 11:27:09 PM org.glassfish.grizzly.http.server.HttpServer start |
| 4107 | INFO: [HttpServer] Started. |
| 4108 | Apex Services REST endpoint (ApexDeploymentRestMain: Config=[ApexDeploymentRestParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=RUNNING) started at http://localhost:18989/apexservices/ |
| 4109 | |
| 4110 | .. container:: paragraph |
| 4111 | |
| 4112 | The last line states the URL on which the Deployment Client |
| 4113 | can be accessed. The example above stated |
| 4114 | ``http://localhost:18989/apexservices``. In a web browser |
| 4115 | use the URL ``http://localhost:18989``. |
| 4116 | |
| 4117 | The APEX Full Client |
| 4118 | -------------------- |
| 4119 | |
| 4120 | .. container:: paragraph |
| 4121 | |
| 4122 | The APEX Full Client combines the REST Editor, the |
| 4123 | Monitoring Client, and the Deployment Client into a single |
| 4124 | application. The standard way to use the APEX Full Client is |
| 4125 | via an installation of the *war* file on a webserver. |
| 4126 | However, the Full Client can also be started via command |
| 4127 | line. This will start a Grizzly webserver with the *war* |
| 4128 | deployed. Access to the Full Client is then via the provided |
| 4129 | URL |
| 4130 | |
| 4131 | .. container:: paragraph |
| 4132 | |
| 4133 | On UNIX and Cygwin systems use: |
| 4134 | |
| 4135 | .. container:: ulist |
| 4136 | |
| 4137 | - ``apexApps.sh full-client`` - simply starts the webserver |
| 4138 | with the Full Client |
| 4139 | |
| 4140 | .. container:: paragraph |
| 4141 | |
| 4142 | On Windows systems use: |
| 4143 | |
| 4144 | .. container:: ulist |
| 4145 | |
| 4146 | - ``apexApps.bat full-client`` - simply starts the |
| 4147 | webserver with the Full Client |
| 4148 | |
| 4149 | .. container:: paragraph |
| 4150 | |
| 4151 | The option ``-h`` provides a help screen with all command |
| 4152 | line arguments. |
| 4153 | |
| 4154 | .. container:: listingblock |
| 4155 | |
| 4156 | .. container:: content |
| 4157 | |
| 4158 | .. code:: |
| 4159 | |
| 4160 | usage: org.onap.policy.apex.client.full.rest.ApexServicesRestMain [options...] |
| 4161 | -h,--help outputs the usage of this command |
| 4162 | -p,--port <PORT> port to use for the Apex Services REST calls |
| 4163 | -t,--time-to-live <TIME_TO_LIVE> the amount of time in seconds that the server will run for before terminating |
| 4164 | |
| 4165 | .. container:: paragraph |
| 4166 | |
| 4167 | If the Full Client is started without any arguments the |
| 4168 | final messages will look similar to this: |
| 4169 | |
| 4170 | .. container:: listingblock |
| 4171 | |
| 4172 | .. container:: content |
| 4173 | |
| 4174 | .. code:: |
| 4175 | |
| 4176 | Apex Editor REST endpoint (ApexServicesRestMain: Config=[ApexServicesRestParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=READY) starting at http://localhost:18989/apexservices/ . . . |
| 4177 | Sep 05, 2018 11:28:28 PM org.glassfish.grizzly.http.server.NetworkListener start |
| 4178 | INFO: Started listener bound to [localhost:18989] |
| 4179 | Sep 05, 2018 11:28:28 PM org.glassfish.grizzly.http.server.HttpServer start |
| 4180 | INFO: [HttpServer] Started. |
| 4181 | Apex Editor REST endpoint (ApexServicesRestMain: Config=[ApexServicesRestParameters: URI=http://localhost:18989/apexservices/, TTL=-1sec], State=RUNNING) started at http://localhost:18989/apexservices/ |
| 4182 | |
| 4183 | .. container:: paragraph |
| 4184 | |
| 4185 | The last line states the URL on which the Monitoring Client |
| 4186 | can be accessed. The example above stated |
| 4187 | ``http://localhost:18989/apexservices``. In a web browser |
| 4188 | use the URL ``http://localhost:18989``. |
| 4189 | |
| 4190 | The APEX Application Launcher |
| 4191 | ------------------------------ |
| 4192 | |
| 4193 | .. container:: paragraph |
| 4194 | |
| 4195 | The standard applications (Engine, CLI Editor, REST Editor) |
| 4196 | come with dedicated start scripts. For all other APEX |
| 4197 | applications, we provide an application launcher. |
| 4198 | |
| 4199 | .. container:: paragraph |
| 4200 | |
| 4201 | On UNIX and Cygwin systems use: |
| 4202 | |
| 4203 | .. container:: ulist |
| 4204 | |
| 4205 | - apexApps.sh\` - simply starts the application launcher |
| 4206 | |
| 4207 | .. container:: paragraph |
| 4208 | |
| 4209 | On Windows systems use: |
| 4210 | |
| 4211 | .. container:: ulist |
| 4212 | |
| 4213 | - ``apexApps.bat`` - simply starts the application launcher |
| 4214 | |
| 4215 | .. container:: paragraph |
| 4216 | |
| 4217 | Summary of alternatives to start the APEX application |
| 4218 | launcher: |
| 4219 | |
| 4220 | +-------------------------------------------------+---------------------------------------------------+ |
| 4221 | | Unix, Cygwin | Windows | |
| 4222 | +=================================================+===================================================+ |
| 4223 | | .. container:: | .. container:: | |
| 4224 | | | | |
| 4225 | | .. container:: listingblock | .. container:: listingblock | |
| 4226 | | | | |
| 4227 | | .. container:: content | .. container:: content | |
| 4228 | | | | |
| 4229 | | .. code:: | .. code:: | |
| 4230 | | | | |
| 4231 | | # $APEX_HOME/bin/apexApps.sh [args] | > %APEX_HOME%\bin\apexApps.bat [args] | |
| 4232 | +-------------------------------------------------+---------------------------------------------------+ |
| 4233 | |
| 4234 | .. container:: paragraph |
| 4235 | |
| 4236 | The option ``-h`` provides a help screen with all launcher |
| 4237 | command line arguments. |
| 4238 | |
| 4239 | .. container:: listingblock |
| 4240 | |
| 4241 | .. container:: content |
| 4242 | |
| 4243 | .. code:: |
| 4244 | |
| 4245 | apexApps.sh - runs APEX applications |
| 4246 | |
| 4247 | Usage: apexApps.sh [options] | [<application> [<application options>]] |
| 4248 | |
| 4249 | Options |
| 4250 | -d <app> - describes an application |
| 4251 | -l - lists all applications supported by this script |
| 4252 | -h - this help screen |
| 4253 | |
| 4254 | .. container:: paragraph |
| 4255 | |
| 4256 | Using ``-l`` lists all known application the launcher can |
| 4257 | start. |
| 4258 | |
| 4259 | .. container:: listingblock |
| 4260 | |
| 4261 | .. container:: content |
| 4262 | |
| 4263 | .. code:: |
| 4264 | |
| 4265 | apexApps.sh: supported applications: |
| 4266 | --> ws-echo engine eng-monitoring full-client eng-deployment tpl-event-json model-2-cli rest-editor cli-editor ws-console |
| 4267 | |
| 4268 | .. container:: paragraph |
| 4269 | |
| 4270 | Using the ``-d <name>`` option describes the named |
| 4271 | application, for instance for the ``ws-console``: |
| 4272 | |
| 4273 | .. container:: listingblock |
| 4274 | |
| 4275 | .. container:: content |
| 4276 | |
| 4277 | .. code:: |
| 4278 | |
| 4279 | apexApps.sh: application 'ws-console' |
| 4280 | --> a simple console sending events to APEX, connect to APEX consumer port |
| 4281 | |
| 4282 | .. container:: paragraph |
| 4283 | |
| 4284 | Launching an application is done by calling the script with |
| 4285 | only the application name and any CLI arguments for the |
| 4286 | application. For instance, starting the ``ws-echo`` |
| 4287 | application with port ``8888``: |
| 4288 | |
| 4289 | .. container:: listingblock |
| 4290 | |
| 4291 | .. container:: content |
| 4292 | |
| 4293 | .. code:: |
| 4294 | |
| 4295 | apexApps.sh ws-echo -p 8888 |
| 4296 | |
| 4297 | Application: Create Event Templates |
| 4298 | ----------------------------------- |
| 4299 | |
| 4300 | .. container:: paragraph |
| 4301 | |
| 4302 | **Status: Experimental** |
| 4303 | |
| 4304 | .. container:: paragraph |
| 4305 | |
| 4306 | This application takes a policy model (JSON or XML encoded) |
| 4307 | and generates templates for events in JSON format. This can |
| 4308 | help when a policy defines rather complex trigger or action |
| 4309 | events or complex events between states. The application can |
| 4310 | produce events for the types: stimuli (policy trigger |
| 4311 | events), internal (events between policy states), and |
| 4312 | response (action events). |
| 4313 | |
| 4314 | +----------------------------------------------------------------+------------------------------------------------------------------+ |
| 4315 | | Unix, Cygwin | Windows | |
| 4316 | +================================================================+==================================================================+ |
| 4317 | | .. container:: | .. container:: | |
| 4318 | | | | |
| 4319 | | .. container:: listingblock | .. container:: listingblock | |
| 4320 | | | | |
| 4321 | | .. container:: content | .. container:: content | |
| 4322 | | | | |
| 4323 | | .. code:: | .. code:: | |
| 4324 | | | | |
| 4325 | | # $APEX_HOME/bin/apexApps.sh tpl-event-json [args] | > %APEX_HOME%\bin\apexApps.bat tpl-event-json [args] | |
| 4326 | +----------------------------------------------------------------+------------------------------------------------------------------+ |
| 4327 | |
| 4328 | .. container:: paragraph |
| 4329 | |
| 4330 | The option ``-h`` provides a help screen. |
| 4331 | |
| 4332 | .. container:: listingblock |
| 4333 | |
| 4334 | .. container:: content |
| 4335 | |
| 4336 | .. code:: |
| 4337 | |
| 4338 | gen-model2event v{release-version} - generates JSON templates for events generated from a policy model |
| 4339 | usage: gen-model2event |
| 4340 | -h,--help prints this help and usage screen |
| 4341 | -m,--model <MODEL-FILE> set the input policy model file |
| 4342 | -t,--type <TYPE> set the event type for generation, one of: |
| 4343 | stimuli (trigger events), response (action |
| 4344 | events), internal (events between states) |
| 4345 | -v,--version prints the application version |
| 4346 | |
| 4347 | .. container:: paragraph |
| 4348 | |
| 4349 | The created templates are not valid events, instead they use |
| 4350 | some markup for values one will need to change to actual |
| 4351 | values. For instance, running the tool with the *Sample |
| 4352 | Domain* policy model as: |
| 4353 | |
| 4354 | .. container:: listingblock |
| 4355 | |
| 4356 | .. container:: content |
| 4357 | |
| 4358 | .. code:: |
| 4359 | |
| 4360 | apexApps.sh tpl-event-json -m $APEX_HOME/examples/models/SampleDomain/SamplePolicyModelJAVA.json -t stimuli |
| 4361 | |
| 4362 | .. container:: paragraph |
| 4363 | |
| 4364 | will produce the following status messages: |
| 4365 | |
| 4366 | .. container:: listingblock |
| 4367 | |
| 4368 | .. container:: content |
| 4369 | |
| 4370 | .. code:: |
| 4371 | |
| 4372 | gen-model2event: starting Event generator |
| 4373 | --> model file: examples/models/SampleDomain/SamplePolicyModelJAVA.json |
| 4374 | --> type: stimuli |
| 4375 | |
| 4376 | .. container:: paragraph |
| 4377 | |
| 4378 | and then run the generator application producing two event |
| 4379 | templates. The first template is called ``Event0000``. |
| 4380 | |
| 4381 | .. container:: listingblock |
| 4382 | |
| 4383 | .. container:: content |
| 4384 | |
| 4385 | .. code:: |
| 4386 | |
| 4387 | { |
| 4388 | "name" : "Event0000", |
| 4389 | "nameSpace" : "org.onap.policy.apex.sample.events", |
| 4390 | "version" : "0.0.1", |
| 4391 | "source" : "Outside", |
| 4392 | "target" : "Match", |
| 4393 | "TestTemperature" : ###double: 0.0###, |
| 4394 | "TestTimestamp" : ###long: 0###, |
| 4395 | "TestMatchCase" : ###integer: 0###, |
| 4396 | "TestSlogan" : "###string###" |
| 4397 | } |
| 4398 | |
| 4399 | .. container:: paragraph |
| 4400 | |
| 4401 | The values for the keys are marked with ``#`` and the |
| 4402 | expected type of the value. To create an actual stimuli |
| 4403 | event, all these markers need to be change to actual values, |
| 4404 | for instance: |
| 4405 | |
| 4406 | .. container:: listingblock |
| 4407 | |
| 4408 | .. container:: content |
| 4409 | |
| 4410 | .. code:: |
| 4411 | |
| 4412 | { |
| 4413 | "name" : "Event0000", |
| 4414 | "nameSpace" : "org.onap.policy.apex.sample.events", |
| 4415 | "version" : "0.0.1", |
| 4416 | "source" : "Outside", |
| 4417 | "target" : "Match", |
| 4418 | "TestTemperature" : 25, |
| 4419 | "TestTimestamp" : 123456789123456789, |
| 4420 | "TestMatchCase" : 1, |
| 4421 | "TestSlogan" : "Testing the Match Case with Temperature 25" |
| 4422 | } |
| 4423 | |
| 4424 | Application: Convert a Policy Model to CLI Editor Commands |
| 4425 | ---------------------------------------------------------- |
| 4426 | |
| 4427 | .. container:: paragraph |
| 4428 | |
| 4429 | **Status: Experimental** |
| 4430 | |
| 4431 | .. container:: paragraph |
| 4432 | |
| 4433 | This application takes a policy model (JSON or XML encoded) |
| 4434 | and generates commands for the APEX CLI Editor. This |
| 4435 | effectively reverses a policy specification realized with |
| 4436 | the CLI Editor. |
| 4437 | |
| 4438 | +-------------------------------------------------------------+---------------------------------------------------------------+ |
| 4439 | | Unix, Cygwin | Windows | |
| 4440 | +=============================================================+===============================================================+ |
| 4441 | | .. container:: | .. container:: | |
| 4442 | | | | |
| 4443 | | .. container:: listingblock | .. container:: listingblock | |
| 4444 | | | | |
| 4445 | | .. container:: content | .. container:: content | |
| 4446 | | | | |
| 4447 | | .. code:: | .. code:: | |
| 4448 | | | | |
| 4449 | | # $APEX_HOME/bin/apexApps.sh model-2-cli [args] | > %APEX_HOME%\bin\apexApps.bat model-2-cli [args] | |
| 4450 | +-------------------------------------------------------------+---------------------------------------------------------------+ |
| 4451 | |
| 4452 | .. container:: paragraph |
| 4453 | |
| 4454 | The option ``-h`` provides a help screen. |
| 4455 | |
| 4456 | .. container:: listingblock |
| 4457 | |
| 4458 | .. container:: content |
| 4459 | |
| 4460 | .. code:: |
| 4461 | |
| 4462 | usage: gen-model2cli |
| 4463 | -h,--help prints this help and usage screen |
| 4464 | -m,--model <MODEL-FILE> set the input policy model file |
| 4465 | -sv,--skip-validation switch of validation of the input file |
| 4466 | -v,--version prints the application version |
| 4467 | |
| 4468 | .. container:: paragraph |
| 4469 | |
| 4470 | For instance, running the tool with the *Sample Domain* |
| 4471 | policy model as: |
| 4472 | |
| 4473 | .. container:: listingblock |
| 4474 | |
| 4475 | .. container:: content |
| 4476 | |
| 4477 | .. code:: |
| 4478 | |
| 4479 | apexApps.sh model-2-cli -m $APEX_HOME/examples/models/SampleDomain/SamplePolicyModelJAVA.json |
| 4480 | |
| 4481 | .. container:: paragraph |
| 4482 | |
| 4483 | will produce the following status messages: |
| 4484 | |
| 4485 | .. container:: listingblock |
| 4486 | |
| 4487 | .. container:: content |
| 4488 | |
| 4489 | .. code:: |
| 4490 | |
| 4491 | gen-model2cli: starting CLI generator |
| 4492 | --> model file: examples/models/SampleDomain/SamplePolicyModelJAVA.json |
| 4493 | |
| 4494 | .. container:: paragraph |
| 4495 | |
| 4496 | and then run the generator application producing all CLI |
| 4497 | Editor commands and printing them to standard out. |
| 4498 | |
| 4499 | Application: Websocket Clients (Echo and Console) |
| 4500 | ------------------------------------------------- |
| 4501 | |
| 4502 | .. container:: paragraph |
| 4503 | |
| 4504 | **Status: Production** |
| 4505 | |
| 4506 | .. container:: paragraph |
| 4507 | |
| 4508 | The application launcher also provides a Websocket echo |
| 4509 | client and a Websocket console client. The echo client |
| 4510 | connects to APEX and prints all events it receives from |
| 4511 | APEX. The console client connects to APEX, reads input from |
| 4512 | the command line, and sends this input as events to APEX. |
| 4513 | |
| 4514 | +------------------------------------------------------------+--------------------------------------------------------------+ |
| 4515 | | Unix, Cygwin | Windows | |
| 4516 | +============================================================+==============================================================+ |
| 4517 | | .. container:: | .. container:: | |
| 4518 | | | | |
| 4519 | | .. container:: listingblock | .. container:: listingblock | |
| 4520 | | | | |
| 4521 | | .. container:: content | .. container:: content | |
| 4522 | | | | |
| 4523 | | .. code:: | .. code:: | |
| 4524 | | | | |
| 4525 | | # $APEX_HOME/bin/apexApps.sh ws-echo [args] | > %APEX_HOME%\bin\apexApps.bat ws-echo [args] | |
| 4526 | | # $APEX_HOME/bin/apexApps.sh ws-console [args] | > %APEX_HOME%\bin\apexApps.bat ws-console [args] | |
| 4527 | +------------------------------------------------------------+--------------------------------------------------------------+ |
| 4528 | |
| 4529 | .. container:: paragraph |
| 4530 | |
| 4531 | The arguments are the same for both applications: |
| 4532 | |
| 4533 | .. container:: ulist |
| 4534 | |
| 4535 | - ``-p`` defines the Websocket port to connect to (defaults |
| 4536 | to ``8887``) |
| 4537 | |
| 4538 | - ``-s`` defines the host on which a Websocket server is |
| 4539 | running (defaults to ``localhost``) |
| 4540 | |
| 4541 | .. container:: paragraph |
| 4542 | |
| 4543 | A discussion on how to use these two applications to build |
| 4544 | an APEX system is detailed HowTo-Websockets. |
| 4545 | |
| 4546 | My First Policy |
| 4547 | ^^^^^^^^^^^^^^^ |
| 4548 | |
| 4549 | Introduction |
| 4550 | ------------ |
| 4551 | .. container:: paragraph |
| 4552 | |
| 4553 | Consider a scenario where a supermarket chain called |
| 4554 | *HyperM* controls how it sells items in a policy-based |
| 4555 | manner. Each time an item is processed by *HyperM*'s |
| 4556 | point-of-sale (PoS) system an event is generated and |
| 4557 | published about that item of stock being sold. This event |
| 4558 | can then be used to update stock levels, etc.. |
| 4559 | |
| 4560 | .. container:: paragraph |
| 4561 | |
| 4562 | *HyperM* want to extend this approach to allow some checks |
| 4563 | to be performed before the sale can be completed. This can |
| 4564 | be achieved by requesting a policy-controlled decision as |
| 4565 | each item is processed by for sale by each PoS system. The |
| 4566 | decision process is integrated with *HyperM*'s other IT |
| 4567 | systems that manage stock control, sourcing and purchasing, |
| 4568 | personnel systems, etc. |
| 4569 | |
| 4570 | .. container:: paragraph |
| 4571 | |
| 4572 | In this document we will show how APEX and APEX Policies can |
| 4573 | be used to achieve this, starting with a simple policy, |
| 4574 | building up to more complicated policy that demonstrates the |
| 4575 | features of APEX. |
| 4576 | |
| 4577 | Data Models |
| 4578 | ----------- |
| 4579 | |
| 4580 | Sales Input Event |
| 4581 | ################# |
| 4582 | |
| 4583 | .. container:: paragraph |
| 4584 | |
| 4585 | Each time a PoS system processes a sales item an event |
| 4586 | with the following format is emitted: |
| 4587 | |
| 4588 | .. table:: Table 1. Sale Input Event |
| 4589 | |
| 4590 | +----------------------+----------------------+-----------------------+ |
| 4591 | | Event | Fields | Description | |
| 4592 | +======================+======================+=======================+ |
| 4593 | | SALE_INPUT | time, sale_ID, | Event indicating a | |
| 4594 | | | amount, item_ID, | sale of an item is | |
| 4595 | | | quantity, | occurring | |
| 4596 | | | assistant_ID, | | |
| 4597 | | | branch_ID, notes, … | | |
| 4598 | +----------------------+----------------------+-----------------------+ |
| 4599 | |
| 4600 | .. container:: paragraph |
| 4601 | |
| 4602 | In each ``SALE_INPUT`` event the ``sale_ID`` field is a |
| 4603 | unique ID generated by the PoS system. A timestamp for |
| 4604 | the event is stored in the ``time`` field. The ``amount`` |
| 4605 | field refers to the value of the item(s) to be sold (in |
| 4606 | cents). The ``item_ID`` field is a unique identifier for |
| 4607 | each item type, and can be used to retrieve more |
| 4608 | information about the item from *HyperM*'s stock control |
| 4609 | system. The ``quantity`` field refers to the quantity of |
| 4610 | the item to be sold. The ``assistant_ID`` field is a |
| 4611 | unique identifier for the PoS operator, and can be used |
| 4612 | to retrieve more information about the operator from the |
| 4613 | *HyperM*'s personnel system. Since *HyperM* has many |
| 4614 | branches the ``branch_ID`` identifies the shop. The |
| 4615 | ``notes`` field contains arbitrary notes about the sale. |
| 4616 | |
| 4617 | Sales Decision Event |
| 4618 | #################### |
| 4619 | |
| 4620 | .. container:: paragraph |
| 4621 | |
| 4622 | After a ``SALE_INPUT`` event is emitted by the PoS system |
| 4623 | *HyperM*'s policy-based controlled sales checking system |
| 4624 | emits a Sale Authorization Event indicating whether the |
| 4625 | sale is authorized or denied. The PoS system can then |
| 4626 | listen for this event before continuing with the sale. |
| 4627 | |
| 4628 | .. table:: Table 2. Sale Authorisation Event |
| 4629 | |
| 4630 | +----------------------+----------------------+-----------------------+ |
| 4631 | | Event | Fields | Description | |
| 4632 | +======================+======================+=======================+ |
| 4633 | | SALE_AUTH | sale_ID, time, | Event indicating a | |
| 4634 | | | authorized, amount, | sale of an item is | |
| 4635 | | | item_ID, quantity, | authorized or denied | |
| 4636 | | | assistant_ID, | | |
| 4637 | | | branch_ID, notes, | | |
| 4638 | | | message… | | |
| 4639 | +----------------------+----------------------+-----------------------+ |
| 4640 | |
| 4641 | .. container:: paragraph |
| 4642 | |
| 4643 | In each ``SALE_AUTH`` event the ``sale_ID`` field is |
| 4644 | copied from the ``SALE_INPUT`` event that trigger the |
| 4645 | decision request. The ``SALE_AUTH`` event is also |
| 4646 | timestamped using the ``time`` field, and a field called |
| 4647 | ``authorised`` is set to ``true`` or ``false`` depending |
| 4648 | on whether the sale is authorized or denied. The |
| 4649 | ``message`` field carries an optional message about why a |
| 4650 | sale was not authorized. The other fields from the |
| 4651 | ``SALE_INPUT`` event are also included for completeness. |
| 4652 | |
| 4653 | Stock Control: Items |
| 4654 | #################### |
| 4655 | |
| 4656 | .. container:: paragraph |
| 4657 | |
| 4658 | *HyperM* maintains information about each item for sale |
| 4659 | in a database table called ``ITEMS``. |
| 4660 | |
| 4661 | .. table:: Table 3. Items Database |
| 4662 | |
| 4663 | +----------------------+----------------------+-----------------------+ |
| 4664 | | Table | Fields | Description | |
| 4665 | +======================+======================+=======================+ |
| 4666 | | ITEMS | item_ID, | Database table | |
| 4667 | | | description, | describing each item | |
| 4668 | | | cost_price, barcode, | for sale | |
| 4669 | | | supplier_ID, | | |
| 4670 | | | category, … | | |
| 4671 | +----------------------+----------------------+-----------------------+ |
| 4672 | |
| 4673 | .. container:: paragraph |
| 4674 | |
| 4675 | The database table ``ITEMS`` has a row for each items |
| 4676 | that *HyperM* sells. Each item is identified by an |
| 4677 | ``item_ID`` value. The ``description`` field stores a |
| 4678 | description of the item. The cost price of the item is |
| 4679 | given in ``cost_price``. The barcode of the item is |
| 4680 | encoded in ``barcode``, while the item supplier is |
| 4681 | identified by ``supplier_ID``. Items may also be |
| 4682 | classified into categories using the ``category`` field. |
| 4683 | Useful categories might include: ``soft drinks``, |
| 4684 | ``alcoholic drinks``, ``cigarettes``, ``knives``, |
| 4685 | ``confectionery``, ``bakery``, ``fruit&vegetables``, |
| 4686 | ``meat``, etc.. |
| 4687 | |
| 4688 | Personnel System: Assistants |
| 4689 | ############################ |
| 4690 | |
| 4691 | .. table:: Table 4. Assistants Database |
| 4692 | |
| 4693 | +----------------------+----------------------+-----------------------+ |
| 4694 | | Table | Fields | Description | |
| 4695 | +======================+======================+=======================+ |
| 4696 | | ASSISTANTS | assistant_ID, | Database table | |
| 4697 | | | surname, firstname, | describing each | |
| 4698 | | | middlename, age, | *HyperM* sales | |
| 4699 | | | grade, phone_number, | assistant | |
| 4700 | | | … | | |
| 4701 | +----------------------+----------------------+-----------------------+ |
| 4702 | |
| 4703 | .. container:: paragraph |
| 4704 | |
| 4705 | The database table ``ASSISTANTS`` has a row for each |
| 4706 | sales assistant employed by *HyperM*. Each assistant is |
| 4707 | identified by an ``assistant_ID`` value, with their name |
| 4708 | given in the ``firstname``, ``middlename`` and |
| 4709 | ``surname`` fields. The assistant’s age in years is given |
| 4710 | in ``age``, while their phone number is contained in the |
| 4711 | ``phone_number`` field. The assistant’s grade is encoded |
| 4712 | in ``grade``. Useful values for ``grade`` might include: |
| 4713 | ``trainee``, ``operator``, ``supervisor``, etc.. |
| 4714 | |
| 4715 | Locations: Branches |
| 4716 | #################### |
| 4717 | |
| 4718 | .. table:: Table 5. Branches Database |
| 4719 | |
| 4720 | +----------------------+----------------------+-----------------------+ |
| 4721 | | Table | Fields | Description | |
| 4722 | +======================+======================+=======================+ |
| 4723 | | BRANCHES | branch_ID, | Database table | |
| 4724 | | | branch_Name, | describing each | |
| 4725 | | | category, street, | *HyperM* branch | |
| 4726 | | | city, country, | | |
| 4727 | | | postcode, … | | |
| 4728 | +----------------------+----------------------+-----------------------+ |
| 4729 | |
| 4730 | .. container:: paragraph |
| 4731 | |
| 4732 | *HyperM* operates a number of branches. Each branch is |
| 4733 | described in the ``BRANCHES`` database table. Each branch |
| 4734 | is identified by a ``branch_ID``, with a branch name |
| 4735 | given in ``branch_Name``. The address for the branch is |
| 4736 | encoded in ``street``, ``city``, ``country`` and |
| 4737 | ``postcode``. The branch category is given in the |
| 4738 | ``category`` field. Useful values for ``category`` might |
| 4739 | include: ``Small``, ``Large``, ``Super``, ``Hyper``, |
| 4740 | etc.. |
| 4741 | |
| 4742 | Policy Step 1 |
| 4743 | ------------- |
| 4744 | |
| 4745 | Scenario |
| 4746 | ######### |
| 4747 | .. container:: paragraph |
| 4748 | |
| 4749 | For the first version of our policy, let’s start with |
| 4750 | something simple. Let us assume that there exists some |
| 4751 | restriction that alcohol products cannot be sold before |
| 4752 | 11:30am. In this section we will go through the necessary |
| 4753 | steps to define a policy that can enforce this for |
| 4754 | *HyperM*. |
| 4755 | |
| 4756 | .. container:: ulist |
| 4757 | |
| 4758 | - Alcohol cannot be sold before 11:30am. |
| 4759 | |
| 4760 | Create the an new empty Policy Model ``MyFirstPolicyModel`` |
| 4761 | ########################################################### |
| 4762 | |
| 4763 | .. container:: paragraph |
| 4764 | |
| 4765 | Since an organisation like *HyperM* may have many |
| 4766 | policies covering many different domains, policies should |
| 4767 | be grouped into policy sets. In order to edit or deploy a |
| 4768 | policy, or policy set, the definition of the policy(ies) |
| 4769 | and all required events, tasks, states, etc., are grouped |
| 4770 | together into a 'Policy Model'. An organization might |
| 4771 | define many Policy Models, each containing a different |
| 4772 | set of policies. |
| 4773 | |
| 4774 | .. container:: paragraph |
| 4775 | |
| 4776 | So the first step is to create a new empty Policy Model |
| 4777 | called ``MyFirstPolicyModel``. Using the APEX Policy |
| 4778 | Editor, click on the 'File' menus and select 'New'. Then |
| 4779 | define our new policy model called |
| 4780 | ``MyFirstPolicyModel``. Use the 'Generate UUID' button to |
| 4781 | create a new unique ID for the policy model, and fill in |
| 4782 | a description for the policy model. Press the ``Submit`` |
| 4783 | button to save your changes. |
| 4784 | |
| 4785 | .. container:: imageblock |
| 4786 | |
| 4787 | .. container:: content |
| 4788 | |
| 4789 | |File > New to create a new Policy Model| |
| 4790 | |
| 4791 | .. container:: title |
| 4792 | |
| 4793 | Figure 4. Create a new Policy Model 1/2 |
| 4794 | |
| 4795 | .. container:: imageblock |
| 4796 | |
| 4797 | .. container:: content |
| 4798 | |
| 4799 | |Create a new Policy Model| |
| 4800 | |
| 4801 | .. container:: title |
| 4802 | |
| 4803 | Figure 5. Create a new Policy Model 2/2 |
| 4804 | |
| 4805 | Create the input event ``SALE_INPUT`` and the output event ``SALE_AUTH`` |
| 4806 | ######################################################################## |
| 4807 | |
| 4808 | .. container:: paragraph |
| 4809 | |
| 4810 | Using the APEX Policy Editor, click on the 'Events' tab. |
| 4811 | In the 'Events' pane, right click and select 'New': |
| 4812 | |
| 4813 | .. container:: imageblock |
| 4814 | |
| 4815 | .. container:: content |
| 4816 | |
| 4817 | |Right click to create a new event| |
| 4818 | |
| 4819 | .. container:: title |
| 4820 | |
| 4821 | Figure 6. Create a new Event type |
| 4822 | |
| 4823 | .. container:: paragraph |
| 4824 | |
| 4825 | Create a new event type called ``SALE_INPUT``. Use the |
| 4826 | 'Generate UUID' button to create a new unique ID for the |
| 4827 | event type, and fill in a description for the event. Add |
| 4828 | a namespace, e.g. ``com.hyperm``. We can add hard-coded |
| 4829 | strings for the ``Source`` and ``Target``, e.g. ``POS`` |
| 4830 | and ``APEX``. At this stage we will not add any parameter |
| 4831 | fields, we will leave this until later. Use the |
| 4832 | ``Submit`` button to create the event. |
| 4833 | |
| 4834 | .. container:: imageblock |
| 4835 | |
| 4836 | .. container:: content |
| 4837 | |
| 4838 | |Fill in the necessary information for the |
| 4839 | 'SALE_INPUT' event and click 'Submit'| |
| 4840 | |
| 4841 | .. container:: title |
| 4842 | |
| 4843 | Figure 7. Populate the ``SALE_INPUT`` event |
| 4844 | |
| 4845 | .. container:: paragraph |
| 4846 | |
| 4847 | Repeat the same steps for a new event type called |
| 4848 | ``SALE_AUTH``. Just use ``APEX`` as source and ``POS`` as |
| 4849 | target, since this is the output event coming from APEX |
| 4850 | going to the sales point. |
| 4851 | |
| 4852 | .. container:: paragraph |
| 4853 | |
| 4854 | Before we can add parameter fields to an event we must |
| 4855 | first define APEX Context Item Schemas that can be used |
| 4856 | by those fields. |
| 4857 | |
| 4858 | .. container:: paragraph |
| 4859 | |
| 4860 | To create new item schemas, click on the 'Context Item |
| 4861 | Schemas' tab. In that 'Context Item Schemas' pane, right |
| 4862 | click and select 'Create new ContextSchema'. |
| 4863 | |
| 4864 | .. container:: imageblock |
| 4865 | |
| 4866 | .. container:: content |
| 4867 | |
| 4868 | |Right click to create a new Item Schema| |
| 4869 | |
| 4870 | .. container:: title |
| 4871 | |
| 4872 | Figure 8. Create new Data Types |
| 4873 | |
| 4874 | .. container:: paragraph |
| 4875 | |
| 4876 | Create item schemas with the following characteristics, |
| 4877 | each with its own unique UUID: |
| 4878 | |
| 4879 | .. table:: Table 6. Item Schemas |
| 4880 | |
| 4881 | +-------------------+-----------------+-----------------+----------------------+ |
| 4882 | | Name | Schema Flavour | Schema | Description | |
| 4883 | | | | Definition | | |
| 4884 | +===================+=================+=================+======================+ |
| 4885 | | timestamp_type | Java | java.lang.Long | A type for | |
| 4886 | | | | | ``time`` values | |
| 4887 | +-------------------+-----------------+-----------------+----------------------+ |
| 4888 | | sale_ID_type | Java | java.lang.Long | A type for | |
| 4889 | | | | | ``sale_ID`` | |
| 4890 | | | | | values | |
| 4891 | +-------------------+-----------------+-----------------+----------------------+ |
| 4892 | | price_type | Java | java.lang.Long | A type for | |
| 4893 | | | | | ``amount``/``price`` | |
| 4894 | | | | | values | |
| 4895 | +-------------------+-----------------+-----------------+----------------------+ |
| 4896 | | item_ID_type | Java | java.lang.Long | A type for | |
| 4897 | | | | | ``item_ID`` | |
| 4898 | | | | | values | |
| 4899 | +-------------------+-----------------+-----------------+----------------------+ |
| 4900 | | assistant_ID_type | Java | java.lang.Long | A type for | |
| 4901 | | | | | ``assistant_ID`` | |
| 4902 | | | | | values | |
| 4903 | +-------------------+-----------------+-----------------+----------------------+ |
| 4904 | | quantity_type | Java | java.lang.Integ | A type for | |
| 4905 | | | | er | ``quantity`` | |
| 4906 | | | | | values | |
| 4907 | +-------------------+-----------------+-----------------+----------------------+ |
| 4908 | | branch_ID_type | Java | java.lang.Long | A type for | |
| 4909 | | | | | ``branch_ID`` | |
| 4910 | | | | | values | |
| 4911 | +-------------------+-----------------+-----------------+----------------------+ |
| 4912 | | notes_type | Java | java.lang.Strin | A type for | |
| 4913 | | | | g | ``notes`` | |
| 4914 | | | | | values | |
| 4915 | +-------------------+-----------------+-----------------+----------------------+ |
| 4916 | | authorised_type | Java | java.lang.Boole | A type for | |
| 4917 | | | | an | ``authorised`` | |
| 4918 | | | | | values | |
| 4919 | +-------------------+-----------------+-----------------+----------------------+ |
| 4920 | | message_type | Java | java.lang.Strin | A type for | |
| 4921 | | | | g | ``message`` | |
| 4922 | | | | | values | |
| 4923 | +-------------------+-----------------+-----------------+----------------------+ |
| 4924 | |
| 4925 | .. container:: imageblock |
| 4926 | |
| 4927 | .. container:: content |
| 4928 | |
| 4929 | |Create a new Item Schema| |
| 4930 | |
| 4931 | .. container:: title |
| 4932 | |
| 4933 | Figure 9. Create new Item Schemas |
| 4934 | |
| 4935 | .. container:: paragraph |
| 4936 | |
| 4937 | The item schemas can now be seen on the 'Context Item |
| 4938 | Schemas' tab, and can be updated at any time by |
| 4939 | right-clicking on the item schemas on the 'Context Item |
| 4940 | Schemas' tab. Now we can go back to the event definitions |
| 4941 | for ``SALE_INPUT`` and ``SALE_AUTH`` and add some |
| 4942 | parameter fields. |
| 4943 | |
| 4944 | .. tip |
| 4945 | |
| 4946 | .. container:: title |
| 4947 | |
| 4948 | Field Schema types |
| 4949 | |
| 4950 | .. container:: paragraph |
| 4951 | |
| 4952 | APEX natively supports schema definitions in ``Java`` and ``Avro``. |
| 4953 | |
| 4954 | .. container:: paragraph |
| 4955 | |
| 4956 | ``Java`` schema definitions are simply the name of a Java Class. There are some restrictions: |
| 4957 | |
| 4958 | .. container:: ulist |
| 4959 | |
| 4960 | - the class must be instantiatable, i.e. not an Java interface or abstract class |
| 4961 | |
| 4962 | - primitive types are not supported, i.e. use ``java.lang.Integer`` instead of ``int``, etc. |
| 4963 | |
| 4964 | - it must be possible to find the class, i.e. the class must be contained in the Java classpath. |
| 4965 | |
| 4966 | .. container:: paragraph |
| 4967 | |
| 4968 | ``Avro`` schema definitions can be any valid `Avro <https://avro.apache.org/docs/current/spec.html>`__ |
| 4969 | schema. For events using fields defined with ``Avro`` schemas, any incoming event containing that field must |
| 4970 | contain a value that conforms to the Avro schema. |
| 4971 | |
| 4972 | .. container:: paragraph |
| 4973 | |
| 4974 | Click on the 'Events' tab, then right click the |
| 4975 | ``SALE_INPUT`` row and select 'Edit Event |
| 4976 | :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` |
| 4977 | event add the following event parameters: |
| 4978 | |
| 4979 | .. table:: Table 7. Event Parameter Fields for the ``SALE_INPUT`` Event |
| 4980 | |
| 4981 | +----------------------+----------------------+-----------------------+ |
| 4982 | | Parameter Name | Parameter Type | Optional | |
| 4983 | +======================+======================+=======================+ |
| 4984 | | time | timestamp_type | no | |
| 4985 | +----------------------+----------------------+-----------------------+ |
| 4986 | | sale_ID | sale_ID_type | no | |
| 4987 | +----------------------+----------------------+-----------------------+ |
| 4988 | | amount | price_type | no | |
| 4989 | +----------------------+----------------------+-----------------------+ |
| 4990 | | item_ID | item_ID_type | no | |
| 4991 | +----------------------+----------------------+-----------------------+ |
| 4992 | | quantity | quantity_type | no | |
| 4993 | +----------------------+----------------------+-----------------------+ |
| 4994 | | assistant_ID | assistant_ID_type | no | |
| 4995 | +----------------------+----------------------+-----------------------+ |
| 4996 | | branch_ID | branch_ID_type | no | |
| 4997 | +----------------------+----------------------+-----------------------+ |
| 4998 | | notes | notes_type | *yes* | |
| 4999 | +----------------------+----------------------+-----------------------+ |
| 5000 | |
| 5001 | .. container:: paragraph |
| 5002 | |
| 5003 | Remember to click the 'Submit' button at the bottom of |
| 5004 | the event definition pane. |
| 5005 | |
| 5006 | .. tip:: |
| 5007 | Optional Fields in APEX Events |
| 5008 | Parameter fields can be *optional* in events. If a parameter is not marked as *optional* then by default it |
| 5009 | is *mandatory*, so it must appear in any input event passed to APEX. If an *optional* field is not set |
| 5010 | for an output event then value will be set to ``null``. |
| 5011 | |
| 5012 | .. container:: imageblock |
| 5013 | |
| 5014 | .. container:: content |
| 5015 | |
| 5016 | |Add new event parameters to an event| |
| 5017 | |
| 5018 | .. container:: title |
| 5019 | |
| 5020 | Figure 10. Add typed parameter fields to an event |
| 5021 | |
| 5022 | .. container:: paragraph |
| 5023 | |
| 5024 | Select the ``SALE_AUTH`` event and add the following |
| 5025 | event parameters: |
| 5026 | |
| 5027 | .. table:: Table 8. Event Parameter Fields for the ``SALE_AUTH`` Event |
| 5028 | |
| 5029 | +----------------------+----------------------+-----------------------+ |
| 5030 | | Parameter Name | Parameter Type | no | |
| 5031 | +======================+======================+=======================+ |
| 5032 | | sale_ID | sale_ID_type | no | |
| 5033 | +----------------------+----------------------+-----------------------+ |
| 5034 | | time | timestamp_type | no | |
| 5035 | +----------------------+----------------------+-----------------------+ |
| 5036 | | authorised | authorised_type | no | |
| 5037 | +----------------------+----------------------+-----------------------+ |
| 5038 | | message | message_type | *yes* | |
| 5039 | +----------------------+----------------------+-----------------------+ |
| 5040 | | amount | price_type | no | |
| 5041 | +----------------------+----------------------+-----------------------+ |
| 5042 | | item_ID | item_ID_type | no | |
| 5043 | +----------------------+----------------------+-----------------------+ |
| 5044 | | assistant_ID | assistant_ID_type | no | |
| 5045 | +----------------------+----------------------+-----------------------+ |
| 5046 | | quantity | quantity_type | no | |
| 5047 | +----------------------+----------------------+-----------------------+ |
| 5048 | | branch_ID | branch_ID_type | no | |
| 5049 | +----------------------+----------------------+-----------------------+ |
| 5050 | | notes | notes_type | *yes* | |
| 5051 | +----------------------+----------------------+-----------------------+ |
| 5052 | |
| 5053 | .. container:: paragraph |
| 5054 | |
| 5055 | Remember to click the 'Submit' button at the bottom of |
| 5056 | the event definition pane. |
| 5057 | |
| 5058 | .. container:: paragraph |
| 5059 | |
| 5060 | The events for our policy are now defined. |
| 5061 | |
| 5062 | Create a new Policy and add the *"No Booze before 11:30"* check |
| 5063 | ############################################################### |
| 5064 | |
| 5065 | .. container:: paragraph |
| 5066 | |
| 5067 | APEX policies are defined using a state-machine model. |
| 5068 | Each policy comprises one or more *states* that can be |
| 5069 | individually executed. Where there is more than one |
| 5070 | *state* the states are chained together to form a |
| 5071 | `Directed Acyclic Graph |
| 5072 | (DAG) <https://en.wikipedia.org/wiki/Directed_acyclic_graph>`__ |
| 5073 | of states. A *state* is triggered by passing it a single |
| 5074 | input (or 'trigger') event and once executed each state |
| 5075 | then emits an output event. For each *state* the logic |
| 5076 | for the *state* is embedded in one or more *tasks*. Each |
| 5077 | *task* contains specific *task logic* that is executed by |
| 5078 | the APEX execution environment each time the *task* is |
| 5079 | invoked. Where there is more than one *task* in a *state* |
| 5080 | then the *state* also defines some *task selection logic* |
| 5081 | to select an appropriate task each time the *state* is |
| 5082 | executed. |
| 5083 | |
| 5084 | .. container:: paragraph |
| 5085 | |
| 5086 | Therefore, to create a new policy we must first define |
| 5087 | one or more tasks. |
| 5088 | |
| 5089 | .. container:: paragraph |
| 5090 | |
| 5091 | To create a new Task click on the 'Tasks' tab. In the |
| 5092 | 'Tasks' pane, right click and select 'Create new Task'. |
| 5093 | Create a new Task called ``MorningBoozeCheck``. Use the |
| 5094 | 'Generate UUID' button to create a new unique ID for the |
| 5095 | task, and fill in a description for the task. |
| 5096 | |
| 5097 | .. container:: imageblock |
| 5098 | |
| 5099 | .. container:: content |
| 5100 | |
| 5101 | |Right click to create a new task| |
| 5102 | |
| 5103 | .. container:: title |
| 5104 | |
| 5105 | Figure 11. Create a new Task |
| 5106 | |
| 5107 | .. container:: paragraph |
| 5108 | |
| 5109 | Tasks are configured with a set of *input fields* and a |
| 5110 | set of *output fields*. To add new input/output fields |
| 5111 | for a task use the 'Add Task Input Field' and 'Add Task |
| 5112 | Output Field' button. The list of input and out fields to |
| 5113 | add for the ``MorningBoozeCheck`` task are given below. |
| 5114 | The input fields are drawn from the parameters in the |
| 5115 | state’s input event, and the task’s output fields are |
| 5116 | used to populate the state’s output event. The task’s |
| 5117 | input and output fields must be a subset of the event |
| 5118 | parameters defined for the input and output events for |
| 5119 | any state that uses that task. (You may have noticed that |
| 5120 | the input and output fields for the ``MorningBoozeCheck`` |
| 5121 | task have the exact same names and reuse the item schemas |
| 5122 | that we used for the parameters in the ``SALE_INPUT`` and |
| 5123 | ``SALE_AUTH`` events respectively). |
| 5124 | |
| 5125 | .. table:: Table 9. Input fields for ``MorningBoozeCheck`` task |
| 5126 | |
| 5127 | +-----------------------------------+-----------------------------------+ |
| 5128 | | Parameter Name | Parameter Type | |
| 5129 | +===================================+===================================+ |
| 5130 | | time | timestamp_type | |
| 5131 | +-----------------------------------+-----------------------------------+ |
| 5132 | | sale_ID | sale_ID_type | |
| 5133 | +-----------------------------------+-----------------------------------+ |
| 5134 | | amount | price_type | |
| 5135 | +-----------------------------------+-----------------------------------+ |
| 5136 | | item_ID | item_ID_type | |
| 5137 | +-----------------------------------+-----------------------------------+ |
| 5138 | | quantity | quantity_type | |
| 5139 | +-----------------------------------+-----------------------------------+ |
| 5140 | | assistant_ID | assistant_ID_type | |
| 5141 | +-----------------------------------+-----------------------------------+ |
| 5142 | | branch_ID | branch_ID_type | |
| 5143 | +-----------------------------------+-----------------------------------+ |
| 5144 | | notes | notes_type | |
| 5145 | +-----------------------------------+-----------------------------------+ |
| 5146 | |
| 5147 | .. table:: Table 10. Output fields for ``MorningBoozeCheck`` task |
| 5148 | |
| 5149 | +-----------------------------------+-----------------------------------+ |
| 5150 | | Parameter Name | Parameter Type | |
| 5151 | +===================================+===================================+ |
| 5152 | | sale_ID | sale_ID_type | |
| 5153 | +-----------------------------------+-----------------------------------+ |
| 5154 | | time | timestamp_type | |
| 5155 | +-----------------------------------+-----------------------------------+ |
| 5156 | | authorised | authorised_type | |
| 5157 | +-----------------------------------+-----------------------------------+ |
| 5158 | | message | message_type | |
| 5159 | +-----------------------------------+-----------------------------------+ |
| 5160 | | amount | price_type | |
| 5161 | +-----------------------------------+-----------------------------------+ |
| 5162 | | item_ID | item_ID_type | |
| 5163 | +-----------------------------------+-----------------------------------+ |
| 5164 | | assistant_ID | assistant_ID_type | |
| 5165 | +-----------------------------------+-----------------------------------+ |
| 5166 | | quantity | quantity_type | |
| 5167 | +-----------------------------------+-----------------------------------+ |
| 5168 | | branch_ID | branch_ID_type | |
| 5169 | +-----------------------------------+-----------------------------------+ |
| 5170 | | notes | notes_type | |
| 5171 | +-----------------------------------+-----------------------------------+ |
| 5172 | |
| 5173 | .. container:: imageblock |
| 5174 | |
| 5175 | .. container:: content |
| 5176 | |
| 5177 | |Add input and out fields for the task| |
| 5178 | |
| 5179 | .. container:: title |
| 5180 | |
| 5181 | Figure 12. Add input and out fields for the Task |
| 5182 | |
| 5183 | .. container:: paragraph |
| 5184 | |
| 5185 | Each task must include some 'Task Logic' that implements |
| 5186 | the behaviour for the task. Task logic can be defined in |
| 5187 | a number of different ways using a choice of languages. |
| 5188 | For this task we will author the logic using the |
| 5189 | Java-like scripting language called |
| 5190 | ```MVEL`` <https://en.wikipedia.org/wiki/MVEL>`__. |
| 5191 | |
| 5192 | .. container:: paragraph |
| 5193 | |
| 5194 | For simplicity use the following code for the task logic. |
| 5195 | Paste the script text into the 'Task Logic' box, and use |
| 5196 | "MVEL" as the 'Task Logic Type / Flavour'. |
| 5197 | |
| 5198 | .. container:: paragraph |
| 5199 | |
| 5200 | This logic assumes that all items with ``item_ID`` |
| 5201 | between 1000 and 2000 contain alcohol, which is not very |
| 5202 | realistic, but we will see a better approach for this |
| 5203 | later. It also uses the standard ``Java`` time utilities |
| 5204 | to check if the current time is between ``00:00:00 GMT`` |
| 5205 | and ``11:30:00 GMT``. For a detailed guide to how to |
| 5206 | write your own logic in |
| 5207 | ```JavaScript`` <https://en.wikipedia.org/wiki/JavaScript>`__, |
| 5208 | ```MVEL`` <https://en.wikipedia.org/wiki/MVEL>`__ or one |
| 5209 | of the other supported languages please refer to APEX |
| 5210 | Programmers Guide. |
| 5211 | |
| 5212 | .. container:: listingblock |
| 5213 | |
| 5214 | .. container:: title |
| 5215 | |
| 5216 | MVEL code for the ``MorningBoozeCheck`` task |
| 5217 | |
| 5218 | .. container:: content |
| 5219 | |
| 5220 | .. code:: |
| 5221 | |
| 5222 | /* |
| 5223 | * ============LICENSE_START======================================================= |
| 5224 | * Copyright (C) 2016-2018 Ericsson. All rights reserved. |
| 5225 | * ================================================================================ |
| 5226 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5227 | * you may not use this file except in compliance with the License. |
| 5228 | * You may obtain a copy of the License at |
| 5229 | * |
| 5230 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 5231 | * |
| 5232 | * Unless required by applicable law or agreed to in writing, software |
| 5233 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 5234 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 5235 | * See the License for the specific language governing permissions and |
| 5236 | * limitations under the License. |
| 5237 | * |
| 5238 | * SPDX-License-Identifier: Apache-2.0 |
| 5239 | * ============LICENSE_END========================================================= |
| 5240 | */ |
| 5241 | import java.util.Date; |
| 5242 | import java.util.Calendar; |
| 5243 | import java.util.TimeZone; |
| 5244 | import java.text.SimpleDateFormat; |
| 5245 | |
| 5246 | logger.info("Task Execution: '"+subject.id+"'. Input Fields: '"+inFields+"'"); |
| 5247 | |
| 5248 | outFields.put("amount" , inFields.get("amount")); |
| 5249 | outFields.put("assistant_ID", inFields.get("assistant_ID")); |
| 5250 | outFields.put("notes" , inFields.get("notes")); |
| 5251 | outFields.put("quantity" , inFields.get("quantity")); |
| 5252 | outFields.put("branch_ID" , inFields.get("branch_ID")); |
| 5253 | outFields.put("item_ID" , inFields.get("item_ID")); |
| 5254 | outFields.put("time" , inFields.get("time")); |
| 5255 | outFields.put("sale_ID" , inFields.get("sale_ID")); |
| 5256 | |
| 5257 | item_id = inFields.get("item_ID"); |
| 5258 | |
| 5259 | //The events used later to test this task use GMT timezone! |
| 5260 | gmt = TimeZone.getTimeZone("GMT"); |
| 5261 | timenow = Calendar.getInstance(gmt); |
| 5262 | df = new SimpleDateFormat("HH:mm:ss z"); |
| 5263 | df.setTimeZone(gmt); |
| 5264 | timenow.setTimeInMillis(inFields.get("time")); |
| 5265 | |
| 5266 | midnight = timenow.clone(); |
| 5267 | midnight.set( |
| 5268 | timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), |
| 5269 | timenow.get(Calendar.DATE),0,0,0); |
| 5270 | eleven30 = timenow.clone(); |
| 5271 | eleven30.set( |
| 5272 | timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), |
| 5273 | timenow.get(Calendar.DATE),11,30,0); |
| 5274 | |
| 5275 | itemisalcohol = false; |
| 5276 | if(item_id != null && item_id >=1000 && item_id < 2000) |
| 5277 | itemisalcohol = true; |
| 5278 | |
| 5279 | if( itemisalcohol |
| 5280 | && timenow.after(midnight) && timenow.before(eleven30)){ |
| 5281 | outFields.put("authorised", false); |
| 5282 | outFields.put("message", "Sale not authorised by policy task "+subject.taskName+ |
| 5283 | " for time "+df.format(timenow.getTime())+ |
| 5284 | ". Alcohol can not be sold between "+df.format(midnight.getTime())+ |
| 5285 | " and "+df.format(eleven30.getTime())); |
| 5286 | return true; |
| 5287 | } |
| 5288 | else{ |
| 5289 | outFields.put("authorised", true); |
| 5290 | outFields.put("message", "Sale authorised by policy task "+subject.taskName+ |
| 5291 | " for time "+df.format(timenow.getTime())); |
| 5292 | return true; |
| 5293 | } |
| 5294 | |
| 5295 | /* |
| 5296 | This task checks if a sale request is for an item that is an alcoholic drink. |
| 5297 | If the local time is between 00:00:00 GMT and 11:30:00 GMT then the sale is not |
| 5298 | authorised. Otherwise the sale is authorised. |
| 5299 | In this implementation we assume that items with item_ID value between 1000 and |
| 5300 | 2000 are all alcoholic drinks :-) |
| 5301 | */ |
| 5302 | |
| 5303 | .. container:: imageblock |
| 5304 | |
| 5305 | .. container:: content |
| 5306 | |
| 5307 | |Add task logic the task| |
| 5308 | |
| 5309 | .. container:: title |
| 5310 | |
| 5311 | Figure 13. Add Task Logic the Task |
| 5312 | |
| 5313 | .. container:: paragraph |
| 5314 | |
| 5315 | An alternative version of the same logic is available in |
| 5316 | JavaScript. Just use "JAVASCRIPT" as the 'Task Logic Type |
| 5317 | / Flavour' instead. |
| 5318 | |
| 5319 | .. container:: listingblock |
| 5320 | |
| 5321 | .. container:: title |
| 5322 | |
| 5323 | Javascript alternative for the ``MorningBoozeCheck`` |
| 5324 | task |
| 5325 | |
| 5326 | .. container:: content |
| 5327 | |
| 5328 | .. code:: |
| 5329 | |
| 5330 | /* |
| 5331 | * ============LICENSE_START======================================================= |
| 5332 | * Copyright (C) 2016-2018 Ericsson. All rights reserved. |
| 5333 | * ================================================================================ |
| 5334 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5335 | * you may not use this file except in compliance with the License. |
| 5336 | * You may obtain a copy of the License at |
| 5337 | * |
| 5338 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 5339 | * |
| 5340 | * Unless required by applicable law or agreed to in writing, software |
| 5341 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 5342 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 5343 | * See the License for the specific language governing permissions and |
| 5344 | * limitations under the License. |
| 5345 | * |
| 5346 | * SPDX-License-Identifier: Apache-2.0 |
| 5347 | * ============LICENSE_END========================================================= |
| 5348 | */ |
| 5349 | |
| 5350 | var returnValueType = Java.type("java.lang.Boolean"); |
| 5351 | var returnValue = new returnValueType(true); |
| 5352 | |
| 5353 | // Load compatibility script for imports etc |
| 5354 | load("nashorn:mozilla_compat.js"); |
| 5355 | importPackage(java.text); |
| 5356 | importClass(java.text.SimpleDateFormat); |
| 5357 | |
| 5358 | executor.logger.info("Task Execution: '"+executor.subject.id+"'. Input Fields: '"+executor.inFields+"'"); |
| 5359 | |
| 5360 | executor.outFields.put("amount" , executor.inFields.get("amount")); |
| 5361 | executor.outFields.put("assistant_ID", executor.inFields.get("assistant_ID")); |
| 5362 | executor.outFields.put("notes" , executor.inFields.get("notes")); |
| 5363 | executor.outFields.put("quantity" , executor.inFields.get("quantity")); |
| 5364 | executor.outFields.put("branch_ID" , executor.inFields.get("branch_ID")); |
| 5365 | executor.outFields.put("item_ID" , executor.inFields.get("item_ID")); |
| 5366 | executor.outFields.put("time" , executor.inFields.get("time")); |
| 5367 | executor.outFields.put("sale_ID" , executor.inFields.get("sale_ID")); |
| 5368 | |
| 5369 | item_id = executor.inFields.get("item_ID"); |
| 5370 | |
| 5371 | //All times in this script are in GMT/UTC since the policy and events assume time is in GMT. |
| 5372 | var timenow_gmt = new Date(Number(executor.inFields.get("time"))); |
| 5373 | |
| 5374 | var midnight_gmt = new Date(Number(executor.inFields.get("time"))); |
| 5375 | midnight_gmt.setUTCHours(0,0,0,0); |
| 5376 | |
| 5377 | var eleven30_gmt = new Date(Number(executor.inFields.get("time"))); |
| 5378 | eleven30_gmt.setUTCHours(11,30,0,0); |
| 5379 | |
| 5380 | var timeformatter = new java.text.SimpleDateFormat("HH:mm:ss z"); |
| 5381 | |
| 5382 | var itemisalcohol = false; |
| 5383 | if(item_id != null && item_id >=1000 && item_id < 2000) |
| 5384 | itemisalcohol = true; |
| 5385 | |
| 5386 | if( itemisalcohol |
| 5387 | && timenow_gmt.getTime() >= midnight_gmt.getTime() |
| 5388 | && timenow_gmt.getTime() < eleven30_gmt.getTime()) { |
| 5389 | |
| 5390 | executor.outFields.put("authorised", false); |
| 5391 | executor.outFields.put("message", "Sale not authorised by policy task " + |
| 5392 | executor.subject.taskName+ " for time " + timeformatter.format(timenow_gmt.getTime()) + |
| 5393 | ". Alcohol can not be sold between " + timeformatter.format(midnight_gmt.getTime()) + |
| 5394 | " and " + timeformatter.format(eleven30_gmt.getTime())); |
| 5395 | } |
| 5396 | else{ |
| 5397 | executor.outFields.put("authorised", true); |
| 5398 | executor.outFields.put("message", "Sale authorised by policy task " + |
| 5399 | executor.subject.taskName + " for time "+timeformatter.format(timenow_gmt.getTime())); |
| 5400 | } |
| 5401 | |
| 5402 | /* |
| 5403 | This task checks if a sale request is for an item that is an alcoholic drink. |
| 5404 | If the local time is between 00:00:00 GMT and 11:30:00 GMT then the sale is not |
| 5405 | authorised. Otherwise the sale is authorised. |
| 5406 | In this implementation we assume that items with item_ID value between 1000 and |
| 5407 | 2000 are all alcoholic drinks :-) |
| 5408 | */ |
| 5409 | |
| 5410 | .. container:: paragraph |
| 5411 | |
| 5412 | The task definition is now complete so click the 'Submit' |
| 5413 | button to save the task. The task can now be seen on the |
| 5414 | 'Tasks' tab, and can be updated at any time by |
| 5415 | right-clicking on the task on the 'Task' tab. Now that we |
| 5416 | have created our task, we can can create a policy that |
| 5417 | uses that task. |
| 5418 | |
| 5419 | .. container:: paragraph |
| 5420 | |
| 5421 | To create a new Policy click on the 'Policies' tab. In |
| 5422 | the 'Policies' pane, right click and select 'Create new |
| 5423 | Policy': |
| 5424 | |
| 5425 | .. container:: paragraph |
| 5426 | |
| 5427 | Create a new Policy called ``MyFirstPolicy``. Use the |
| 5428 | 'Generate UUID' button to create a new unique ID for the |
| 5429 | policy, and fill in a description for the policy. Use |
| 5430 | 'FREEFORM' as the 'Policy Flavour'. |
| 5431 | |
| 5432 | .. container:: paragraph |
| 5433 | |
| 5434 | Each policy must have at least one state. Since this is |
| 5435 | 'freeform' policy we can add as many states as we wish. |
| 5436 | Let’s start with one state. Add a new state called |
| 5437 | ``BoozeAuthDecide`` to this ``MyFirstPolicy`` policy |
| 5438 | using the 'Add new State' button after filling in the |
| 5439 | name of our new state. |
| 5440 | |
| 5441 | .. container:: imageblock |
| 5442 | |
| 5443 | .. container:: content |
| 5444 | |
| 5445 | |Create a new policy| |
| 5446 | |
| 5447 | .. container:: title |
| 5448 | |
| 5449 | Figure 14. Create a new Policy |
| 5450 | |
| 5451 | .. container:: paragraph |
| 5452 | |
| 5453 | Each state must uses one input event type. For this new |
| 5454 | state select the ``SALE_INPUT`` event as the input event. |
| 5455 | |
| 5456 | .. container:: paragraph |
| 5457 | |
| 5458 | Each policy must define a 'First State' and a 'Policy |
| 5459 | Trigger Event'. The 'Policy Trigger Event' is the input |
| 5460 | event for the policy as a whole. This event is then |
| 5461 | passed to the first state in the chain of states in the |
| 5462 | policy, therefore the 'Policy Trigger Event' will be the |
| 5463 | input event for the first state. Each policy can only |
| 5464 | have one 'First State'. For our ``MyFirstPolicy`` policy, |
| 5465 | select ``BoozeAuthDecide`` as the 'First State'. This |
| 5466 | will automatically select ``SALE_INPUT`` as the 'Policy |
| 5467 | Trigger Event' for our policy. |
| 5468 | |
| 5469 | .. container:: imageblock |
| 5470 | |
| 5471 | .. container:: content |
| 5472 | |
| 5473 | |Create a state| |
| 5474 | |
| 5475 | .. container:: title |
| 5476 | |
| 5477 | Figure 15. Create a new State |
| 5478 | |
| 5479 | .. container:: paragraph |
| 5480 | |
| 5481 | In this case we will create a reference the pre-existing |
| 5482 | ``MorningBoozeCheck`` task that we defined above using |
| 5483 | the 'Add New Task' button. Select the |
| 5484 | ``MorningBoozeCheck`` task, and use the name of the task |
| 5485 | as the 'Local Name' for the task. |
| 5486 | |
| 5487 | .. container:: paragraph |
| 5488 | |
| 5489 | in the case where a state references more than one task, |
| 5490 | a 'Default Task' must be selected for the state and some |
| 5491 | logic ('Task Selection Logic') must be specified to |
| 5492 | select the appropriate task at execution time. Since our |
| 5493 | new state ``BoozeAuthDecide`` only has one task the |
| 5494 | default task is automatically selected and no 'Task |
| 5495 | Selection Logic' is required. |
| 5496 | |
| 5497 | .. note:: |
| 5498 | .. container:: title |
| 5499 | |
| 5500 | State Output Mappings |
| 5501 | |
| 5502 | .. container:: paragraph |
| 5503 | |
| 5504 | In a 'Policy' 'State' a 'State Output Mapping' has 3 roles: |
| 5505 | 1) Select which 'State' should be executed next, 2) Select |
| 5506 | the type of the state’s 'Outgoing Event', and 3) |
| 5507 | Populate the state’s 'Outgoing Event'. This is how states are |
| 5508 | chained together to form a (`Directed Acyclic Graph |
| 5509 | (DAG) <https://en.wikipedia.org/wiki/Directed_acyclic_graph>`__ ) |
| 5510 | of states. The final state(s) of a policy are those that do |
| 5511 | not select any 'next' state. Since a 'State' can only |
| 5512 | accept a single type of event, the type of the event emitted |
| 5513 | by a previous 'State' must be match the incoming event type |
| 5514 | of the next 'State'. This is also how the last state(s) in |
| 5515 | a policy can emit events of different types. The 'State |
| 5516 | Output Mapping' is also responsible for taking the |
| 5517 | fields that are output by the task executed in the state and |
| 5518 | populating the state’s output event before it is emitted. |
| 5519 | |
| 5520 | .. container:: paragraph |
| 5521 | |
| 5522 | Each 'Task' referenced in 'State' must have a defined |
| 5523 | 'Output Mapping' to take the output of the task, select an |
| 5524 | 'Outgoing Event' type for the state, populate the state’s |
| 5525 | outgoing event, and then select the next state to be |
| 5526 | executed (if any). |
| 5527 | |
| 5528 | .. container:: paragraph |
| 5529 | |
| 5530 | There are 2 basic types of output mappings: |
| 5531 | |
| 5532 | .. container:: olist arabic |
| 5533 | |
| 5534 | #. **Direct Output Mappings** have a single value for |
| 5535 | 'Next State' and a single value for 'State Output |
| 5536 | Event'. The outgoing event for the state is |
| 5537 | automatically created, any outgoing event parameters |
| 5538 | that were present in the incoming event are copied |
| 5539 | into the outgoing event, then any task output fields |
| 5540 | that have the same name and type as parameters in the |
| 5541 | outgoing event are automatically copied into |
| 5542 | the outgoing event. |
| 5543 | |
| 5544 | #. **Logic-based State Output Mappings / Finalizers** |
| 5545 | have some logic defined that dynamically selects |
| 5546 | and creates the 'State Outgoing Event', manages |
| 5547 | the population of the outgoing event parameters |
| 5548 | (perhaps changing or adding to the outputs from the |
| 5549 | task), and then dynamically selects the next state to |
| 5550 | be executed (if any). |
| 5551 | |
| 5552 | .. container:: paragraph |
| 5553 | |
| 5554 | Each task reference must also have an associated 'Output |
| 5555 | State Mapping' so we need an 'Output State Mapping' for |
| 5556 | the ``BoozeAuthDecide`` state to use when the |
| 5557 | ``MorningBoozeCheck`` task is executed. The simplest type |
| 5558 | of output mapping is a 'Direct Output Mapping'. |
| 5559 | |
| 5560 | .. container:: paragraph |
| 5561 | |
| 5562 | Create a new 'Direct Output Mapping' for the state called |
| 5563 | ``MorningBoozeCheck_Output_Direct`` using the 'Add New |
| 5564 | Direct State Output Mapping' button. Select ``SALE_AUTH`` |
| 5565 | as the output event and select ``None`` for the next |
| 5566 | state value. We can then select this output mapping for |
| 5567 | use when the the ``MorningBoozeCheck`` task is executed. |
| 5568 | Since there is only state, and only one task for that |
| 5569 | state, this output mapping ensures that the |
| 5570 | ``BoozeAuthDecide`` state is the only state executed and |
| 5571 | the state (and the policy) can only emit events of type |
| 5572 | ``SALE_AUTH``. (You may remember that the output fields |
| 5573 | for the ``MorningBoozeCheck`` task have the exact same |
| 5574 | names and reuse the item schemas that we used for the |
| 5575 | parameters in ``SALE_AUTH`` event. The |
| 5576 | ``MorningBoozeCheck_Output_Direct`` direct output mapping |
| 5577 | can now automatically copy the values from the |
| 5578 | ``MorningBoozeCheck`` task directly into outgoing |
| 5579 | ``SALE_AUTH`` events.) |
| 5580 | |
| 5581 | .. container:: imageblock |
| 5582 | |
| 5583 | .. container:: content |
| 5584 | |
| 5585 | |Add a Task and Output Mapping| |
| 5586 | |
| 5587 | .. container:: title |
| 5588 | |
| 5589 | Figure 16. Add a Task and Output Mapping |
| 5590 | |
| 5591 | .. container:: paragraph |
| 5592 | |
| 5593 | Click the 'Submit' button to complete the definition of |
| 5594 | our ``MyFirstPolicy`` policy. The policy |
| 5595 | ``MyFirstPolicy`` can now be seen in the list of policies |
| 5596 | on the 'Policies' tab, and can be updated at any time by |
| 5597 | right-clicking on the policy on the 'Policies' tab. |
| 5598 | |
| 5599 | .. container:: paragraph |
| 5600 | |
| 5601 | The ``MyFirstPolicyModel``, including our |
| 5602 | ``MyFirstPolicy`` policy can now be checked for errors. |
| 5603 | Click on the 'Model' menu and select 'Validate'. The |
| 5604 | model should validate without any 'Warning' or 'Error' |
| 5605 | messages. If you see any 'Error' or 'Warning' messages, |
| 5606 | carefully read the message as a hint to find where you |
| 5607 | might have made a mistake when defining some aspect of |
| 5608 | your policy model. |
| 5609 | |
| 5610 | .. container:: imageblock |
| 5611 | |
| 5612 | .. container:: content |
| 5613 | |
| 5614 | |Validate the policy model for error using the 'Model' |
| 5615 | > 'Validate' menu item| |
| 5616 | |
| 5617 | .. container:: title |
| 5618 | |
| 5619 | Figure 17. Validate a Policy Model |
| 5620 | |
| 5621 | .. container:: paragraph |
| 5622 | |
| 5623 | Congratulations, you have now completed your first APEX |
| 5624 | policy. The policy model containing our new policy can |
| 5625 | now be exported from the editor and saved. Click on the |
| 5626 | 'File' menu and select 'Download' to save the policy |
| 5627 | model in JSON format. The exported policy model is then |
| 5628 | available in the directory you selected, for instance |
| 5629 | ``$APEX_HOME/examples/models/MyFirstPolicy/1/MyFirstPolicyModel_0.0.1.json``. |
| 5630 | The exported policy can now be loaded into the APEX |
| 5631 | Policy Engine, or can be re-loaded and edited by the APEX |
| 5632 | Policy Editor. |
| 5633 | |
| 5634 | .. container:: imageblock |
| 5635 | |
| 5636 | .. container:: content |
| 5637 | |
| 5638 | |Download the completed policy model using the 'File' |
| 5639 | > 'Download' menu item| |
| 5640 | |
| 5641 | .. container:: title |
| 5642 | |
| 5643 | Figure 18. Export a Policy Model |
| 5644 | |
| 5645 | Test Policy Step 1 |
| 5646 | ################## |
| 5647 | |
| 5648 | .. container:: paragraph |
| 5649 | |
| 5650 | To start a new APEX Engine you can use the following |
| 5651 | configuration. In a full APEX installation you can find |
| 5652 | this configuration in |
| 5653 | ``$APEX_HOME/examples/config/MyFirstPolicy/1/MyFirstPolicyConfigStdin2StdoutJsonEvent.json``. |
| 5654 | This configuration expects incoming events to be in |
| 5655 | ``JSON`` format and to be passed into the APEX Engine |
| 5656 | from ``stdin``, and result events will be printed in |
| 5657 | ``JSON`` format to ``stdout``. This configuration loads |
| 5658 | the policy model stored in the file |
| 5659 | 'MyFirstPolicyModel_0.0.1.json' as exported from the APEX |
| 5660 | Editor. Note, you may need to edit this file to provide |
| 5661 | the full path to wherever you stored the exported policy |
| 5662 | model file. |
| 5663 | |
| 5664 | .. container:: listingblock |
| 5665 | |
| 5666 | .. container:: title |
| 5667 | |
| 5668 | JSON to load and execute *My First Policy*, read input |
| 5669 | JSON events from ``stdin``, and emit output events to |
| 5670 | ``stdout`` |
| 5671 | |
| 5672 | .. container:: content |
| 5673 | |
| 5674 | .. code:: |
| 5675 | |
| 5676 | { |
| 5677 | "engineServiceParameters" : { |
| 5678 | "name" : "MyFirstPolicyApexEngine", |
| 5679 | "version" : "0.0.1", |
| 5680 | "id" : 101, |
| 5681 | "instanceCount" : 4, |
| 5682 | "deploymentPort" : 12345, |
| 5683 | "policyModelFileName" : "examples/models/MyFirstPolicy/1/MyFirstPolicyModel_0.0.1.json", |
| 5684 | "engineParameters" : { |
| 5685 | "executorParameters" : { |
| 5686 | "MVEL" : { |
| 5687 | "parameterClassName" : "org.onap.policy.apex.plugins.executor.mvel.MVELExecutorParameters" |
| 5688 | }, |
| 5689 | "JAVASCRIPT" : { |
| 5690 | "parameterClassName" : "org.onap.policy.apex.plugins.executor.javascript.JavascriptExecutorParameters" |
| 5691 | } |
| 5692 | } |
| 5693 | } |
| 5694 | }, |
| 5695 | "eventOutputParameters": { |
| 5696 | "FirstProducer": { |
| 5697 | "carrierTechnologyParameters" : { |
| 5698 | "carrierTechnology" : "FILE", |
| 5699 | "parameters" : { |
| 5700 | "standardIO" : true |
| 5701 | } |
| 5702 | }, |
| 5703 | "eventProtocolParameters" : { |
| 5704 | "eventProtocol" : "JSON" |
| 5705 | } |
| 5706 | } |
| 5707 | }, |
| 5708 | "eventInputParameters": { |
| 5709 | "FirstConsumer": { |
| 5710 | "carrierTechnologyParameters" : { |
| 5711 | "carrierTechnology" : "FILE", |
| 5712 | "parameters" : { |
| 5713 | "standardIO" : true |
| 5714 | } |
| 5715 | }, |
| 5716 | "eventProtocolParameters" : { |
| 5717 | "eventProtocol" : "JSON" |
| 5718 | } |
| 5719 | } |
| 5720 | } |
| 5721 | } |
| 5722 | |
| 5723 | .. container:: paragraph |
| 5724 | |
| 5725 | To test the policy try paste the following events into |
| 5726 | the console as the APEX engine executes: |
| 5727 | |
| 5728 | .. table:: Table 11. Inputs and Outputs when testing *My First Policy* |
| 5729 | |
| 5730 | +------------------------------------------+-------------------------------------------+-----------+ |
| 5731 | | Input Event (JSON) | Output Event (JSON) | comment | |
| 5732 | +==========================================+===========================================+===========+ |
| 5733 | | .. container:: | .. container:: | Request | |
| 5734 | | | | to buy a | |
| 5735 | | .. container:: listingblock | .. container:: listingblock | non-alcoh | |
| 5736 | | | | olic | |
| 5737 | | | .. container:: content | item | |
| 5738 | | .. container:: content | | (``item_I | |
| 5739 | | | .. code:: | D=5123``) | |
| 5740 | | | | at | |
| 5741 | | .. code:: | { | *10:13:09 | |
| 5742 | | | "name": "SALE_AUTH", | * | |
| 5743 | | | | on | |
| 5744 | | { | "version": "0.0.1", | *Tuesday, | |
| 5745 | | "nameSpace": "com.hyperm", | "nameSpace": "com.hyperm", | 10 | |
| 5746 | | "name" : "SALE_INPUT", | "source": "", | January | |
| 5747 | | "version": "0.0.1", | "target": "", | 2017*. | |
| 5748 | | "time" : 1483351989000, | "amount": 299, | Sale is | |
| 5749 | | "sale_ID": 99999991, | "assistant_ID": 23, | authorize | |
| 5750 | | "amount": 299, | "authorised": true, | d. | |
| 5751 | | "item_ID": 5123, | "branch_ID": 1, | | |
| 5752 | | "quantity": 1, | "item_ID": 5123, | | |
| 5753 | | "assistant_ID": 23, | "message": "Sale authorised | | |
| 5754 | | "branch_ID": 1, | by policy task MorningBo | | |
| 5755 | | "notes": "Special Offer!!" | ozeCheck for time 10:13:09 | | |
| 5756 | | } | GMT", | | |
| 5757 | | | "notes": "Special Offer!!", | | |
| 5758 | | | "quantity": 1, | | |
| 5759 | | | "sale_ID": 99999991, | | |
| 5760 | | | "time": 1483351989000 | | |
| 5761 | | | } | | |
| 5762 | | | | | |
| 5763 | | | | | |
| 5764 | | | | | |
| 5765 | +------------------------------------------+-------------------------------------------+-----------+ |
| 5766 | | .. container:: | .. container:: | Request | |
| 5767 | | | | to buy | |
| 5768 | | .. container:: listingblock | .. container:: listingblock | alcohol | |
| 5769 | | | | item | |
| 5770 | | .. container:: content | .. container:: content | (``item_I | |
| 5771 | | | | D=1249``) | |
| 5772 | | .. code:: | .. code:: | at | |
| 5773 | | | | *08:41:06 | |
| 5774 | | { | { | * | |
| 5775 | | "nameSpace": "com.hyperm", | "nameSpace": "com.hyperm", | on | |
| 5776 | | "name": "SALE_INPUT", | "name": "SALE_AUTH", | *Monday, | |
| 5777 | | "version": "0.0.1", | "source": "", | 02 | |
| 5778 | | "time": 1483346466000, | "target": "", | January | |
| 5779 | | "sale_ID": 99999992, | "amount": 1249, | 2017*. | |
| 5780 | | "version": "0.0.1", | "assistant_ID": 12, | | |
| 5781 | | "amount": 1249, | "authorised": false, | Sale is | |
| 5782 | | "item_ID": 1012, | "branch_ID": 2, | not | |
| 5783 | | "quantity": 1, | "item_ID": 1012, | authorize | |
| 5784 | | "assistant_ID": 12, | "message": "Sale not | d. | |
| 5785 | | "branch_ID": 2 | authorised by policy task | | |
| 5786 | | } | MorningBoozeCheck for time | | |
| 5787 | | | 08:41:06 GMT. Alcohol can | | |
| 5788 | | | not be sold between | | |
| 5789 | | | 00:00:00 GMT and 11:30:00 | | |
| 5790 | | | GMT", | | |
| 5791 | | | "notes": null, | | |
| 5792 | | | "quantity": 1, | | |
| 5793 | | | "sale_ID": 99999992, | | |
| 5794 | | | "time": 1483346466000 | | |
| 5795 | | | } | | |
| 5796 | +------------------------------------------+-------------------------------------------+-----------+ |
| 5797 | | .. container:: | .. container:: | Request | |
| 5798 | | | | to buy | |
| 5799 | | .. container:: listingblock | .. container:: listingblock | alcohol | |
| 5800 | | | | (``item_I | |
| 5801 | | | .. container:: content | D=1943``) | |
| 5802 | | .. container:: content | | at | |
| 5803 | | | .. code:: | *20:17:13 | |
| 5804 | | | | * | |
| 5805 | | .. code:: | { | on | |
| 5806 | | | "name": "SALE_AUTH", | *Tuesday, | |
| 5807 | | { | "version": "0.0.1", | 20 | |
| 5808 | | "nameSpace": "com.hyperm", | "nameSpace": "com.hyperm", | December | |
| 5809 | | "name" : "SALE_INPUT", | "source": "", | 2016*. | |
| 5810 | | "version": "0.0.1", | "target": "", | | |
| 5811 | | "time" : 1482265033000, | "amount": 4799, | Sale is | |
| 5812 | | "sale_ID": 99999993, | "assistant_ID": 9, | authorize | |
| 5813 | | "amount": 4799, | "authorised": true, | d. | |
| 5814 | | "item_ID": 1943, | "branch_ID": 3, | | |
| 5815 | | "quantity": 2, | "item_ID": 1943, | | |
| 5816 | | "assistant_ID": 9, | "message": "Sale authorised | | |
| 5817 | | "branch_ID": 3 | by policy task MorningBo | | |
| 5818 | | } | ozeCheck for time 20:17:13 | | |
| 5819 | | | GMT", | | |
| 5820 | | | "notes": null, | | |
| 5821 | | | "quantity": 2, | | |
| 5822 | | | "sale_ID": 99999993, | | |
| 5823 | | | "time": 1482265033000 | | |
| 5824 | | | } | | |
| 5825 | +------------------------------------------+-------------------------------------------+-----------+ |
| 5826 | |
| 5827 | 4.3.6. Policy 1 in CLI Editor |
| 5828 | ############################# |
| 5829 | |
| 5830 | .. container:: paragraph |
| 5831 | |
| 5832 | An equivalent version of the ``MyFirstPolicyModel`` |
| 5833 | policy model can again be generated using the APEX CLI |
| 5834 | editor. A sample APEX CLI script is shown below: |
| 5835 | |
| 5836 | .. container:: listingblock |
| 5837 | |
| 5838 | .. container:: title |
| 5839 | |
| 5840 | APEX CLI Editor code for Policy 1 |
| 5841 | |
| 5842 | .. container:: content |
| 5843 | |
| 5844 | .. code:: |
| 5845 | |
| 5846 | #------------------------------------------------------------------------------- |
| 5847 | # ============LICENSE_START======================================================= |
| 5848 | # Copyright (C) 2016-2018 Ericsson. All rights reserved. |
| 5849 | # ================================================================================ |
| 5850 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 5851 | # you may not use this file except in compliance with the License. |
| 5852 | # You may obtain a copy of the License at |
| 5853 | # |
| 5854 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 5855 | # |
| 5856 | # Unless required by applicable law or agreed to in writing, software |
| 5857 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 5858 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 5859 | # See the License for the specific language governing permissions and |
| 5860 | # limitations under the License. |
| 5861 | # |
| 5862 | # SPDX-License-Identifier: Apache-2.0 |
| 5863 | # ============LICENSE_END========================================================= |
| 5864 | #------------------------------------------------------------------------------- |
| 5865 | |
| 5866 | model create name=MyFirstPolicyModel version=0.0.1 uuid=540226fb-55ee-4f0e-a444-983a0494818e description="This is my first Apex Policy Model." |
| 5867 | |
| 5868 | 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 |
| 5869 | |
| 5870 | 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 |
| 5871 | |
| 5872 | 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 |
| 5873 | |
| 5874 | 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 |
| 5875 | |
| 5876 | 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 |
| 5877 | |
| 5878 | 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 |
| 5879 | |
| 5880 | 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 |
| 5881 | |
| 5882 | 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 |
| 5883 | |
| 5884 | 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 |
| 5885 | |
| 5886 | 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 |
| 5887 | |
| 5888 | task create name=MorningBoozeCheck version=0.0.1 uuid=3351b0f4-cf06-4fa2-8823-edf67bd30223 description=LS |
| 5889 | This task checks if the sales request is for an item that contains alcohol. |
| 5890 | If the local time is between 00:00:00 and 11:30:00 then the sale is not authorised. Otherwise the sale is authorised. |
| 5891 | In this implementation we assume that all items with item_ID values between 1000 and 2000 contain alcohol :-) |
| 5892 | LE |
| 5893 | task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 |
| 5894 | task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=amount schemaName=price_type schemaVersion=0.0.1 |
| 5895 | task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 |
| 5896 | task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true |
| 5897 | task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=quantity schemaName=quantity_type schemaVersion=0.0.1 |
| 5898 | task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 |
| 5899 | task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 |
| 5900 | task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=time schemaName=timestamp_type schemaVersion=0.0.1 |
| 5901 | task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 |
| 5902 | task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=amount schemaName=price_type schemaVersion=0.0.1 |
| 5903 | task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 |
| 5904 | task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true |
| 5905 | task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=quantity schemaName=quantity_type schemaVersion=0.0.1 |
| 5906 | task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 |
| 5907 | task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 |
| 5908 | task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=authorised schemaName=authorised_type schemaVersion=0.0.1 |
| 5909 | task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=time schemaName=timestamp_type schemaVersion=0.0.1 |
| 5910 | task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=message schemaName=message_type schemaVersion=0.0.1 optional=true |
| 5911 | task logic create name=MorningBoozeCheck version=0.0.1 logicFlavour=MVEL logic=LS |
| 5912 | /* |
| 5913 | * ============LICENSE_START======================================================= |
| 5914 | * Copyright (C) 2016-2018 Ericsson. All rights reserved. |
| 5915 | * ================================================================================ |
| 5916 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5917 | * you may not use this file except in compliance with the License. |
| 5918 | * You may obtain a copy of the License at |
| 5919 | * |
| 5920 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 5921 | * |
| 5922 | * Unless required by applicable law or agreed to in writing, software |
| 5923 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 5924 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 5925 | * See the License for the specific language governing permissions and |
| 5926 | * limitations under the License. |
| 5927 | * |
| 5928 | * SPDX-License-Identifier: Apache-2.0 |
| 5929 | * ============LICENSE_END========================================================= |
| 5930 | */ |
| 5931 | import java.util.Date; |
| 5932 | import java.util.Calendar; |
| 5933 | import java.util.TimeZone; |
| 5934 | import java.text.SimpleDateFormat; |
| 5935 | |
| 5936 | logger.info("Task Execution: '"+subject.id+"'. Input Fields: '"+inFields+"'"); |
| 5937 | |
| 5938 | outFields.put("amount" , inFields.get("amount")); |
| 5939 | outFields.put("assistant_ID", inFields.get("assistant_ID")); |
| 5940 | outFields.put("notes" , inFields.get("notes")); |
| 5941 | outFields.put("quantity" , inFields.get("quantity")); |
| 5942 | outFields.put("branch_ID" , inFields.get("branch_ID")); |
| 5943 | outFields.put("item_ID" , inFields.get("item_ID")); |
| 5944 | outFields.put("time" , inFields.get("time")); |
| 5945 | outFields.put("sale_ID" , inFields.get("sale_ID")); |
| 5946 | |
| 5947 | item_id = inFields.get("item_ID"); |
| 5948 | |
| 5949 | //The events used later to test this task use GMT timezone! |
| 5950 | gmt = TimeZone.getTimeZone("GMT"); |
| 5951 | timenow = Calendar.getInstance(gmt); |
| 5952 | df = new SimpleDateFormat("HH:mm:ss z"); |
| 5953 | df.setTimeZone(gmt); |
| 5954 | timenow.setTimeInMillis(inFields.get("time")); |
| 5955 | |
| 5956 | midnight = timenow.clone(); |
| 5957 | midnight.set( |
| 5958 | timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), |
| 5959 | timenow.get(Calendar.DATE),0,0,0); |
| 5960 | eleven30 = timenow.clone(); |
| 5961 | eleven30.set( |
| 5962 | timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), |
| 5963 | timenow.get(Calendar.DATE),11,30,0); |
| 5964 | |
| 5965 | itemisalcohol = false; |
| 5966 | if(item_id != null && item_id >=1000 && item_id < 2000) |
| 5967 | itemisalcohol = true; |
| 5968 | |
| 5969 | if( itemisalcohol |
| 5970 | && timenow.after(midnight) && timenow.before(eleven30)){ |
| 5971 | outFields.put("authorised", false); |
| 5972 | outFields.put("message", "Sale not authorised by policy task "+subject.taskName+ |
| 5973 | " for time "+df.format(timenow.getTime())+ |
| 5974 | ". Alcohol can not be sold between "+df.format(midnight.getTime())+ |
| 5975 | " and "+df.format(eleven30.getTime())); |
| 5976 | return true; |
| 5977 | } |
| 5978 | else{ |
| 5979 | outFields.put("authorised", true); |
| 5980 | outFields.put("message", "Sale authorised by policy task "+subject.taskName+ |
| 5981 | " for time "+df.format(timenow.getTime())); |
| 5982 | return true; |
| 5983 | } |
| 5984 | |
| 5985 | /* |
| 5986 | This task checks if a sale request is for an item that is an alcoholic drink. |
| 5987 | If the local time is between 00:00:00 GMT and 11:30:00 GMT then the sale is not |
| 5988 | authorised. Otherwise the sale is authorised. |
| 5989 | In this implementation we assume that items with item_ID value between 1000 and |
| 5990 | 2000 are all alcoholic drinks :-) |
| 5991 | */ |
| 5992 | LE |
| 5993 | |
| 5994 | 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" |
| 5995 | event parameter create name=SALE_AUTH version=0.0.1 parName=amount schemaName=price_type schemaVersion=0.0.1 |
| 5996 | event parameter create name=SALE_AUTH version=0.0.1 parName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 |
| 5997 | event parameter create name=SALE_AUTH version=0.0.1 parName=authorised schemaName=authorised_type schemaVersion=0.0.1 |
| 5998 | event parameter create name=SALE_AUTH version=0.0.1 parName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 |
| 5999 | event parameter create name=SALE_AUTH version=0.0.1 parName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 |
| 6000 | event parameter create name=SALE_AUTH version=0.0.1 parName=message schemaName=message_type schemaVersion=0.0.1 optional=true |
| 6001 | event parameter create name=SALE_AUTH version=0.0.1 parName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true |
| 6002 | event parameter create name=SALE_AUTH version=0.0.1 parName=quantity schemaName=quantity_type schemaVersion=0.0.1 |
| 6003 | event parameter create name=SALE_AUTH version=0.0.1 parName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 |
| 6004 | event parameter create name=SALE_AUTH version=0.0.1 parName=time schemaName=timestamp_type schemaVersion=0.0.1 |
| 6005 | |
| 6006 | 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" |
| 6007 | event parameter create name=SALE_INPUT version=0.0.1 parName=amount schemaName=price_type schemaVersion=0.0.1 |
| 6008 | event parameter create name=SALE_INPUT version=0.0.1 parName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 |
| 6009 | event parameter create name=SALE_INPUT version=0.0.1 parName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 |
| 6010 | event parameter create name=SALE_INPUT version=0.0.1 parName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 |
| 6011 | event parameter create name=SALE_INPUT version=0.0.1 parName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true |
| 6012 | event parameter create name=SALE_INPUT version=0.0.1 parName=quantity schemaName=quantity_type schemaVersion=0.0.1 |
| 6013 | event parameter create name=SALE_INPUT version=0.0.1 parName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 |
| 6014 | event parameter create name=SALE_INPUT version=0.0.1 parName=time schemaName=timestamp_type schemaVersion=0.0.1 |
| 6015 | |
| 6016 | |
| 6017 | 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 |
| 6018 | policy state create name=MyFirstPolicy version=0.0.1 stateName=BoozeAuthDecide triggerName=SALE_INPUT triggerVersion=0.0.1 defaultTaskName=MorningBoozeCheck defaultTaskVersion=0.0.1 |
| 6019 | 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 |
| 6020 | 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 |
| 6021 | |
| 6022 | Policy Step 2 |
| 6023 | ------------- |
| 6024 | |
| 6025 | Scenario |
| 6026 | ######### |
| 6027 | .. container:: paragraph |
| 6028 | |
| 6029 | *HyperM* have just opened a new branch in a different |
| 6030 | country, but that country has different rules about when |
| 6031 | alcohol can be sold! In this section we will go through |
| 6032 | the necessary steps to extend our policy to enforce this |
| 6033 | for *HyperM*. |
| 6034 | |
| 6035 | .. container:: ulist |
| 6036 | |
| 6037 | - In some branches alcohol cannot be sold before 1pm, |
| 6038 | and not at all on Sundays. |
| 6039 | |
| 6040 | .. container:: paragraph |
| 6041 | |
| 6042 | Although there are a number of ways to accomplish this |
| 6043 | the easiest approach for us is to define another task and |
| 6044 | then select which task is appropriate at runtime |
| 6045 | depending on the branch identifier in the incoming event. |
| 6046 | |
| 6047 | Extend the Policy with the new Scenario |
| 6048 | ####################################### |
| 6049 | |
| 6050 | .. container:: paragraph |
| 6051 | |
| 6052 | To create a new Task click on the 'Tasks' tab. In the |
| 6053 | 'Tasks' pane, right click and select 'Create new Task': |
| 6054 | |
| 6055 | .. container:: paragraph |
| 6056 | |
| 6057 | Create a new Task called ``MorningBoozeCheckAlt1``. Use |
| 6058 | the 'Generate UUID' button to create a new unique ID for |
| 6059 | the task, and fill in a description for the task. Select |
| 6060 | the same input and output fields that we used earlier |
| 6061 | when we defined the ``MorningBoozeCheck`` task earlier. |
| 6062 | |
| 6063 | .. table:: Table 12. Input fields for ``MorningBoozeCheckAlt1`` task |
| 6064 | |
| 6065 | +-----------------------------------+-----------------------------------+ |
| 6066 | | Parameter Name | Parameter Type | |
| 6067 | +===================================+===================================+ |
| 6068 | | time | timestamp_type | |
| 6069 | +-----------------------------------+-----------------------------------+ |
| 6070 | | sale_ID | sale_ID_type | |
| 6071 | +-----------------------------------+-----------------------------------+ |
| 6072 | | amount | price_type | |
| 6073 | +-----------------------------------+-----------------------------------+ |
| 6074 | | item_ID | item_ID_type | |
| 6075 | +-----------------------------------+-----------------------------------+ |
| 6076 | | quantity | quantity_type | |
| 6077 | +-----------------------------------+-----------------------------------+ |
| 6078 | | assistant_ID | assistant_ID_type | |
| 6079 | +-----------------------------------+-----------------------------------+ |
| 6080 | | branch_ID | branch_ID_type | |
| 6081 | +-----------------------------------+-----------------------------------+ |
| 6082 | | notes | notes_type | |
| 6083 | +-----------------------------------+-----------------------------------+ |
| 6084 | |
| 6085 | .. table:: Table 13. Output fields for ``MorningBoozeCheckAlt1`` task |
| 6086 | |
| 6087 | +-----------------------------------+-----------------------------------+ |
| 6088 | | Parameter Name | Parameter Type | |
| 6089 | +===================================+===================================+ |
| 6090 | | sale_ID | sale_ID_type | |
| 6091 | +-----------------------------------+-----------------------------------+ |
| 6092 | | time | timestamp_type | |
| 6093 | +-----------------------------------+-----------------------------------+ |
| 6094 | | authorised | authorised_type | |
| 6095 | +-----------------------------------+-----------------------------------+ |
| 6096 | | message | message_type | |
| 6097 | +-----------------------------------+-----------------------------------+ |
| 6098 | | amount | price_type | |
| 6099 | +-----------------------------------+-----------------------------------+ |
| 6100 | | item_ID | item_ID_type | |
| 6101 | +-----------------------------------+-----------------------------------+ |
| 6102 | | assistant_ID | assistant_ID_type | |
| 6103 | +-----------------------------------+-----------------------------------+ |
| 6104 | | quantity | quantity_type | |
| 6105 | +-----------------------------------+-----------------------------------+ |
| 6106 | | branch_ID | branch_ID_type | |
| 6107 | +-----------------------------------+-----------------------------------+ |
| 6108 | | notes | notes_type | |
| 6109 | +-----------------------------------+-----------------------------------+ |
| 6110 | |
| 6111 | .. container:: paragraph |
| 6112 | |
| 6113 | This task also requires some 'Task Logic' to implement |
| 6114 | the new behaviour for this task. |
| 6115 | |
| 6116 | .. container:: paragraph |
| 6117 | |
| 6118 | For simplicity use the following code for the task logic. |
| 6119 | It again assumes that all items with ``item_ID`` between |
| 6120 | 1000 and 2000 contain alcohol. We again use the standard |
| 6121 | ``Java`` time utilities to check if the current time is |
| 6122 | between ``00:00:00 CET`` and ``13:00:00 CET`` or if it is |
| 6123 | ``Sunday``. |
| 6124 | |
| 6125 | .. container:: paragraph |
| 6126 | |
| 6127 | For this task we will again author the logic using the |
| 6128 | ```MVEL`` <https://en.wikipedia.org/wiki/MVEL>`__ |
| 6129 | scripting language. Sample task logic code (specified in |
| 6130 | ```MVEL`` <https://en.wikipedia.org/wiki/MVEL>`__) is |
| 6131 | given below. For a detailed guide to how to write your |
| 6132 | own logic in |
| 6133 | ```JavaScript`` <https://en.wikipedia.org/wiki/JavaScript>`__, |
| 6134 | ```MVEL`` <https://en.wikipedia.org/wiki/MVEL>`__ or one |
| 6135 | of the other supported languages please refer to APEX |
| 6136 | Programmers Guide. |
| 6137 | |
| 6138 | .. container:: listingblock |
| 6139 | |
| 6140 | .. container:: title |
| 6141 | |
| 6142 | MVEL code for the ``MorningBoozeCheckAlt1`` task |
| 6143 | |
| 6144 | .. container:: content |
| 6145 | |
| 6146 | .. code:: |
| 6147 | |
| 6148 | /* |
| 6149 | * ============LICENSE_START======================================================= |
| 6150 | * Copyright (C) 2016-2018 Ericsson. All rights reserved. |
| 6151 | * ================================================================================ |
| 6152 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 6153 | * you may not use this file except in compliance with the License. |
| 6154 | * You may obtain a copy of the License at |
| 6155 | * |
| 6156 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 6157 | * |
| 6158 | * Unless required by applicable law or agreed to in writing, software |
| 6159 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 6160 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 6161 | * See the License for the specific language governing permissions and |
| 6162 | * limitations under the License. |
| 6163 | * |
| 6164 | * SPDX-License-Identifier: Apache-2.0 |
| 6165 | * ============LICENSE_END========================================================= |
| 6166 | */ |
| 6167 | import java.util.Date; |
| 6168 | import java.util.Calendar; |
| 6169 | import java.util.TimeZone; |
| 6170 | import java.text.SimpleDateFormat; |
| 6171 | |
| 6172 | logger.info("Task Execution: '"+subject.id+"'. Input Event: '"+inFields+"'"); |
| 6173 | |
| 6174 | outFields.put("amount" , inFields.get("amount")); |
| 6175 | outFields.put("assistant_ID", inFields.get("assistant_ID")); |
| 6176 | outFields.put("notes" , inFields.get("notes")); |
| 6177 | outFields.put("quantity" , inFields.get("quantity")); |
| 6178 | outFields.put("branch_ID" , inFields.get("branch_ID")); |
| 6179 | outFields.put("item_ID" , inFields.get("item_ID")); |
| 6180 | outFields.put("time" , inFields.get("time")); |
| 6181 | outFields.put("sale_ID" , inFields.get("sale_ID")); |
| 6182 | |
| 6183 | item_id = inFields.get("item_ID"); |
| 6184 | |
| 6185 | //The events used later to test this task use CET timezone! |
| 6186 | cet = TimeZone.getTimeZone("CET"); |
| 6187 | timenow = Calendar.getInstance(cet); |
| 6188 | df = new SimpleDateFormat("HH:mm:ss z"); |
| 6189 | df.setTimeZone(cet); |
| 6190 | timenow.setTimeInMillis(inFields.get("time")); |
| 6191 | |
| 6192 | midnight = timenow.clone(); |
| 6193 | midnight.set( |
| 6194 | timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), |
| 6195 | timenow.get(Calendar.DATE),0,0,0); |
| 6196 | onepm = timenow.clone(); |
| 6197 | onepm.set( |
| 6198 | timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), |
| 6199 | timenow.get(Calendar.DATE),13,0,0); |
| 6200 | |
| 6201 | itemisalcohol = false; |
| 6202 | if(item_id != null && item_id >=1000 && item_id < 2000) |
| 6203 | itemisalcohol = true; |
| 6204 | |
| 6205 | if( itemisalcohol && |
| 6206 | ( (timenow.after(midnight) && timenow.before(onepm)) |
| 6207 | || |
| 6208 | (timenow.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) |
| 6209 | )){ |
| 6210 | outFields.put("authorised", false); |
| 6211 | outFields.put("message", "Sale not authorised by policy task "+subject.taskName+ |
| 6212 | " for time "+df.format(timenow.getTime())+ |
| 6213 | ". Alcohol can not be sold between "+df.format(midnight.getTime())+ |
| 6214 | " and "+df.format(onepm.getTime()) +" or on Sunday"); |
| 6215 | return true; |
| 6216 | } |
| 6217 | else{ |
| 6218 | outFields.put("authorised", true); |
| 6219 | outFields.put("message", "Sale authorised by policy task "+subject.taskName+ |
| 6220 | " for time "+df.format(timenow.getTime())); |
| 6221 | return true; |
| 6222 | } |
| 6223 | |
| 6224 | /* |
| 6225 | This task checks if a sale request is for an item that is an alcoholic drink. |
| 6226 | If the local time is between 00:00:00 CET and 13:00:00 CET then the sale is not authorised. |
| 6227 | Also alcohol sales are not allowed on Sundays. Otherwise the sale is authorised. |
| 6228 | In this implementation we assume that items with item_ID between 1000 and 2000 are all alcoholic drinks :-) |
| 6229 | */ |
| 6230 | |
| 6231 | .. container:: imageblock |
| 6232 | |
| 6233 | .. container:: content |
| 6234 | |
| 6235 | |Create a new alternative task MorningBoozeCheckAlt1| |
| 6236 | |
| 6237 | .. container:: title |
| 6238 | |
| 6239 | Figure 19. Create a new Task |
| 6240 | |
| 6241 | .. container:: paragraph |
| 6242 | |
| 6243 | The task definition is now complete so click the 'Submit' |
| 6244 | button to save the task. Now that we have created our |
| 6245 | task, we can can add this task to the single pre-existing |
| 6246 | state (``BoozeAuthDecide``) in our policy. |
| 6247 | |
| 6248 | .. container:: paragraph |
| 6249 | |
| 6250 | To edit the ``BoozeAuthDecide`` state in our policy click |
| 6251 | on the 'Policies' tab. In the 'Policies' pane, right |
| 6252 | click on our ``MyFirstPolicy`` policy and select 'Edit'. |
| 6253 | Navigate to the ``BoozeAuthDecide`` state in the 'states' |
| 6254 | section at the bottom of the policy definition pane. |
| 6255 | |
| 6256 | .. container:: imageblock |
| 6257 | |
| 6258 | .. container:: content |
| 6259 | |
| 6260 | |Right click to edit a policy| |
| 6261 | |
| 6262 | .. container:: title |
| 6263 | |
| 6264 | Figure 20. Edit a Policy |
| 6265 | |
| 6266 | .. container:: paragraph |
| 6267 | |
| 6268 | To add our new task ``MorningBoozeCheckAlt1``, scroll |
| 6269 | down to the ``BoozeAuthDecide`` state in the 'States' |
| 6270 | section. In the 'State Tasks' section for |
| 6271 | ``BoozeAuthDecide`` use the 'Add new task' button. Select |
| 6272 | our new ``MorningBoozeCheckAlt1`` task, and use the name |
| 6273 | of the task as the 'Local Name' for the task. The |
| 6274 | ``MorningBoozeCheckAlt1`` task can reuse the same |
| 6275 | ``MorningBoozeCheck_Output_Direct`` 'Direct State Output |
| 6276 | Mapping' that we used for the ``MorningBoozeCheck`` task. |
| 6277 | (Recall that the role of the 'State Output Mapping' is to |
| 6278 | select the output event for the state, and select the |
| 6279 | next state to be executed. These both remain the same as |
| 6280 | before.) |
| 6281 | |
| 6282 | .. container:: paragraph |
| 6283 | |
| 6284 | Since our state has more than one task we must define |
| 6285 | some logic to determine which task should be used each |
| 6286 | time the state is executed. This *task selection logic* |
| 6287 | is defined in the state definition. For our |
| 6288 | ``BoozeAuthDecide`` state we want the choice of which |
| 6289 | task to use to be based on the ``branch_ID`` from which |
| 6290 | the ``SALE_INPUT`` event originated. For simplicity sake |
| 6291 | let us assume that branches with ``branch_ID`` between |
| 6292 | ``0`` and ``999`` should use the ``MorningBoozeCheck`` |
| 6293 | task, and the branches with with ``branch_ID`` between |
| 6294 | ``1000`` and ``1999`` should use the |
| 6295 | ``MorningBoozeCheckAlt1`` task. |
| 6296 | |
| 6297 | .. container:: paragraph |
| 6298 | |
| 6299 | This time, for variety, we will author the task selection |
| 6300 | logic using the |
| 6301 | ```JavaScript`` <https://en.wikipedia.org/wiki/JavaScript>`__ |
| 6302 | scripting language. Sample task selection logic code |
| 6303 | (specified in |
| 6304 | ```JavaScript`` <https://en.wikipedia.org/wiki/JavaScript>`__) |
| 6305 | is given below. Paste the script text into the 'Task |
| 6306 | Selection Logic' box, and use "JAVASCRIPT" as the 'Task |
| 6307 | Selection Logic Type / Flavour'. It is necessary to mark |
| 6308 | one of the tasks as the 'Default Task' so that the task |
| 6309 | selection logic always has a fallback default option in |
| 6310 | cases where a particular task cannot be selected. In this |
| 6311 | case the ``MorningBoozeCheck`` task can be the default |
| 6312 | task. |
| 6313 | |
| 6314 | .. container:: listingblock |
| 6315 | |
| 6316 | .. container:: title |
| 6317 | |
| 6318 | JavaScript code for the ``BoozeAuthDecide`` task |
| 6319 | selection logic |
| 6320 | |
| 6321 | .. container:: content |
| 6322 | |
| 6323 | .. code:: |
| 6324 | |
| 6325 | /* |
| 6326 | * ============LICENSE_START======================================================= |
| 6327 | * Copyright (C) 2016-2018 Ericsson. All rights reserved. |
| 6328 | * ================================================================================ |
| 6329 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 6330 | * you may not use this file except in compliance with the License. |
| 6331 | * You may obtain a copy of the License at |
| 6332 | * |
| 6333 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 6334 | * |
| 6335 | * Unless required by applicable law or agreed to in writing, software |
| 6336 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 6337 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 6338 | * See the License for the specific language governing permissions and |
| 6339 | * limitations under the License. |
| 6340 | * |
| 6341 | * SPDX-License-Identifier: Apache-2.0 |
| 6342 | * ============LICENSE_END========================================================= |
| 6343 | */ |
| 6344 | |
| 6345 | |
| 6346 | var returnValueType = Java.type("java.lang.Boolean"); |
| 6347 | var returnValue = new returnValueType(true); |
| 6348 | |
| 6349 | executor.logger.info("Task Selection Execution: '"+executor.subject.id+ |
| 6350 | "'. Input Event: '"+executor.inFields+"'"); |
| 6351 | |
| 6352 | branchid = executor.inFields.get("branch_ID"); |
| 6353 | taskorig = executor.subject.getTaskKey("MorningBoozeCheck"); |
| 6354 | taskalt = executor.subject.getTaskKey("MorningBoozeCheckAlt1"); |
| 6355 | taskdef = executor.subject.getDefaultTaskKey(); |
| 6356 | |
| 6357 | if(branchid >=0 && branchid <1000){ |
| 6358 | taskorig.copyTo(executor.selectedTask); |
| 6359 | } |
| 6360 | else if (branchid >=1000 && branchid <2000){ |
| 6361 | taskalt.copyTo(executor.selectedTask); |
| 6362 | } |
| 6363 | else{ |
| 6364 | taskdef.copyTo(executor.selectedTask); |
| 6365 | } |
| 6366 | |
| 6367 | /* |
| 6368 | This task selection logic selects task "MorningBoozeCheck" for branches with |
| 6369 | 0<=branch_ID<1000 and selects task "MorningBoozeCheckAlt1" for branches with |
| 6370 | 1000<=branch_ID<2000. Otherwise the default task is selected. |
| 6371 | In this case the default task is also "MorningBoozeCheck" |
| 6372 | */ |
| 6373 | |
| 6374 | .. container:: imageblock |
| 6375 | |
| 6376 | .. container:: content |
| 6377 | |
| 6378 | |State definition with 2 Tasks and Task Selection |
| 6379 | Logic| |
| 6380 | |
| 6381 | .. container:: title |
| 6382 | |
| 6383 | Figure 21. State definition with 2 Tasks and Task |
| 6384 | Selection Logic |
| 6385 | |
| 6386 | .. container:: paragraph |
| 6387 | |
| 6388 | When complete don’t forget to click the 'Submit' button |
| 6389 | at the bottom of 'Policies' pane for our |
| 6390 | ``MyFirstPolicy`` policy after updating the |
| 6391 | ``BoozeAuthDecide`` state. |
| 6392 | |
| 6393 | .. container:: paragraph |
| 6394 | |
| 6395 | Congratulations, you have now completed the second step |
| 6396 | towards your first APEX policy. The policy model |
| 6397 | containing our new policy can again be validated and |
| 6398 | exported from the editor and saved as shown in Step 1. |
| 6399 | |
| 6400 | .. container:: paragraph |
| 6401 | |
| 6402 | The exported policy model is then available in the |
| 6403 | directory you selected, as |
| 6404 | `MyFirstPolicyModel_0.0.1.json <files/mfp-files/2/MyFirstPolicyModel_0.0.1.json>`__. |
| 6405 | The exported policy can now be loaded into the APEX |
| 6406 | Policy Engine, or can be re-loaded and edited by the APEX |
| 6407 | Policy Editor. |
| 6408 | |
| 6409 | Test Policy Step 2 |
| 6410 | ################## |
| 6411 | |
| 6412 | .. container:: paragraph |
| 6413 | |
| 6414 | To start a new APEX Engine you can use the following |
| 6415 | configuration. In a full APEX installation you can find |
| 6416 | this configuration in |
| 6417 | ``$APEX_HOME/examples/config/MyFirstPolicy/2/MyFirstPolicyConfigStdin2StdoutJsonEvent.json``. |
| 6418 | Note, this has changed from the configuration file in |
| 6419 | Step 1 to enable the ``JAVASCRIPT`` executor for our new |
| 6420 | 'Task Selection Logic'. |
| 6421 | |
| 6422 | .. container:: listingblock |
| 6423 | |
| 6424 | .. container:: title |
| 6425 | |
| 6426 | JSON to load and execute *My First Policy*, read input |
| 6427 | JSON events from ``stdin``, and emit output events to |
| 6428 | ``stdout`` |
| 6429 | |
| 6430 | .. container:: content |
| 6431 | |
| 6432 | .. code:: |
| 6433 | |
| 6434 | { |
| 6435 | "engineServiceParameters" : { |
| 6436 | "name" : "MyFirstPolicyApexEngine", |
| 6437 | "version" : "0.0.1", |
| 6438 | "id" : 102, |
| 6439 | "instanceCount" : 4, |
| 6440 | "deploymentPort" : 12345, |
| 6441 | "policyModelFileName" : "examples/models/MyFirstPolicy/2/MyFirstPolicyModel_0.0.1.json", |
| 6442 | "engineParameters" : { |
| 6443 | "executorParameters" : { |
| 6444 | "MVEL" : { |
| 6445 | "parameterClassName" : "org.onap.policy.apex.plugins.executor.mvel.MVELExecutorParameters" |
| 6446 | }, |
| 6447 | "JAVASCRIPT" : { |
| 6448 | "parameterClassName" : "org.onap.policy.apex.plugins.executor.javascript.JavascriptExecutorParameters" |
| 6449 | } |
| 6450 | } |
| 6451 | } |
| 6452 | }, |
| 6453 | "eventOutputParameters": { |
| 6454 | "FirstProducer": { |
| 6455 | "carrierTechnologyParameters" : { |
| 6456 | "carrierTechnology" : "FILE", |
| 6457 | "parameters" : { |
| 6458 | "standardIO" : true |
| 6459 | } |
| 6460 | }, |
| 6461 | "eventProtocolParameters" : { |
| 6462 | "eventProtocol" : "JSON" |
| 6463 | } |
| 6464 | } |
| 6465 | }, |
| 6466 | "eventInputParameters": { |
| 6467 | "FirstConsumer": { |
| 6468 | "carrierTechnologyParameters" : { |
| 6469 | "carrierTechnology" : "FILE", |
| 6470 | "parameters" : { |
| 6471 | "standardIO" : true |
| 6472 | } |
| 6473 | }, |
| 6474 | "eventProtocolParameters" : { |
| 6475 | "eventProtocol" : "JSON" |
| 6476 | } |
| 6477 | } |
| 6478 | } |
| 6479 | } |
| 6480 | |
| 6481 | .. container:: paragraph |
| 6482 | |
| 6483 | To test the policy try paste the following events into |
| 6484 | the console as the APEX engine executes. Note, all tests |
| 6485 | from Step 1 will still work perfectly since none of those |
| 6486 | events originate from a branch with ``branch_ID`` between |
| 6487 | ``1000`` and ``2000``. The 'Task Selection Logic' will |
| 6488 | therefore pick the ``MorningBoozeCheck`` task as |
| 6489 | expected, and will therefore give the same results. |
| 6490 | |
| 6491 | .. table:: Table 14. Inputs and Outputs when testing *My First Policy* |
| 6492 | |
| 6493 | +----------------------------------------------+------------------------------------------------------------+---------------------------+ |
| 6494 | | Input Event (JSON) | Output Event (JSON) | comment | |
| 6495 | +==============================================+============================================================+===========================+ |
| 6496 | | .. container:: | .. container:: | Request to buy | |
| 6497 | | | | alcohol item | |
| 6498 | | .. container:: listingblock | .. container:: listingblock | (``item_ID=1249``) | |
| 6499 | | | | | |
| 6500 | | | | at *08:41:06 | |
| 6501 | | | .. container:: content | GMT* on *Monday, | |
| 6502 | | .. container:: content | | 02 January | |
| 6503 | | | .. code:: | 2017*. | |
| 6504 | | | | | |
| 6505 | | | { | Sale is not | |
| 6506 | | .. code:: | "nameSpace": "com.hyperm", | authorized. Uses | |
| 6507 | | | "name": "SALE_AUTH", | the | |
| 6508 | | | "version": "0.0.1", | ``MorningBoozeCheck`` | |
| 6509 | | { | "source": "", | | |
| 6510 | | "nameSpace": "com.hyperm", | "target": "", | task. | |
| 6511 | | "name": "SALE_INPUT", | "amount": 1249, | | |
| 6512 | | "version": "0.0.1", | "assistant_ID":12, | Note this test | |
| 6513 | | "time": 1483346466000, | "authorised": false, | is copied from | |
| 6514 | | "sale_ID": 99999992, | "branch_ID": 2, | Step 1 above, | |
| 6515 | | "amount": 1249, | "item_ID": 1012, | and demonstrates | |
| 6516 | | "item_ID": 1012, | "message": "Sale not authorised by policy ta | that the | |
| 6517 | | "quantity": 1, | sk MorningBoozeCheck for time 08:41:06 GMT.| original | |
| 6518 | | "assistant_ID": 12, | Alcohol can not be sold between 00:00:00 | ``MorningBoozeCheck`` | |
| 6519 | | "branch_ID": 2 | GMT and 11:30:00 GMT", | | |
| 6520 | | } | "notes": null, | task is | |
| 6521 | | | "quantity": 1, | executed. | |
| 6522 | | | "sale_ID": 99999992, | | |
| 6523 | | | "time": 1483346466000 | | |
| 6524 | | | } | | |
| 6525 | +----------------------------------------------+------------------------------------------------------------+---------------------------+ |
| 6526 | | .. container:: | .. container:: | Request to buy | |
| 6527 | | | | alcohol | |
| 6528 | | .. container:: listingblock | .. container:: listingblock | (``item_ID=1047``) | |
| 6529 | | | | | |
| 6530 | | | | at *10:14:33* on | |
| 6531 | | | .. container:: content | *Thursday, 22 | |
| 6532 | | .. container:: content | | December 2016*. | |
| 6533 | | | .. code:: | | |
| 6534 | | | | Sale is not | |
| 6535 | | | { | authorized. Uses | |
| 6536 | | .. code:: | "nameSpace" : "com.hyperm", | the | |
| 6537 | | | "name" : "SALE_AUTH", | ``MorningBoozeCheckAlt1`` | |
| 6538 | | | "version" : "0.0.1", | task. | |
| 6539 | | { | "source" : "", | | |
| 6540 | | | "target" : "", | | |
| 6541 | | "nameSpace": "com.hyperm", | "sale_ID" : 99999981, | | |
| 6542 | | "name": "SALE_INPUT", | "amount" : 299, | | |
| 6543 | | "version": "0.0.1", | "assistant_ID": 1212, | | |
| 6544 | | "time": 1482398073000, | "notes" : null, | | |
| 6545 | | "sale_ID": 99999981, | "quantity" : 1, | | |
| 6546 | | "amount": 299, | "branch_ID" : 1002, | | |
| 6547 | | "item_ID": 1047, | "item_ID" : 1047, | | |
| 6548 | | "quantity": 1, | "authorised" : false, | | |
| 6549 | | "assistant_ID": 1212, | "time" : 1482398073000, | | |
| 6550 | | "branch_ID": 1002 | "message" : "Sale not authorised by policy t | | |
| 6551 | | } | ask MorningBoozeCheckAlt1 fortime | | |
| 6552 | | | 10:14:33 CET. Alcohol can not be sold | | |
| 6553 | | | between 00:00:00 CET and 13:00:00 CET or on | | |
| 6554 | | | Sunday" | | |
| 6555 | | | } | | |
| 6556 | +----------------------------------------------+------------------------------------------------------------+---------------------------+ |
| 6557 | | .. container:: | .. container:: | Request to buy | |
| 6558 | | | | alcohol | |
| 6559 | | .. container:: listingblock | .. container:: listingblock | (``item_ID=1443``) | |
| 6560 | | | | | |
| 6561 | | | | at *17:19:37* on | |
| 6562 | | | .. container:: content | *Sunday, 18 | |
| 6563 | | .. container:: content | | December 2016*. | |
| 6564 | | | .. code:: | | |
| 6565 | | | | Sale is not | |
| 6566 | | | { | authorized. Uses | |
| 6567 | | .. code:: | "nameSpace" : "com.hyperm", | the | |
| 6568 | | | | ``MorningBoozeCheckAlt1`` | |
| 6569 | | | "name" : "SALE_AUTH", | task. | |
| 6570 | | { | | | |
| 6571 | | "nameSpace": "com.hyperm", | "version" : "0.0.1", | | |
| 6572 | | "name": "SALE_INPUT", | "source" : "", | | |
| 6573 | | "version": "0.0.1", | "target" : "", | | |
| 6574 | | "time": 1482077977000, | "sale_ID" : 99999982, | | |
| 6575 | | "sale_ID": 99999982, | "amount" : 2199, | | |
| 6576 | | "amount": 2199, | "assistant_ID" : 94, | | |
| 6577 | | "item_ID": 1443, | "notes" : "Buy 3, get 1 free!!", | | |
| 6578 | | "quantity": 12, | "quantity" : 12, | | |
| 6579 | | "assistant_ID": 94, | "branch_ID" : 1003, | | |
| 6580 | | "branch_ID": 1003, | "item_ID" : 1443, | | |
| 6581 | | "notes": "Buy 3, get 1 free!!" | "authorised" : false, | | |
| 6582 | | } | "time" : 1482077977000, | | |
| 6583 | | | "message" : "Sale not authorised by policy t | | |
| 6584 | | | ask MorningBoozeCheckAlt1 for | | |
| 6585 | | | time 17:19:37 CET. Alcohol c | | |
| 6586 | | | an not be sold between 00:00: | | |
| 6587 | | | 00 CET and 13:00:00 CET or on | | |
| 6588 | | | Sunday" | | |
| 6589 | +----------------------------------------------+------------------------------------------------------------+---------------------------+ |
| 6590 | | .. container:: | .. container:: | Request to buy | |
| 6591 | | | | non-alcoholic | |
| 6592 | | .. container:: listingblock | .. container:: listingblock | item | |
| 6593 | | | | (``item_ID=5321``) | |
| 6594 | | | | | |
| 6595 | | | .. container:: content | at *11:13:09* on | |
| 6596 | | .. container:: content | | *Monday, 2 | |
| 6597 | | | .. code:: | January 2017*. | |
| 6598 | | | | | |
| 6599 | | | { | Sale is | |
| 6600 | | .. code:: | "nameSpace" : "com.hyperm", | authorized. Uses | |
| 6601 | | | "name" : "SALE_AUTH", | the | |
| 6602 | | { | "version" : "0.0.1", | ``MorningBoozeCheckAlt1`` | |
| 6603 | | "nameSpace": "com.hyperm", | "source" : "", | task. | |
| 6604 | | "name": "SALE_INPUT", | "target" : "", | | |
| 6605 | | "version": "0.0.1", | "sale_ID" : 99999983, | | |
| 6606 | | "time": 1483351989000, | "amount" : 699, | | |
| 6607 | | "sale_ID": 99999983, | "assistant_ID" : 2323, | | |
| 6608 | | "amount": 699, | "notes" : "", | | |
| 6609 | | "item_ID": 5321, | "quantity" : 1, | | |
| 6610 | | "quantity": 1, | "branch_ID" : 1001, | | |
| 6611 | | "assistant_ID": 2323, | "item_ID" : 5321, | | |
| 6612 | | "branch_ID": 1001, | "authorised" : true, | | |
| 6613 | | "notes": "" | "time" : 1483351989000, | | |
| 6614 | | } | "message" : "Sale authorised by policy task | | |
| 6615 | | | MorningBoozeCheckAlt1 for time 11:13:09 CET"| | |
| 6616 | | | } | | |
| 6617 | +----------------------------------------------+------------------------------------------------------------+---------------------------+ |
| 6618 | |
| 6619 | Policy 2 in CLI Editor |
| 6620 | ###################### |
| 6621 | |
| 6622 | .. container:: paragraph |
| 6623 | |
| 6624 | An equivalent version of the ``MyFirstPolicyModel`` |
| 6625 | policy model can again be generated using the APEX CLI |
| 6626 | editor. A sample APEX CLI script is shown below: |
| 6627 | |
| 6628 | .. container:: listingblock |
| 6629 | |
| 6630 | .. container:: title |
| 6631 | |
| 6632 | APEX CLI Editor code for Policy 2 |
| 6633 | |
| 6634 | .. container:: content |
| 6635 | |
| 6636 | .. code:: |
| 6637 | |
| 6638 | #------------------------------------------------------------------------------- |
| 6639 | # ============LICENSE_START======================================================= |
| 6640 | # Copyright (C) 2016-2018 Ericsson. All rights reserved. |
| 6641 | # ================================================================================ |
| 6642 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 6643 | # you may not use this file except in compliance with the License. |
| 6644 | # You may obtain a copy of the License at |
| 6645 | # |
| 6646 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 6647 | # |
| 6648 | # Unless required by applicable law or agreed to in writing, software |
| 6649 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 6650 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 6651 | # See the License for the specific language governing permissions and |
| 6652 | # limitations under the License. |
| 6653 | # |
| 6654 | # SPDX-License-Identifier: Apache-2.0 |
| 6655 | # ============LICENSE_END========================================================= |
| 6656 | #------------------------------------------------------------------------------- |
| 6657 | |
| 6658 | model create name=MyFirstPolicyModel version=0.0.1 uuid=540226fb-55ee-4f0e-a444-983a0494818e description="This is my first Apex Policy Model." |
| 6659 | |
| 6660 | 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 |
| 6661 | |
| 6662 | 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 |
| 6663 | |
| 6664 | 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 |
| 6665 | |
| 6666 | 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 |
| 6667 | |
| 6668 | 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 |
| 6669 | |
| 6670 | 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 |
| 6671 | |
| 6672 | 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 |
| 6673 | |
| 6674 | 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 |
| 6675 | |
| 6676 | 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 |
| 6677 | |
| 6678 | 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 |
| 6679 | |
| 6680 | task create name=MorningBoozeCheck version=0.0.1 uuid=3351b0f4-cf06-4fa2-8823-edf67bd30223 description=LS |
| 6681 | This task checks if the sales request is for an item that contains alcohol. |
| 6682 | If the local time is between 00:00:00 and 11:30:00 then the sale is not authorised. Otherwise the sale is authorised. |
| 6683 | In this implementation we assume that all items with item_ID values between 1000 and 2000 contain alcohol :-) |
| 6684 | LE |
| 6685 | task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 |
| 6686 | task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=amount schemaName=price_type schemaVersion=0.0.1 |
| 6687 | task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 |
| 6688 | task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true |
| 6689 | task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=quantity schemaName=quantity_type schemaVersion=0.0.1 |
| 6690 | task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 |
| 6691 | task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 |
| 6692 | task inputfield create name=MorningBoozeCheck version=0.0.1 fieldName=time schemaName=timestamp_type schemaVersion=0.0.1 |
| 6693 | task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 |
| 6694 | task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=amount schemaName=price_type schemaVersion=0.0.1 |
| 6695 | task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 |
| 6696 | task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true |
| 6697 | task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=quantity schemaName=quantity_type schemaVersion=0.0.1 |
| 6698 | task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 |
| 6699 | task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 |
| 6700 | task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=authorised schemaName=authorised_type schemaVersion=0.0.1 |
| 6701 | task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=time schemaName=timestamp_type schemaVersion=0.0.1 |
| 6702 | task outputfield create name=MorningBoozeCheck version=0.0.1 fieldName=message schemaName=message_type schemaVersion=0.0.1 optional=true |
| 6703 | task logic create name=MorningBoozeCheck version=0.0.1 logicFlavour=MVEL logic=LS |
| 6704 | /* |
| 6705 | * ============LICENSE_START======================================================= |
| 6706 | * Copyright (C) 2016-2018 Ericsson. All rights reserved. |
| 6707 | * ================================================================================ |
| 6708 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 6709 | * you may not use this file except in compliance with the License. |
| 6710 | * You may obtain a copy of the License at |
| 6711 | * |
| 6712 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 6713 | * |
| 6714 | * Unless required by applicable law or agreed to in writing, software |
| 6715 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 6716 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 6717 | * See the License for the specific language governing permissions and |
| 6718 | * limitations under the License. |
| 6719 | * |
| 6720 | * SPDX-License-Identifier: Apache-2.0 |
| 6721 | * ============LICENSE_END========================================================= |
| 6722 | */ |
| 6723 | import java.util.Date; |
| 6724 | import java.util.Calendar; |
| 6725 | import java.util.TimeZone; |
| 6726 | import java.text.SimpleDateFormat; |
| 6727 | |
| 6728 | logger.info("Task Execution: '"+subject.id+"'. Input Fields: '"+inFields+"'"); |
| 6729 | |
| 6730 | outFields.put("amount" , inFields.get("amount")); |
| 6731 | outFields.put("assistant_ID", inFields.get("assistant_ID")); |
| 6732 | outFields.put("notes" , inFields.get("notes")); |
| 6733 | outFields.put("quantity" , inFields.get("quantity")); |
| 6734 | outFields.put("branch_ID" , inFields.get("branch_ID")); |
| 6735 | outFields.put("item_ID" , inFields.get("item_ID")); |
| 6736 | outFields.put("time" , inFields.get("time")); |
| 6737 | outFields.put("sale_ID" , inFields.get("sale_ID")); |
| 6738 | |
| 6739 | item_id = inFields.get("item_ID"); |
| 6740 | |
| 6741 | //The events used later to test this task use GMT timezone! |
| 6742 | gmt = TimeZone.getTimeZone("GMT"); |
| 6743 | timenow = Calendar.getInstance(gmt); |
| 6744 | df = new SimpleDateFormat("HH:mm:ss z"); |
| 6745 | df.setTimeZone(gmt); |
| 6746 | timenow.setTimeInMillis(inFields.get("time")); |
| 6747 | |
| 6748 | midnight = timenow.clone(); |
| 6749 | midnight.set( |
| 6750 | timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), |
| 6751 | timenow.get(Calendar.DATE),0,0,0); |
| 6752 | eleven30 = timenow.clone(); |
| 6753 | eleven30.set( |
| 6754 | timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), |
| 6755 | timenow.get(Calendar.DATE),11,30,0); |
| 6756 | |
| 6757 | itemisalcohol = false; |
| 6758 | if(item_id != null && item_id >=1000 && item_id < 2000) |
| 6759 | itemisalcohol = true; |
| 6760 | |
| 6761 | if( itemisalcohol |
| 6762 | && timenow.after(midnight) && timenow.before(eleven30)){ |
| 6763 | outFields.put("authorised", false); |
| 6764 | outFields.put("message", "Sale not authorised by policy task "+subject.taskName+ |
| 6765 | " for time "+df.format(timenow.getTime())+ |
| 6766 | ". Alcohol can not be sold between "+df.format(midnight.getTime())+ |
| 6767 | " and "+df.format(eleven30.getTime())); |
| 6768 | return true; |
| 6769 | } |
| 6770 | else{ |
| 6771 | outFields.put("authorised", true); |
| 6772 | outFields.put("message", "Sale authorised by policy task "+subject.taskName+ |
| 6773 | " for time "+df.format(timenow.getTime())); |
| 6774 | return true; |
| 6775 | } |
| 6776 | |
| 6777 | /* |
| 6778 | This task checks if a sale request is for an item that is an alcoholic drink. |
| 6779 | If the local time is between 00:00:00 GMT and 11:30:00 GMT then the sale is not |
| 6780 | authorised. Otherwise the sale is authorised. |
| 6781 | In this implementation we assume that items with item_ID value between 1000 and |
| 6782 | 2000 are all alcoholic drinks :-) |
| 6783 | */ |
| 6784 | LE |
| 6785 | |
| 6786 | task create name=MorningBoozeCheckAlt1 version=0.0.1 uuid=bc6d90c9-c902-4686-afd3-925b30e39990 description=LS |
| 6787 | This task checks if a sale request is for an item that is an alcoholic drink. |
| 6788 | If the local time is between 00:00:00 CET and 13:00:00 CET then the sale is not authorised. |
| 6789 | Also alcohol sales are not allowed on Sundays. Otherwise the sale is authorised. |
| 6790 | In this implementation we assume that items with item_ID between 1000 and 2000 are all alcoholic drinks |
| 6791 | LE |
| 6792 | task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 |
| 6793 | task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=amount schemaName=price_type schemaVersion=0.0.1 |
| 6794 | task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 |
| 6795 | task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true |
| 6796 | task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=quantity schemaName=quantity_type schemaVersion=0.0.1 |
| 6797 | task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 |
| 6798 | task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 |
| 6799 | task inputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=time schemaName=timestamp_type schemaVersion=0.0.1 |
| 6800 | task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 |
| 6801 | task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=amount schemaName=price_type schemaVersion=0.0.1 |
| 6802 | task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 |
| 6803 | task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true |
| 6804 | task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=quantity schemaName=quantity_type schemaVersion=0.0.1 |
| 6805 | task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 |
| 6806 | task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 |
| 6807 | task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=authorised schemaName=authorised_type schemaVersion=0.0.1 |
| 6808 | task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=time schemaName=timestamp_type schemaVersion=0.0.1 |
| 6809 | task outputfield create name=MorningBoozeCheckAlt1 version=0.0.1 fieldName=message schemaName=message_type schemaVersion=0.0.1 optional=true |
| 6810 | task logic create name=MorningBoozeCheckAlt1 version=0.0.1 logicFlavour=MVEL logic=LS |
| 6811 | /* |
| 6812 | * ============LICENSE_START======================================================= |
| 6813 | * Copyright (C) 2016-2018 Ericsson. All rights reserved. |
| 6814 | * ================================================================================ |
| 6815 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 6816 | * you may not use this file except in compliance with the License. |
| 6817 | * You may obtain a copy of the License at |
| 6818 | * |
| 6819 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 6820 | * |
| 6821 | * Unless required by applicable law or agreed to in writing, software |
| 6822 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 6823 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 6824 | * See the License for the specific language governing permissions and |
| 6825 | * limitations under the License. |
| 6826 | * |
| 6827 | * SPDX-License-Identifier: Apache-2.0 |
| 6828 | * ============LICENSE_END========================================================= |
| 6829 | */ |
| 6830 | import java.util.Date; |
| 6831 | import java.util.Calendar; |
| 6832 | import java.util.TimeZone; |
| 6833 | import java.text.SimpleDateFormat; |
| 6834 | |
| 6835 | logger.info("Task Execution: '"+subject.id+"'. Input Event: '"+inFields+"'"); |
| 6836 | |
| 6837 | outFields.put("amount" , inFields.get("amount")); |
| 6838 | outFields.put("assistant_ID", inFields.get("assistant_ID")); |
| 6839 | outFields.put("notes" , inFields.get("notes")); |
| 6840 | outFields.put("quantity" , inFields.get("quantity")); |
| 6841 | outFields.put("branch_ID" , inFields.get("branch_ID")); |
| 6842 | outFields.put("item_ID" , inFields.get("item_ID")); |
| 6843 | outFields.put("time" , inFields.get("time")); |
| 6844 | outFields.put("sale_ID" , inFields.get("sale_ID")); |
| 6845 | |
| 6846 | item_id = inFields.get("item_ID"); |
| 6847 | |
| 6848 | //The events used later to test this task use CET timezone! |
| 6849 | cet = TimeZone.getTimeZone("CET"); |
| 6850 | timenow = Calendar.getInstance(cet); |
| 6851 | df = new SimpleDateFormat("HH:mm:ss z"); |
| 6852 | df.setTimeZone(cet); |
| 6853 | timenow.setTimeInMillis(inFields.get("time")); |
| 6854 | |
| 6855 | midnight = timenow.clone(); |
| 6856 | midnight.set( |
| 6857 | timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), |
| 6858 | timenow.get(Calendar.DATE),0,0,0); |
| 6859 | onepm = timenow.clone(); |
| 6860 | onepm.set( |
| 6861 | timenow.get(Calendar.YEAR),timenow.get(Calendar.MONTH), |
| 6862 | timenow.get(Calendar.DATE),13,0,0); |
| 6863 | |
| 6864 | itemisalcohol = false; |
| 6865 | if(item_id != null && item_id >=1000 && item_id < 2000) |
| 6866 | itemisalcohol = true; |
| 6867 | |
| 6868 | if( itemisalcohol && |
| 6869 | ( (timenow.after(midnight) && timenow.before(onepm)) |
| 6870 | || |
| 6871 | (timenow.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) |
| 6872 | )){ |
| 6873 | outFields.put("authorised", false); |
| 6874 | outFields.put("message", "Sale not authorised by policy task "+subject.taskName+ |
| 6875 | " for time "+df.format(timenow.getTime())+ |
| 6876 | ". Alcohol can not be sold between "+df.format(midnight.getTime())+ |
| 6877 | " and "+df.format(onepm.getTime()) +" or on Sunday"); |
| 6878 | return true; |
| 6879 | } |
| 6880 | else{ |
| 6881 | outFields.put("authorised", true); |
| 6882 | outFields.put("message", "Sale authorised by policy task "+subject.taskName+ |
| 6883 | " for time "+df.format(timenow.getTime())); |
| 6884 | return true; |
| 6885 | } |
| 6886 | |
| 6887 | /* |
| 6888 | This task checks if a sale request is for an item that is an alcoholic drink. |
| 6889 | If the local time is between 00:00:00 CET and 13:00:00 CET then the sale is not authorised. |
| 6890 | Also alcohol sales are not allowed on Sundays. Otherwise the sale is authorised. |
| 6891 | In this implementation we assume that items with item_ID between 1000 and 2000 are all alcoholic drinks :-) |
| 6892 | */ |
| 6893 | LE |
| 6894 | |
| 6895 | 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" |
| 6896 | event parameter create name=SALE_AUTH version=0.0.1 parName=amount schemaName=price_type schemaVersion=0.0.1 |
| 6897 | event parameter create name=SALE_AUTH version=0.0.1 parName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 |
| 6898 | event parameter create name=SALE_AUTH version=0.0.1 parName=authorised schemaName=authorised_type schemaVersion=0.0.1 |
| 6899 | event parameter create name=SALE_AUTH version=0.0.1 parName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 |
| 6900 | event parameter create name=SALE_AUTH version=0.0.1 parName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 |
| 6901 | event parameter create name=SALE_AUTH version=0.0.1 parName=message schemaName=message_type schemaVersion=0.0.1 optional=true |
| 6902 | event parameter create name=SALE_AUTH version=0.0.1 parName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true |
| 6903 | event parameter create name=SALE_AUTH version=0.0.1 parName=quantity schemaName=quantity_type schemaVersion=0.0.1 |
| 6904 | event parameter create name=SALE_AUTH version=0.0.1 parName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 |
| 6905 | event parameter create name=SALE_AUTH version=0.0.1 parName=time schemaName=timestamp_type schemaVersion=0.0.1 |
| 6906 | |
| 6907 | 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" |
| 6908 | event parameter create name=SALE_INPUT version=0.0.1 parName=amount schemaName=price_type schemaVersion=0.0.1 |
| 6909 | event parameter create name=SALE_INPUT version=0.0.1 parName=assistant_ID schemaName=assistant_ID_type schemaVersion=0.0.1 |
| 6910 | event parameter create name=SALE_INPUT version=0.0.1 parName=branch_ID schemaName=branch_ID_type schemaVersion=0.0.1 |
| 6911 | event parameter create name=SALE_INPUT version=0.0.1 parName=item_ID schemaName=item_ID_type schemaVersion=0.0.1 |
| 6912 | event parameter create name=SALE_INPUT version=0.0.1 parName=notes schemaName=notes_type schemaVersion=0.0.1 optional=true |
| 6913 | event parameter create name=SALE_INPUT version=0.0.1 parName=quantity schemaName=quantity_type schemaVersion=0.0.1 |
| 6914 | event parameter create name=SALE_INPUT version=0.0.1 parName=sale_ID schemaName=sale_ID_type schemaVersion=0.0.1 |
| 6915 | event parameter create name=SALE_INPUT version=0.0.1 parName=time schemaName=timestamp_type schemaVersion=0.0.1 |
| 6916 | |
| 6917 | |
| 6918 | 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 |
| 6919 | policy state create name=MyFirstPolicy version=0.0.1 stateName=BoozeAuthDecide triggerName=SALE_INPUT triggerVersion=0.0.1 defaultTaskName=MorningBoozeCheck defaultTaskVersion=0.0.1 |
| 6920 | 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 |
| 6921 | 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 |
| 6922 | 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 |
| 6923 | policy state selecttasklogic create name=MyFirstPolicy version=0.0.1 stateName=BoozeAuthDecide logicFlavour=JAVASCRIPT logic=LS |
| 6924 | /* |
| 6925 | * ============LICENSE_START======================================================= |
| 6926 | * Copyright (C) 2016-2018 Ericsson. All rights reserved. |
| 6927 | * ================================================================================ |
| 6928 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 6929 | * you may not use this file except in compliance with the License. |
| 6930 | * You may obtain a copy of the License at |
| 6931 | * |
| 6932 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 6933 | * |
| 6934 | * Unless required by applicable law or agreed to in writing, software |
| 6935 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 6936 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 6937 | * See the License for the specific language governing permissions and |
| 6938 | * limitations under the License. |
| 6939 | * |
| 6940 | * SPDX-License-Identifier: Apache-2.0 |
| 6941 | * ============LICENSE_END========================================================= |
| 6942 | */ |
| 6943 | |
| 6944 | var returnValueType = Java.type("java.lang.Boolean"); |
| 6945 | var returnValue = new returnValueType(true); |
| 6946 | |
| 6947 | executor.logger.info("Task Selection Execution: '"+executor.subject.id+"'. Input Event: '"+executor.inFields+"'"); |
| 6948 | |
| 6949 | branchid = executor.inFields.get("branch_ID"); |
| 6950 | taskorig = executor.subject.getTaskKey("MorningBoozeCheck"); |
| 6951 | taskalt = executor.subject.getTaskKey("MorningBoozeCheckAlt1"); |
| 6952 | taskdef = executor.subject.getDefaultTaskKey(); |
| 6953 | |
| 6954 | if(branchid >=0 && branchid <1000){ |
| 6955 | taskorig.copyTo(executor.selectedTask); |
| 6956 | } |
| 6957 | else if (branchid >=1000 && branchid <2000){ |
| 6958 | taskalt.copyTo(executor.selectedTask); |
| 6959 | } |
| 6960 | else{ |
| 6961 | taskdef.copyTo(executor.selectedTask); |
| 6962 | } |
| 6963 | |
| 6964 | /* |
| 6965 | 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" |
| 6966 | */ |
| 6967 | LE |
| 6968 | |
| 6969 | APEX Logging |
| 6970 | ^^^^^^^^^^^^ |
| 6971 | |
| 6972 | Introduction to APEX Logging |
| 6973 | ---------------------------- |
| 6974 | |
| 6975 | .. container:: paragraph |
| 6976 | |
| 6977 | All APEX components make extensive use of logging using the |
| 6978 | logging façade `SLF4J <https://www.slf4j.org/>`__ with the |
| 6979 | backend `Logback <https://logback.qos.ch/>`__. Both are used |
| 6980 | off-the-shelve, so the standard documentation and |
| 6981 | configuration apply to APEX logging. For details on how to |
| 6982 | work with logback please see the `logback |
| 6983 | manual <https://logback.qos.ch/manual/index.html>`__. |
| 6984 | |
| 6985 | .. container:: paragraph |
| 6986 | |
| 6987 | The APEX applications is the logback configuration file |
| 6988 | ``$APEX_HOME/etc/logback.xml`` (Windows: |
| 6989 | ``%APEX_HOME%\etc\logback.xml``). The logging backend is set |
| 6990 | to no debug, i.e. logs from the logging framework should be |
| 6991 | hidden at runtime. |
| 6992 | |
| 6993 | .. container:: paragraph |
| 6994 | |
| 6995 | The configurable log levels work as expected: |
| 6996 | |
| 6997 | .. container:: ulist |
| 6998 | |
| 6999 | - *error* (or *ERROR*) is used for serious errors in the |
| 7000 | APEX runtime engine |
| 7001 | |
| 7002 | - *warn* (or *WARN*) is used for warnings, which in general |
| 7003 | can be ignored but might indicate some deeper problems |
| 7004 | |
| 7005 | - *info* (or *INFO*) is used to provide generally |
| 7006 | interesting messages for startup and policy execution |
| 7007 | |
| 7008 | - *debug* (or *DEBUG*) provides more details on startup and |
| 7009 | policy execution |
| 7010 | |
| 7011 | - *trace* (or *TRACE*) gives full details on every aspect |
| 7012 | of the APEX engine from start to end |
| 7013 | |
| 7014 | .. container:: paragraph |
| 7015 | |
| 7016 | The loggers can also be configured as expected. The standard |
| 7017 | configuration (after installing APEX) uses log level *info* |
| 7018 | on all APEX classes (components). |
| 7019 | |
| 7020 | .. container:: paragraph |
| 7021 | |
| 7022 | The applications and scripts in ``$APEX_HOME/bin`` (Windows: |
| 7023 | ``%APEX_HOME\bin``) are configured to use the logback |
| 7024 | configuration ``$APEX_HOME/etc/logback.xml`` (Windows: |
| 7025 | ``%APEX_HOME\etc\logback.xml``). There are multiple ways to |
| 7026 | use different logback configurations, for instance: |
| 7027 | |
| 7028 | .. container:: ulist |
| 7029 | |
| 7030 | - Maintain multiple configurations in ``etc``, for instance |
| 7031 | a ``logback-debug.xml`` for deep debugging and a |
| 7032 | ``logback-production.xml`` for APEX in production mode, |
| 7033 | then copy the required configuration file to the used |
| 7034 | ``logback.xml`` prior starting APEX |
| 7035 | |
| 7036 | - Edit the scripts in ``bin`` to use a different logback |
| 7037 | configuration file (only recommended if you are familiar |
| 7038 | with editing bash scripts or windows batch files) |
| 7039 | |
| 7040 | Standard Logging Configuration |
| 7041 | ------------------------------ |
| 7042 | |
| 7043 | .. container:: paragraph |
| 7044 | |
| 7045 | The standard logging configuration defines a context *APEX*, |
| 7046 | which is used in the standard output pattern. The location |
| 7047 | for log files is defined in the property ``VAR_LOG`` and set |
| 7048 | to ``/var/log/onap/policy/apex-pdp``. The standard status |
| 7049 | listener is set to *NOP* and the overall logback |
| 7050 | configuration is set to no debug. |
| 7051 | |
| 7052 | .. container:: listingblock |
| 7053 | |
| 7054 | .. container:: content |
| 7055 | |
| 7056 | .. code:: |
| 7057 | :number-lines: |
| 7058 | |
| 7059 | <configuration debug="false"> |
| 7060 | <statusListener class="ch.qos.logback.core.status.NopStatusListener" /> |
| 7061 | |
| 7062 | <contextName>Apex</contextName> |
| 7063 | <property name="VAR_LOG" value="/var/log/onap/policy/apex-pdp/" /> |
| 7064 | |
| 7065 | ...appenders |
| 7066 | ...loggers |
| 7067 | </configuration> |
| 7068 | |
| 7069 | .. container:: paragraph |
| 7070 | |
| 7071 | The first appender defined is called ``STDOUT`` for logs to standard |
| 7072 | out. |
| 7073 | |
| 7074 | .. container:: listingblock |
| 7075 | |
| 7076 | .. container:: content |
| 7077 | |
| 7078 | .. code:: |
| 7079 | :number-lines: |
| 7080 | |
| 7081 | <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> |
| 7082 | <encoder> |
| 7083 | <Pattern>%d %contextName [%t] %level %logger{36} - %msg%n</Pattern> |
| 7084 | </encoder> |
| 7085 | </appender> |
| 7086 | |
| 7087 | .. container:: paragraph |
| 7088 | |
| 7089 | The root level logger then is set to the level *info* using the |
| 7090 | standard out appender. |
| 7091 | |
| 7092 | .. container:: listingblock |
| 7093 | |
| 7094 | .. container:: content |
| 7095 | |
| 7096 | .. code:: |
| 7097 | :number-lines: |
| 7098 | |
| 7099 | <root level="info"> |
| 7100 | <appender-ref ref="STDOUT" /> |
| 7101 | </root> |
| 7102 | |
| 7103 | .. container:: paragraph |
| 7104 | |
| 7105 | The second appender is called ``FILE``. It writes logs to a file |
| 7106 | ``apex.log``. |
| 7107 | |
| 7108 | .. container:: listingblock |
| 7109 | |
| 7110 | .. container:: content |
| 7111 | |
| 7112 | .. code:: |
| 7113 | :number-lines: |
| 7114 | |
| 7115 | <appender name="FILE" class="ch.qos.logback.core.FileAppender"> |
| 7116 | <file>${VAR_LOG}/apex.log</file> |
| 7117 | <encoder> |
| 7118 | <pattern>%d %-5relative [procId=${processId}] [%thread] %-5level %logger{26} - %msg %n %ex{full}</pattern> |
| 7119 | </encoder> |
| 7120 | </appender> |
| 7121 | |
| 7122 | .. container:: paragraph |
| 7123 | |
| 7124 | The third appender is called ``CTXT_FILE``. It writes logs to a file |
| 7125 | ``apex_ctxt.log``. |
| 7126 | |
| 7127 | .. container:: listingblock |
| 7128 | |
| 7129 | .. container:: content |
| 7130 | |
| 7131 | .. code:: |
| 7132 | :number-lines: |
| 7133 | |
| 7134 | <appender name="CTXT_FILE" class="ch.qos.logback.core.FileAppender"> |
| 7135 | <file>${VAR_LOG}/apex_ctxt.log</file> |
| 7136 | <encoder> |
| 7137 | <pattern>%d %-5relative [procId=${processId}] [%thread] %-5level %logger{26} - %msg %n %ex{full}</pattern> |
| 7138 | </encoder> |
| 7139 | </appender> |
| 7140 | |
| 7141 | .. container:: paragraph |
| 7142 | |
| 7143 | The last definitions are for specific loggers. The first logger |
| 7144 | captures all standard APEX classes. It is configured for log level |
| 7145 | *info* and uses the standard output and file appenders. The second |
| 7146 | logger captures APEX context classes responsible for context |
| 7147 | monitoring. It is configured for log level *trace* and uses the |
| 7148 | context file appender. |
| 7149 | |
| 7150 | .. container:: listingblock |
| 7151 | |
| 7152 | .. container:: content |
| 7153 | |
| 7154 | .. code:: |
| 7155 | :number-lines: |
| 7156 | |
| 7157 | |
| 7158 | <logger name="org.onap.policy.apex" level="info" additivity="false"> |
| 7159 | <appender-ref ref="STDOUT" /> |
| 7160 | <appender-ref ref="FILE" /> |
| 7161 | </logger> |
| 7162 | |
| 7163 | <logger name="org.onap.policy.apex.core.context.monitoring" level="TRACE" additivity="false"> |
| 7164 | <appender-ref ref="CTXT_FILE" /> |
| 7165 | </logger> |
| 7166 | |
| 7167 | Adding Logback Status and Debug |
| 7168 | ------------------------------- |
| 7169 | |
| 7170 | .. container:: paragraph |
| 7171 | |
| 7172 | To activate logback status messages change the status listener |
| 7173 | from 'NOP' to for instance console. |
| 7174 | |
| 7175 | .. container:: listingblock |
| 7176 | |
| 7177 | .. container:: content |
| 7178 | |
| 7179 | .. code:: |
| 7180 | |
| 7181 | <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" /> |
| 7182 | |
| 7183 | .. container:: paragraph |
| 7184 | |
| 7185 | To activate all logback debugging, for instance to debug a new |
| 7186 | logback configuration, activate the debug attribute in the |
| 7187 | configuration. |
| 7188 | |
| 7189 | .. container:: listingblock |
| 7190 | |
| 7191 | .. container:: content |
| 7192 | |
| 7193 | .. code:: |
| 7194 | |
| 7195 | <configuration debug="true"> |
| 7196 | ... |
| 7197 | </configuration> |
| 7198 | |
| 7199 | Logging External Components |
| 7200 | --------------------------- |
| 7201 | |
| 7202 | .. container:: paragraph |
| 7203 | |
| 7204 | Logback can also be configured to log any other, external |
| 7205 | components APEX is using, if they are using the common logging |
| 7206 | framework. |
| 7207 | |
| 7208 | .. container:: paragraph |
| 7209 | |
| 7210 | For instance, the context component of APEX is using *Infinispan* |
| 7211 | and one can add a logger for this external component. The |
| 7212 | following example adds a logger for *Infinispan* using the |
| 7213 | standard output appender. |
| 7214 | |
| 7215 | .. container:: listingblock |
| 7216 | |
| 7217 | .. container:: content |
| 7218 | |
| 7219 | .. code:: |
| 7220 | |
| 7221 | <logger name="org.infinispan" level="INFO" additivity="false"> |
| 7222 | <appender-ref ref="STDOUT" /> |
| 7223 | </logger> |
| 7224 | |
| 7225 | .. container:: paragraph |
| 7226 | |
| 7227 | Another example is Apache Zookeeper. The following example adds a |
| 7228 | logger for Zookeeper using the standard outout appender. |
| 7229 | |
| 7230 | .. container:: listingblock |
| 7231 | |
| 7232 | .. container:: content |
| 7233 | |
| 7234 | .. code:: |
| 7235 | |
| 7236 | <logger name="org.apache.zookeeper.ClientCnxn" level="INFO" additivity="false"> |
| 7237 | <appender-ref ref="STDOUT" /> |
| 7238 | </logger> |
| 7239 | |
| 7240 | Configuring loggers for Policy Logic |
| 7241 | ------------------------------------ |
| 7242 | |
| 7243 | .. container:: paragraph |
| 7244 | |
| 7245 | The logging for the logic inside a policy (task logic, task |
| 7246 | selection logic, state finalizer logic) can be configured separate |
| 7247 | from standard logging. The logger for policy logic is |
| 7248 | ``org.onap.policy.apex.executionlogging``. The following example |
| 7249 | defines |
| 7250 | |
| 7251 | .. container:: ulist |
| 7252 | |
| 7253 | - a new appender for standard out using a very simple pattern |
| 7254 | (simply the actual message) |
| 7255 | |
| 7256 | - a logger for policy logic to standard out using the new |
| 7257 | appender and the already described file appender. |
| 7258 | |
| 7259 | .. container:: listingblock |
| 7260 | |
| 7261 | .. container:: content |
| 7262 | |
| 7263 | .. code:: |
| 7264 | |
| 7265 | <appender name="POLICY_APPENDER_STDOUT" class="ch.qos.logback.core.ConsoleAppender"> |
| 7266 | <encoder> |
| 7267 | <pattern>policy: %msg\n</pattern> |
| 7268 | </encoder> |
| 7269 | </appender> |
| 7270 | |
| 7271 | <logger name="org.onap.policy.apex.executionlogging" level="info" additivity="false"> |
| 7272 | <appender-ref ref="POLICY_APPENDER_STDOUT" /> |
| 7273 | <appender-ref ref="FILE" /> |
| 7274 | </logger> |
| 7275 | |
| 7276 | .. container:: paragraph |
| 7277 | |
| 7278 | It is also possible to use specific logging for parts of policy |
| 7279 | logic. The following example defines a logger for task logic. |
| 7280 | |
| 7281 | .. container:: listingblock |
| 7282 | |
| 7283 | .. container:: content |
| 7284 | |
| 7285 | .. code:: |
| 7286 | |
| 7287 | <logger name="org.onap.policy.apex.executionlogging.TaskExecutionLogging" level="TRACE" additivity="false"> |
| 7288 | <appender-ref ref="POLICY_APPENDER_STDOUT" /> |
| 7289 | </logger> |
| 7290 | |
| 7291 | Rolling File Appenders |
| 7292 | ---------------------- |
| 7293 | |
| 7294 | .. container:: paragraph |
| 7295 | |
| 7296 | Rolling file appenders are a good option for more complex logging |
| 7297 | of a production or complex testing APEX installation. The standard |
| 7298 | logback configuration can be used for these use cases. This |
| 7299 | section gives two examples for the standard logging and for |
| 7300 | context logging. |
| 7301 | |
| 7302 | .. container:: paragraph |
| 7303 | |
| 7304 | First the standard logging. The following example defines a |
| 7305 | rolling file appender. The appender rolls over on a daily basis. |
| 7306 | It allows for a file size of 100 MB. |
| 7307 | |
| 7308 | .. container:: listingblock |
| 7309 | |
| 7310 | .. container:: content |
| 7311 | |
| 7312 | .. code:: |
| 7313 | |
| 7314 | <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| 7315 | <file>${VAR_LOG}/apex.log</file> |
| 7316 | <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
| 7317 | <!-- rollover daily --> |
| 7318 | <!-- <fileNamePattern>xstream-%d{yyyy-MM-dd}.%i.txt</fileNamePattern> --> |
| 7319 | <fileNamePattern>${VAR_LOG}/apex_%d{yyyy-MM-dd}.%i.log.gz |
| 7320 | </fileNamePattern> |
| 7321 | <maxHistory>4</maxHistory> |
| 7322 | <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> |
| 7323 | <!-- or whenever the file size reaches 100MB --> |
| 7324 | <maxFileSize>100MB</maxFileSize> |
| 7325 | </timeBasedFileNamingAndTriggeringPolicy> |
| 7326 | </rollingPolicy> |
| 7327 | <encoder> |
| 7328 | <pattern> |
| 7329 | %d %-5relative [procId=${processId}] [%thread] %-5level %logger{26} - %msg %ex{full} %n |
| 7330 | </pattern> |
| 7331 | </encoder> |
| 7332 | </appender> |
| 7333 | |
| 7334 | .. container:: paragraph |
| 7335 | |
| 7336 | A very similar configuration can be used for a rolling file |
| 7337 | appender logging APEX context. |
| 7338 | |
| 7339 | .. container:: listingblock |
| 7340 | |
| 7341 | .. container:: content |
| 7342 | |
| 7343 | .. code:: |
| 7344 | |
| 7345 | <appender name="CTXT-FILE" |
| 7346 | class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| 7347 | <file>${VAR_LOG}/apex_ctxt.log</file> |
| 7348 | <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
| 7349 | <fileNamePattern>${VAR_LOG}/apex_ctxt_%d{yyyy-MM-dd}.%i.log.gz |
| 7350 | </fileNamePattern> |
| 7351 | <maxHistory>4</maxHistory> |
| 7352 | <timeBasedFileNamingAndTriggeringPolicy |
| 7353 | class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> |
| 7354 | <maxFileSize>100MB</maxFileSize> |
| 7355 | </timeBasedFileNamingAndTriggeringPolicy> |
| 7356 | </rollingPolicy> |
| 7357 | <encoder> |
| 7358 | <pattern> |
| 7359 | %d %-5relative [procId=${processId}] [%thread] %-5level %logger{26} - %msg %ex{full} %n |
| 7360 | </pattern> |
| 7361 | </encoder> |
| 7362 | </appender> |
| 7363 | |
| 7364 | Example Configuration for Logging Logic |
| 7365 | --------------------------------------- |
| 7366 | |
| 7367 | .. container:: paragraph |
| 7368 | |
| 7369 | The following example shows a configuration that logs policy logic |
| 7370 | to standard out and a file (*info*). All other APEX components are |
| 7371 | logging to a file (*debug*).. This configuration an be used in a |
| 7372 | pre-production phase with the APEX engine still running in a |
| 7373 | separate terminal to monitor policy execution. This logback |
| 7374 | configuration is in the APEX installation as |
| 7375 | ``etc/logback-logic.xml``. |
| 7376 | |
| 7377 | .. container:: listingblock |
| 7378 | |
| 7379 | .. container:: content |
| 7380 | |
| 7381 | .. code:: |
| 7382 | |
| 7383 | <configuration debug="false"> |
| 7384 | <statusListener class="ch.qos.logback.core.status.NopStatusListener" /> |
| 7385 | |
| 7386 | <contextName>Apex</contextName> |
| 7387 | <property name="VAR_LOG" value="/var/log/onap/policy/apex-pdp/" /> |
| 7388 | |
| 7389 | <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> |
| 7390 | <encoder> |
| 7391 | <Pattern>%d %contextName [%t] %level %logger{36} - %msg%n</Pattern> |
| 7392 | </encoder> |
| 7393 | </appender> |
| 7394 | |
| 7395 | <appender name="FILE" class="ch.qos.logback.core.FileAppender"> |
| 7396 | <file>${VAR_LOG}/apex.log</file> |
| 7397 | <encoder> |
| 7398 | <pattern> |
| 7399 | %d %-5relative [procId=${processId}] [%thread] %-5level%logger{26} - %msg %n %ex{full} |
| 7400 | </pattern> |
| 7401 | </encoder> |
| 7402 | </appender> |
| 7403 | |
| 7404 | <appender name="POLICY_APPENDER_STDOUT" class="ch.qos.logback.core.ConsoleAppender"> |
| 7405 | <encoder> |
| 7406 | <pattern>policy: %msg\n</pattern> |
| 7407 | </encoder> |
| 7408 | </appender> |
| 7409 | |
| 7410 | <root level="error"> |
| 7411 | <appender-ref ref="STDOUT" /> |
| 7412 | </root> |
| 7413 | |
| 7414 | <logger name="org.onap.policy.apex" level="debug" additivity="false"> |
| 7415 | <appender-ref ref="FILE" /> |
| 7416 | </logger> |
| 7417 | |
| 7418 | <logger name="org.onap.policy.apex.executionlogging" level="info" additivity="false"> |
| 7419 | <appender-ref ref="POLICY_APPENDER_STDOUT" /> |
| 7420 | <appender-ref ref="FILE" /> |
| 7421 | </logger> |
| 7422 | </configuration> |
| 7423 | |
| 7424 | Example Configuration for a Production Server |
| 7425 | --------------------------------------------- |
| 7426 | |
| 7427 | .. container:: paragraph |
| 7428 | |
| 7429 | The following example shows a configuration that logs all APEX |
| 7430 | components, including policy logic, to a file (*debug*). This |
| 7431 | configuration an be used in a production phase with the APEX |
| 7432 | engine being executed as a service on a system without console |
| 7433 | output. This logback configuration is in the APEX installation as |
| 7434 | ``logback-server.xml`` |
| 7435 | |
| 7436 | .. container:: listingblock |
| 7437 | |
| 7438 | .. container:: content |
| 7439 | |
| 7440 | .. code:: |
| 7441 | |
| 7442 | <configuration debug="false"> |
| 7443 | <statusListener class="ch.qos.logback.core.status.NopStatusListener" /> |
| 7444 | |
| 7445 | <contextName>Apex</contextName> |
| 7446 | <property name="VAR_LOG" value="/var/log/onap/policy/apex-pdp/" /> |
| 7447 | |
| 7448 | <appender name="FILE" class="ch.qos.logback.core.FileAppender"> |
| 7449 | <file>${VAR_LOG}/apex.log</file> |
| 7450 | <encoder> |
| 7451 | <pattern> |
| 7452 | %d %-5relative [procId=${processId}] [%thread] %-5level%logger{26} - %msg %n %ex{full} |
| 7453 | </pattern> |
| 7454 | </encoder> |
| 7455 | </appender> |
| 7456 | |
| 7457 | <root level="debug"> |
| 7458 | <appender-ref ref="FILE" /> |
| 7459 | </root> |
| 7460 | |
| 7461 | <logger name="org.onap.policy.apex.executionlogging" level="debug" additivity="false"> |
| 7462 | <appender-ref ref="FILE" /> |
| 7463 | </logger> |
| 7464 | </configuration> |
| 7465 | |
| 7466 | Building a System with Websocket Backend |
| 7467 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 7468 | |
| 7469 | Websockets |
| 7470 | ---------- |
| 7471 | |
| 7472 | .. container:: paragraph |
| 7473 | |
| 7474 | Websocket is a protocol to run sockets of HTTP. Since it in |
| 7475 | essence a socket, the connection is realized between a |
| 7476 | server (waiting for connections) and a client (connecting to |
| 7477 | a server). Server/client separation is only important for |
| 7478 | connection establishment, once connected, everyone can |
| 7479 | send/receive on the same socket (as any standard socket |
| 7480 | would allow). |
| 7481 | |
| 7482 | .. container:: paragraph |
| 7483 | |
| 7484 | Standard Websocket implementations are simple, no |
| 7485 | publish/subscribe and no special event handling. Most |
| 7486 | servers simply send all incoming messages to all |
| 7487 | connections. There is a PubSub definition on top of |
| 7488 | Websocket called `WAMP <http://wamp-proto.org/>`__. APEX |
| 7489 | does not support WAMP at the moment. |
| 7490 | |
| 7491 | Websocket in Java |
| 7492 | ----------------- |
| 7493 | |
| 7494 | .. container:: paragraph |
| 7495 | |
| 7496 | In Java, `JSR |
| 7497 | 356 <http://www.oracle.com/technetwork/articles/java/jsr356-1937161.html>`__ |
| 7498 | defines the standard Websocket API. This JSR is part of Jave |
| 7499 | EE 7 standard. For Java SE, several implementations exist in |
| 7500 | open source. Since Websockets are a stable standard and |
| 7501 | simple, most implementations are stable and ready to use. A |
| 7502 | lot of products support Websockets, like Spring, JBoss, |
| 7503 | Netty, … there are also Kafka extensions for Websockets. |
| 7504 | |
| 7505 | Websocket Example Code for Websocket clients (FOSS) |
| 7506 | --------------------------------------------------- |
| 7507 | |
| 7508 | .. container:: paragraph |
| 7509 | |
| 7510 | There are a lot of implementations and examples available on |
| 7511 | Github for Websocket clients. If one is using Java EE 7, |
| 7512 | then one can also use the native Websocket implementation. |
| 7513 | Good examples for clients using simply Java SE are here: |
| 7514 | |
| 7515 | .. container:: ulist |
| 7516 | |
| 7517 | - `Websocket |
| 7518 | implementation <https://github.com/TooTallNate/Java-WebSocket>`__ |
| 7519 | |
| 7520 | - `Websocket sending client example, using |
| 7521 | AWT <https://github.com/TooTallNate/Java-WebSocket/blob/master/src/main/example/ChatClient.java>`__ |
| 7522 | |
| 7523 | - `Websocket receiving client example (simple echo |
| 7524 | client) <https://github.com/TooTallNate/Java-WebSocket/blob/master/src/main/example/ExampleClient.java>`__ |
| 7525 | |
| 7526 | .. container:: paragraph |
| 7527 | |
| 7528 | For Java EE, the native Websocket API is explained here: |
| 7529 | |
| 7530 | .. container:: ulist |
| 7531 | |
| 7532 | - `Oracle |
| 7533 | docs <http://www.oracle.com/technetwork/articles/java/jsr356-1937161.html>`__ |
| 7534 | |
| 7535 | - link: `An |
| 7536 | example <http://www.programmingforliving.com/2013/08/jsr-356-java-api-for-websocket-client-api.html>`__ |
| 7537 | |
| 7538 | BCP: Websocket Configuration |
| 7539 | ---------------------------- |
| 7540 | |
| 7541 | .. container:: paragraph |
| 7542 | |
| 7543 | The probably best is to configure APEX for Websocket servers |
| 7544 | for input (ingress, consume) and output (egress, produce) |
| 7545 | interfaces. This means that APEX will start Websocket |
| 7546 | servers on named ports and wait for clients to connect. |
| 7547 | Advantage: once APEX is running all connectivity |
| 7548 | infrastructure is running as well. Consequence: if APEX is |
| 7549 | not running, everyone else is in the dark, too. |
| 7550 | |
| 7551 | .. container:: paragraph |
| 7552 | |
| 7553 | The best protocol to be used is JSON string. Each event on |
| 7554 | any interface is then a string with a JSON encoding. JSON |
| 7555 | string is a little bit slower than byte code, but we doubt |
| 7556 | that this will be noticeable. A further advantage of JSON |
| 7557 | strings over Websockets with APEX starting the servers: it |
| 7558 | is very easy to connect web browsers to such a system. |
| 7559 | Simple connect the web browser to the APEX sockets and |
| 7560 | send/read JSON strings. |
| 7561 | |
| 7562 | .. container:: paragraph |
| 7563 | |
| 7564 | Once APEX is started you simply connect Websocket clients to |
| 7565 | it, and send/receive event. When APEX is terminated, the |
| 7566 | Websocket servers go down, and the clients will be |
| 7567 | disconnected. APEX does not (yet) support auto-client |
| 7568 | reconnect nor WAMP, so clients might need to be restarted or |
| 7569 | reconnected manually after an APEX boot. |
| 7570 | |
| 7571 | Demo with VPN Policy Model |
| 7572 | -------------------------- |
| 7573 | |
| 7574 | .. container:: paragraph |
| 7575 | |
| 7576 | We assume that you have an APEX installation using the full |
| 7577 | package, i.e. APEX with all examples, of version ``0.5.6`` |
| 7578 | or higher. We will use the VPN policy from the APEX examples |
| 7579 | here. |
| 7580 | |
| 7581 | .. container:: paragraph |
| 7582 | |
| 7583 | Now, have the following ready to start the demo: |
| 7584 | |
| 7585 | .. container:: ulist |
| 7586 | |
| 7587 | - 3 terminals on the host where APEX is running (we need 1 |
| 7588 | for APEX and 1 for each client) |
| 7589 | |
| 7590 | - the events in the file |
| 7591 | ``$APEX_HOME/examples/events/VPN/SetupEvents.json`` open |
| 7592 | in an editor (we need to send those events to APEX) |
| 7593 | |
| 7594 | - the events in the file |
| 7595 | ``$APEX_HOME/examples/events/VPN/Link09Events.json`` open |
| 7596 | in an editor (we need to send those events to APEX) |
| 7597 | |
| 7598 | A Websocket Configuration for the VPN Domain |
| 7599 | ############################################ |
| 7600 | |
| 7601 | .. container:: paragraph |
| 7602 | |
| 7603 | Create a new APEX configuration using the VPN policy |
| 7604 | model and configuring APEX as discussed above for |
| 7605 | Websockets. Copy the following configuration into |
| 7606 | ``$APEX_HOME/examples/config/VPN/Ws2WsServerAvroContextJsonEvent.json`` |
| 7607 | (for Windows use |
| 7608 | ``%APEX_HOME%\examples\config\VPN\Ws2WsServerAvroContextJsonEvent.json``): |
| 7609 | |
| 7610 | .. container:: listingblock |
| 7611 | |
| 7612 | .. container:: content |
| 7613 | |
| 7614 | .. code:: |
| 7615 | :number-lines: |
| 7616 | |
| 7617 | { |
| 7618 | "engineServiceParameters" : { |
| 7619 | "name" : "VPNApexEngine", |
| 7620 | "version" : "0.0.1", |
| 7621 | "id" : 45, |
| 7622 | "instanceCount" : 1, |
| 7623 | "deploymentPort" : 12345, |
| 7624 | "policyModelFileName" : "examples/models/VPN/VPNPolicyModelAvro.json", |
| 7625 | "engineParameters" : { |
| 7626 | "executorParameters" : { |
| 7627 | "MVEL" : { |
| 7628 | "parameterClassName" : "org.onap.policy.apex.plugins.executor.mvel.MVELExecutorParameters" |
| 7629 | } |
| 7630 | }, |
| 7631 | "contextParameters" : { |
| 7632 | "parameterClassName" : "org.onap.policy.apex.context.parameters.ContextParameters", |
| 7633 | "schemaParameters":{ |
| 7634 | "Avro":{ |
| 7635 | "parameterClassName" : "org.onap.policy.apex.plugins.context.schema.avro.AvroSchemaHelperParameters" |
| 7636 | } |
| 7637 | } |
| 7638 | } |
| 7639 | } |
| 7640 | }, |
| 7641 | "producerCarrierTechnologyParameters" : { |
| 7642 | "carrierTechnology" : "WEBSOCKET", |
| 7643 | "parameterClassName" : "org.onap.policy.apex.plugins.event.carrier.websocket.WEBSOCKETCarrierTechnologyParameters", |
| 7644 | "parameters" : { |
| 7645 | "wsClient" : false, |
| 7646 | "port" : 42452 |
| 7647 | } |
| 7648 | }, |
| 7649 | "producerEventProtocolParameters" : { |
| 7650 | "eventProtocol" : "JSON" |
| 7651 | }, |
| 7652 | "consumerCarrierTechnologyParameters" : { |
| 7653 | "carrierTechnology" : "WEBSOCKET", |
| 7654 | "parameterClassName" : "org.onap.policy.apex.plugins.event.carrier.websocket.WEBSOCKETCarrierTechnologyParameters", |
| 7655 | "parameters" : { |
| 7656 | "wsClient" : false, |
| 7657 | "port" : 42450 |
| 7658 | } |
| 7659 | }, |
| 7660 | "consumerEventProtocolParameters" : { |
| 7661 | "eventProtocol" : "JSON" |
| 7662 | } |
| 7663 | } |
| 7664 | |
| 7665 | Start APEX Engine |
| 7666 | ################# |
| 7667 | |
| 7668 | .. container:: paragraph |
| 7669 | |
| 7670 | In a new terminal, start APEX with the new configuration for |
| 7671 | Websocket-Server ingress/egress: |
| 7672 | |
| 7673 | .. container:: listingblock |
| 7674 | |
| 7675 | .. container:: content |
| 7676 | |
| 7677 | .. code:: |
| 7678 | :number-lines: |
| 7679 | |
| 7680 | #: $APEX_HOME/bin/apexEngine.sh -c $APEX_HOME/examples/config/VPN/Ws2WsServerAvroContextJsonEvent.json |
| 7681 | |
| 7682 | .. container:: listingblock |
| 7683 | |
| 7684 | .. container:: content |
| 7685 | |
| 7686 | .. code:: |
| 7687 | :number-lines: |
| 7688 | |
| 7689 | #: %APEX_HOME%\bin\apexEngine.bat -c %APEX_HOME%\examples\config\VPN\Ws2WsServerAvroContextJsonEvent.json |
| 7690 | |
| 7691 | .. container:: paragraph |
| 7692 | |
| 7693 | Wait for APEX to start, it takes a while to create all Websocket |
| 7694 | servers (about 8 seconds on a standard laptop without cached |
| 7695 | binaries). depending on your log messages, you will see no (some, a |
| 7696 | lot) log messages. If APEX starts correctly, the last few messages |
| 7697 | you should see are: |
| 7698 | |
| 7699 | .. container:: listingblock |
| 7700 | |
| 7701 | .. container:: content |
| 7702 | |
| 7703 | .. code:: |
| 7704 | :number-lines: |
| 7705 | |
| 7706 | 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) |
| 7707 | 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 ... |
| 7708 | 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 |
| 7709 | Started Apex service |
| 7710 | |
| 7711 | .. container:: paragraph |
| 7712 | |
| 7713 | APEX is running in the new terminal and will produce output when the |
| 7714 | policy is triggered/executed. |
| 7715 | |
| 7716 | Run the Websocket Echo Client |
| 7717 | ############################# |
| 7718 | |
| 7719 | .. container:: paragraph |
| 7720 | |
| 7721 | The echo client is included in an APEX full installation. To run |
| 7722 | the client, open a new shell (Unix, Cygwin) or command prompt |
| 7723 | (``cmd`` on Windows). Then use the APEX application launcher to |
| 7724 | start the client. |
| 7725 | |
| 7726 | .. important:: |
| 7727 | APEX engine needs to run first |
| 7728 | The example assumes that an APEX engine configured for *produce* carrier technology Websocket and *JSON* event protocol is executed first. |
| 7729 | |
| 7730 | +---------------------------------------------------------+-----------------------------------------------------------+ |
| 7731 | | Unix, Cygwin | Windows | |
| 7732 | +=========================================================+===========================================================+ |
| 7733 | | .. container:: | .. container:: | |
| 7734 | | | | |
| 7735 | | .. container:: listingblock | .. container:: listingblock | |
| 7736 | | | | |
| 7737 | | .. container:: content | .. container:: content | |
| 7738 | | | | |
| 7739 | | .. code:: | .. code:: | |
| 7740 | | | | |
| 7741 | | # $APEX_HOME/bin/apexApps.sh ws-echo [args] | > %APEX_HOME%\bin\apexApps.bat ws-echo [args] | |
| 7742 | +---------------------------------------------------------+-----------------------------------------------------------+ |
| 7743 | |
| 7744 | .. container:: paragraph |
| 7745 | |
| 7746 | Use the following command line arguments for server and port of |
| 7747 | the Websocket server. The port should be the same as configured in |
| 7748 | the APEX engine. The server host should be the host on which the |
| 7749 | APEX engine is running |
| 7750 | |
| 7751 | .. container:: ulist |
| 7752 | |
| 7753 | - ``-p`` defines the Websocket port to connect to (defaults to |
| 7754 | ``8887``) |
| 7755 | |
| 7756 | - ``-s`` defines the host on which a Websocket server is running |
| 7757 | (defaults to ``localhost``) |
| 7758 | |
| 7759 | .. container:: paragraph |
| 7760 | |
| 7761 | Let’s assume that there is an APEX engine running, configured for |
| 7762 | produce Websocket carrier technology, as server, for port 42452, |
| 7763 | with produce event protocol JSON,. If we start the console client |
| 7764 | on the same host, we can omit the ``-s`` options. We start the |
| 7765 | console client as: |
| 7766 | |
| 7767 | .. container:: listingblock |
| 7768 | |
| 7769 | .. container:: content |
| 7770 | |
| 7771 | .. code:: |
| 7772 | |
| 7773 | # $APEX_HOME/bin/apexApps.sh ws-echo -p 42452 (1) |
| 7774 | > %APEX_HOME%\bin\apexApps.bat ws-echo -p 42452 (2) |
| 7775 | |
| 7776 | .. container:: colist arabic |
| 7777 | |
| 7778 | +-------+--------------------------------+ |
| 7779 | | **1** | Start client on Unix or Cygwin | |
| 7780 | +-------+--------------------------------+ |
| 7781 | | **2** | Start client on Windows | |
| 7782 | +-------+--------------------------------+ |
| 7783 | |
| 7784 | .. container:: paragraph |
| 7785 | |
| 7786 | Once started successfully, the client will produce the following |
| 7787 | messages (assuming we used ``-p 42452`` and an APEX engine is |
| 7788 | running on ``localhost`` with the same port: |
| 7789 | |
| 7790 | .. container:: listingblock |
| 7791 | |
| 7792 | .. container:: content |
| 7793 | |
| 7794 | .. code:: |
| 7795 | |
| 7796 | ws-simple-echo: starting simple event echo |
| 7797 | --> server: localhost |
| 7798 | --> port: 42452 |
| 7799 | |
| 7800 | Once started, the application will simply print out all received events to standard out. |
| 7801 | Each received event will be prefixed by '---' and suffixed by '====' |
| 7802 | |
| 7803 | |
| 7804 | ws-simple-echo: opened connection to APEX (Web Socket Protocol Handshake) |
| 7805 | |
| 7806 | Run the Websocket Console Client |
| 7807 | ################################ |
| 7808 | |
| 7809 | .. container:: paragraph |
| 7810 | |
| 7811 | The console client is included in an APEX full installation. To |
| 7812 | run the client, open a new shell (Unix, Cygwin) or command prompt |
| 7813 | (``cmd`` on Windows). Then use the APEX application launcher to |
| 7814 | start the client. |
| 7815 | |
| 7816 | .. important:: |
| 7817 | APEX engine needs to run first |
| 7818 | The example assumes that an APEX engine configured for *consume* carrier technology Websocket and *JSON* event |
| 7819 | protocol is executed first. |
| 7820 | |
| 7821 | +------------------------------------------------------------+--------------------------------------------------------------+ |
| 7822 | | Unix, Cygwin | Windows | |
| 7823 | +============================================================+==============================================================+ |
| 7824 | | .. container:: | .. container:: | |
| 7825 | | | | |
| 7826 | | .. container:: listingblock | .. container:: listingblock | |
| 7827 | | | | |
| 7828 | | .. container:: content | .. container:: content | |
| 7829 | | | | |
| 7830 | | .. code:: | .. code:: | |
| 7831 | | | | |
| 7832 | | # $APEX_HOME/bin/apexApps.sh ws-console [args] | > %APEX_HOME%\bin\apexApps.bat ws-console [args] | |
| 7833 | +------------------------------------------------------------+--------------------------------------------------------------+ |
| 7834 | |
| 7835 | .. container:: paragraph |
| 7836 | |
| 7837 | Use the following command line arguments for server and port of |
| 7838 | the Websocket server. The port should be the same as configured in |
| 7839 | the APEX engine. The server host should be the host on which the |
| 7840 | APEX engine is running |
| 7841 | |
| 7842 | .. container:: ulist |
| 7843 | |
| 7844 | - ``-p`` defines the Websocket port to connect to (defaults to |
| 7845 | ``8887``) |
| 7846 | |
| 7847 | - ``-s`` defines the host on which a Websocket server is running |
| 7848 | (defaults to ``localhost``) |
| 7849 | |
| 7850 | .. container:: paragraph |
| 7851 | |
| 7852 | Let’s assume that there is an APEX engine running, configured for |
| 7853 | consume Websocket carrier technology, as server, for port 42450, |
| 7854 | with consume event protocol JSON,. If we start the console client |
| 7855 | on the same host, we can omit the ``-s`` options. We start the |
| 7856 | console client as: |
| 7857 | |
| 7858 | .. container:: listingblock |
| 7859 | |
| 7860 | .. container:: content |
| 7861 | |
| 7862 | .. code:: |
| 7863 | |
| 7864 | # $APEX_HOME/bin/apexApps.sh ws-console -p 42450 (1) |
| 7865 | > %APEX_HOME%\bin\apexApps.sh ws-console -p 42450 (2) |
| 7866 | |
| 7867 | .. container:: colist arabic |
| 7868 | |
| 7869 | +-------+--------------------------------+ |
| 7870 | | **1** | Start client on Unix or Cygwin | |
| 7871 | +-------+--------------------------------+ |
| 7872 | | **2** | Start client on Windows | |
| 7873 | +-------+--------------------------------+ |
| 7874 | |
| 7875 | .. container:: paragraph |
| 7876 | |
| 7877 | Once started successfully, the client will produce the following |
| 7878 | messages (assuming we used ``-p 42450`` and an APEX engine is |
| 7879 | running on ``localhost`` with the same port: |
| 7880 | |
| 7881 | .. container:: listingblock |
| 7882 | |
| 7883 | .. container:: content |
| 7884 | |
| 7885 | .. code:: |
| 7886 | |
| 7887 | ws-simple-console: starting simple event console |
| 7888 | --> server: localhost |
| 7889 | --> port: 42450 |
| 7890 | |
| 7891 | - terminate the application typing 'exit<enter>' or using 'CTRL+C' |
| 7892 | - events are created by a non-blank starting line and terminated by a blank line |
| 7893 | |
| 7894 | |
| 7895 | ws-simple-console: opened connection to APEX (Web Socket Protocol Handshake) |
| 7896 | |
| 7897 | Send Events |
| 7898 | ########### |
| 7899 | |
| 7900 | .. container:: paragraph |
| 7901 | |
| 7902 | Now you have the full system up and running: |
| 7903 | |
| 7904 | .. container:: ulist |
| 7905 | |
| 7906 | - Terminal 1: APEX ready and loaded |
| 7907 | |
| 7908 | - Terminal 2: an echo client, printing received messages produced |
| 7909 | by the VPN policy |
| 7910 | |
| 7911 | - Terminal 2: a console client, waiting for input on the console |
| 7912 | (standard in) and sending text to APEX |
| 7913 | |
| 7914 | .. container:: paragraph |
| 7915 | |
| 7916 | We started the engine with the VPN policy example. So all the |
| 7917 | events we are using now are located in files in the following |
| 7918 | example directory: |
| 7919 | |
| 7920 | .. container:: listingblock |
| 7921 | |
| 7922 | .. container:: content |
| 7923 | |
| 7924 | .. code:: |
| 7925 | :number-lines: |
| 7926 | |
| 7927 | #: $APEX_HOME/examples/events/VPN |
| 7928 | > %APEX_HOME%\examples\events\VPN |
| 7929 | |
| 7930 | .. container:: paragraph |
| 7931 | |
| 7932 | To sends events, simply copy the content of the event files into |
| 7933 | Terminal 3 (the console client). It will read multi-line JSON text |
| 7934 | and send the events. So copy the content of ``SetupEvents.json`` into |
| 7935 | the client. APEX will trigger a policy and produce some output, the |
| 7936 | echo client will also print some events created in the policy. In |
| 7937 | Terminal 1 (APEX) you’ll see some status messages from the policy as: |
| 7938 | |
| 7939 | .. container:: listingblock |
| 7940 | |
| 7941 | .. container:: content |
| 7942 | |
| 7943 | .. code:: |
| 7944 | :number-lines: |
| 7945 | |
| 7946 | {Link=L09, LinkUp=true} |
| 7947 | L09 true |
| 7948 | outFields: {Link=L09, LinkUp=true} |
| 7949 | {Link=L10, LinkUp=true} |
| 7950 | L09 true |
| 7951 | L10 true |
| 7952 | outFields: {Link=L10, LinkUp=true} |
| 7953 | {CustomerName=C, LinkList=L09 L10, SlaDT=300, YtdDT=300} |
| 7954 | *** Customers *** |
| 7955 | C 300 300 [L09, L10] |
| 7956 | outFields: {CustomerName=C, LinkList=L09 L10, SlaDT=300, YtdDT=300} |
| 7957 | {CustomerName=A, LinkList=L09 L10, SlaDT=300, YtdDT=50} |
| 7958 | *** Customers *** |
| 7959 | A 300 50 [L09, L10] |
| 7960 | C 300 300 [L09, L10] |
| 7961 | outFields: {CustomerName=A, LinkList=L09 L10, SlaDT=300, YtdDT=50} |
| 7962 | {CustomerName=D, LinkList=L09 L10, SlaDT=300, YtdDT=400} |
| 7963 | *** Customers *** |
| 7964 | A 300 50 [L09, L10] |
| 7965 | C 300 300 [L09, L10] |
| 7966 | D 300 400 [L09, L10] |
| 7967 | outFields: {CustomerName=D, LinkList=L09 L10, SlaDT=300, YtdDT=400} |
| 7968 | {CustomerName=B, LinkList=L09 L10, SlaDT=300, YtdDT=299} |
| 7969 | *** Customers *** |
| 7970 | A 300 50 [L09, L10] |
| 7971 | B 300 299 [L09, L10] |
| 7972 | C 300 300 [L09, L10] |
| 7973 | D 300 400 [L09, L10] |
| 7974 | outFields: {CustomerName=B, LinkList=L09 L10, SlaDT=300, YtdDT=299} |
| 7975 | |
| 7976 | .. container:: paragraph |
| 7977 | |
| 7978 | In Terminal 2 (echo-client) you see the received events, the last two |
| 7979 | should look like: |
| 7980 | |
| 7981 | .. container:: listingblock |
| 7982 | |
| 7983 | .. container:: content |
| 7984 | |
| 7985 | .. code:: |
| 7986 | :number-lines: |
| 7987 | |
| 7988 | ws-simple-echo: received |
| 7989 | --------------------------------- |
| 7990 | { |
| 7991 | "name": "VPNCustomerCtxtActEvent", |
| 7992 | "version": "0.0.1", |
| 7993 | "nameSpace": "org.onap.policy.apex.domains.vpn.events", |
| 7994 | "source": "Source", |
| 7995 | "target": "Target", |
| 7996 | "CustomerName": "C", |
| 7997 | "LinkList": "L09 L10", |
| 7998 | "SlaDT": 300, |
| 7999 | "YtdDT": 300 |
| 8000 | } |
| 8001 | ================================= |
| 8002 | |
| 8003 | ws-simple-echo: received |
| 8004 | --------------------------------- |
| 8005 | { |
| 8006 | "name": "VPNCustomerCtxtActEvent", |
| 8007 | "version": "0.0.1", |
| 8008 | "nameSpace": "org.onap.policy.apex.domains.vpn.events", |
| 8009 | "source": "Source", |
| 8010 | "target": "Target", |
| 8011 | "CustomerName": "D", |
| 8012 | "LinkList": "L09 L10", |
| 8013 | "SlaDT": 300, |
| 8014 | "YtdDT": 400 |
| 8015 | } |
| 8016 | ================================= |
| 8017 | |
| 8018 | .. container:: paragraph |
| 8019 | |
| 8020 | Congratulations, you have triggered a policy in APEX using |
| 8021 | Websockets, the policy did run through, created events, picked up by |
| 8022 | the echo-client. |
| 8023 | |
| 8024 | .. container:: paragraph |
| 8025 | |
| 8026 | Now you can send the Link 09 and Link 10 events, they will trigger |
| 8027 | the actual VPN policy and some calculations are made. Let’s take the |
| 8028 | Link 09 events from ``Link09Events.json``, copy them all into |
| 8029 | Terminal 3 (the console). APEX will run the policy (with some status |
| 8030 | output), and the echo client will receive and print events. |
| 8031 | |
| 8032 | .. container:: paragraph |
| 8033 | |
| 8034 | To terminate the applications, simply press ``CTRL+C`` in Terminal 1 |
| 8035 | (APEX). This will also terminate the echo-client in Terminal 2. Then |
| 8036 | type ``exit<enter>`` in Terminal 3 (or ``CTRL+C``) to terminate the |
| 8037 | console-client. |
| 8038 | |
| 8039 | .. container:: |
| 8040 | :name: footer |
| 8041 | |
| 8042 | .. container:: |
| 8043 | :name: footer-text |
| 8044 | |
| 8045 | 2.0.0-SNAPSHOT |
| 8046 | Last updated 2018-09-10 15:38:16 IST |
| 8047 | |
| 8048 | .. |Extract the TAR archive| image:: images/install-guide/win-extract-tar-gz.png |
| 8049 | .. |Extract the APEX distribution| image:: images/install-guide/win-extract-tar.png |
| 8050 | .. |REST Editor Start Screen| image:: images/install-guide/rest-start.png |
| 8051 | .. |REST Editor with loaded SampleDomain Policy Model| image:: images/install-guide/rest-loaded.png |
| 8052 | .. |APEX Configuration Matrix| image:: images/apex-intro/ApexEngineConfig.png |
| 8053 | .. |File > New to create a new Policy Model| image:: images/mfp/MyFirstPolicy_P1_newPolicyModel1.png |
| 8054 | .. |Create a new Policy Model| image:: images/mfp/MyFirstPolicy_P1_newPolicyModel2.png |
| 8055 | .. |Right click to create a new event| image:: images/mfp/MyFirstPolicy_P1_newEvent1.png |
| 8056 | .. |Fill in the necessary information for the 'SALE_INPUT' event and click 'Submit'| image:: images/mfp/MyFirstPolicy_P1_newEvent2.png |
| 8057 | .. |Right click to create a new Item Schema| image:: images/mfp/MyFirstPolicy_P1_newItemSchema1.png |
| 8058 | .. |Create a new Item Schema| image:: images/mfp/MyFirstPolicy_P1_newItemSchema2.png |
| 8059 | .. |Add new event parameters to an event| image:: images/mfp/MyFirstPolicy_P1_newEvent3.png |
| 8060 | .. |Right click to create a new task| image:: images/mfp/MyFirstPolicy_P1_newTask1.png |
| 8061 | .. |Add input and out fields for the task| image:: images/mfp/MyFirstPolicy_P1_newTask2.png |
| 8062 | .. |Add task logic the task| image:: images/mfp/MyFirstPolicy_P1_newTask3.png |
| 8063 | .. |Create a new policy| image:: images/mfp/MyFirstPolicy_P1_newPolicy1.png |
| 8064 | .. |Create a state| image:: images/mfp/MyFirstPolicy_P1_newState1.png |
| 8065 | .. |Add a Task and Output Mapping| image:: images/mfp/MyFirstPolicy_P1_newState2.png |
| 8066 | .. |Validate the policy model for error using the 'Model' > 'Validate' menu item| image:: images/mfp/MyFirstPolicy_P1_validatePolicyModel.png |
| 8067 | .. |Download the completed policy model using the 'File' > 'Download' menu item| image:: images/mfp/MyFirstPolicy_P1_exportPolicyModel1.png |
| 8068 | .. |Create a new alternative task MorningBoozeCheckAlt1| image:: images/mfp/MyFirstPolicy_P2_newTask1.png |
| 8069 | .. |Right click to edit a policy| image:: images/mfp/MyFirstPolicy_P2_editPolicy1.png |
| 8070 | .. |State definition with 2 Tasks and Task Selection Logic| image:: images/mfp/MyFirstPolicy_P2_editState1.png |
| 8071 | |