Apex-pdp documentation conversion from .adoc to .rst
[policy/parent.git] / docs / apex / APEX-PCVS-Example.rst
1 .. This work is licensed under a Creative Commons Attribution 4.0 International License.
2 .. http://creativecommons.org/licenses/by/4.0
3
4 .. _apex-PCVSExample:
5
6 Policy-controlled Video Streaming (pcvs) with APEX
7 **************************************************
8
9 .. contents::
10     :depth: 3
11
12 Introduction
13 ^^^^^^^^^^^^
14
15       .. container:: sectionbody
16
17            .. container:: paragraph
18
19                   This module contains several demos for
20                   Policy-controlled Video Streaming (PCVS). Each demo
21                   defines a policy using AVRO and Javascript (or other
22                   scripting languages for the policy logic). To run the
23                   demo, a vanilla Ubuntu server with some extra software
24                   packages is required:
25
26                .. container:: ulist
27
28                   -  Mininet as network simulator
29
30                   -  Floodlight as SDN controller
31
32                   -  Kafka as messaging system
33
34                   -  Zookeeper for Kafka configuration
35
36                   -  APEX for policy control
37
38 Install Ubuntu Server and SW
39 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
40
41           .. container:: sect1
42
43             .. rubric:: Install Demo
44                :name: install_demo
45
46             .. container:: sectionbody
47
48                .. container:: paragraph
49
50                   Requirements:
51
52                .. container:: ulist
53
54                   -  Ubuntu server: 1.4 GB
55
56                   -  Ubuntu with Xubuntu Desktop, git, Firefox: 2.3 GB
57
58                   -  Ubuntu with all, system updated: 3 GB
59
60                   -  With ZK, Kafka, VLC, Mininet, Floodlight, Python:
61                      4.4 GB
62
63                   -  APEX Build (M2 and built): M2 ~ 2 GB, APEX ~3.5 GB
64
65                   -  APEX install (not build locally): ~ 300 MB
66
67                .. container:: paragraph
68
69                   On a Ubuntu OS (install a stable or LTS server first)
70
71                .. container:: listingblock
72
73                   .. container:: content
74
75                      ::
76
77                         # pre for Ubuntu, tools and X
78                         sudo apt-get  -y install --no-install-recommends software-properties-common
79                         sudo apt-get  -y install --no-install-recommends build-essential
80                         sudo apt-get  -y install --no-install-recommends git
81                         sudo aptitude -y install --no-install-recommends xubuntu-desktop
82                         sudo apt-get  -y install --no-install-recommends firefox
83
84
85                         # install Java
86                         sudo add-apt-repository ppa:webupd8team/java
87                         sudo apt-get update
88                         sudo apt-get -y install --no-install-recommends oracle-java8-installer
89                         java -version
90
91
92                         # reboot system, run system update, then continue
93
94                         # if VBox additions are needed, install and reboot
95                         sudo (cd /usr/local/share; wget https://www.virtualbox.org/download/testcase/VBoxGuestAdditions_5.2.7-120528.iso)
96                         sudo mount /usr/local/share/VBoxGuestAdditions_5.2.7-120528.iso /media/cdrom
97                         sudo (cd /media/cdrom;VBoxLinuxAdditions.run)
98
99
100                         # update apt-get DB
101                         sudo apt-get update
102
103                         # if APEX is build from source, install maven and rpm
104                         sudo apt-get install maven rpm
105
106                         # install ZooKeeper
107                         sudo apt-get install zookeeperd
108
109                         # install Kafka
110                         (cd /tmp;wget http://ftp.heanet.ie/mirrors/www.apache.org/dist/kafka/1.0.0/kafka_2.12-1.0.0.tgz --show-progress)
111                         sudo mkdir /opt/Kafka
112                         sudo tar -xvf /tmp/kafka_2.12-1.0.0.tgz -C /opt/Kafka/
113
114                         # install mininet
115                         cd /usr/local/src
116                         sudo git clone https://github.com/mininet/mininet.git
117                         (cd mininet;util/install.sh -a)
118
119                         # install floodlight, requires ant
120                         sudo apt-get install ant
121                         cd /usr/local/src
122                         sudo wget --no-check-certificate https://github.com/floodlight/floodlight/archive/master.zip
123                         sudo unzip master.zip
124                         cd floodlight-master
125                         sudo ant
126                         sudo mkdir /var/lib/floodlight
127                         sudo chmod 777 /var/lib/floodlight
128
129                         # install python pip
130                         sudo apt-get install python-pip
131
132                         # install kafka-python (need newer version from github)
133                         cd /usr/local/src
134                         sudo git clone https://github.com/dpkp/kafka-python
135                         sudo pip install ./kafka-python
136
137                         # install vlc
138                         sudo apt-get install vlc
139
140                .. container:: paragraph
141
142                   Install APEX either from source or from a distribution
143                   package. See the APEX documentation for details. We
144                   assume that APEX is installed in
145                   ``/opt/ericsson/apex/apex``
146
147                .. container:: paragraph
148
149                   Copy the LinkMonitor file to Kafka-Python
150
151                .. container:: listingblock
152
153                   .. container:: content
154
155                      ::
156
157                         sudo cp /opt/ericsson/apex/apex/examples/scripts/pcvs/vpnsla/LinkMonitor.py /usr/local/src/kafka-python
158
159                .. container:: paragraph
160
161                   Change the Logback configuration in APEX to logic
162                   logging
163
164                .. container:: listingblock
165
166                   .. container:: content
167
168                      ::
169
170                         (cd /opt/ericsson/apex/apex/etc; sudo cp logback-logic.xml logback.xml)
171
172          .. container:: sect1
173
174             .. rubric:: Get the Demo Video
175                :name: get_the_demo_video
176
177             .. container:: sectionbody
178
179                .. container:: ulist
180
181                   -  For all download options of the movie please visit
182                      http://bbb3d.renderfarming.net/download.html
183
184                   -  For lower-res downloads and mirrors see
185                      https://peach.blender.org/download
186
187                .. container:: listingblock
188
189                   .. container:: content
190
191                      ::
192
193                         sudo mkdir /usr/local/src/videos
194
195                .. container:: paragraph
196
197                   Standard 720p (recommended)
198
199                .. container:: listingblock
200
201                   .. container:: content
202
203                      ::
204
205                         (cd /usr/local/src/videos; sudo curl -o big_buck_bunny_480p_surround.avi http://download.blender.org/peach/bigbuckbunny_movies/big_buck_bunny_480p_surround-fix.avi)
206
207                .. container:: paragraph
208
209                   Full HD video
210
211                .. container:: listingblock
212
213                   .. container:: content
214
215                      ::
216
217                         (cd videos; sudo curl -o bbb_sunflower_1080p_60fps_normal.mp4 http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflower_1080p_60fps_normal.mp4)
218
219
220
221 VPN SLA Demo
222 ^^^^^^^^^^^^^
223
224           .. container:: sect1
225
226             .. container:: sectionbody
227
228                .. container:: paragraph
229
230                   This demo uses a network with several central office
231                   and core switches, over which two VPNs are run. A
232                   customer ``A`` has two location ``A1`` and ``A2`` and
233                   a VPN between them. A customer ``B`` has two location
234                   ``B1`` and ``B2`` and a VPN between them.
235
236                .. container:: imageblock
237
238                   .. container:: content
239
240                      |VPN SLA Architecture|
241
242                .. container:: paragraph
243
244                   The architecture above shows the scenario. The
245                   components are realized in this demo as follows:
246
247                .. container:: ulist
248
249                   -  *CEP / Analytics* - a simple Python script taking
250                      events from Kafka and sending them to APEX
251
252                   -  *APEX / Policy* - the APEX engine running the VPA
253                      SLA policy
254
255                   -  *Controller* - A vanilla Floodlight controller
256                      taking events from the Link Monitor and configuring
257                      Mininet
258
259                   -  *Network* - A network created using Mininet
260
261                .. container:: paragraph
262
263                   The demo requires to start some software (detailed
264                   below). To show actual video streams, we use ``VLC``.
265                   If you do not want to show video streams, but only the
266                   policy, skip the ``VLC`` section.
267
268                .. container:: paragraph
269
270                   All shown scripts are available in a full APEX
271                   installation in
272                   ``$APEX_HOME/examples/scripts/pcvs/vpnsla``.
273
274                .. container:: sect2
275
276                   .. rubric:: Start all Software
277                      :name: start_all_software
278
279                   .. container:: paragraph
280
281                      Create environment variables in a file, say
282                      ``env.sh``. In each new Xterm
283
284                   .. container:: ulist
285
286                      -  Source these environment settings, e.g.
287                         ``. ./env.sh``
288
289                      -  Run the commands below as root (``sudo`` per
290                         command or ``sudo -i`` for interactive mode as
291                         shown below)
292
293                   .. container:: listingblock
294
295                      .. container:: content
296
297                         ::
298
299                            #!/usr/bin/env bash
300
301                            export src_dir=/usr/local/src
302                            export APEX_HOME=/opt/ericsson/apex/apex
303                            export APEX_USER=apexuser
304
305                   .. container:: paragraph
306
307                      In a new Xterm, start Floodlight
308
309                   .. container:: listingblock
310
311                      .. container:: content
312
313                         ::
314
315                            sudo -i
316                            . ./env.sh
317                            cd $src_dir/floodlight-master && java -jar target/floodlight.jar
318
319                   .. container:: paragraph
320
321                      In a new Xterm start Mininet
322
323                   .. container:: listingblock
324
325                      .. container:: content
326
327                         ::
328
329                            sudo -i
330                            . ./env.sh
331                            mn -c && python $APEX_HOME/examples/scripts/pcvs/vpnsla/MininetTopology.py
332
333                   .. container:: paragraph
334
335                      In a new Xterm, start Kafka
336
337                   .. container:: listingblock
338
339                      .. container:: content
340
341                         ::
342
343                            sudo -i
344                            . ./env.sh
345                            /opt/Kafka/kafka_2.12-1.0.0/bin/kafka-server-start.sh /opt/Kafka/kafka_2.12-1.0.0/config/server.properties
346
347                   .. container:: paragraph
348
349                      In a new Xerm start APEX with the Kafka
350                      configuration for this demo
351
352                   .. container:: listingblock
353
354                      .. container:: content
355
356                         ::
357
358                            cd $APEX_HOME
359                            ./bin/apexApps.sh engine -c examples/config/pcvs/vpnsla/kafka2kafka.json
360
361                   .. container:: paragraph
362
363                      In a new Xterm start the Link Monitor. The Link
364                      Monitor has a 30 second sleep to slow down the
365                      demonstration. So the first action of it comes 30
366                      seconds after start. Every new action in 30 second
367                      intervals.
368
369                   .. container:: listingblock
370
371                      .. container:: content
372
373                         ::
374
375                            sudo -i
376                            . ./env.sh
377                            cd $src_dir
378                            xterm -hold -e 'python3 $src_dir/kafka-python/LinkMonitor.py' &
379
380                   .. container:: paragraph
381
382                      Now all software should be started and the demo is
383                      running. The Link Monitor will send link up events,
384                      picked up by APEX which triggers the policy. Since
385                      there is no problem, the policy will do nothing.
386
387                .. container:: sect2
388
389                   .. rubric:: Create 2 Video Streams with VLC
390                      :name: create_2_video_streams_with_vlc
391
392                   .. container:: paragraph
393
394                      In the Mininet console, type ``xterm A1 A2`` and
395                      ``xterm B1 B2`` to open terminals on these nodes.
396
397                   .. container:: paragraph
398
399                      ``A2`` and ``B2`` are the receiving nodes. In these
400                      terminals, run ``vlc-wrapper``. In each opened VLC
401                      window do
402
403                   .. container:: ulist
404
405                      -  Click Media â†’ Open Network Stream
406
407                      -  Give the URL as ``rtp://@:5004``
408
409                   .. container:: paragraph
410
411                      ``A1`` and ``B1`` are the sending nodes (sending
412                      the video stream) In these terminals, run
413                      ``vlc-wrapper``. In each opened VLC window do
414
415                   .. container:: ulist
416
417                      -  Click Media â†’ Stream
418
419                      -  Add the video (from ``/usr/local/src/videos``)
420
421                      -  Click ``Stream``
422
423                      -  Click ``Next``
424
425                      -  Change the destination
426                         ``RTP / MPEG Transport Stream`` and click
427                         ``Add``
428
429                      -  Change the address and type to ``10.0.0.2`` in
430                         ``A1`` and to ``10.0.0.4`` in ``B1``
431
432                      -  Turn off ``Active Transcoding`` (this is
433                         important to minimize CPU load)
434
435                      -  Click ``Next``
436
437                      -  Click ``Stream``
438
439                   .. container:: paragraph
440
441                      The video should be streaming across the network
442                      from ``A1`` to ``A2`` and from ``B1`` to ``B2``. If
443                      the video streams a slow or interrupted the CPU
444                      load is too high. In these cases either try a
445                      better machine or use a different (lower quality)
446                      video stream.
447
448                .. container:: sect2
449
450                   .. rubric:: Take out L09 and let the Policy do it’s
451                      Magic
452                      :name: take_out_l09_and_let_the_policy_do_it_s_magic
453
454                   .. container:: paragraph
455
456                      Now it is time to take out the link ``L09``. This
457                      will be picked up by the Link Monitor, which sends
458                      a new event (L09 DOWN) to the policy. The policy
459                      then will calculate which customer should be
460                      impeded (throttled). This will continue, until SLAs
461                      are violated, then a priority calculation will kick
462                      in (Customer ``A`` is prioritized in the setup).
463
464                   .. container:: paragraph
465
466                      To initiate this, simply type ``link s5 s6 down``
467                      in the Mininet console followed by ``exit``.
468
469                   .. container:: paragraph
470
471                      If you have the video streams running, you will see
472                      one or the other struggeling, depending on the
473                      policy decision.
474
475                .. container:: sect2
476
477                   .. rubric:: Reset the Demo
478                      :name: reset_the_demo
479
480                   .. container:: paragraph
481
482                      If you want to reset the demo, simple stop (in this
483                      order) the following process
484
485                   .. container:: ulist
486
487                      -  Link Monitor
488
489                      -  APEX
490
491                      -  Mininet
492
493                      -  Floodlight
494
495                   .. container:: paragraph
496
497                      Then restart them in this order
498
499                   .. container:: ulist
500
501                      -  Floodlight
502
503                      -  Mininet
504
505                      -  APEX
506
507                      -  Link Monitor
508
509                .. container:: sect2
510
511                   .. rubric:: Monitor the Demo
512                      :name: monitor_the_demo
513
514                   .. container:: paragraph
515
516                      Floodlight and APEX provide REST interfaces for
517                      monitoring.
518
519                   .. container:: ulist
520
521                      -  Floodlight: see `Floodlight
522                         Docs <https://floodlight.atlassian.net/wiki/spaces/floodlightcontroller/pages/40403023/Web+GUI>`__
523                         for details on how to access the monitoring. In
524                         a standard installation as we use here, pointing
525                         browser to the URL
526                         ``http://localhost:8080/ui/pages/index.html``
527                         should work on the same host
528
529                      -  APEX please see the APEX documentation for
530                         `Monitoring
531                         Client <https://ericsson.github.io/apex-docs/user-manual/engine-apps/um-engapps-eng-monitoring.html>`__
532                         or `Full
533                         Client <https://ericsson.github.io/apex-docs/user-manual/engine-apps/um-engapps-full-client.html>`__
534                         for details on how to monitor APEX.
535
536
537 VPN SLA Policy
538 ^^^^^^^^^^^^^^
539
540             .. container:: sectionbody
541
542                .. container:: paragraph
543
544                   The VPN SLA policy is designed as a MEDA policy. The
545                   first state (M = Match) takes the trigger event (a
546                   link up or down) and checks if this is a change to the
547                   known topology. The second state (E = Establish) takes
548                   all available information (trigger event, local
549                   context) and defines what situation we have. The third
550                   state (D = Decide) takes the situation and selects
551                   which algorithm is best to process it. This state can
552                   select between ``none`` (nothing to do), ``solved`` (a
553                   problem is solved now), ``sla`` (compare the current
554                   customer SLA situation and select one to impede), and
555                   ``priority`` (impede non-priority customers). The
556                   fourth and final state (A = Act) selects the right
557                   action for the taken decision and creates the response
558                   event sent to the orchestrator.
559
560                .. container:: paragraph
561
562                   We have added three more policies to set the local
563                   context: one for adding nodes, one for adding edges
564                   (links), and one for adding customers. These policies
565                   do not realize any action, they are only here for
566                   updating the local context. This mechanism is the
567                   fasted way to update local context, and it is
568                   independent of any context plugin.
569
570                .. container:: paragraph
571
572                   The policy uses data defined in Avro, so we have a
573                   number of Avro schema definitions.
574
575 Context Schemas
576 ---------------
577
578          .. container:: sect1
579
580             .. container:: sectionbody
581
582                .. container:: paragraph
583
584                   The context schemas are for the local context. We
585                   model edges and nodes for the topology, customers, and
586                   problems with all information on detected problems.
587
588                .. container:: listingblock
589
590                   .. container:: content
591
592                      .. code:: CodeRay
593
594                         {
595                             "type" : "record",
596                             "name" : "TopologyEdges",
597                             "fields" : [
598                                 {"name": "name",   "type": "string",  "doc": "Name of the Edge, typically a link name"},
599                                 {"name": "start",  "type": "string",  "doc": "Edge endpoint: start - a node name"},
600                                 {"name": "end",    "type": "string",  "doc": "Edge endpoint: end - a node name"},
601                                 {"name": "active", "type": "boolean", "doc": "Flag for active/inactive edges, inactive means a link is down"}
602                             ]
603                         }
604
605                .. container:: listingblock
606
607                   .. container:: content
608
609                      .. code:: CodeRay
610
611                         {
612                             "type" : "record",
613                             "name" : "TopologyNodes",
614                             "fields" : [
615                                 {"name" : "name",   "type" : "string", "doc": "The name of the node"},
616                                 {"name" : "mnname", "type" : "string", "doc": "The name of the node in Mininet"}
617                             ]
618                         }
619
620                .. container:: listingblock
621
622                   .. container:: content
623
624                      .. code:: CodeRay
625
626                         {
627                             "type" : "record",
628                             "name" : "Customer",
629                             "fields" : [
630                                 {"name" : "customerName", "type" : "string"},
631                                 {"name" : "dtSLA"       , "type" : "int"},
632                                 {"name" : "dtYTD"       , "type" : "int"},
633                                 {"name" : "priority"    , "type" : "boolean"},
634                                 {"name" : "satisfaction", "type" : "int"},
635                                 {
636                                     "name": "links",
637                                     "doc": "Links used by this customer",
638                                     "type": {"type"  : "array", "items" : "string"}
639                                 }
640                             ]
641                         }
642
643
644 Trigger Schemas
645 ---------------
646
647         .. container:: sect1
648
649             .. container:: sectionbody
650
651                .. container:: paragraph
652
653                   The trigger event provides a status as ``UP`` or
654                   ``DOWN``. To avoid tests for these strings in the
655                   logic, we defined an Avro schema for an enumeration.
656                   This does not impact the trigger system (it can still
657                   send the strings), but makes the task logic simpler.
658
659                .. container:: listingblock
660
661                   .. container:: content
662
663                      .. code:: CodeRay
664
665                         {
666                             "type": "enum",
667                             "name": "Status",
668                             "symbols" : [
669                                 "UP",
670                                 "DOWN"
671                             ]
672                         }
673
674 Context Logic Nodes
675 --------------------
676
677          .. container:: sect1
678
679             .. container:: sectionbody
680
681                .. container:: paragraph
682
683                   The node context logic simply takes the trigger event
684                   (for context) and creates a new node in the local
685                   context topology.
686
687                .. container:: listingblock
688
689                   .. container:: content
690
691                      .. code:: CodeRay
692
693                         /*
694                          * ============LICENSE_START=======================================================
695                          *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
696                          * ================================================================================
697                          * Licensed under the Apache License, Version 2.0 (the "License");
698                          * you may not use this file except in compliance with the License.
699                          * You may obtain a copy of the License at
700                          *
701                          *      http://www.apache.org/licenses/LICENSE-2.0
702                          *
703                          * Unless required by applicable law or agreed to in writing, software
704                          * distributed under the License is distributed on an "AS IS" BASIS,
705                          * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
706                          * See the License for the specific language governing permissions and
707                          * limitations under the License.
708                          *
709                          * SPDX-License-Identifier: Apache-2.0
710                          * ============LICENSE_END=========================================================
711                          */
712
713                         load("nashorn:mozilla_compat.js");
714
715                         var logger = executor.logger;
716                         logger.trace("start: " + executor.subject.id);
717                         logger.trace("-- infields: " + executor.inFields);
718
719                         var ifNodeName = executor.inFields["nodeName"];
720                         var ifMininetName = executor.inFields["mininetName"];
721
722                         var albumTopoNodes = executor.getContextAlbum("albumTopoNodes");
723
724                         logger.trace("-- got infields, testing existing node");
725
726                         var ctxtNode = albumTopoNodes.get(ifNodeName);
727                         if (ctxtNode != null) {
728                             albumTopoNodes.remove(ifNodeName);
729                             logger.trace("-- removed node: <" + ifNodeName + ">");
730                         }
731
732                         logger.trace("-- creating node: <" + ifNodeName + ">");
733                         ctxtNode = "{name:" + ifNodeName + ", mnname:" + ifMininetName + "}";
734                         albumTopoNodes.put(ifNodeName, ctxtNode);
735
736                         if (logger.isTraceEnabled()) {
737                             logger.trace("   >> *** Nodes ***");
738                             if (albumTopoNodes != null) {
739                                 for (var i = 0; i < albumTopoNodes.values().size(); i++) {
740                                     logger.trace("   >> >> " + albumTopoNodes.values().get(i).get("name") + " : "
741                                             + albumTopoNodes.values().get(i).get("mnname"));
742                                 }
743                             } else {
744                                 logger.trace("   >> >> node album is null");
745                             }
746                         }
747
748                         executor.outFields["report"] = "node ctxt :: added node " + ifNodeName;
749
750                         logger.info("vpnsla: ctxt added node " + ifNodeName);
751
752                         var returnValueType = Java.type("java.lang.Boolean");
753                         var returnValue = new returnValueType(true);
754                         logger.trace("finished: " + executor.subject.id);
755                         logger.debug(".");
756
757 Context Logic Edges
758 --------------------
759
760          .. container:: sect1
761
762             .. container:: sectionbody
763
764                .. container:: paragraph
765
766                   The edge context logic simply takes the trigger event
767                   (for context) and creates a new edge in the local
768                   context topology.
769
770                .. container:: listingblock
771
772                   .. container:: content
773
774                      .. code:: CodeRay
775
776                         /*
777                          * ============LICENSE_START=======================================================
778                          *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
779                          * ================================================================================
780                          * Licensed under the Apache License, Version 2.0 (the "License");
781                          * you may not use this file except in compliance with the License.
782                          * You may obtain a copy of the License at
783                          *
784                          *      http://www.apache.org/licenses/LICENSE-2.0
785                          *
786                          * Unless required by applicable law or agreed to in writing, software
787                          * distributed under the License is distributed on an "AS IS" BASIS,
788                          * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
789                          * See the License for the specific language governing permissions and
790                          * limitations under the License.
791                          *
792                          * SPDX-License-Identifier: Apache-2.0
793                          * ============LICENSE_END=========================================================
794                          */
795
796                         load("nashorn:mozilla_compat.js");
797
798                         var logger = executor.logger;
799                         logger.trace("start: " + executor.subject.id);
800                         logger.trace("-- infields: " + executor.inFields);
801
802                         var ifEdgeName = executor.inFields["edgeName"];
803                         var ifEdgeStatus = executor.inFields["status"];
804
805                         var albumTopoEdges = executor.getContextAlbum("albumTopoEdges");
806
807                         logger.trace("-- got infields, testing existing edge");
808
809                         var ctxtEdge = albumTopoEdges.get(ifEdgeName);
810                         if (ctxtEdge != null) {
811                             albumTopoEdges.remove(ifEdgeName);
812                             logger.trace("-- removed edge: <" + ifEdgeName + ">");
813                         }
814
815                         logger.trace("-- creating edge: <" + ifEdgeName + ">");
816                         ctxtEdge = "{name:" + ifEdgeName + ", start:" + executor.inFields["start"] + ", end:" + executor.inFields["end"]
817                                 + ", active:" + ifEdgeStatus + "}";
818                         albumTopoEdges.put(ifEdgeName, ctxtEdge);
819
820                         if (logger.isTraceEnabled()) {
821                             logger.trace("   >> *** Edges ***");
822                             if (albumTopoEdges != null) {
823                                 for (var i = 0; i < albumTopoEdges.values().size(); i++) {
824                                     logger.trace("   >> >> " + albumTopoEdges.values().get(i).get("name") + " \t "
825                                             + albumTopoEdges.values().get(i).get("start") + " --> " + albumTopoEdges.values().get(i).get("end")
826                                             + " \t " + albumTopoEdges.values().get(i).get("active"));
827                                 }
828                             } else {
829                                 logger.trace("   >> >> edge album is null");
830                             }
831                         }
832
833                         executor.outFields["report"] = "edge ctxt :: added edge " + ifEdgeName;
834
835                         logger.info("vpnsla: ctxt added edge " + ifEdgeName);
836
837                         var returnValueType = Java.type("java.lang.Boolean");
838                         var returnValue = new returnValueType(true);
839                         logger.trace("finished: " + executor.subject.id);
840                         logger.debug(".");
841
842 Context Logic Customer
843 ----------------------
844
845          .. container:: sect1
846
847             .. container:: sectionbody
848
849                .. container:: paragraph
850
851                   The customer context logic simply takes the trigger
852                   event (for context) and creates a new customer in the
853                   local context topology.
854
855                .. container:: listingblock
856
857                   .. container:: content
858
859                      .. code:: CodeRay
860
861                         /*
862                          * ============LICENSE_START=======================================================
863                          *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
864                          * ================================================================================
865                          * Licensed under the Apache License, Version 2.0 (the "License");
866                          * you may not use this file except in compliance with the License.
867                          * You may obtain a copy of the License at
868                          *
869                          *      http://www.apache.org/licenses/LICENSE-2.0
870                          *
871                          * Unless required by applicable law or agreed to in writing, software
872                          * distributed under the License is distributed on an "AS IS" BASIS,
873                          * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
874                          * See the License for the specific language governing permissions and
875                          * limitations under the License.
876                          *
877                          * SPDX-License-Identifier: Apache-2.0
878                          * ============LICENSE_END=========================================================
879                          */
880
881                         load("nashorn:mozilla_compat.js");
882
883                         var logger = executor.logger;
884                         logger.trace("start: " + executor.subject.id);
885                         logger.trace("-- infields: " + executor.inFields);
886
887                         var ifCustomerName = executor.inFields["customerName"];
888                         var ifLinks = executor.inFields["links"];
889
890                         logger.trace("-- got infields, testing existing customer");
891                         var ctxtCustomer = executor.getContextAlbum("albumCustomerMap").get(ifCustomerName);
892                         if (ctxtCustomer != null) {
893                             executor.getContextAlbum("albumCustomerMap").remove(ifCustomerName);
894                             logger.trace("-- removed customer: <" + ifCustomerName + ">");
895                         }
896
897                         logger.trace("-- creating customer: <" + ifCustomerName + ">");
898                         var links = new Array();
899                         for (var i = 0; i < ifLinks.split(" ").length; i++) {
900                             var link = executor.getContextAlbum("albumTopoEdges").get(ifLinks.split(" ")[i]);
901                             if (link != null) {
902                                 logger.trace("-- link: <" + ifLinks.split(" ")[i] + ">");
903                                 links.push(ifLinks.split(" ")[i]);
904                             } else {
905                                 logger.trace("-- unknown link: <" + ifLinks.split(" ")[i] + "> for customer <" + ifCustomerName + ">");
906                             }
907                         }
908                         logger.trace("-- links: <" + links + ">");
909                         ctxtCustomer = "{customerName:" + ifCustomerName + ", dtSLA:" + executor.inFields["dtSLA"] + ", dtYTD:"
910                                 + executor.inFields["dtYTD"] + ", priority:" + executor.inFields["priority"] + ", satisfaction:"
911                                 + executor.inFields["satisfaction"] + ", links:[" + links + "]}";
912
913                         executor.getContextAlbum("albumCustomerMap").put(ifCustomerName, ctxtCustomer);
914
915                         if (logger.isTraceEnabled()) {
916                             logger.trace("   >> *** Customers ***");
917                             if (executor.getContextAlbum("albumCustomerMap") != null) {
918                                 for (var i = 0; i < executor.getContextAlbum("albumCustomerMap").values().size(); i++) {
919                                     logger.trace("   >> >> " + executor.getContextAlbum("albumCustomerMap").values().get(i).get("customerName")
920                                             + " : " + "dtSLA=" + executor.getContextAlbum("albumCustomerMap").values().get(i).get("dtSLA")
921                                             + " : " + "dtYTD=" + executor.getContextAlbum("albumCustomerMap").values().get(i).get("dtYTD")
922                                             + " : " + "links=" + executor.getContextAlbum("albumCustomerMap").values().get(i).get("links")
923                                             + " : " + "priority="
924                                             + executor.getContextAlbum("albumCustomerMap").values().get(i).get("priority") + " : "
925                                             + "satisfaction="
926                                             + executor.getContextAlbum("albumCustomerMap").values().get(i).get("satisfaction"));
927                                 }
928                             } else {
929                                 logger.trace("   >> >> customer album is null");
930                             }
931                         }
932
933                         executor.outFields["report"] = "customer ctxt :: added customer: " + ifCustomerName;
934
935                         logger.info("vpnsla: ctxt added customer " + ifCustomerName);
936
937                         var returnValueType = Java.type("java.lang.Boolean");
938                         var returnValue = new returnValueType(true);
939                         logger.trace("finished: " + executor.subject.id);
940                         logger.debug(".");
941
942 Logic: Match
943 ------------
944
945          .. container:: sect1
946
947             .. container:: sectionbody
948
949                .. container:: paragraph
950
951                   This is the logic for the match state. It is kept very
952                   simple. Beside taking the trigger event, it also
953                   creates a timestamp. This timestamp is later used for
954                   SLA and downtime calculations as well as for some
955                   performance information of the policy.
956
957                .. container:: listingblock
958
959                   .. container:: content
960
961                      .. code:: CodeRay
962
963                         /*
964                          * ============LICENSE_START=======================================================
965                          *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
966                          * ================================================================================
967                          * Licensed under the Apache License, Version 2.0 (the "License");
968                          * you may not use this file except in compliance with the License.
969                          * You may obtain a copy of the License at
970                          *
971                          *      http://www.apache.org/licenses/LICENSE-2.0
972                          *
973                          * Unless required by applicable law or agreed to in writing, software
974                          * distributed under the License is distributed on an "AS IS" BASIS,
975                          * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
976                          * See the License for the specific language governing permissions and
977                          * limitations under the License.
978                          *
979                          * SPDX-License-Identifier: Apache-2.0
980                          * ============LICENSE_END=========================================================
981                          */
982
983                         load("nashorn:mozilla_compat.js");
984
985                         var now = new Date().getTime();
986                         executor.outFields["matchStart"] = now;
987
988                         importClass(org.slf4j.LoggerFactory);
989
990                         var logger = executor.logger;
991                         logger.trace("start: " + executor.subject.id);
992                         logger.trace("-- infields: " + executor.inFields);
993
994                         var rootLogger = LoggerFactory.getLogger(logger.ROOT_LOGGER_NAME);
995
996                         var ifEdgeName = executor.inFields["edgeName"];
997                         var ifLinkStatus = executor.inFields["status"];
998
999                         var albumTopoEdges = executor.getContextAlbum("albumTopoEdges");
1000
1001                         logger.trace("-- got infields, checking albumTopoEdges changes");
1002
1003                         var active = false;
1004                         switch (ifLinkStatus.toString()) {
1005                         case "UP":
1006                             active = true;
1007                             break;
1008                         case "DOWN":
1009                             active = false;
1010                             break;
1011                         default:
1012                             active = false;
1013                             logger.error("-- trigger sent unknown link status <" + ifLinkStatus + "> for link <" + ifEdgeName + ">");
1014                             rootLogger.error(executor.subject.id + " " + "-- trigger sent unknown link status <" + ifLinkStatus
1015                                     + "> for link <" + ifEdgeName + ">");
1016                         }
1017
1018                         var link = albumTopoEdges.get(ifEdgeName);
1019                         if (link == null) {
1020                             logger.trace("-- link <" + ifEdgeName + "> not in albumTopoEdges");
1021                         } else {
1022                             logger.trace("-- found link <" + link + "> in albumTopoEdges");
1023                             logger.trace("-- active <" + active + "> : link.active <" + link.get("active") + ">");
1024                             if (active != link.get("active")) {
1025                                 link.put("active", active);
1026                                 logger.trace("-- link <" + ifEdgeName + "> status changed to <active:" + link.get("active") + ">");
1027                                 executor.outFields["hasChanged"] = true;
1028                             } else {
1029                                 logger.trace("-- link <" + ifEdgeName + "> status not changed <active:" + link.get("active") + ">");
1030                                 executor.outFields["hasChanged"] = false;
1031                             }
1032                         }
1033
1034                         executor.outFields["edgeName"] = ifEdgeName;
1035                         executor.outFields["status"] = ifLinkStatus;
1036
1037                         logger.info("vpnsla: detected " + ifEdgeName + " as " + ifLinkStatus);
1038
1039                         var returnValueType = Java.type("java.lang.Boolean");
1040                         var returnValue = new returnValueType(true);
1041                         logger.trace("finished: " + executor.subject.id);
1042                         logger.debug(".m");
1043
1044
1045 Logic: Policy Establish State
1046 -----------------------------
1047
1048          .. container:: sect1
1049
1050             .. container:: sectionbody
1051
1052                .. container:: paragraph
1053
1054                   This is the logic for the establish state. It is the
1055                   most complicated logic, since establishing a situation
1056                   for a decision is the most important part of any
1057                   policy. First, the policy describes what we find (the
1058                   switch block), in terms of 8 normal situations and 1
1059                   extreme error case.
1060
1061                .. container:: paragraph
1062
1063                   If required, it creates local context information for
1064                   the problem (if it is new) or updates it (if the
1065                   problem still exists). It also calculates customer SLA
1066                   downtime and checks for any SLA violations. Finally,
1067                   it creates a situation object.
1068
1069                .. container:: listingblock
1070
1071                   .. container:: content
1072
1073                      .. code:: CodeRay
1074
1075                         /*
1076                          * ============LICENSE_START=======================================================
1077                          *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
1078                          * ================================================================================
1079                          * Licensed under the Apache License, Version 2.0 (the "License");
1080                          * you may not use this file except in compliance with the License.
1081                          * You may obtain a copy of the License at
1082                          *
1083                          *      http://www.apache.org/licenses/LICENSE-2.0
1084                          *
1085                          * Unless required by applicable law or agreed to in writing, software
1086                          * distributed under the License is distributed on an "AS IS" BASIS,
1087                          * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1088                          * See the License for the specific language governing permissions and
1089                          * limitations under the License.
1090                          *
1091                          * SPDX-License-Identifier: Apache-2.0
1092                          * ============LICENSE_END=========================================================
1093                          */
1094
1095                         load("nashorn:mozilla_compat.js");
1096                         importClass(org.slf4j.LoggerFactory);
1097
1098                         importClass(java.util.ArrayList);
1099
1100                         importClass(org.apache.avro.generic.GenericData.Array);
1101                         importClass(org.apache.avro.generic.GenericRecord);
1102                         importClass(org.apache.avro.Schema);
1103
1104                         var logger = executor.logger;
1105                         logger.trace("start: " + executor.subject.id);
1106                         logger.trace("-- infields: " + executor.inFields);
1107
1108                         var rootLogger = LoggerFactory.getLogger(logger.ROOT_LOGGER_NAME);
1109
1110                         var ifEdgeName = executor.inFields["edgeName"];
1111                         var ifEdgeStatus = executor.inFields["status"].toString();
1112                         var ifhasChanged = executor.inFields["hasChanged"];
1113                         var ifMatchStart = executor.inFields["matchStart"];
1114
1115                         var albumCustomerMap = executor.getContextAlbum("albumCustomerMap");
1116                         var albumProblemMap = executor.getContextAlbum("albumProblemMap");
1117
1118                         var linkProblem = albumProblemMap.get(ifEdgeName);
1119
1120                         // create outfiled for situation
1121                         var situation = executor.subject.getOutFieldSchemaHelper("situation").createNewInstance();
1122                         situation.put("violatedSLAs", new ArrayList());
1123
1124                         // create a string as states+hasChanged+linkProblem and switch over it
1125                         var switchTest = ifEdgeStatus + ":" + ifhasChanged + ":" + (linkProblem == null ? "no" : "yes");
1126                         switch (switchTest) {
1127                         case "UP:false:no":
1128                             logger.trace("-- edge <" + ifEdgeName + "> UP:false:no => everything ok");
1129                             logger.info("vpnsla: everything ok");
1130                             situation.put("problemID", "NONE");
1131                             break;
1132                         case "UP:false:yes":
1133                             logger.trace("-- edge <" + ifEdgeName + "> UP:false:yes ==> did we miss earlier up?, removing problem");
1134                             albumProblemMap.remove(ifEdgeName);
1135                             linkProblem = null;
1136                             situation.put("problemID", "NONE");
1137                             break;
1138                         case "UP:true:no":
1139                             logger.trace("-- edge <" + ifEdgeName + "> UP:true:no ==> did we miss the earlier down?, creating new problem");
1140                             situation.put("problemID", ifEdgeName);
1141                             break;
1142                         case "UP:true:yes":
1143                             logger.trace("-- edge <" + ifEdgeName + "> UP:true:yes ==> detected solution, link up again");
1144                             logger.info("vpnsla: problem solved");
1145                             linkProblem.put("endTime", ifMatchStart);
1146                             linkProblem.put("status", "SOLVED");
1147                             situation.put("problemID", "NONE");
1148                             break;
1149                         case "DOWN:false:no":
1150                             logger.trace("-- edge <" + ifEdgeName + "> DOWN:false:no ==> did we miss an earlier down?, creating new problem");
1151                             situation.put("problemID", ifEdgeName);
1152                             break;
1153                         case "DOWN:false:yes":
1154                             logger.trace("-- edge <" + ifEdgeName + "> DOWN:false:yes ==> problem STILL exists");
1155                             logger.info("vpnsla: problem still exists");
1156                             linkProblem.put("status", "STILL");
1157                             situation.put("problemID", ifEdgeName);
1158                             break;
1159                         case "DOWN:true:no":
1160                             logger.trace("-- edge <" + ifEdgeName + "> DOWN:true:no ==> found NEW problem");
1161                             logger.info("vpnsla: this is a new problem");
1162                             situation.put("problemID", ifEdgeName);
1163                             break;
1164                         case "DOWN:true:yes":
1165                             logger.trace("-- edge <" + ifEdgeName
1166                                     + "> DOWN:true:yes ==> did we miss to remove an earlier problem?, remove and create new problem");
1167                             linkProblem = null;
1168                             situation.put("problemID", ifEdgeName);
1169                             break;
1170
1171                         default:
1172                             logger.error("-- input wrong for edge" + ifEdgeName + ": edge status <" + ifEdgeStatus
1173                                     + "> unknown or null on hasChanged <" + ifhasChanged + ">");
1174                             rootLogger.error("-- input wrong for edge" + ifEdgeName + ": edge status <" + ifEdgeStatus
1175                                     + "> unknown or null on hasChanged <" + ifhasChanged + ">");
1176                         }
1177
1178                         // create new problem if situation requires it
1179                         if (situation.get("problemID").equals(ifEdgeName) && linkProblem == null) {
1180                             logger.trace("-- edge <" + ifEdgeName + "> creating new problem");
1181                             linkProblem = albumProblemMap.getSchemaHelper().createNewInstance();
1182                             linkProblem.put("edge", ifEdgeName);
1183                             linkProblem.put("startTime", ifMatchStart);
1184                             linkProblem.put("lastUpdate", ifMatchStart);
1185                             linkProblem.put("endTime", 0);
1186                             linkProblem.put("status", "NEW");
1187                             linkProblem.put("edgeUsedBy", new ArrayList());
1188                             linkProblem.put("impededLast", new ArrayList());
1189
1190                             for (var i = 0; i < albumCustomerMap.values().size(); i++) {
1191                                 var customer = albumCustomerMap.values().get(i);
1192                                 var customerLinks = albumCustomerMap.values().get(i).get("links");
1193                                 for (var k = 0; k < customerLinks.size(); k++) {
1194                                     if (customerLinks.get(k) == ifEdgeName) {
1195                                         linkProblem.get("edgeUsedBy").add(customer.get("customerName"));
1196                                     }
1197                                 }
1198                             }
1199                             albumProblemMap.put(ifEdgeName, linkProblem);
1200                             logger.trace("-- edge <" + ifEdgeName + "> problem created as <" + linkProblem + ">");
1201                         }
1202
1203                         // set dtYTD if situation requires it
1204                         if (linkProblem != null && (linkProblem.get("status") == "STILL" || linkProblem.get("status") == "SOLVED")) {
1205                             var linkDownTimeinSecs = (ifMatchStart - linkProblem.get("lastUpdate")) / 1000;
1206                             logger.trace("-- edge <" + ifEdgeName + "> down time: " + linkDownTimeinSecs + " s");
1207                             for (var k = 0; k < linkProblem.get("impededLast").size(); k++) {
1208                                 for (var i = 0; i < albumCustomerMap.values().size(); i++) {
1209                                     var customer = albumCustomerMap.values().get(i);
1210                                     if (customer.get("customerName").equals(linkProblem.get("impededLast").get(k))) {
1211                                         logger.info("-- vpnsla: customer " + customer.get("customerName") + " YDT downtime increased from "
1212                                                 + customer.get("dtYTD") + " to " + (customer.get("dtYTD") + linkDownTimeinSecs));
1213                                         customer.put("dtYTD", (customer.get("dtYTD") + linkDownTimeinSecs))
1214                                     }
1215                                 }
1216                             }
1217                             // set lastUpdate to this policy execution for next execution calculation
1218                             linkProblem.put("lastUpdate", ifMatchStart);
1219                         }
1220
1221                         // check SLA violations if situation requires it
1222                         if (linkProblem != null && linkProblem.get("status") != "SOLVED") {
1223                             logger.info(">e> customer\tDT SLA\tDT YTD\tviolation");
1224                             for (var i = 0; i < albumCustomerMap.values().size(); i++) {
1225                                 var customer = albumCustomerMap.values().get(i);
1226                                 if (customer.get("dtYTD") > customer.get("dtSLA")) {
1227                                     situation.get("violatedSLAs").add(customer.get("customerName"));
1228                                     logger.info(">e> " + customer.get("customerName") + "\t\t" + customer.get("dtSLA") + "s\t"
1229                                             + customer.get("dtYTD") + "s\t" + "!!");
1230                                 } else {
1231                                     logger.info(">e> " + customer.get("customerName") + "\t\t" + customer.get("dtSLA") + "s\t"
1232                                             + customer.get("dtYTD") + "s");
1233                                 }
1234                             }
1235                         }
1236
1237                         executor.outFields["situation"] = situation;
1238
1239                         logger.trace("-- out fields <" + executor.outFields + ">");
1240
1241                         var returnValueType = Java.type("java.lang.Boolean");
1242                         var returnValue = new returnValueType(true);
1243                         logger.trace("finished: " + executor.subject.id);
1244                         logger.debug(".e");
1245
1246 Logic: Policy Decide State
1247 --------------------------
1248
1249          .. container:: sect1
1250
1251             .. container:: sectionbody
1252
1253                .. container:: paragraph
1254
1255                   The decide state can select between different
1256                   algorithms depending on the situation. So it needs a
1257                   Task Selection Logic (TSL). This TSL select a task in
1258                   the current policy execution (i.e. potentially a
1259                   different one per execution).
1260
1261                .. container:: listingblock
1262
1263                   .. container:: content
1264
1265                      .. code:: CodeRay
1266
1267                         /*
1268                          * ============LICENSE_START=======================================================
1269                          *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
1270                          * ================================================================================
1271                          * Licensed under the Apache License, Version 2.0 (the "License");
1272                          * you may not use this file except in compliance with the License.
1273                          * You may obtain a copy of the License at
1274                          *
1275                          *      http://www.apache.org/licenses/LICENSE-2.0
1276                          *
1277                          * Unless required by applicable law or agreed to in writing, software
1278                          * distributed under the License is distributed on an "AS IS" BASIS,
1279                          * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1280                          * See the License for the specific language governing permissions and
1281                          * limitations under the License.
1282                          *
1283                          * SPDX-License-Identifier: Apache-2.0
1284                          * ============LICENSE_END=========================================================
1285                          */
1286
1287                         load("nashorn:mozilla_compat.js");
1288                         importClass(org.slf4j.LoggerFactory);
1289
1290                         var logger = executor.logger;
1291                         logger.trace("start: " + executor.subject.id + " - TSL");
1292
1293                         var rootLogger = LoggerFactory.getLogger(logger.ROOT_LOGGER_NAME);
1294
1295                         var ifSituation = executor.inFields["situation"];
1296
1297                         var albumProblemMap = executor.getContextAlbum("albumProblemMap");
1298
1299                         var returnValueType = Java.type("java.lang.Boolean");
1300                         if (ifSituation.get("problemID") == "NONE") {
1301                             logger.trace("-- situation has no problem, selecting <VpnSlaPolicyDecideNoneTask>");
1302                             executor.subject.getTaskKey("VpnSlaPolicyDecideNoneTask").copyTo(executor.selectedTask);
1303                             var returnValue = new returnValueType(true);
1304                         } else if (albumProblemMap.get(ifSituation.get("problemID")).get("status") == "SOLVED") {
1305                             logger.trace("-- situation is solved, selecting <VpnSlaPolicyDecideSolvedTask>");
1306                             executor.subject.getTaskKey("VpnSlaPolicyDecideSolvedTask").copyTo(executor.selectedTask);
1307                             var returnValue = new returnValueType(true);
1308                         } else if (ifSituation.get("violatedSLAs") != null && ifSituation.get("violatedSLAs").size() > 0) {
1309                             logger.trace("-- situation is problem with violations, selecting <VpnSlaPolicyDecidePriorityTask>");
1310                             executor.subject.getTaskKey("VpnSlaPolicyDecidePriorityTask").copyTo(executor.selectedTask);
1311                             var returnValue = new returnValueType(true);
1312                         } else if (ifSituation.get("violatedSLAs") != null && ifSituation.get("violatedSLAs").size() == 0) {
1313                             logger.trace("-- situation is problem without violations, selecting <VpnSlaPolicyDecideSlaTask>");
1314                             executor.subject.getTaskKey("VpnSlaPolicyDecideSlaTask").copyTo(executor.selectedTask);
1315                             var returnValue = new returnValueType(true);
1316                         } else {
1317                             logger.error("-- detected unknown decision for situation <" + ifSituation.get("problemID") + ">");
1318                             rootLogger.error(executor.subject.id + " " + "-- detected unknown decision for situation <"
1319                                     + ifSituation.get("problemID") + ">");
1320                             var returnValue = new returnValueType(false);
1321                         }
1322
1323                         logger.trace("finished: " + executor.subject.id);
1324                         logger.debug(".d-tsl");
1325
1326                .. container:: paragraph
1327
1328                   The actual task logic are then ``none``, ``solved``,
1329                   ``sla``, and ``priority``.
1330
1331 Logic: Decide None
1332 -------------------
1333
1334          .. container:: sect1
1335
1336             .. container:: sectionbody
1337
1338                .. container:: listingblock
1339
1340                   .. container:: content
1341
1342                      .. code:: CodeRay
1343
1344                         /*
1345                          * ============LICENSE_START=======================================================
1346                          *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
1347                          * ================================================================================
1348                          * Licensed under the Apache License, Version 2.0 (the "License");
1349                          * you may not use this file except in compliance with the License.
1350                          * You may obtain a copy of the License at
1351                          *
1352                          *      http://www.apache.org/licenses/LICENSE-2.0
1353                          *
1354                          * Unless required by applicable law or agreed to in writing, software
1355                          * distributed under the License is distributed on an "AS IS" BASIS,
1356                          * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1357                          * See the License for the specific language governing permissions and
1358                          * limitations under the License.
1359                          *
1360                          * SPDX-License-Identifier: Apache-2.0
1361                          * ============LICENSE_END=========================================================
1362                          */
1363
1364                         load("nashorn:mozilla_compat.js");
1365                         importClass(org.slf4j.LoggerFactory);
1366
1367                         importClass(java.util.ArrayList);
1368
1369                         importClass(org.apache.avro.generic.GenericData.Array);
1370                         importClass(org.apache.avro.generic.GenericRecord);
1371                         importClass(org.apache.avro.Schema);
1372
1373                         var logger = executor.logger;
1374                         logger.trace("start: " + executor.subject.id);
1375                         logger.trace("-- infields: " + executor.inFields);
1376
1377                         var rootLogger = LoggerFactory.getLogger(logger.ROOT_LOGGER_NAME);
1378
1379                         var ifSituation = executor.inFields["situation"];
1380
1381                         // create outfiled for decision
1382                         var decision = executor.subject.getOutFieldSchemaHelper("decision").createNewInstance();
1383                         decision.put("description", "None, everything is ok");
1384                         decision.put("decision", "NONE");
1385                         decision.put("customers", new ArrayList());
1386
1387                         var returnValueType = Java.type("java.lang.Boolean");
1388                         if (ifSituation.get("problemID") == "NONE") {
1389                             logger.trace("-- no problem, everything ok");
1390                             var returnValue = new returnValueType(true);
1391                         } else {
1392                             logger.trace("-- wrong problemID <" + problemID + "> for NONE task, we should not be here");
1393                             rootLogger.error(executor.subject.id + " " + "-- wrong problemID <" + problemID
1394                                     + "> for NONE task, we should not be here");
1395                             var returnValue = new returnValueType(false);
1396                         }
1397
1398                         executor.outFields["decision"] = decision;
1399
1400                         logger.trace("finished: " + executor.subject.id);
1401                         logger.debug(".d-non");
1402
1403 Logic: Decide Solved
1404 ---------------------
1405
1406          .. container:: sect1
1407
1408             .. container:: sectionbody
1409
1410                .. container:: listingblock
1411
1412                   .. container:: content
1413
1414                      .. code:: CodeRay
1415
1416                         /*
1417                          * ============LICENSE_START=======================================================
1418                          *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
1419                          * ================================================================================
1420                          * Licensed under the Apache License, Version 2.0 (the "License");
1421                          * you may not use this file except in compliance with the License.
1422                          * You may obtain a copy of the License at
1423                          *
1424                          *      http://www.apache.org/licenses/LICENSE-2.0
1425                          *
1426                          * Unless required by applicable law or agreed to in writing, software
1427                          * distributed under the License is distributed on an "AS IS" BASIS,
1428                          * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1429                          * See the License for the specific language governing permissions and
1430                          * limitations under the License.
1431                          *
1432                          * SPDX-License-Identifier: Apache-2.0
1433                          * ============LICENSE_END=========================================================
1434                          */
1435
1436                         load("nashorn:mozilla_compat.js");
1437                         importClass(org.slf4j.LoggerFactory);
1438
1439                         importClass(java.util.ArrayList);
1440
1441                         importClass(org.apache.avro.generic.GenericData.Array);
1442                         importClass(org.apache.avro.generic.GenericRecord);
1443                         importClass(org.apache.avro.Schema);
1444
1445                         var logger = executor.logger;
1446                         logger.trace("start: " + executor.subject.id);
1447                         logger.trace("-- infields: " + executor.inFields);
1448
1449                         var rootLogger = LoggerFactory.getLogger(logger.ROOT_LOGGER_NAME);
1450
1451                         var ifSituation = executor.inFields["situation"];
1452
1453                         var albumProblemMap = executor.getContextAlbum("albumProblemMap");
1454
1455                         // create outfiled for decision
1456                         var decision = executor.subject.getOutFieldSchemaHelper("decision").createNewInstance();
1457                         decision.put("description", "None, everything is ok");
1458                         decision.put("decision", "REBUILD");
1459                         decision.put("customers", new ArrayList());
1460                         decision.put("problemID", ifSituation.get("problemID"));
1461
1462                         var returnValueType = Java.type("java.lang.Boolean");
1463                         if (albumProblemMap.get(ifSituation.get("problemID")).get("status") == "SOLVED") {
1464                             logger.trace("-- problem solved");
1465                             var returnValue = new returnValueType(true);
1466                         } else {
1467                             logger.trace("-- wrong problemID <" + problemID + "> for SOLVED task, we should not be here");
1468                             rootLogger.error(executor.subject.id + " " + "-- wrong problemID <" + problemID
1469                                     + "> for SOLVED task, we should not be here");
1470                             var returnValue = new returnValueType(false);
1471                         }
1472
1473                         executor.outFields["decision"] = decision;
1474
1475                         logger.info("vpnsla: sla solved, problem solved");
1476
1477                         logger.trace("finished: " + executor.subject.id);
1478                         logger.debug(".d-non");
1479
1480 Logic: Decide SLA
1481 ------------------
1482
1483          .. container:: sect1
1484
1485             .. container:: sectionbody
1486
1487                .. container:: listingblock
1488
1489                   .. container:: content
1490
1491                      .. code:: CodeRay
1492
1493                         /*
1494                          * ============LICENSE_START=======================================================
1495                          *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
1496                          * ================================================================================
1497                          * Licensed under the Apache License, Version 2.0 (the "License");
1498                          * you may not use this file except in compliance with the License.
1499                          * You may obtain a copy of the License at
1500                          *
1501                          *      http://www.apache.org/licenses/LICENSE-2.0
1502                          *
1503                          * Unless required by applicable law or agreed to in writing, software
1504                          * distributed under the License is distributed on an "AS IS" BASIS,
1505                          * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1506                          * See the License for the specific language governing permissions and
1507                          * limitations under the License.
1508                          *
1509                          * SPDX-License-Identifier: Apache-2.0
1510                          * ============LICENSE_END=========================================================
1511                          */
1512
1513                         load("nashorn:mozilla_compat.js");
1514                         importClass(org.slf4j.LoggerFactory);
1515
1516                         importClass(java.util.ArrayList);
1517
1518                         importClass(org.apache.avro.generic.GenericData.Array);
1519                         importClass(org.apache.avro.generic.GenericRecord);
1520                         importClass(org.apache.avro.Schema);
1521
1522                         var logger = executor.logger;
1523                         logger.trace("start: " + executor.subject.id);
1524                         logger.trace("-- infields: " + executor.inFields);
1525
1526                         var rootLogger = LoggerFactory.getLogger(logger.ROOT_LOGGER_NAME);
1527
1528                         var ifSituation = executor.inFields["situation"];
1529
1530                         var albumCustomerMap = executor.getContextAlbum("albumCustomerMap");
1531                         var albumProblemMap = executor.getContextAlbum("albumProblemMap");
1532
1533                         // create outfiled for decision
1534                         var decision = executor.subject.getOutFieldSchemaHelper("decision").createNewInstance();
1535                         decision.put("description", "Impede given customers selected based on maximum SLA delta");
1536                         decision.put("decision", "IMPEDE");
1537                         decision.put("problemID", ifSituation.get("problemID"));
1538                         decision.put("customers", new ArrayList());
1539
1540                         var problem = albumProblemMap.get(ifSituation.get("problemID"));
1541                         var returnValueType = Java.type("java.lang.Boolean");
1542                         if (problem != null && ifSituation.get("violatedSLAs").size() == 0) {
1543                             logger.trace("-- impede by maximum SLA");
1544                             var customer = "";
1545                             var customerSla = 0;
1546                             for (var i = 0; i < problem.get("edgeUsedBy").size(); i++) {
1547                                 customerCtxt = albumCustomerMap.get(problem.get("edgeUsedBy").get(i).toString());
1548                                 if (customerSla == 0) {
1549                                     customerSla = customerCtxt.get("dtSLA") - customerCtxt.get("dtYTD");
1550                                 }
1551                                 if ((customerCtxt.get("dtSLA") - customerCtxt.get("dtYTD")) >= customerSla) {
1552                                     customer = customerCtxt.get("customerName");
1553                                     customerSla = (customerCtxt.get("dtSLA") - customerCtxt.get("dtYTD"));
1554                                 }
1555                             }
1556                             decision.get("customers").add(customer);
1557                             var returnValue = new returnValueType(true);
1558                         } else {
1559                             logger.trace("-- wrong problemID <" + ifSituation.get("problemID") + "> for SLA task, we should not be here");
1560                             rootLogger.error(executor.subject.id + " " + "-- wrong problemID <" + ifSituation.get("problemID")
1561                                     + "> for SLA task, we should not be here");
1562                             var returnValue = new returnValueType(false);
1563                         }
1564
1565                         // set impededLast to decision[customers]
1566                         problem.get("impededLast").clear();
1567                         problem.get("impededLast").addAll(decision.get("customers"));
1568
1569                         executor.outFields["decision"] = decision;
1570                         logger.trace("-- decision: " + decision);
1571
1572                         logger.info("vpnsla: sla balance, impeding customers " + decision.get("customers"));
1573
1574                         logger.trace("finished: " + executor.subject.id);
1575                         logger.debug(".d-sla");
1576
1577 Logic: Decide Priority
1578 ----------------------
1579
1580          .. container:: sect2
1581
1582             .. container:: listingblock
1583
1584                .. container:: content
1585
1586                   .. code:: CodeRay
1587
1588                      /*
1589                       * ============LICENSE_START=======================================================
1590                       *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
1591                       * ================================================================================
1592                       * Licensed under the Apache License, Version 2.0 (the "License");
1593                       * you may not use this file except in compliance with the License.
1594                       * You may obtain a copy of the License at
1595                       *
1596                       *      http://www.apache.org/licenses/LICENSE-2.0
1597                       *
1598                       * Unless required by applicable law or agreed to in writing, software
1599                       * distributed under the License is distributed on an "AS IS" BASIS,
1600                       * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1601                       * See the License for the specific language governing permissions and
1602                       * limitations under the License.
1603                       *
1604                       * SPDX-License-Identifier: Apache-2.0
1605                       * ============LICENSE_END=========================================================
1606                       */
1607
1608                      load("nashorn:mozilla_compat.js");
1609                      importClass(org.slf4j.LoggerFactory);
1610
1611                      importClass(java.util.ArrayList);
1612
1613                      importClass(org.apache.avro.generic.GenericData.Array);
1614                      importClass(org.apache.avro.generic.GenericRecord);
1615                      importClass(org.apache.avro.Schema);
1616
1617                      var logger = executor.logger;
1618                      logger.trace("start: " + executor.subject.id);
1619                      logger.trace("-- infields: " + executor.inFields);
1620
1621                      var rootLogger = LoggerFactory.getLogger(logger.ROOT_LOGGER_NAME);
1622
1623                      var ifSituation = executor.inFields["situation"];
1624
1625                      var albumCustomerMap = executor.getContextAlbum("albumCustomerMap");
1626                      var albumProblemMap = executor.getContextAlbum("albumProblemMap");
1627
1628                      // create outfiled for decision
1629                      var decision = executor.subject.getOutFieldSchemaHelper("decision").createNewInstance();
1630                      decision.put("description", "None, everything is ok");
1631                      decision.put("decision", "IMPEDE");
1632                      decision.put("problemID", ifSituation.get("problemID"));
1633                      decision.put("customers", new ArrayList());
1634
1635                      var problem = albumProblemMap.get(ifSituation.get("problemID"));
1636                      var returnValueType = Java.type("java.lang.Boolean");
1637                      if (problem != null && ifSituation.get("violatedSLAs").size() > 0) {
1638                          logger.trace("-- impede by priority");
1639                          for (var i = 0; i < problem.get("edgeUsedBy").size(); i++) {
1640                              customerCtxt = albumCustomerMap.get(problem.get("edgeUsedBy").get(i).toString());
1641                              if (customerCtxt.get("priority") == false) {
1642                                  decision.get("customers").add(customerCtxt.get("customerName"));
1643                              }
1644                          }
1645                          var returnValue = new returnValueType(true);
1646                      } else {
1647                          logger.trace("-- wrong problemID <" + ifSituation.get("problemID") + "> for PRIORITY task, we should not be here");
1648                          rootLogger.error(executor.subject.id + " " + "-- wrong problemID <" + ifSituation.get("problemID")
1649                                  + "> for PRIORITY task, we should not be here");
1650                          var returnValue = new returnValueType(false);
1651                      }
1652
1653                      // set impededLast to decision[customers]
1654                      problem.get("impededLast").clear();
1655                      problem.get("impededLast").addAll(decision.get("customers"));
1656
1657                      executor.outFields["decision"] = decision;
1658                      logger.trace("-- decision: " + decision);
1659
1660                      logger.info("vpnsla: priority, impeding customers " + decision.get("customers"));
1661
1662                      logger.trace("finished: " + executor.subject.id);
1663                      logger.debug(".d-pri");
1664
1665 Logic: Policy Act State
1666 ------------------------
1667
1668          .. container:: sect1
1669
1670             .. container:: sectionbody
1671
1672                .. container:: paragraph
1673
1674                   This is the logic for the act state. It is simply
1675                   selecting an action, and creating the repsonse event
1676                   for the orchestrator (the output of the policy).
1677
1678                .. container:: listingblock
1679
1680                   .. container:: content
1681
1682                      .. code:: CodeRay
1683
1684                         /*
1685                          * ============LICENSE_START=======================================================
1686                          *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
1687                          * ================================================================================
1688                          * Licensed under the Apache License, Version 2.0 (the "License");
1689                          * you may not use this file except in compliance with the License.
1690                          * You may obtain a copy of the License at
1691                          *
1692                          *      http://www.apache.org/licenses/LICENSE-2.0
1693                          *
1694                          * Unless required by applicable law or agreed to in writing, software
1695                          * distributed under the License is distributed on an "AS IS" BASIS,
1696                          * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1697                          * See the License for the specific language governing permissions and
1698                          * limitations under the License.
1699                          *
1700                          * SPDX-License-Identifier: Apache-2.0
1701                          * ============LICENSE_END=========================================================
1702                          */
1703
1704                         load("nashorn:mozilla_compat.js");
1705
1706                         var logger = executor.logger;
1707                         logger.trace("start: " + executor.subject.id);
1708                         logger.trace("-- infields: " + executor.inFields);
1709
1710                         var ifDecision = executor.inFields["decision"];
1711                         var ifMatchStart = executor.inFields["matchStart"];
1712
1713                         var albumCustomerMap = executor.getContextAlbum("albumCustomerMap");
1714                         var albumProblemMap = executor.getContextAlbum("albumProblemMap");
1715
1716                         switch (ifDecision.get("decision").toString()) {
1717                         case "NONE":
1718                             executor.outFields["edgeName"] = "";
1719                             executor.outFields["action"] = "";
1720                             break;
1721                         case "IMPEDE":
1722                             for (var i = 0; i < ifDecision.get("customers").size(); i++) {
1723                                 customer = albumCustomerMap.get(ifDecision.get("customers").get(i).toString());
1724                                 executor.outFields["edgeName"] = customer.get("links").get(0);
1725                                 executor.outFields["action"] = "firewall";
1726                             }
1727                             break;
1728                         case "REBUILD":
1729                             // finally solved, remove problem
1730                             albumProblemMap.remove(ifDecision.get("problemID"));
1731                             executor.outFields["edgeName"] = "L10"; // this is ###static###
1732                             executor.outFields["action"] = "rebuild"; // this is ###static###
1733                             break;
1734                         default:
1735
1736                         }
1737
1738                         var returnValueType = Java.type("java.lang.Boolean");
1739                         var returnValue = new returnValueType(true);
1740
1741                         if (executor.outFields["action"] != "") {
1742                             logger.info("vpnsla: action is to " + executor.outFields["action"] + " " + executor.outFields["edgeName"]);
1743                         } else {
1744                             logger.info("vpnsla: no action required");
1745                         }
1746
1747                         logger.trace("-- outfields: " + executor.outFields);
1748                         logger.trace("finished: " + executor.subject.id);
1749                         logger.debug(".a");
1750
1751                         var now = new Date().getTime();
1752                         logger.info("VPN SLA finished in " + (now - ifMatchStart) + " ms");
1753
1754 CLI Spec
1755 --------
1756
1757          .. container:: sect1
1758
1759             .. rubric:: Complete Policy Definition
1760                :name: complete_policy_definition
1761
1762             .. container:: sectionbody
1763
1764                .. container:: paragraph
1765
1766                   The complete policy definition is realized using the
1767                   APEX CLI Editor. The script below shows the actual
1768                   policy specification. All logic and schemas are
1769                   included (as macro file).
1770
1771                .. container:: listingblock
1772
1773                   .. container:: content
1774
1775                      .. code:: CodeRay
1776
1777                         #-------------------------------------------------------------------------------
1778                         # ============LICENSE_START=======================================================
1779                         #  Copyright (C) 2016-2018 Ericsson. All rights reserved.
1780                         # ================================================================================
1781                         # Licensed under the Apache License, Version 2.0 (the "License");
1782                         # you may not use this file except in compliance with the License.
1783                         # You may obtain a copy of the License at
1784                         #
1785                         #      http://www.apache.org/licenses/LICENSE-2.0
1786                         #
1787                         # Unless required by applicable law or agreed to in writing, software
1788                         # distributed under the License is distributed on an "AS IS" BASIS,
1789                         # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1790                         # See the License for the specific language governing permissions and
1791                         # limitations under the License.
1792                         #
1793                         # SPDX-License-Identifier: Apache-2.0
1794                         # ============LICENSE_END=========================================================
1795                         #-------------------------------------------------------------------------------
1796
1797                         # ============LICENSE_START=======================================================
1798                         #  Copyright (C) 2016-2018 Ericsson. All rights reserved.
1799                         # ================================================================================
1800                         # Licensed under the Apache License, Version 2.0 (the "License");
1801                         # you may not use this file except in compliance with the License.
1802                         # You may obtain a copy of the License at
1803                         #
1804                         #      http://www.apache.org/licenses/LICENSE-2.0
1805                         #
1806                         # Unless required by applicable law or agreed to in writing, software
1807                         # distributed under the License is distributed on an "AS IS" BASIS,
1808                         # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1809                         # See the License for the specific language governing permissions and
1810                         # limitations under the License.
1811                         #
1812                         # SPDX-License-Identifier: Apache-2.0
1813                         # ============LICENSE_END=========================================================
1814
1815                         model create name=PCVS-VpnSla version=1.0.0 description="Policies-Controlled Video Streaming, VPN SLA Policy Model"
1816
1817
1818
1819                         schema create name=reportDecl version=1.0.0 description="Report of activities of a policy/task" flavour=Java schema=java.lang.String
1820                         event create name=ReportOut version=1.0.0 description="Report of a policy (issued by a task)" nameSpace=org.onap.policy.apex.examples.pcvs.vpnsla source="APEX" target="CtxtManagement"
1821                         event parameter create name=ReportOut version=1.0.0 parName=report schemaName=reportDecl schemaVersion=1.0.0
1822
1823                         schema create name=timestampDecl version=1.0.0 description="Timestamp" flavour=Java schema=java.lang.Long
1824
1825
1826
1827                         schema create name=ctxtEdgeNameDecl version=1.0.0 description="Topology Edges: edge (link) name" flavour=Java schema=java.lang.String
1828                         schema create name=ctxtEdgeStartDecl version=1.0.0 description="Topology Edges: edge endpoint (start)" flavour=Java schema=java.lang.String
1829                         schema create name=ctxtEdgeEndDecl version=1.0.0 description="Topology Edges: edge endpoint (end)" flavour=Java schema=java.lang.String
1830                         schema create name=ctxtEdgeStatusDecl version=1.0.0 description="Topology Edges: edge status as up (true) or down (false)" flavour=Java schema=java.lang.Boolean
1831
1832                         schema create name=ctxtTopologyEdgesDecl version=1.0.0 description="Topology Edges Context Map" flavour=Avro schema=LS
1833                         #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/avro/topology-edges.avsc"
1834                         LE
1835                         album create name=albumTopoEdges scope=global writable=true schemaName=ctxtTopologyEdgesDecl
1836
1837
1838                         task create name=EdgeContextTask version=1.0.0 description="This task adds event context to edge context"
1839                         task inputfield create name=EdgeContextTask version=1.0.0 fieldName=edgeName schemaName=ctxtEdgeNameDecl schemaVersion=1.0.0
1840                         task inputfield create name=EdgeContextTask version=1.0.0 fieldName=start schemaName=ctxtEdgeStartDecl schemaVersion=1.0.0
1841                         task inputfield create name=EdgeContextTask version=1.0.0 fieldName=end schemaName=ctxtEdgeEndDecl schemaVersion=1.0.0
1842                         task inputfield create name=EdgeContextTask version=1.0.0 fieldName=status schemaName=ctxtEdgeStatusDecl schemaVersion=1.0.0
1843                         task outputfield create name=EdgeContextTask version=1.0.0 fieldName=report schemaName=reportDecl schemaVersion=1.0.0
1844                         task contextref create name=EdgeContextTask albumName=albumTopoEdges
1845                         task logic create name=EdgeContextTask logicFlavour=JAVASCRIPT logic=LS
1846                         #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/logic/ctxt-edges.js"
1847                         LE
1848
1849                         event create name=EdgeContextEventIn version=1.0.0 description="Event to add an Edge to engine Context" nameSpace=org.onap.policy.apex.examples.pcvs.vpnsla source="CtxtManagement" target="APEX"
1850                         event parameter create name=EdgeContextEventIn version=1.0.0 parName=edgeName schemaName=ctxtEdgeNameDecl schemaVersion=1.0.0
1851                         event parameter create name=EdgeContextEventIn version=1.0.0 parName=start schemaName=ctxtEdgeStartDecl schemaVersion=1.0.0
1852                         event parameter create name=EdgeContextEventIn version=1.0.0 parName=end schemaName=ctxtEdgeEndDecl schemaVersion=1.0.0
1853                         event parameter create name=EdgeContextEventIn version=1.0.0 parName=status schemaName=ctxtEdgeStatusDecl schemaVersion=1.0.0
1854
1855                         policy create name=EdgeContextPolicy version=1.0.0 description="Policy that adds an edge to context" template=FREEFORM firstState=EdgeContextState
1856                         policy state create name=EdgeContextPolicy version=1.0.0 stateName=EdgeContextState triggerName=EdgeContextEventIn triggerVersion=1.0.0 defaultTaskName=EdgeContextTask defaultTaskVersion=1.0.0
1857                         policy state output create name=EdgeContextPolicy version=1.0.0 stateName=EdgeContextState outputName=EdgeContextState_Output_Direct eventName=ReportOut eventVersion=1.0.0 nextState=NULL
1858                         policy state taskref create name=EdgeContextPolicy version=1.0.0 stateName=EdgeContextState taskLocalName=doContext taskName=EdgeContextTask taskVersion=1.0.0 outputType=DIRECT outputName=EdgeContextState_Output_Direct
1859
1860
1861
1862                         schema create name=ctxtNodeNameDecl version=1.0.0 description="Topology Nodes: node name" flavour=Java schema=java.lang.String
1863                         schema create name=ctxtNodeMininetNameDecl version=1.0.0 description="Topology Nodes: node name in Mininet" flavour=Java schema=java.lang.String
1864
1865                         schema create name=ctxtTopologyNodesDecl version=1.0.0 description="Topology Nodes Context Map" flavour=Avro schema=LS
1866                         #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/avro/topology-nodes.avsc"
1867                         LE
1868                         album create name=albumTopoNodes scope=global writable=true schemaName=ctxtTopologyNodesDecl
1869
1870                         task create name=NodeContextTask version=1.0.0 description="This task adds event context to node context"
1871                         task inputfield create name=NodeContextTask version=1.0.0 fieldName=nodeName schemaName=ctxtNodeNameDecl schemaVersion=1.0.0
1872                         task inputfield create name=NodeContextTask version=1.0.0 fieldName=mininetName schemaName=ctxtNodeMininetNameDecl schemaVersion=1.0.0
1873                         task outputfield create name=NodeContextTask version=1.0.0 fieldName=report schemaName=reportDecl schemaVersion=1.0.0
1874                         task contextref create name=NodeContextTask albumName=albumTopoNodes
1875                         task logic create name=NodeContextTask logicFlavour=JAVASCRIPT logic=LS
1876                         #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/logic/ctxt-nodes.js"
1877                         LE
1878
1879                         event create name=NodeContextEventIn version=1.0.0 description="Event to add Node to engine Context" nameSpace=org.onap.policy.apex.examples.pcvs.vpnsla source="CtxtManagement" target="APEX"
1880                         event parameter create name=NodeContextEventIn version=1.0.0 parName=nodeName schemaName=ctxtNodeNameDecl schemaVersion=1.0.0
1881                         event parameter create name=NodeContextEventIn version=1.0.0 parName=mininetName schemaName=ctxtNodeMininetNameDecl schemaVersion=1.0.0
1882
1883                         policy create name=NodeContextPolicy version=1.0.0 description="Policy that adds an node to context" template=FREEFORM firstState=NodeContextState
1884                         policy state create name=NodeContextPolicy version=1.0.0 stateName=NodeContextState triggerName=NodeContextEventIn triggerVersion=1.0.0 defaultTaskName=NodeContextTask defaultTaskVersion=1.0.0
1885                         policy state output create name=NodeContextPolicy version=1.0.0 stateName=NodeContextState outputName=NodeContextState_Output_Direct eventName=ReportOut eventVersion=1.0.0 nextState=NULL
1886                         policy state taskref create name=NodeContextPolicy version=1.0.0 stateName=NodeContextState taskLocalName=doContext taskName=NodeContextTask taskVersion=1.0.0 outputType=DIRECT outputName=NodeContextState_Output_Direct
1887
1888
1889
1890
1891                         schema create name=ctxtCustomerNameDecl version=1.0.0 description="Customer Context: customer name" flavour=Java schema=java.lang.String
1892                         schema create name=ctxtCustomerPriorityDecl version=1.0.0 description="Customer Context: priority flag" flavour=Java schema=java.lang.Boolean
1893                         schema create name=ctxtCustomerSatisfactionDecl version=1.0.0 description="Customer Context: satisfaction in percent" flavour=Java schema=java.lang.Integer
1894                         schema create name=ctxtCustomerDowntimeSLADecl version=1.0.0 description="Customer Context: contracted downtime as per SLA" flavour=Java schema=java.lang.Integer
1895                         schema create name=ctxtCustomerDowntimeYTDDecl version=1.0.0 description="Customer Context: year-to-date downtime experienced" flavour=Java schema=java.lang.Integer
1896                         schema create name=ctxtCustomerLinksDecl version=1.0.0 description="Customer Context: links a customer uses (for events/task)" flavour=Java schema=java.lang.String
1897
1898                         schema create name=ctxtCustomerMapDecl version=1.0.0 description="Map of customers with all known information" flavour=Avro schema=LS
1899                         #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/avro/customers.avsc"
1900                         LE
1901                         album create name=albumCustomerMap scope=global writable=true schemaName=ctxtCustomerMapDecl
1902
1903                         task create name=CustomerContextTask version=1.0.0 description="This task adds event context to customer context"
1904                         task inputfield create name=CustomerContextTask version=1.0.0 fieldName=customerName schemaName=ctxtCustomerNameDecl schemaVersion=1.0.0
1905                         task inputfield create name=CustomerContextTask version=1.0.0 fieldName=priority schemaName=ctxtCustomerPriorityDecl schemaVersion=1.0.0
1906                         task inputfield create name=CustomerContextTask version=1.0.0 fieldName=satisfaction schemaName=ctxtCustomerSatisfactionDecl schemaVersion=1.0.0
1907                         task inputfield create name=CustomerContextTask version=1.0.0 fieldName=dtSLA schemaName=ctxtCustomerDowntimeSLADecl schemaVersion=1.0.0
1908                         task inputfield create name=CustomerContextTask version=1.0.0 fieldName=dtYTD schemaName=ctxtCustomerDowntimeYTDDecl schemaVersion=1.0.0
1909                         task inputfield create name=CustomerContextTask version=1.0.0 fieldName=links schemaName=ctxtCustomerLinksDecl schemaVersion=1.0.0
1910                         task outputfield create name=CustomerContextTask version=1.0.0 fieldName=report schemaName=reportDecl schemaVersion=1.0.0
1911                         task contextref create name=CustomerContextTask albumName=albumCustomerMap
1912                         task contextref create name=CustomerContextTask albumName=albumTopoEdges
1913                         task logic create name=CustomerContextTask logicFlavour=JAVASCRIPT logic=LS
1914                         #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/logic/ctxt-customer.js"
1915                         LE
1916
1917                         event create name=CustomerContextEventIn version=1.0.0 description="Event to add Customers to engine Context" nameSpace=org.onap.policy.apex.examples.pcvs.vpnsla source="CtxtManagement" target="APEX"
1918                         event parameter create name=CustomerContextEventIn version=1.0.0 parName=customerName schemaName=ctxtCustomerNameDecl schemaVersion=1.0.0
1919                         event parameter create name=CustomerContextEventIn version=1.0.0 parName=priority schemaName=ctxtCustomerPriorityDecl schemaVersion=1.0.0
1920                         event parameter create name=CustomerContextEventIn version=1.0.0 parName=satisfaction schemaName=ctxtCustomerSatisfactionDecl schemaVersion=1.0.0
1921                         event parameter create name=CustomerContextEventIn version=1.0.0 parName=dtSLA schemaName=ctxtCustomerDowntimeSLADecl schemaVersion=1.0.0
1922                         event parameter create name=CustomerContextEventIn version=1.0.0 parName=dtYTD schemaName=ctxtCustomerDowntimeYTDDecl schemaVersion=1.0.0
1923                         event parameter create name=CustomerContextEventIn version=1.0.0 parName=links schemaName=ctxtCustomerLinksDecl schemaVersion=1.0.0
1924
1925                         policy create name=CustomerContextPolicy version=1.0.0 description="Policy that adds Customer information to engine context" template=FREEFORM firstState=CustomerContextState
1926                         policy state create name=CustomerContextPolicy version=1.0.0 stateName=CustomerContextState triggerName=CustomerContextEventIn triggerVersion=1.0.0 defaultTaskName=CustomerContextTask defaultTaskVersion=1.0.0
1927                         policy state output create name=CustomerContextPolicy version=1.0.0 stateName=CustomerContextState outputName=CustomerContextState_Output_Direct eventName=ReportOut eventVersion=1.0.0 nextState=NULL
1928                         policy state taskref create name=CustomerContextPolicy version=1.0.0 stateName=CustomerContextState taskLocalName=doContext taskName=CustomerContextTask taskVersion=1.0.0 outputType=DIRECT outputName=CustomerContextState_Output_Direct
1929
1930
1931
1932
1933                         schema create name=edgeNameDecl version=1.0.0 description="Edge name" flavour=Java schema=java.lang.String
1934                         schema create name=edgeStatusDecl version=1.0.0 description="Statuf of the edge (UP, DOWN)" flavour=Avro schema=LS
1935                         #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/avro/link-status.avsc"
1936                         LE
1937                         schema create name=edgeChangedDecl version=1.0.0 description="Status Change (true:change, false:no change)" flavour=Java schema=java.lang.Boolean
1938
1939                         task create name=VpnSlaPolicyMatchTask version=1.0.0 description="Pre-process an edge event"
1940                         task inputfield create name=VpnSlaPolicyMatchTask version=1.0.0 fieldName=edgeName schemaName=edgeNameDecl schemaVersion=1.0.0
1941                         task inputfield create name=VpnSlaPolicyMatchTask version=1.0.0 fieldName=status schemaName=edgeStatusDecl schemaVersion=1.0.0
1942                         task outputfield create name=VpnSlaPolicyMatchTask version=1.0.0 fieldName=edgeName schemaName=edgeNameDecl schemaVersion=1.0.0
1943                         task outputfield create name=VpnSlaPolicyMatchTask version=1.0.0 fieldName=status schemaName=edgeStatusDecl schemaVersion=1.0.0
1944                         task outputfield create name=VpnSlaPolicyMatchTask version=1.0.0 fieldName=hasChanged schemaName=edgeChangedDecl schemaVersion=1.0.0
1945                         task outputfield create name=VpnSlaPolicyMatchTask version=1.0.0 fieldName=matchStart schemaName=timestampDecl schemaVersion=1.0.0
1946                         task contextref create name=VpnSlaPolicyMatchTask albumName=albumTopoEdges
1947                         task logic create name=VpnSlaPolicyMatchTask logicFlavour=JAVASCRIPT logic=LS
1948                         #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/logic/task-match.js"
1949                         LE
1950
1951
1952
1953
1954                         schema create name=problemMapDecl version=1.0.0 description="Map of problems with all known Information" flavour=Avro schema=LS
1955                         #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/avro/problems.avsc"
1956                         LE
1957                         album create name=albumProblemMap scope=global writable=true schemaName=problemMapDecl
1958
1959                         schema create name=establishSituationDecl version=1.0.0 description="Establish: the situation that was established" flavour=Avro schema=LS
1960                         #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/avro/situation.avsc"
1961                         LE
1962
1963                         task create name=VpnSlaPolicyEstablishTask version=1.0.0 description="Task taking a match event and establishing a situation"
1964                         task inputfield create name=VpnSlaPolicyEstablishTask version=1.0.0 fieldName=edgeName schemaName=edgeNameDecl schemaVersion=1.0.0
1965                         task inputfield create name=VpnSlaPolicyEstablishTask version=1.0.0 fieldName=status schemaName=edgeStatusDecl schemaVersion=1.0.0
1966                         task inputfield create name=VpnSlaPolicyEstablishTask version=1.0.0 fieldName=hasChanged schemaName=edgeChangedDecl schemaVersion=1.0.0
1967                         task inputfield create name=VpnSlaPolicyEstablishTask version=1.0.0 fieldName=matchStart schemaName=timestampDecl schemaVersion=1.0.0
1968                         task outputfield create name=VpnSlaPolicyEstablishTask version=1.0.0 fieldName=situation schemaName=establishSituationDecl schemaVersion=1.0.0
1969                         task outputfield create name=VpnSlaPolicyEstablishTask version=1.0.0 fieldName=matchStart schemaName=timestampDecl schemaVersion=1.0.0
1970                         task contextref create name=VpnSlaPolicyEstablishTask albumName=albumProblemMap
1971                         task contextref create name=VpnSlaPolicyEstablishTask albumName=albumCustomerMap
1972                         task logic create name=VpnSlaPolicyEstablishTask logicFlavour=JAVASCRIPT logic=LS
1973                         #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/logic/task-establish.js"
1974                         LE
1975
1976
1977
1978
1979                         schema create name=decideDecisionDecl version=1.0.0 description="Decide: the taken decision" flavour=Avro schema=LS
1980                         #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/avro/decision.avsc"
1981                         LE
1982
1983                         task create name=VpnSlaPolicyDecideNoneTask version=1.0.0 description="Decide task for a 'none' problem"
1984                         task inputfield create name=VpnSlaPolicyDecideNoneTask version=1.0.0 fieldName=situation schemaName=establishSituationDecl schemaVersion=1.0.0
1985                         task inputfield create name=VpnSlaPolicyDecideNoneTask version=1.0.0 fieldName=matchStart schemaName=timestampDecl schemaVersion=1.0.0
1986                         task outputfield create name=VpnSlaPolicyDecideNoneTask version=1.0.0 fieldName=decision schemaName=decideDecisionDecl schemaVersion=1.0.0
1987                         task outputfield create name=VpnSlaPolicyDecideNoneTask version=1.0.0 fieldName=matchStart schemaName=timestampDecl schemaVersion=1.0.0
1988                         task logic create name=VpnSlaPolicyDecideNoneTask logicFlavour=JAVASCRIPT logic=LS
1989                         #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/logic/task-decide-none.js"
1990                         LE
1991
1992
1993                         task create name=VpnSlaPolicyDecideSlaTask version=1.0.0 description="Decide task solving the problem by balancing SLAs"
1994                         task inputfield create name=VpnSlaPolicyDecideSlaTask version=1.0.0 fieldName=situation schemaName=establishSituationDecl schemaVersion=1.0.0
1995                         task inputfield create name=VpnSlaPolicyDecideSlaTask version=1.0.0 fieldName=matchStart schemaName=timestampDecl schemaVersion=1.0.0
1996                         task outputfield create name=VpnSlaPolicyDecideSlaTask version=1.0.0 fieldName=decision schemaName=decideDecisionDecl schemaVersion=1.0.0
1997                         task outputfield create name=VpnSlaPolicyDecideSlaTask version=1.0.0 fieldName=matchStart schemaName=timestampDecl schemaVersion=1.0.0
1998                         task contextref create name=VpnSlaPolicyDecideSlaTask albumName=albumCustomerMap
1999                         task contextref create name=VpnSlaPolicyDecideSlaTask albumName=albumProblemMap
2000                         task logic create name=VpnSlaPolicyDecideSlaTask logicFlavour=JAVASCRIPT logic=LS
2001                         #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/logic/task-decide-sla.js"
2002                         LE
2003
2004
2005                         task create name=VpnSlaPolicyDecidePriorityTask version=1.0.0 description="Decide task solving the problem by using customer priorities"
2006                         task inputfield create name=VpnSlaPolicyDecidePriorityTask version=1.0.0 fieldName=situation schemaName=establishSituationDecl schemaVersion=1.0.0
2007                         task inputfield create name=VpnSlaPolicyDecidePriorityTask version=1.0.0 fieldName=matchStart schemaName=timestampDecl schemaVersion=1.0.0
2008                         task outputfield create name=VpnSlaPolicyDecidePriorityTask version=1.0.0 fieldName=decision schemaName=decideDecisionDecl schemaVersion=1.0.0
2009                         task outputfield create name=VpnSlaPolicyDecidePriorityTask version=1.0.0 fieldName=matchStart schemaName=timestampDecl schemaVersion=1.0.0
2010                         task contextref create name=VpnSlaPolicyDecidePriorityTask albumName=albumCustomerMap
2011                         task contextref create name=VpnSlaPolicyDecidePriorityTask albumName=albumProblemMap
2012                         task logic create name=VpnSlaPolicyDecidePriorityTask logicFlavour=JAVASCRIPT logic=LS
2013                         #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/logic/task-decide-priority.js"
2014                         LE
2015
2016
2017                         task create name=VpnSlaPolicyDecideSolvedTask version=1.0.0 description="Decide task solving the problem by using customer priorities"
2018                         task inputfield create name=VpnSlaPolicyDecideSolvedTask version=1.0.0 fieldName=situation schemaName=establishSituationDecl schemaVersion=1.0.0
2019                         task inputfield create name=VpnSlaPolicyDecideSolvedTask version=1.0.0 fieldName=matchStart schemaName=timestampDecl schemaVersion=1.0.0
2020                         task outputfield create name=VpnSlaPolicyDecideSolvedTask version=1.0.0 fieldName=decision schemaName=decideDecisionDecl schemaVersion=1.0.0
2021                         task outputfield create name=VpnSlaPolicyDecideSolvedTask version=1.0.0 fieldName=matchStart schemaName=timestampDecl schemaVersion=1.0.0
2022                         task contextref create name=VpnSlaPolicyDecideSolvedTask albumName=albumProblemMap
2023                         task logic create name=VpnSlaPolicyDecideSolvedTask logicFlavour=JAVASCRIPT logic=LS
2024                         #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/logic/task-decide-solved.js"
2025                         LE
2026
2027
2028
2029
2030                         schema create name=actionDecl version=1.0.0 description="An action for the actioning system" flavour=Java schema=java.lang.String
2031
2032                         task create name=VpnSlaPolicyActTask version=1.0.0 description="Task issueing an action for taken decision"
2033                         task inputfield create name=VpnSlaPolicyActTask version=1.0.0 fieldName=decision schemaName=decideDecisionDecl schemaVersion=1.0.0
2034                         task inputfield create name=VpnSlaPolicyActTask version=1.0.0 fieldName=matchStart schemaName=timestampDecl schemaVersion=1.0.0
2035                         task outputfield create name=VpnSlaPolicyActTask version=1.0.0 fieldName=edgeName schemaName=edgeNameDecl schemaVersion=1.0.0
2036                         task outputfield create name=VpnSlaPolicyActTask version=1.0.0 fieldName=action schemaName=actionDecl schemaVersion=1.0.0
2037                         task contextref create name=VpnSlaPolicyActTask albumName=albumCustomerMap
2038                         task contextref create name=VpnSlaPolicyActTask albumName=albumProblemMap
2039                         task logic create name=VpnSlaPolicyActTask logicFlavour=JAVASCRIPT logic=LS
2040                         #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/logic/task-act.js"
2041                         LE
2042
2043
2044
2045
2046
2047
2048
2049                         event create name=VpnSlaTrigger version=1.0.0 description="Event triggering the VPN SLA policy" nameSpace=org.onap.policy.apex.examples.pcvs.vpnsla source="TriggerSys" target="VpnSlaMatch"
2050                         event parameter create name=VpnSlaTrigger version=1.0.0 parName=edgeName schemaName=edgeNameDecl schemaVersion=1.0.0
2051                         event parameter create name=VpnSlaTrigger version=1.0.0 parName=status schemaName=edgeStatusDecl schemaVersion=1.0.0
2052
2053                         event create name=VpnSlaMatchOut version=1.0.0 description="Event with matched trigger for the VPN SLA policy" nameSpace=org.onap.policy.apex.examples.pcvs.vpnsla source="VpnSlaMatch" target="VpnSlaEstablish"
2054                         event parameter create name=VpnSlaMatchOut version=1.0.0 parName=edgeName schemaName=edgeNameDecl schemaVersion=1.0.0
2055                         event parameter create name=VpnSlaMatchOut version=1.0.0 parName=status schemaName=edgeStatusDecl schemaVersion=1.0.0
2056                         event parameter create name=VpnSlaMatchOut version=1.0.0 parName=hasChanged schemaName=edgeChangedDecl schemaVersion=1.0.0
2057                         event parameter create name=VpnSlaMatchOut version=1.0.0 parName=matchStart schemaName=timestampDecl schemaVersion=1.0.0
2058
2059                         event create name=VpnSlaEstablishOut version=1.0.0 description="Event with situation for the SLA policy" nameSpace=org.onap.policy.apex.examples.pcvs.vpnsla source="SlaEstablish" target="SlaDecide"
2060                         event parameter create name=VpnSlaEstablishOut version=1.0.0 parName=situation schemaName=establishSituationDecl schemaVersion=1.0.0
2061                         event parameter create name=VpnSlaEstablishOut version=1.0.0 parName=matchStart schemaName=timestampDecl schemaVersion=1.0.0
2062
2063                         event create name=VpnSlaDecideOut version=1.0.0 description="Event with a decision for the SLA policy" nameSpace=org.onap.policy.apex.examples.pcvs.vpnsla source="SlaDecide" target="SlaAct"
2064                         event parameter create name=VpnSlaDecideOut version=1.0.0 parName=decision schemaName=decideDecisionDecl schemaVersion=1.0.0
2065                         event parameter create name=VpnSlaDecideOut version=1.0.0 parName=matchStart schemaName=timestampDecl schemaVersion=1.0.0
2066
2067                         event create name=VpnSlaActOut version=1.0.0 description="Event action" nameSpace=org.onap.policy.apex.examples.pcvs.vpnsla source="SlaAct" target="ActioningSystem"
2068                         event parameter create name=VpnSlaActOut version=1.0.0 parName=edgeName schemaName=edgeNameDecl schemaVersion=1.0.0
2069                         event parameter create name=VpnSlaActOut version=1.0.0 parName=action schemaName=actionDecl schemaVersion=1.0.0
2070
2071
2072                         policy create name=VpnSlaPolicy version=1.0.0 description="Policy deciding customer treatment based on SLAs as MEDA policy" template=FREEFORM firstState=VpnSlaPolicyMatchState
2073
2074                         policy state create name=VpnSlaPolicy version=1.0.0 stateName=VpnSlaPolicyActState triggerName=VpnSlaDecideOut triggerVersion=1.0.0 defaultTaskName=VpnSlaPolicyActTask defaultTaskVersion=1.0.0
2075                         policy state output create name=VpnSlaPolicy version=1.0.0 stateName=VpnSlaPolicyActState outputName=SlaPolicyAct_Output_Direct eventName=VpnSlaActOut eventVersion=1.0.0 nextState=NULL
2076                         policy state taskref create name=VpnSlaPolicy version=1.0.0 stateName=VpnSlaPolicyActState taskLocalName=act taskName=VpnSlaPolicyActTask taskVersion=1.0.0 outputType=DIRECT outputName=SlaPolicyAct_Output_Direct
2077
2078                         policy state create name=VpnSlaPolicy version=1.0.0 stateName=VpnSlaPolicyDecideState triggerName=VpnSlaEstablishOut triggerVersion=1.0.0 defaultTaskName=VpnSlaPolicyDecideSlaTask defaultTaskVersion=1.0.0
2079                         policy state contextref create name=VpnSlaPolicy version=1.0.0 stateName=VpnSlaPolicyDecideState albumName=albumProblemMap
2080                         policy state selecttasklogic create name=VpnSlaPolicy stateName=VpnSlaPolicyDecideState logicFlavour=JAVASCRIPT logic=LS
2081                         #MACROFILE:"src/main/resources/org/onap/policy/apex/examples/pcvs/vpnsla/logic/tsl-decide.js"
2082                         LE
2083                         policy state output create name=VpnSlaPolicy version=1.0.0 stateName=VpnSlaPolicyDecideState outputName=VpnSlaPolicyDecide_Output_Direct eventName=VpnSlaDecideOut eventVersion=1.0.0 nextState=VpnSlaPolicyActState
2084                         policy state taskref create name=VpnSlaPolicy version=1.0.0 stateName=VpnSlaPolicyDecideState taskLocalName=decideNone taskName=VpnSlaPolicyDecideNoneTask taskVersion=1.0.0 outputType=DIRECT outputName=VpnSlaPolicyDecide_Output_Direct
2085                         policy state taskref create name=VpnSlaPolicy version=1.0.0 stateName=VpnSlaPolicyDecideState taskLocalName=decideNone taskName=VpnSlaPolicyDecideSolvedTask taskVersion=1.0.0 outputType=DIRECT outputName=VpnSlaPolicyDecide_Output_Direct
2086                         policy state taskref create name=VpnSlaPolicy version=1.0.0 stateName=VpnSlaPolicyDecideState taskLocalName=decideSla taskName=VpnSlaPolicyDecideSlaTask taskVersion=1.0.0 outputType=DIRECT outputName=VpnSlaPolicyDecide_Output_Direct
2087                         policy state taskref create name=VpnSlaPolicy version=1.0.0 stateName=VpnSlaPolicyDecideState taskLocalName=decidePriority taskName=VpnSlaPolicyDecidePriorityTask taskVersion=1.0.0 outputType=DIRECT outputName=VpnSlaPolicyDecide_Output_Direct
2088
2089                         policy state create name=VpnSlaPolicy version=1.0.0 stateName=VpmSlaPolicyEstablishState triggerName=VpnSlaMatchOut triggerVersion=1.0.0 defaultTaskName=VpnSlaPolicyEstablishTask defaultTaskVersion=1.0.0
2090                         policy state output create name=VpnSlaPolicy version=1.0.0 stateName=VpmSlaPolicyEstablishState outputName=VpnSlaPolicyEstablish_Output_Direct eventName=VpnSlaEstablishOut eventVersion=1.0.0 nextState=VpnSlaPolicyDecideState
2091                         policy state taskref create name=VpnSlaPolicy version=1.0.0 stateName=VpmSlaPolicyEstablishState taskLocalName=establish taskName=VpnSlaPolicyEstablishTask taskVersion=1.0.0 outputType=DIRECT outputName=VpnSlaPolicyEstablish_Output_Direct
2092
2093                         policy state create name=VpnSlaPolicy version=1.0.0 stateName=VpnSlaPolicyMatchState triggerName=VpnSlaTrigger triggerVersion=1.0.0 defaultTaskName=VpnSlaPolicyMatchTask defaultTaskVersion=1.0.0
2094                         policy state output create name=VpnSlaPolicy version=1.0.0 stateName=VpnSlaPolicyMatchState outputName=VpnSlaPolicyMatch_Output_Direct eventName=VpnSlaMatchOut eventVersion=1.0.0 nextState=VpmSlaPolicyEstablishState
2095                         policy state taskref create name=VpnSlaPolicy version=1.0.0 stateName=VpnSlaPolicyMatchState taskLocalName=match taskName=VpnSlaPolicyMatchTask taskVersion=1.0.0 outputType=DIRECT outputName=VpnSlaPolicyMatch_Output_Direct
2096
2097
2098
2099                         validate
2100                         quit
2101
2102 Context Events Nodes
2103 --------------------
2104
2105          .. container:: sect1
2106
2107             .. container:: sectionbody
2108
2109                .. container:: paragraph
2110
2111                   The following events create all nodes of the topology.
2112
2113                .. container:: listingblock
2114
2115                   .. container:: content
2116
2117                      .. code:: CodeRay
2118
2119                         {
2120                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2121                             "name": "NodeContextEventIn",
2122                             "version": "1.0.0",
2123                             "source": "CtxtManagement",
2124                             "target" : "VpnSlaPolicy_NodeContext",
2125                             "nodeName": "A1",
2126                             "mininetName": "nn"
2127                         }
2128
2129                         {
2130                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2131                             "name": "NodeContextEventIn",
2132                             "version": "1.0.0",
2133                             "source": "CtxtManagement",
2134                             "target" : "VpnSlaPolicy_NodeContext",
2135                             "nodeName": "A2",
2136                             "mininetName": "nn"
2137                         }
2138
2139                         {
2140                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2141                             "name": "NodeContextEventIn",
2142                             "version": "1.0.0",
2143                             "source": "CtxtManagement",
2144                             "target" : "VpnSlaPolicy_NodeContext",
2145                             "nodeName": "B1",
2146                             "mininetName": "nn"
2147                         }
2148
2149                         {
2150                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2151                             "name": "NodeContextEventIn",
2152                             "version": "1.0.0",
2153                             "source": "CtxtManagement",
2154                             "target" : "VpnSlaPolicy_NodeContext",
2155                             "nodeName": "B2",
2156                             "mininetName": "nn"
2157                         }
2158
2159
2160                         {
2161                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2162                             "name": "NodeContextEventIn",
2163                             "version": "1.0.0",
2164                             "source": "CtxtManagement",
2165                             "target" : "VpnSlaPolicy_NodeContext",
2166                             "nodeName": "A1CO",
2167                             "mininetName": "s1"
2168                         }
2169
2170                         {
2171                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2172                             "name": "NodeContextEventIn",
2173                             "version": "1.0.0",
2174                             "source": "CtxtManagement",
2175                             "target" : "VpnSlaPolicy_NodeContext",
2176                             "nodeName": "A2CO",
2177                             "mininetName": "s2"
2178                         }
2179
2180                         {
2181                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2182                             "name": "NodeContextEventIn",
2183                             "version": "1.0.0",
2184                             "source": "CtxtManagement",
2185                             "target" : "VpnSlaPolicy_NodeContext",
2186                             "nodeName": "B1CO",
2187                             "mininetName": "s3"
2188                         }
2189
2190                         {
2191                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2192                             "name": "NodeContextEventIn",
2193                             "version": "1.0.0",
2194                             "source": "CtxtManagement",
2195                             "target" : "VpnSlaPolicy_NodeContext",
2196                             "nodeName": "B2CO",
2197                             "mininetName": "s4"
2198                         }
2199
2200                         {
2201                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2202                             "name": "NodeContextEventIn",
2203                             "version": "1.0.0",
2204                             "source": "CtxtManagement",
2205                             "target" : "VpnSlaPolicy_NodeContext",
2206                             "nodeName": "BBL",
2207                             "mininetName": "s5"
2208                         }
2209
2210                         {
2211                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2212                             "name": "NodeContextEventIn",
2213                             "version": "1.0.0",
2214                             "source": "CtxtManagement",
2215                             "target" : "VpnSlaPolicy_NodeContext",
2216                             "nodeName": "BBR",
2217                             "mininetName": "s6"
2218                         }
2219
2220 Context Events Edges
2221 --------------------
2222
2223          .. container:: sect1
2224
2225             .. container:: sectionbody
2226
2227                .. container:: paragraph
2228
2229                   The following events create all edges of the topology.
2230
2231                .. container:: listingblock
2232
2233                   .. container:: content
2234
2235                      .. code:: CodeRay
2236
2237                         {
2238                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2239                             "name": "EdgeContextEventIn",
2240                             "version": "1.0.0",
2241                             "source": "CtxtManagement",
2242                             "target" : "VpnSlaPolicy_EdgeContext",
2243                             "edgeName": "L01",
2244                             "start": "A1",
2245                             "end": "A1CO",
2246                             "status": true
2247                         }
2248
2249                         {
2250                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2251                             "name": "EdgeContextEventIn",
2252                             "version": "1.0.0",
2253                             "source": "CtxtManagement",
2254                             "target" : "VpnSlaPolicy_EdgeContext",
2255                             "edgeName": "L02",
2256                             "start": "B1",
2257                             "end": "B1CO",
2258                             "status": true
2259                         }
2260
2261                         {
2262                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2263                             "name": "EdgeContextEventIn",
2264                             "version": "1.0.0",
2265                             "source": "CtxtManagement",
2266                             "target" : "VpnSlaPolicy_EdgeContext",
2267                             "edgeName": "L03",
2268                             "start": "A2",
2269                             "end": "A2CO",
2270                             "status": true
2271                         }
2272
2273                         {
2274                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2275                             "name": "EdgeContextEventIn",
2276                             "version": "1.0.0",
2277                             "source": "CtxtManagement",
2278                             "target" : "VpnSlaPolicy_EdgeContext",
2279                             "edgeName": "L04",
2280                             "start": "B2",
2281                             "end": "B2CO",
2282                             "status": true
2283                         }
2284
2285                         {
2286                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2287                             "name": "EdgeContextEventIn",
2288                             "version": "1.0.0",
2289                             "source": "CtxtManagement",
2290                             "target" : "VpnSlaPolicy_EdgeContext",
2291                             "edgeName": "L05",
2292                             "start": "A1CO",
2293                             "end": "BBL",
2294                             "status": true
2295                         }
2296
2297                         {
2298                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2299                             "name": "EdgeContextEventIn",
2300                             "version": "1.0.0",
2301                             "source": "CtxtManagement",
2302                             "target" : "VpnSlaPolicy_EdgeContext",
2303                             "edgeName": "L06",
2304                             "start": "B1CO",
2305                             "end": "BBL",
2306                             "status": true
2307                         }
2308
2309                         {
2310                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2311                             "name": "EdgeContextEventIn",
2312                             "version": "1.0.0",
2313                             "source": "CtxtManagement",
2314                             "target" : "VpnSlaPolicy_EdgeContext",
2315                             "edgeName": "L07",
2316                             "start": "A2CO",
2317                             "end": "BBR",
2318                             "status": true
2319                         }
2320
2321                         {
2322                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2323                             "name": "EdgeContextEventIn",
2324                             "version": "1.0.0",
2325                             "source": "CtxtManagement",
2326                             "target" : "VpnSlaPolicy_EdgeContext",
2327                             "edgeName": "L08",
2328                             "start": "B2CO",
2329                             "end": "BBR",
2330                             "status": true
2331                         }
2332
2333                         {
2334                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2335                             "name": "EdgeContextEventIn",
2336                             "version": "1.0.0",
2337                             "source": "CtxtManagement",
2338                             "target" : "VpnSlaPolicy_EdgeContext",
2339                             "edgeName": "L09",
2340                             "start": "BBL",
2341                             "end": "BBR",
2342                             "status": true
2343                         }
2344
2345                         {
2346                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2347                             "name": "EdgeContextEventIn",
2348                             "version": "1.0.0",
2349                             "source": "CtxtManagement",
2350                             "target" : "VpnSlaPolicy_EdgeContext",
2351                             "edgeName": "L10",
2352                             "start": "BBR",
2353                             "end": "BBL",
2354                             "status": true
2355                         }
2356
2357 Context Events Customers
2358 ------------------------
2359
2360          .. container:: sect1
2361
2362             .. container:: sectionbody
2363
2364                .. container:: paragraph
2365
2366                   The following events create all customers of the
2367                   topology.
2368
2369                .. container:: listingblock
2370
2371                   .. container:: content
2372
2373                      .. code:: CodeRay
2374
2375                         {
2376                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2377                             "name": "CustomerContextEventIn",
2378                             "version": "1.0.0",
2379                             "source": "CtxtManagement",
2380                             "target" : "VpnSlaPolicy_CustomerContext",
2381                             "customerName": "A",
2382                             "links": "L01 L05 L09 L10",
2383                             "dtSLA": 180,
2384                             "dtYTD": 10,
2385                             "priority": false,
2386                             "satisfaction": 80
2387                         }
2388
2389                         {
2390                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2391                             "name": "CustomerContextEventIn",
2392                             "version": "1.0.0",
2393                             "source": "CtxtManagement",
2394                             "target" : "VpnSlaPolicy_CustomerContext",
2395                             "customerName": "B",
2396                             "links": "L02 L07 L09 L10",
2397                             "dtSLA": 180,
2398                             "dtYTD": 120,
2399                             "priority": true,
2400                             "satisfaction": 99
2401                         }
2402
2403 Trigger Examples
2404 ----------------
2405
2406          .. container:: sect1
2407
2408             .. container:: sectionbody
2409
2410                .. container:: paragraph
2411
2412                   The following events are examples for trigger events
2413
2414                .. container:: listingblock
2415
2416                   .. container:: content
2417
2418                      .. code:: CodeRay
2419
2420                         {
2421                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2422                             "name": "VpnSlaTrigger",
2423                             "version": "1.0.0",
2424                             "source": "ExampleEvents",
2425                             "target" : "VpnSlaPolicy",
2426                             "edgeName": "L09",
2427                             "status": "UP"
2428                         }
2429
2430                         {
2431                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2432                             "name": "VpnSlaTrigger",
2433                             "version": "1.0.0",
2434                             "source": "ExampleEvents",
2435                             "target" : "VpnSlaPolicy",
2436                             "edgeName": "L09",
2437                             "status": "UP"
2438                         }
2439
2440                         {
2441                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2442                             "name": "VpnSlaTrigger",
2443                             "version": "1.0.0",
2444                             "source": "ExampleEvents",
2445                             "target" : "VpnSlaPolicy",
2446                             "edgeName": "L09",
2447                             "status": "DOWN"
2448                         }
2449
2450                         {
2451                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2452                             "name": "VpnSlaTrigger",
2453                             "version": "1.0.0",
2454                             "source": "ExampleEvents",
2455                             "target" : "VpnSlaPolicy",
2456                             "edgeName": "L09",
2457                             "status": "DOWN"
2458                         }
2459
2460                         {
2461                             "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2462                             "name": "VpnSlaTrigger",
2463                             "version": "1.0.0",
2464                             "source": "ExampleEvents",
2465                             "target" : "VpnSlaPolicy",
2466                             "edgeName": "L09",
2467                             "status": "UP"
2468                         }
2469
2470 Link Monitor
2471 ------------
2472
2473          .. container:: sect1
2474
2475             .. container:: sectionbody
2476
2477                .. container:: paragraph
2478
2479                   The Link Monitor is a Python script. At startup, it
2480                   sends the context events to APEX to initialize the
2481                   topology and the customers. Then it takes events from
2482                   Kafka and sends them to APEX.
2483
2484                .. container:: listingblock
2485
2486                   .. container:: content
2487
2488                      .. code:: CodeRay
2489
2490                         # ============LICENSE_START=======================================================
2491                         #  Copyright (C) 2016-2018 Ericsson. All rights reserved.
2492                         # ================================================================================
2493                         # Licensed under the Apache License, Version 2.0 (the "License");
2494                         # you may not use this file except in compliance with the License.
2495                         # You may obtain a copy of the License at
2496                         #
2497                         #      http://www.apache.org/licenses/LICENSE-2.0
2498                         #
2499                         # Unless required by applicable law or agreed to in writing, software
2500                         # distributed under the License is distributed on an "AS IS" BASIS,
2501                         # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2502                         # See the License for the specific language governing permissions and
2503                         # limitations under the License.
2504                         #
2505                         # SPDX-License-Identifier: Apache-2.0
2506                         # ============LICENSE_END=========================================================
2507
2508                         import http.client
2509                         import json
2510                         import time
2511                         from kafka import KafkaConsumer, KafkaProducer
2512
2513                         class StaticFlowPusher(object):
2514
2515                             def __init__(self, server):
2516                                 self.server = server
2517
2518                             def get(self, data):
2519                                 ret = self.rest_call({}, 'GET')
2520                                 return json.loads(ret[2])
2521
2522                             def set(self, data):
2523                                 ret = self.rest_call(data, 'POST')
2524                                 return ret[0] == 200
2525
2526                             def remove(self, objtype, data):
2527                                 ret = self.rest_call(data, 'DELETE')
2528                                 return ret[0] == 200
2529
2530                             def getControllerSummary(self, data):
2531                                 ret = self.rest_call_controller_summary({}, 'GET')
2532                                 return json.loads(ret[2])
2533
2534                             def getLinks(self, data):
2535                                 ret = self.rest_call_links({}, 'GET')
2536                                 return json.loads(ret[2].decode())
2537
2538                             def rest_call(self, data, action):
2539                                 path = '/wm/staticflowpusher/json'
2540                                 headers = {
2541                                     'Content-type': 'application/json',
2542                                     'Accept': 'application/json',
2543                                     }
2544                                 body = json.dumps(data)
2545                                 conn = http.client.HTTPConnection(self.server, 8080)
2546                                 conn.request(action, path, body, headers)
2547                                 response = conn.getresponse()
2548                                 ret = (response.status, response.reason, response.read())
2549                                 print(ret)
2550                                 conn.close()
2551                                 return ret
2552
2553                             def rest_call_controller_summary(self, data, action):
2554                                 path = '/wm/core/controller/summary/json'
2555                                 headers = {
2556                                     'Content-type': 'application/json',
2557                                     'Accept': 'application/json',
2558                                     }
2559                                 body = json.dumps(data)
2560                                 conn = http.client.HTTPConnection(self.server, 8080)
2561                                 conn.request(action, path, body, headers)
2562                                 response = conn.getresponse()
2563                                 ret = (response.status, response.reason, response.read())
2564                                 print(ret)
2565                                 conn.close()
2566                                 return ret
2567
2568                             def rest_call_links(self, data, action):
2569                                 path = '/wm/topology/links/json'
2570                                 headers = {
2571                                     'Content-type': 'application/json',
2572                                     'Accept': 'application/json',
2573                                     }
2574                                 body = json.dumps(data)
2575                                 conn = http.client.HTTPConnection(self.server, 8080)
2576                                 conn.request(action, path, body, headers)
2577                                 response = conn.getresponse()
2578                                 ret = (response.status, response.reason, response.read())
2579                                 conn.close()
2580                                 return ret
2581
2582                         pusher = StaticFlowPusher('127.0.1.1')
2583
2584
2585                         def parseLinks(links):
2586                                 #print("\n\n\n",links)
2587                                 result = []
2588                                 for link in links:
2589                                         list = []
2590                                         #print("\n\n\n",link)
2591                                         #print("\nsrc-switch : s", link['src-switch'][len(link['src-switch'])-1])
2592                                         #print("\ndst-switch : s", link['dst-switch'][len(link['dst-switch'])-1])
2593                                         list.append("s")
2594                                         list.append(link['src-switch'][len(link['src-switch'])-1])
2595                                         list.append("-s")
2596                                         list.append(link['dst-switch'][len(link['dst-switch'])-1])
2597                                         result.append(''.join(list))
2598                                 #print(result, "\n")
2599                                 return result
2600
2601
2602
2603                         counter =0
2604                         healthyList = []
2605                         testableList = []
2606                         healthyLinks = ""
2607                         testableLinks = ""
2608                         producer = KafkaProducer(bootstrap_servers='localhost:9092')
2609                         while(True):
2610                                 time.sleep(30)
2611                                 switchLinks = pusher.getLinks({})
2612                                 if counter == 0:
2613                                         healthyList = parseLinks(switchLinks)
2614                                         #Build All Links
2615                                         print("READING LINKS FROM MININET\n")
2616                                         for l in healthyList:
2617                                                 link = ""
2618                                                 #print(l, "\n")
2619                                                 #Links between switches [s6-s7 is ignored so it matches VPN SCENARIO]
2620                                                 if(l == "s1-s5"):
2621                                                         link = "{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'EdgeContextEventIn','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy_EdgeContext','status': true,'edgeName': 'L05', 'start': 'A1CO','end': 'BBL'}"
2622                                                         producer.send("apex-in-0", bytes(link, encoding="ascii"))
2623                                                 if(l == "s5-s6"):
2624                                                         link = "{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'EdgeContextEventIn','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy_EdgeContext','status': true,'edgeName': 'L09', 'start': 'BBL','end': 'BBR'}"
2625                                                         producer.send("apex-in-0", bytes(link, encoding="ascii"))
2626                                                 if(l == "s2-s6"):
2627                                                         link = "{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'EdgeContextEventIn','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy_EdgeContext','status': true,'edgeName': 'L07', 'start': 'A2CO','end': 'BBR'}"
2628                                                         producer.send("apex-in-0", bytes(link, encoding="ascii"))
2629                                                 if(l == "s5-s7"):
2630                                                         link = "{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'EdgeContextEventIn','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy_EdgeContext','status': true,'edgeName': 'L10', 'start': 'BBR','end': 'BBL'}"
2631                                                         producer.send("apex-in-0", bytes(link, encoding="ascii"))
2632                                                 if(l == "s3-s5"):
2633                                                         link = "{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'EdgeContextEventIn','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy_EdgeContext','status': true,'edgeName': 'L06', 'start': 'B1CO','end': 'BBL'}"
2634                                                         producer.send("apex-in-0", bytes(link, encoding="ascii"))
2635                                                 if(l == "s4-s6"):
2636                                                         link = "{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'EdgeContextEventIn','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy_EdgeContext','status': true,'edgeName': 'L08', 'start': 'B2CO','end': 'BBR'}"
2637                                                         producer.send("apex-in-0", bytes(link, encoding="ascii"))
2638                                         #Links between switches and hosts [NoT SENT IN FROM FLOODLIGHT]
2639                                         producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'EdgeContextEventIn','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy_EdgeContext','status': true,'edgeName': 'L01', 'start': 'A1','end': 'A1CO'}")
2640                                         producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'EdgeContextEventIn','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy_EdgeContext','status': true,'edgeName': 'L02', 'start': 'B1','end': 'B1CO'}")
2641                                         producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'EdgeContextEventIn','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy_EdgeContext','status': true,'edgeName': 'L03', 'start': 'A2','end': 'A2CO'}")
2642                                         producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'EdgeContextEventIn','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy_EdgeContext','status': true,'edgeName': 'L04', 'start': 'B2','end': 'B2CO'}")
2643                                         print("LINKS HAVE BEEN SENT TO APEX\n")
2644
2645                                         #Build Customers
2646                                         print("BUILDING CUSTOMERS\n")
2647                                         producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'CustomerContextEventIn','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy_CustomerContext','dtYTD': 10,'dtSLA': 180,'links': 'L01 L05 L09 L10','customerName': 'A', 'priority': true,'satisfaction': 80}")
2648                                         producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'CustomerContextEventIn','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy_CustomerContext','dtYTD': 120,'dtSLA': 180,'links': 'L02 L07 L09 L10','customerName': 'B', 'priority': false,'satisfaction': 99}")
2649                                         print("CUSTOMERS HAVE BEEN SENT TO APEX\n")
2650                                         healthyLinks = switchLinks
2651                                         myfile = open('LinkInfo.json', 'a')
2652                                         myfile.write(str(healthyLinks))
2653                                         myfile.write('\n')
2654                                         myfile.close()
2655                                         print("We start off with", len(healthyLinks), "healthy Links!\n")
2656                                 else:
2657                                         testableList = parseLinks(switchLinks)
2658                                         issueLink = "";
2659                                         for h in healthyList:
2660                                                 issueLink = h
2661                                                 for t in testableList:
2662                                                         if t == h:
2663                                                                 issueLink = ""
2664                                                 if issueLink != "":
2665                                                         print("There is an issue with the links! ", issueLink, " \n")
2666                                                         if(issueLink == "s1-s5"):
2667                                                                 link = "{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'DOWN','edgeName': 'L05'}"
2668                                                                 producer.send("apex-in-0", bytes(link, encoding="ascii"))
2669                                                         if(issueLink == "s5-s6"):
2670                                                                 link = "{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'DOWN','edgeName': 'L09'}"
2671                                                                 producer.send("apex-in-0", bytes(link, encoding="ascii"))
2672                                                         if(issueLink == "s2-s6"):
2673                                                                 link = "{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'DOWN','edgeName': 'L07'}"
2674                                                                 producer.send("apex-in-0", bytes(link, encoding="ascii"))
2675                                                         if(issueLink == "s5-s7"):
2676                                                                 link = "{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'DOWN','edgeName': 'L10'}"
2677                                                                 producer.send("apex-in-0", bytes(link, encoding="ascii"))
2678                                                         if(issueLink == "s3-s5"):
2679                                                                 link = "{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'DOWN','edgeName': 'L06'}"
2680                                                                 producer.send("apex-in-0", bytes(link, encoding="ascii"))
2681                                                         if(issueLink == "s4-s6"):
2682                                                                 link = "{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'DOWN','edgeName': 'L08'}"
2683                                                                 producer.send("apex-in-0", bytes(link, encoding="ascii"))
2684                                                         break
2685                                         if issueLink == "":
2686                                                 print("All Links are working\n")
2687                                                 producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'UP','edgeName': 'L01'}")
2688                                                 producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'UP','edgeName': 'L02'}")
2689                                                 producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'UP','edgeName': 'L03'}")
2690                                                 producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'UP','edgeName': 'L04'}")
2691                                                 producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'UP','edgeName': 'L05'}")
2692                                                 producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'UP','edgeName': 'L06'}")
2693                                                 producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'UP','edgeName': 'L07'}")
2694                                                 producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'UP','edgeName': 'L08'}")
2695                                                 producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'UP','edgeName': 'L09'}")
2696                                                 producer.send("apex-in-0", b"{'nameSpace': 'org.onap.policy.apex.examples.pcvs.vpnsla','name': 'VpnSlaTrigger','version': '1.0.0','source': 'LinkMonitor.py','target': 'VpnSlaPolicy','status': 'UP','edgeName': 'L10'}")
2697
2698                                         testableLinks = switchLinks
2699                                         myfile = open('LinkInfo.json', 'a')
2700                                         myfile.write(str(testableLinks))
2701                                         myfile.write('\n')
2702                                         myfile.close()
2703                                 counter += 1
2704
2705 Mininet Topology
2706 ----------------
2707
2708          .. container:: sect1
2709
2710             .. container:: sectionbody
2711
2712                .. container:: paragraph
2713
2714                   The topology is realized using Mininet. The following
2715                   script is use to estalish the topology and to realize
2716                   network configurations.
2717
2718                .. container:: listingblock
2719
2720                   .. container:: content
2721
2722                      .. code:: CodeRay
2723
2724                         # ============LICENSE_START=======================================================
2725                         #  Copyright (C) 2016-2018 Ericsson. All rights reserved.
2726                         # ================================================================================
2727                         # Licensed under the Apache License, Version 2.0 (the "License");
2728                         # you may not use this file except in compliance with the License.
2729                         # You may obtain a copy of the License at
2730                         #
2731                         #      http://www.apache.org/licenses/LICENSE-2.0
2732                         #
2733                         # Unless required by applicable law or agreed to in writing, software
2734                         # distributed under the License is distributed on an "AS IS" BASIS,
2735                         # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2736                         # See the License for the specific language governing permissions and
2737                         # limitations under the License.
2738                         #
2739                         # SPDX-License-Identifier: Apache-2.0
2740                         # ============LICENSE_END=========================================================
2741
2742                         #Add Mininet to PATH
2743                         import sys
2744                         sys.path.insert(0, "/~/mininet")
2745
2746                         #Kafka
2747                         import httplib
2748                         import json
2749                         import time
2750                         from kafka import KafkaConsumer, KafkaProducer
2751
2752                         #Mininet
2753                         from mininet.clean import *
2754                         from mininet.cli import *
2755                         from mininet.link import *
2756                         from mininet.log import *
2757                         from mininet.net import *
2758                         from mininet.node import *
2759                         from mininet.nodelib import *
2760                         from mininet.topo import *
2761                         from mininet.topolib import *
2762
2763                         class StaticFlowPusher(object):
2764                             def __init__(self, server):
2765                                 self.server = server
2766
2767                             def enableFirewall(self, data):
2768                                 path = "/wm/firewall/module/enable/json"
2769                                 headers = {'Content-Type': 'application/json','Accept': 'application/json',}
2770                                 body = json.dumps(data)
2771                                 conn = httplib.HTTPConnection(self.server, 8080)
2772                                 conn.request("PUT", path, "")
2773                                 response = conn.getresponse()
2774                                 ret = (response.status, response.reason, response.read())
2775                                 conn.close()
2776                                 return ret
2777
2778                             def addRule(self, data):
2779                                 path = '/wm/firewall/rules/json'
2780                                 headers = {'Content-Type': 'application/json','Accept': 'application/json',}
2781                                 body = json.dumps(data)
2782                                 conn = httplib.HTTPConnection(self.server, 8080)
2783                                 conn.request('POST', path, body, headers)
2784                                 response = conn.getresponse()
2785                                 ret = (response.status, response.reason, response.read())
2786                                 conn.close()
2787                                 return ret
2788
2789                             def deleteRule(self, data):
2790                                 path = '/wm/firewall/rules/json'
2791                                 headers = {'Content-Type': 'application/json','Accept': 'application/json',}
2792                                 body = json.dumps(data)
2793                                 conn = httplib.HTTPConnection(self.server, 8080)
2794                                 conn.request('DELETE', path, body, headers)
2795                                 response = conn.getresponse()
2796                                 ret = (response.status, response.reason, response.read())
2797                                 conn.close()
2798                                 return ret
2799
2800                         #Build Pusher(REST/IN)
2801                         pusher = StaticFlowPusher('127.0.0.1')
2802
2803                         net = Mininet(link=TCLink)
2804
2805                         #Create Customers
2806                         customerA1 = net.addHost( 'A1' )
2807                         customerA2 = net.addHost( 'A2' )
2808                         customerB1 = net.addHost( 'B1' )
2809                         customerB2 = net.addHost( 'B2' )
2810
2811                         #Create Switches
2812                         switchA1CO = net.addSwitch( 's1' )
2813                         switchA2CO = net.addSwitch( 's2' )
2814                         switchB1CO = net.addSwitch( 's3' )
2815                         switchB2CO = net.addSwitch( 's4' )
2816                         switchBBL = net.addSwitch( 's5' )
2817                         switchBBR = net.addSwitch( 's6' )
2818                         # we need an extra switch here because Mininet does not allow two links between two switches
2819                         switchEx = net.addSwitch( 's7' )
2820
2821                         #Create Links
2822                         net.addLink( customerA1, switchA1CO )
2823                         net.addLink( customerA2, switchA2CO )
2824                         net.addLink( customerB1, switchB1CO )
2825                         net.addLink( customerB2, switchB2CO )
2826                         net.addLink( switchA1CO, switchBBL )
2827                         net.addLink( switchB1CO, switchBBL )
2828                         net.addLink( switchA2CO, switchBBR )
2829                         net.addLink( switchB2CO, switchBBR )
2830                         net.addLink( switchBBL, switchBBR)
2831                         net.addLink( switchBBR, switchEx, bw=1.2 )
2832                         net.addLink( switchEx, switchBBL )
2833
2834                         #Create Controller
2835                         floodlightController = net.addController(name='c0' , controller=RemoteController , ip='127.0.0.1', port=6653)
2836
2837                         net.start()
2838
2839                         if pusher.enableFirewall({})[0] == 200:
2840                             print("Firewall enabled!")
2841
2842                         #print(pusher.addRule({"switchid": "00:00:00:00:00:00:00:01"})[2])
2843                         s1id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:01"})[2])['rule-id']
2844                         s2id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:02"})[2])['rule-id']
2845                         s3id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:03"})[2])['rule-id']
2846                         s4id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:04"})[2])['rule-id']
2847                         s5id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:05"})[2])['rule-id']
2848                         s6id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:06"})[2])['rule-id']
2849                         s7id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:07"})[2])['rule-id']
2850
2851
2852                         result = 100
2853                         while result!=0:
2854                             result = net.pingAll(None)
2855                         print("Network Simulation Complete")
2856
2857                         #Assume control and when finished "exit"
2858                         cli = CLI( net )
2859
2860                         consumer = KafkaConsumer(bootstrap_servers='localhost:9092',auto_offset_reset='latest')
2861                         consumer.subscribe(['apex-out'])
2862                         print("Starting Message Loop")
2863                         for message in consumer:
2864                             myOutput = json.loads(message.value.decode())
2865                             action = ""
2866                             try:
2867                                 print("Checking Message")
2868                                 #print("SWITCHES= ",net.switches)
2869                                 #print("LINKS= ",net.links)
2870                                 #print("VALUES= ",net.values)
2871                                 if myOutput['edgeName'] != '':
2872                                     print("Message Received: ",myOutput['edgeName'])
2873                                     pusher.deleteRule({"ruleid": s1id})
2874                                     pusher.deleteRule({"ruleid": s2id})
2875                                     pusher.deleteRule({"ruleid": s3id})
2876                                     pusher.deleteRule({"ruleid": s4id})
2877                                     pusher.deleteRule({"ruleid": s5id})
2878                                     pusher.deleteRule({"ruleid": s6id})
2879                                     pusher.deleteRule({"ruleid": s7id})
2880                                     s1id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:01"})[2])['rule-id']
2881                                     s2id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:02"})[2])['rule-id']
2882                                     s3id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:03"})[2])['rule-id']
2883                                     s4id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:04"})[2])['rule-id']
2884                                     s5id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:05"})[2])['rule-id']
2885                                     s6id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:06"})[2])['rule-id']
2886                                     s7id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:07"})[2])['rule-id']
2887                                     if myOutput['edgeName'] == "L01":
2888                                         action = "link s1 s5 down"
2889                                         #net.configLinkStatus('s1', 's5', "down")
2890                                         pusher.deleteRule({"ruleid": s1id})
2891                                         s1id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:01", "action": "DENY"})[2])['rule-id']
2892                                     if myOutput['edgeName'] == "L02":
2893                                         action = "link s3 s5 down"
2894                                         #net.configLinkStatus('s3', 's5', "down")
2895                                         pusher.deleteRule({"ruleid": s3id})
2896                                         s3id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:03", "action": "DENY"})[2])['rule-id']
2897                                     if myOutput['edgeName'] == "L03":
2898                                         action = "link s2 s6 down"
2899                                         #net.configLinkStatus('s2', 's6', "down")
2900                                         pusher.deleteRule({"ruleid": s1id})
2901                                         s1id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:01", "action": "DENY"})[2])['rule-id']
2902                                     if myOutput['edgeName'] == "L04":
2903                                         action = "link s4 s6 down"
2904                                         #net.configLinkStatus('s4', 's6', "down")
2905                                         pusher.deleteRule({"ruleid": s3id})
2906                                         s3id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:03", "action": "DENY"})[2])['rule-id']
2907                                     if myOutput['edgeName'] == "L05":
2908                                         action = "link s1 s5 down"
2909                                         #net.configLinkStatus('s1', 's5', "down")
2910                                         pusher.deleteRule({"ruleid": s1id})
2911                                         s1id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:01", "action": "DENY"})[2])['rule-id']
2912                                     if myOutput['edgeName'] == "L06":
2913                                         action = "link s3 s5 down"
2914                                         #net.configLinkStatus('s3', 's5', "down")
2915                                         pusher.deleteRule({"ruleid": s3id})
2916                                         s3id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:03", "action": "DENY"})[2])['rule-id']
2917                                     if myOutput['edgeName'] == "L07":
2918                                         action = "link s2 s6 down"
2919                                         #net.configLinkStatus('s2', 's6', "down")
2920                                         pusher.deleteRule({"ruleid": s2id})
2921                                         s2id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:02", "action": "DENY"})[2])['rule-id']
2922                                     if myOutput['edgeName'] == "L08":
2923                                         action = "link s4 s6 down"
2924                                         #net.configLinkStatus('s4', 's6', "down")
2925                                         pusher.deleteRule({"ruleid": s4id})
2926                                         s4id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:04", "action": "DENY"})[2])['rule-id']
2927                                     if myOutput['edgeName'] == "L09":
2928                                         action = "link s5 s6 down"
2929                                         #net.configLinkStatus('s5', 's6', "down")
2930                                         pusher.deleteRule({"ruleid": s7id})
2931                                         s7id = json.loads(pusher.addRule({"switchid": "00:00:00:00:00:00:00:07", "action": "DENY"})[2])['rule-id']
2932                                     if myOutput['edgeName'] == "L10":
2933                                         print("L10")
2934                                     #print(action)
2935                                 #print("3")
2936                             except KeyError:
2937                                 print(myOutput)
2938                         print("HA")
2939                         net.stop()
2940
2941    .. container::
2942       :name: footer-text
2943
2944       2.3.0-SNAPSHOT
2945       Last updated 2020-04-03 16:04:24 IST
2946
2947
2948 .. |ONAP| image:: ../../../images/logos.png
2949    :class: builtBy
2950    :target: http://www.onap.org/
2951
2952 .. |VPN SLA Architecture| image:: images/pcvs/vpnsla-arch.png
2953
2954