1 .. This work is licensed under a Creative Commons Attribution 4.0 International License.
2 .. http://creativecommons.org/licenses/by/4.0
6 Policy-controlled Video Streaming (pcvs) with APEX
7 **************************************************
15 .. container:: sectionbody
17 .. container:: paragraph
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
28 - Mininet as network simulator
30 - Floodlight as SDN controller
32 - Kafka as messaging system
34 - Zookeeper for Kafka configuration
36 - APEX for policy control
38 Install Ubuntu Server and SW
39 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
43 .. rubric:: Install Demo
46 .. container:: sectionbody
48 .. container:: paragraph
54 - Ubuntu server: 1.4 GB
56 - Ubuntu with Xubuntu Desktop, git, Firefox: 2.3 GB
58 - Ubuntu with all, system updated: 3 GB
60 - With ZK, Kafka, VLC, Mininet, Floodlight, Python:
63 - APEX Build (M2 and built): M2 ~ 2 GB, APEX ~3.5 GB
65 - APEX install (not build locally): ~ 300 MB
67 .. container:: paragraph
69 On a Ubuntu OS (install a stable or LTS server first)
71 .. container:: listingblock
73 .. container:: content
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
86 sudo add-apt-repository ppa:webupd8team/java
88 sudo apt-get -y install --no-install-recommends oracle-java8-installer
92 # reboot system, run system update, then continue
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)
103 # if APEX is build from source, install maven and rpm
104 sudo apt-get install maven rpm
107 sudo apt-get install zookeeperd
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/
116 sudo git clone https://github.com/mininet/mininet.git
117 (cd mininet;util/install.sh -a)
119 # install floodlight, requires ant
120 sudo apt-get install ant
122 sudo wget --no-check-certificate https://github.com/floodlight/floodlight/archive/master.zip
123 sudo unzip master.zip
126 sudo mkdir /var/lib/floodlight
127 sudo chmod 777 /var/lib/floodlight
130 sudo apt-get install python-pip
132 # install kafka-python (need newer version from github)
134 sudo git clone https://github.com/dpkp/kafka-python
135 sudo pip install ./kafka-python
138 sudo apt-get install vlc
140 .. container:: paragraph
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``
147 .. container:: paragraph
149 Copy the LinkMonitor file to Kafka-Python
151 .. container:: listingblock
153 .. container:: content
157 sudo cp /opt/ericsson/apex/apex/examples/scripts/pcvs/vpnsla/LinkMonitor.py /usr/local/src/kafka-python
159 .. container:: paragraph
161 Change the Logback configuration in APEX to logic
164 .. container:: listingblock
166 .. container:: content
170 (cd /opt/ericsson/apex/apex/etc; sudo cp logback-logic.xml logback.xml)
174 .. rubric:: Get the Demo Video
175 :name: get_the_demo_video
177 .. container:: sectionbody
181 - For all download options of the movie please visit
182 http://bbb3d.renderfarming.net/download.html
184 - For lower-res downloads and mirrors see
185 https://peach.blender.org/download
187 .. container:: listingblock
189 .. container:: content
193 sudo mkdir /usr/local/src/videos
195 .. container:: paragraph
197 Standard 720p (recommended)
199 .. container:: listingblock
201 .. container:: content
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)
207 .. container:: paragraph
211 .. container:: listingblock
213 .. container:: content
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)
226 .. container:: sectionbody
228 .. container:: paragraph
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.
236 .. container:: imageblock
238 .. container:: content
240 |VPN SLA Architecture|
242 .. container:: paragraph
244 The architecture above shows the scenario. The
245 components are realized in this demo as follows:
249 - *CEP / Analytics* - a simple Python script taking
250 events from Kafka and sending them to APEX
252 - *APEX / Policy* - the APEX engine running the VPA
255 - *Controller* - A vanilla Floodlight controller
256 taking events from the Link Monitor and configuring
259 - *Network* - A network created using Mininet
261 .. container:: paragraph
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.
268 .. container:: paragraph
270 All shown scripts are available in a full APEX
272 ``$APEX_HOME/examples/scripts/pcvs/vpnsla``.
276 .. rubric:: Start all Software
277 :name: start_all_software
279 .. container:: paragraph
281 Create environment variables in a file, say
282 ``env.sh``. In each new Xterm
286 - Source these environment settings, e.g.
289 - Run the commands below as root (``sudo`` per
290 command or ``sudo -i`` for interactive mode as
293 .. container:: listingblock
295 .. container:: content
301 export src_dir=/usr/local/src
302 export APEX_HOME=/opt/ericsson/apex/apex
303 export APEX_USER=apexuser
305 .. container:: paragraph
307 In a new Xterm, start Floodlight
309 .. container:: listingblock
311 .. container:: content
317 cd $src_dir/floodlight-master && java -jar target/floodlight.jar
319 .. container:: paragraph
321 In a new Xterm start Mininet
323 .. container:: listingblock
325 .. container:: content
331 mn -c && python $APEX_HOME/examples/scripts/pcvs/vpnsla/MininetTopology.py
333 .. container:: paragraph
335 In a new Xterm, start Kafka
337 .. container:: listingblock
339 .. container:: content
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
347 .. container:: paragraph
349 In a new Xerm start APEX with the Kafka
350 configuration for this demo
352 .. container:: listingblock
354 .. container:: content
359 ./bin/apexApps.sh engine -c examples/config/pcvs/vpnsla/kafka2kafka.json
361 .. container:: paragraph
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
369 .. container:: listingblock
371 .. container:: content
378 xterm -hold -e 'python3 $src_dir/kafka-python/LinkMonitor.py' &
380 .. container:: paragraph
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.
389 .. rubric:: Create 2 Video Streams with VLC
390 :name: create_2_video_streams_with_vlc
392 .. container:: paragraph
394 In the Mininet console, type ``xterm A1 A2`` and
395 ``xterm B1 B2`` to open terminals on these nodes.
397 .. container:: paragraph
399 ``A2`` and ``B2`` are the receiving nodes. In these
400 terminals, run ``vlc-wrapper``. In each opened VLC
405 - Click Media → Open Network Stream
407 - Give the URL as ``rtp://@:5004``
409 .. container:: paragraph
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
417 - Click Media → Stream
419 - Add the video (from ``/usr/local/src/videos``)
425 - Change the destination
426 ``RTP / MPEG Transport Stream`` and click
429 - Change the address and type to ``10.0.0.2`` in
430 ``A1`` and to ``10.0.0.4`` in ``B1``
432 - Turn off ``Active Transcoding`` (this is
433 important to minimize CPU load)
439 .. container:: paragraph
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)
450 .. rubric:: Take out L09 and let the Policy do it’s
452 :name: take_out_l09_and_let_the_policy_do_it_s_magic
454 .. container:: paragraph
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).
464 .. container:: paragraph
466 To initiate this, simply type ``link s5 s6 down``
467 in the Mininet console followed by ``exit``.
469 .. container:: paragraph
471 If you have the video streams running, you will see
472 one or the other struggeling, depending on the
477 .. rubric:: Reset the Demo
478 :name: reset_the_demo
480 .. container:: paragraph
482 If you want to reset the demo, simple stop (in this
483 order) the following process
495 .. container:: paragraph
497 Then restart them in this order
511 .. rubric:: Monitor the Demo
512 :name: monitor_the_demo
514 .. container:: paragraph
516 Floodlight and APEX provide REST interfaces for
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
526 ``http://localhost:8080/ui/pages/index.html``
527 should work on the same host
529 - APEX please see the APEX documentation for
531 Client <https://ericsson.github.io/apex-docs/user-manual/engine-apps/um-engapps-eng-monitoring.html>`__
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.
540 .. container:: sectionbody
542 .. container:: paragraph
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.
560 .. container:: paragraph
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.
570 .. container:: paragraph
572 The policy uses data defined in Avro, so we have a
573 number of Avro schema definitions.
580 .. container:: sectionbody
582 .. container:: paragraph
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.
588 .. container:: listingblock
590 .. container:: content
596 "name" : "TopologyEdges",
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"}
605 .. container:: listingblock
607 .. container:: content
613 "name" : "TopologyNodes",
615 {"name" : "name", "type" : "string", "doc": "The name of the node"},
616 {"name" : "mnname", "type" : "string", "doc": "The name of the node in Mininet"}
620 .. container:: listingblock
622 .. container:: content
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"},
637 "doc": "Links used by this customer",
638 "type": {"type" : "array", "items" : "string"}
649 .. container:: sectionbody
651 .. container:: paragraph
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.
659 .. container:: listingblock
661 .. container:: content
679 .. container:: sectionbody
681 .. container:: paragraph
683 The node context logic simply takes the trigger event
684 (for context) and creates a new node in the local
687 .. container:: listingblock
689 .. container:: content
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
701 * http://www.apache.org/licenses/LICENSE-2.0
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.
709 * SPDX-License-Identifier: Apache-2.0
710 * ============LICENSE_END=========================================================
713 load("nashorn:mozilla_compat.js");
715 var logger = executor.logger;
716 logger.trace("start: " + executor.subject.id);
717 logger.trace("-- infields: " + executor.inFields);
719 var ifNodeName = executor.inFields["nodeName"];
720 var ifMininetName = executor.inFields["mininetName"];
722 var albumTopoNodes = executor.getContextAlbum("albumTopoNodes");
724 logger.trace("-- got infields, testing existing node");
726 var ctxtNode = albumTopoNodes.get(ifNodeName);
727 if (ctxtNode != null) {
728 albumTopoNodes.remove(ifNodeName);
729 logger.trace("-- removed node: <" + ifNodeName + ">");
732 logger.trace("-- creating node: <" + ifNodeName + ">");
733 ctxtNode = "{name:" + ifNodeName + ", mnname:" + ifMininetName + "}";
734 albumTopoNodes.put(ifNodeName, ctxtNode);
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"));
744 logger.trace(" >> >> node album is null");
748 executor.outFields["report"] = "node ctxt :: added node " + ifNodeName;
750 logger.info("vpnsla: ctxt added node " + ifNodeName);
752 var returnValueType = Java.type("java.lang.Boolean");
753 var returnValue = new returnValueType(true);
754 logger.trace("finished: " + executor.subject.id);
762 .. container:: sectionbody
764 .. container:: paragraph
766 The edge context logic simply takes the trigger event
767 (for context) and creates a new edge in the local
770 .. container:: listingblock
772 .. container:: content
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
784 * http://www.apache.org/licenses/LICENSE-2.0
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.
792 * SPDX-License-Identifier: Apache-2.0
793 * ============LICENSE_END=========================================================
796 load("nashorn:mozilla_compat.js");
798 var logger = executor.logger;
799 logger.trace("start: " + executor.subject.id);
800 logger.trace("-- infields: " + executor.inFields);
802 var ifEdgeName = executor.inFields["edgeName"];
803 var ifEdgeStatus = executor.inFields["status"];
805 var albumTopoEdges = executor.getContextAlbum("albumTopoEdges");
807 logger.trace("-- got infields, testing existing edge");
809 var ctxtEdge = albumTopoEdges.get(ifEdgeName);
810 if (ctxtEdge != null) {
811 albumTopoEdges.remove(ifEdgeName);
812 logger.trace("-- removed edge: <" + ifEdgeName + ">");
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);
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"));
829 logger.trace(" >> >> edge album is null");
833 executor.outFields["report"] = "edge ctxt :: added edge " + ifEdgeName;
835 logger.info("vpnsla: ctxt added edge " + ifEdgeName);
837 var returnValueType = Java.type("java.lang.Boolean");
838 var returnValue = new returnValueType(true);
839 logger.trace("finished: " + executor.subject.id);
842 Context Logic Customer
843 ----------------------
847 .. container:: sectionbody
849 .. container:: paragraph
851 The customer context logic simply takes the trigger
852 event (for context) and creates a new customer in the
853 local context topology.
855 .. container:: listingblock
857 .. container:: content
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
869 * http://www.apache.org/licenses/LICENSE-2.0
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.
877 * SPDX-License-Identifier: Apache-2.0
878 * ============LICENSE_END=========================================================
881 load("nashorn:mozilla_compat.js");
883 var logger = executor.logger;
884 logger.trace("start: " + executor.subject.id);
885 logger.trace("-- infields: " + executor.inFields);
887 var ifCustomerName = executor.inFields["customerName"];
888 var ifLinks = executor.inFields["links"];
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 + ">");
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]);
902 logger.trace("-- link: <" + ifLinks.split(" ")[i] + ">");
903 links.push(ifLinks.split(" ")[i]);
905 logger.trace("-- unknown link: <" + ifLinks.split(" ")[i] + "> for customer <" + ifCustomerName + ">");
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 + "]}";
913 executor.getContextAlbum("albumCustomerMap").put(ifCustomerName, ctxtCustomer);
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") + " : "
926 + executor.getContextAlbum("albumCustomerMap").values().get(i).get("satisfaction"));
929 logger.trace(" >> >> customer album is null");
933 executor.outFields["report"] = "customer ctxt :: added customer: " + ifCustomerName;
935 logger.info("vpnsla: ctxt added customer " + ifCustomerName);
937 var returnValueType = Java.type("java.lang.Boolean");
938 var returnValue = new returnValueType(true);
939 logger.trace("finished: " + executor.subject.id);
947 .. container:: sectionbody
949 .. container:: paragraph
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.
957 .. container:: listingblock
959 .. container:: content
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
971 * http://www.apache.org/licenses/LICENSE-2.0
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.
979 * SPDX-License-Identifier: Apache-2.0
980 * ============LICENSE_END=========================================================
983 load("nashorn:mozilla_compat.js");
985 var now = new Date().getTime();
986 executor.outFields["matchStart"] = now;
988 importClass(org.slf4j.LoggerFactory);
990 var logger = executor.logger;
991 logger.trace("start: " + executor.subject.id);
992 logger.trace("-- infields: " + executor.inFields);
994 var rootLogger = LoggerFactory.getLogger(logger.ROOT_LOGGER_NAME);
996 var ifEdgeName = executor.inFields["edgeName"];
997 var ifLinkStatus = executor.inFields["status"];
999 var albumTopoEdges = executor.getContextAlbum("albumTopoEdges");
1001 logger.trace("-- got infields, checking albumTopoEdges changes");
1004 switch (ifLinkStatus.toString()) {
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 + ">");
1018 var link = albumTopoEdges.get(ifEdgeName);
1020 logger.trace("-- link <" + ifEdgeName + "> not in albumTopoEdges");
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;
1029 logger.trace("-- link <" + ifEdgeName + "> status not changed <active:" + link.get("active") + ">");
1030 executor.outFields["hasChanged"] = false;
1034 executor.outFields["edgeName"] = ifEdgeName;
1035 executor.outFields["status"] = ifLinkStatus;
1037 logger.info("vpnsla: detected " + ifEdgeName + " as " + ifLinkStatus);
1039 var returnValueType = Java.type("java.lang.Boolean");
1040 var returnValue = new returnValueType(true);
1041 logger.trace("finished: " + executor.subject.id);
1045 Logic: Policy Establish State
1046 -----------------------------
1048 .. container:: sect1
1050 .. container:: sectionbody
1052 .. container:: paragraph
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
1061 .. container:: paragraph
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.
1069 .. container:: listingblock
1071 .. container:: content
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
1083 * http://www.apache.org/licenses/LICENSE-2.0
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.
1091 * SPDX-License-Identifier: Apache-2.0
1092 * ============LICENSE_END=========================================================
1095 load("nashorn:mozilla_compat.js");
1096 importClass(org.slf4j.LoggerFactory);
1098 importClass(java.util.ArrayList);
1100 importClass(org.apache.avro.generic.GenericData.Array);
1101 importClass(org.apache.avro.generic.GenericRecord);
1102 importClass(org.apache.avro.Schema);
1104 var logger = executor.logger;
1105 logger.trace("start: " + executor.subject.id);
1106 logger.trace("-- infields: " + executor.inFields);
1108 var rootLogger = LoggerFactory.getLogger(logger.ROOT_LOGGER_NAME);
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"];
1115 var albumCustomerMap = executor.getContextAlbum("albumCustomerMap");
1116 var albumProblemMap = executor.getContextAlbum("albumProblemMap");
1118 var linkProblem = albumProblemMap.get(ifEdgeName);
1120 // create outfiled for situation
1121 var situation = executor.subject.getOutFieldSchemaHelper("situation").createNewInstance();
1122 situation.put("violatedSLAs", new ArrayList());
1124 // create a string as states+hasChanged+linkProblem and switch over it
1125 var switchTest = ifEdgeStatus + ":" + ifhasChanged + ":" + (linkProblem == null ? "no" : "yes");
1126 switch (switchTest) {
1128 logger.trace("-- edge <" + ifEdgeName + "> UP:false:no => everything ok");
1129 logger.info("vpnsla: everything ok");
1130 situation.put("problemID", "NONE");
1132 case "UP:false:yes":
1133 logger.trace("-- edge <" + ifEdgeName + "> UP:false:yes ==> did we miss earlier up?, removing problem");
1134 albumProblemMap.remove(ifEdgeName);
1136 situation.put("problemID", "NONE");
1139 logger.trace("-- edge <" + ifEdgeName + "> UP:true:no ==> did we miss the earlier down?, creating new problem");
1140 situation.put("problemID", ifEdgeName);
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");
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);
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);
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);
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");
1168 situation.put("problemID", ifEdgeName);
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 + ">");
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());
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"));
1199 albumProblemMap.put(ifEdgeName, linkProblem);
1200 logger.trace("-- edge <" + ifEdgeName + "> problem created as <" + linkProblem + ">");
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))
1217 // set lastUpdate to this policy execution for next execution calculation
1218 linkProblem.put("lastUpdate", ifMatchStart);
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" + "!!");
1231 logger.info(">e> " + customer.get("customerName") + "\t\t" + customer.get("dtSLA") + "s\t"
1232 + customer.get("dtYTD") + "s");
1237 executor.outFields["situation"] = situation;
1239 logger.trace("-- out fields <" + executor.outFields + ">");
1241 var returnValueType = Java.type("java.lang.Boolean");
1242 var returnValue = new returnValueType(true);
1243 logger.trace("finished: " + executor.subject.id);
1246 Logic: Policy Decide State
1247 --------------------------
1249 .. container:: sect1
1251 .. container:: sectionbody
1253 .. container:: paragraph
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).
1261 .. container:: listingblock
1263 .. container:: content
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
1275 * http://www.apache.org/licenses/LICENSE-2.0
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.
1283 * SPDX-License-Identifier: Apache-2.0
1284 * ============LICENSE_END=========================================================
1287 load("nashorn:mozilla_compat.js");
1288 importClass(org.slf4j.LoggerFactory);
1290 var logger = executor.logger;
1291 logger.trace("start: " + executor.subject.id + " - TSL");
1293 var rootLogger = LoggerFactory.getLogger(logger.ROOT_LOGGER_NAME);
1295 var ifSituation = executor.inFields["situation"];
1297 var albumProblemMap = executor.getContextAlbum("albumProblemMap");
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);
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);
1323 logger.trace("finished: " + executor.subject.id);
1324 logger.debug(".d-tsl");
1326 .. container:: paragraph
1328 The actual task logic are then ``none``, ``solved``,
1329 ``sla``, and ``priority``.
1334 .. container:: sect1
1336 .. container:: sectionbody
1338 .. container:: listingblock
1340 .. container:: content
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
1352 * http://www.apache.org/licenses/LICENSE-2.0
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.
1360 * SPDX-License-Identifier: Apache-2.0
1361 * ============LICENSE_END=========================================================
1364 load("nashorn:mozilla_compat.js");
1365 importClass(org.slf4j.LoggerFactory);
1367 importClass(java.util.ArrayList);
1369 importClass(org.apache.avro.generic.GenericData.Array);
1370 importClass(org.apache.avro.generic.GenericRecord);
1371 importClass(org.apache.avro.Schema);
1373 var logger = executor.logger;
1374 logger.trace("start: " + executor.subject.id);
1375 logger.trace("-- infields: " + executor.inFields);
1377 var rootLogger = LoggerFactory.getLogger(logger.ROOT_LOGGER_NAME);
1379 var ifSituation = executor.inFields["situation"];
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());
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);
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);
1398 executor.outFields["decision"] = decision;
1400 logger.trace("finished: " + executor.subject.id);
1401 logger.debug(".d-non");
1403 Logic: Decide Solved
1404 ---------------------
1406 .. container:: sect1
1408 .. container:: sectionbody
1410 .. container:: listingblock
1412 .. container:: content
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
1424 * http://www.apache.org/licenses/LICENSE-2.0
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.
1432 * SPDX-License-Identifier: Apache-2.0
1433 * ============LICENSE_END=========================================================
1436 load("nashorn:mozilla_compat.js");
1437 importClass(org.slf4j.LoggerFactory);
1439 importClass(java.util.ArrayList);
1441 importClass(org.apache.avro.generic.GenericData.Array);
1442 importClass(org.apache.avro.generic.GenericRecord);
1443 importClass(org.apache.avro.Schema);
1445 var logger = executor.logger;
1446 logger.trace("start: " + executor.subject.id);
1447 logger.trace("-- infields: " + executor.inFields);
1449 var rootLogger = LoggerFactory.getLogger(logger.ROOT_LOGGER_NAME);
1451 var ifSituation = executor.inFields["situation"];
1453 var albumProblemMap = executor.getContextAlbum("albumProblemMap");
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"));
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);
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);
1473 executor.outFields["decision"] = decision;
1475 logger.info("vpnsla: sla solved, problem solved");
1477 logger.trace("finished: " + executor.subject.id);
1478 logger.debug(".d-non");
1483 .. container:: sect1
1485 .. container:: sectionbody
1487 .. container:: listingblock
1489 .. container:: content
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
1501 * http://www.apache.org/licenses/LICENSE-2.0
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.
1509 * SPDX-License-Identifier: Apache-2.0
1510 * ============LICENSE_END=========================================================
1513 load("nashorn:mozilla_compat.js");
1514 importClass(org.slf4j.LoggerFactory);
1516 importClass(java.util.ArrayList);
1518 importClass(org.apache.avro.generic.GenericData.Array);
1519 importClass(org.apache.avro.generic.GenericRecord);
1520 importClass(org.apache.avro.Schema);
1522 var logger = executor.logger;
1523 logger.trace("start: " + executor.subject.id);
1524 logger.trace("-- infields: " + executor.inFields);
1526 var rootLogger = LoggerFactory.getLogger(logger.ROOT_LOGGER_NAME);
1528 var ifSituation = executor.inFields["situation"];
1530 var albumCustomerMap = executor.getContextAlbum("albumCustomerMap");
1531 var albumProblemMap = executor.getContextAlbum("albumProblemMap");
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());
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");
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");
1551 if ((customerCtxt.get("dtSLA") - customerCtxt.get("dtYTD")) >= customerSla) {
1552 customer = customerCtxt.get("customerName");
1553 customerSla = (customerCtxt.get("dtSLA") - customerCtxt.get("dtYTD"));
1556 decision.get("customers").add(customer);
1557 var returnValue = new returnValueType(true);
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);
1565 // set impededLast to decision[customers]
1566 problem.get("impededLast").clear();
1567 problem.get("impededLast").addAll(decision.get("customers"));
1569 executor.outFields["decision"] = decision;
1570 logger.trace("-- decision: " + decision);
1572 logger.info("vpnsla: sla balance, impeding customers " + decision.get("customers"));
1574 logger.trace("finished: " + executor.subject.id);
1575 logger.debug(".d-sla");
1577 Logic: Decide Priority
1578 ----------------------
1580 .. container:: sect2
1582 .. container:: listingblock
1584 .. container:: content
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
1596 * http://www.apache.org/licenses/LICENSE-2.0
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.
1604 * SPDX-License-Identifier: Apache-2.0
1605 * ============LICENSE_END=========================================================
1608 load("nashorn:mozilla_compat.js");
1609 importClass(org.slf4j.LoggerFactory);
1611 importClass(java.util.ArrayList);
1613 importClass(org.apache.avro.generic.GenericData.Array);
1614 importClass(org.apache.avro.generic.GenericRecord);
1615 importClass(org.apache.avro.Schema);
1617 var logger = executor.logger;
1618 logger.trace("start: " + executor.subject.id);
1619 logger.trace("-- infields: " + executor.inFields);
1621 var rootLogger = LoggerFactory.getLogger(logger.ROOT_LOGGER_NAME);
1623 var ifSituation = executor.inFields["situation"];
1625 var albumCustomerMap = executor.getContextAlbum("albumCustomerMap");
1626 var albumProblemMap = executor.getContextAlbum("albumProblemMap");
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());
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"));
1645 var returnValue = new returnValueType(true);
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);
1653 // set impededLast to decision[customers]
1654 problem.get("impededLast").clear();
1655 problem.get("impededLast").addAll(decision.get("customers"));
1657 executor.outFields["decision"] = decision;
1658 logger.trace("-- decision: " + decision);
1660 logger.info("vpnsla: priority, impeding customers " + decision.get("customers"));
1662 logger.trace("finished: " + executor.subject.id);
1663 logger.debug(".d-pri");
1665 Logic: Policy Act State
1666 ------------------------
1668 .. container:: sect1
1670 .. container:: sectionbody
1672 .. container:: paragraph
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).
1678 .. container:: listingblock
1680 .. container:: content
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
1692 * http://www.apache.org/licenses/LICENSE-2.0
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.
1700 * SPDX-License-Identifier: Apache-2.0
1701 * ============LICENSE_END=========================================================
1704 load("nashorn:mozilla_compat.js");
1706 var logger = executor.logger;
1707 logger.trace("start: " + executor.subject.id);
1708 logger.trace("-- infields: " + executor.inFields);
1710 var ifDecision = executor.inFields["decision"];
1711 var ifMatchStart = executor.inFields["matchStart"];
1713 var albumCustomerMap = executor.getContextAlbum("albumCustomerMap");
1714 var albumProblemMap = executor.getContextAlbum("albumProblemMap");
1716 switch (ifDecision.get("decision").toString()) {
1718 executor.outFields["edgeName"] = "";
1719 executor.outFields["action"] = "";
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";
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###
1738 var returnValueType = Java.type("java.lang.Boolean");
1739 var returnValue = new returnValueType(true);
1741 if (executor.outFields["action"] != "") {
1742 logger.info("vpnsla: action is to " + executor.outFields["action"] + " " + executor.outFields["edgeName"]);
1744 logger.info("vpnsla: no action required");
1747 logger.trace("-- outfields: " + executor.outFields);
1748 logger.trace("finished: " + executor.subject.id);
1751 var now = new Date().getTime();
1752 logger.info("VPN SLA finished in " + (now - ifMatchStart) + " ms");
1757 .. container:: sect1
1759 .. rubric:: Complete Policy Definition
1760 :name: complete_policy_definition
1762 .. container:: sectionbody
1764 .. container:: paragraph
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).
1771 .. container:: listingblock
1773 .. container:: content
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
1785 # http://www.apache.org/licenses/LICENSE-2.0
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.
1793 # SPDX-License-Identifier: Apache-2.0
1794 # ============LICENSE_END=========================================================
1795 #-------------------------------------------------------------------------------
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
1804 # http://www.apache.org/licenses/LICENSE-2.0
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.
1812 # SPDX-License-Identifier: Apache-2.0
1813 # ============LICENSE_END=========================================================
1815 model create name=PCVS-VpnSla version=1.0.0 description="Policies-Controlled Video Streaming, VPN SLA Policy Model"
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
1823 schema create name=timestampDecl version=1.0.0 description="Timestamp" flavour=Java schema=java.lang.Long
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
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"
1835 album create name=albumTopoEdges scope=global writable=true schemaName=ctxtTopologyEdgesDecl
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"
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
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
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
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"
1868 album create name=albumTopoNodes scope=global writable=true schemaName=ctxtTopologyNodesDecl
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"
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
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
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
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"
1901 album create name=albumCustomerMap scope=global writable=true schemaName=ctxtCustomerMapDecl
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"
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
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
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"
1937 schema create name=edgeChangedDecl version=1.0.0 description="Status Change (true:change, false:no change)" flavour=Java schema=java.lang.Boolean
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"
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"
1957 album create name=albumProblemMap scope=global writable=true schemaName=problemMapDecl
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"
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"
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"
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"
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"
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"
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"
2030 schema create name=actionDecl version=1.0.0 description="An action for the actioning system" flavour=Java schema=java.lang.String
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"
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
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
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
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
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
2072 policy create name=VpnSlaPolicy version=1.0.0 description="Policy deciding customer treatment based on SLAs as MEDA policy" template=FREEFORM firstState=VpnSlaPolicyMatchState
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
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"
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
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
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
2102 Context Events Nodes
2103 --------------------
2105 .. container:: sect1
2107 .. container:: sectionbody
2109 .. container:: paragraph
2111 The following events create all nodes of the topology.
2113 .. container:: listingblock
2115 .. container:: content
2120 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2121 "name": "NodeContextEventIn",
2123 "source": "CtxtManagement",
2124 "target" : "VpnSlaPolicy_NodeContext",
2130 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2131 "name": "NodeContextEventIn",
2133 "source": "CtxtManagement",
2134 "target" : "VpnSlaPolicy_NodeContext",
2140 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2141 "name": "NodeContextEventIn",
2143 "source": "CtxtManagement",
2144 "target" : "VpnSlaPolicy_NodeContext",
2150 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2151 "name": "NodeContextEventIn",
2153 "source": "CtxtManagement",
2154 "target" : "VpnSlaPolicy_NodeContext",
2161 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2162 "name": "NodeContextEventIn",
2164 "source": "CtxtManagement",
2165 "target" : "VpnSlaPolicy_NodeContext",
2171 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2172 "name": "NodeContextEventIn",
2174 "source": "CtxtManagement",
2175 "target" : "VpnSlaPolicy_NodeContext",
2181 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2182 "name": "NodeContextEventIn",
2184 "source": "CtxtManagement",
2185 "target" : "VpnSlaPolicy_NodeContext",
2191 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2192 "name": "NodeContextEventIn",
2194 "source": "CtxtManagement",
2195 "target" : "VpnSlaPolicy_NodeContext",
2201 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2202 "name": "NodeContextEventIn",
2204 "source": "CtxtManagement",
2205 "target" : "VpnSlaPolicy_NodeContext",
2211 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2212 "name": "NodeContextEventIn",
2214 "source": "CtxtManagement",
2215 "target" : "VpnSlaPolicy_NodeContext",
2220 Context Events Edges
2221 --------------------
2223 .. container:: sect1
2225 .. container:: sectionbody
2227 .. container:: paragraph
2229 The following events create all edges of the topology.
2231 .. container:: listingblock
2233 .. container:: content
2238 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2239 "name": "EdgeContextEventIn",
2241 "source": "CtxtManagement",
2242 "target" : "VpnSlaPolicy_EdgeContext",
2250 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2251 "name": "EdgeContextEventIn",
2253 "source": "CtxtManagement",
2254 "target" : "VpnSlaPolicy_EdgeContext",
2262 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2263 "name": "EdgeContextEventIn",
2265 "source": "CtxtManagement",
2266 "target" : "VpnSlaPolicy_EdgeContext",
2274 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2275 "name": "EdgeContextEventIn",
2277 "source": "CtxtManagement",
2278 "target" : "VpnSlaPolicy_EdgeContext",
2286 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2287 "name": "EdgeContextEventIn",
2289 "source": "CtxtManagement",
2290 "target" : "VpnSlaPolicy_EdgeContext",
2298 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2299 "name": "EdgeContextEventIn",
2301 "source": "CtxtManagement",
2302 "target" : "VpnSlaPolicy_EdgeContext",
2310 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2311 "name": "EdgeContextEventIn",
2313 "source": "CtxtManagement",
2314 "target" : "VpnSlaPolicy_EdgeContext",
2322 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2323 "name": "EdgeContextEventIn",
2325 "source": "CtxtManagement",
2326 "target" : "VpnSlaPolicy_EdgeContext",
2334 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2335 "name": "EdgeContextEventIn",
2337 "source": "CtxtManagement",
2338 "target" : "VpnSlaPolicy_EdgeContext",
2346 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2347 "name": "EdgeContextEventIn",
2349 "source": "CtxtManagement",
2350 "target" : "VpnSlaPolicy_EdgeContext",
2357 Context Events Customers
2358 ------------------------
2360 .. container:: sect1
2362 .. container:: sectionbody
2364 .. container:: paragraph
2366 The following events create all customers of the
2369 .. container:: listingblock
2371 .. container:: content
2376 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2377 "name": "CustomerContextEventIn",
2379 "source": "CtxtManagement",
2380 "target" : "VpnSlaPolicy_CustomerContext",
2381 "customerName": "A",
2382 "links": "L01 L05 L09 L10",
2390 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2391 "name": "CustomerContextEventIn",
2393 "source": "CtxtManagement",
2394 "target" : "VpnSlaPolicy_CustomerContext",
2395 "customerName": "B",
2396 "links": "L02 L07 L09 L10",
2406 .. container:: sect1
2408 .. container:: sectionbody
2410 .. container:: paragraph
2412 The following events are examples for trigger events
2414 .. container:: listingblock
2416 .. container:: content
2421 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2422 "name": "VpnSlaTrigger",
2424 "source": "ExampleEvents",
2425 "target" : "VpnSlaPolicy",
2431 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2432 "name": "VpnSlaTrigger",
2434 "source": "ExampleEvents",
2435 "target" : "VpnSlaPolicy",
2441 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2442 "name": "VpnSlaTrigger",
2444 "source": "ExampleEvents",
2445 "target" : "VpnSlaPolicy",
2451 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2452 "name": "VpnSlaTrigger",
2454 "source": "ExampleEvents",
2455 "target" : "VpnSlaPolicy",
2461 "nameSpace": "org.onap.policy.apex.examples.pcvs.vpnsla",
2462 "name": "VpnSlaTrigger",
2464 "source": "ExampleEvents",
2465 "target" : "VpnSlaPolicy",
2473 .. container:: sect1
2475 .. container:: sectionbody
2477 .. container:: paragraph
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.
2484 .. container:: listingblock
2486 .. container:: content
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
2497 # http://www.apache.org/licenses/LICENSE-2.0
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.
2505 # SPDX-License-Identifier: Apache-2.0
2506 # ============LICENSE_END=========================================================
2511 from kafka import KafkaConsumer, KafkaProducer
2513 class StaticFlowPusher(object):
2515 def __init__(self, server):
2516 self.server = server
2518 def get(self, data):
2519 ret = self.rest_call({}, 'GET')
2520 return json.loads(ret[2])
2522 def set(self, data):
2523 ret = self.rest_call(data, 'POST')
2524 return ret[0] == 200
2526 def remove(self, objtype, data):
2527 ret = self.rest_call(data, 'DELETE')
2528 return ret[0] == 200
2530 def getControllerSummary(self, data):
2531 ret = self.rest_call_controller_summary({}, 'GET')
2532 return json.loads(ret[2])
2534 def getLinks(self, data):
2535 ret = self.rest_call_links({}, 'GET')
2536 return json.loads(ret[2].decode())
2538 def rest_call(self, data, action):
2539 path = '/wm/staticflowpusher/json'
2541 'Content-type': 'application/json',
2542 'Accept': 'application/json',
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())
2553 def rest_call_controller_summary(self, data, action):
2554 path = '/wm/core/controller/summary/json'
2556 'Content-type': 'application/json',
2557 'Accept': 'application/json',
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())
2568 def rest_call_links(self, data, action):
2569 path = '/wm/topology/links/json'
2571 'Content-type': 'application/json',
2572 'Accept': 'application/json',
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())
2582 pusher = StaticFlowPusher('127.0.1.1')
2585 def parseLinks(links):
2586 #print("\n\n\n",links)
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])
2594 list.append(link['src-switch'][len(link['src-switch'])-1])
2596 list.append(link['dst-switch'][len(link['dst-switch'])-1])
2597 result.append(''.join(list))
2598 #print(result, "\n")
2608 producer = KafkaProducer(bootstrap_servers='localhost:9092')
2611 switchLinks = pusher.getLinks({})
2613 healthyList = parseLinks(switchLinks)
2615 print("READING LINKS FROM MININET\n")
2616 for l in healthyList:
2619 #Links between switches [s6-s7 is ignored so it matches VPN SCENARIO]
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"))
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"))
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"))
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"))
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"))
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")
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))
2655 print("We start off with", len(healthyLinks), "healthy Links!\n")
2657 testableList = parseLinks(switchLinks)
2659 for h in healthyList:
2661 for t in testableList:
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"))
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'}")
2698 testableLinks = switchLinks
2699 myfile = open('LinkInfo.json', 'a')
2700 myfile.write(str(testableLinks))
2708 .. container:: sect1
2710 .. container:: sectionbody
2712 .. container:: paragraph
2714 The topology is realized using Mininet. The following
2715 script is use to estalish the topology and to realize
2716 network configurations.
2718 .. container:: listingblock
2720 .. container:: content
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
2731 # http://www.apache.org/licenses/LICENSE-2.0
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.
2739 # SPDX-License-Identifier: Apache-2.0
2740 # ============LICENSE_END=========================================================
2742 #Add Mininet to PATH
2744 sys.path.insert(0, "/~/mininet")
2750 from kafka import KafkaConsumer, KafkaProducer
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 *
2763 class StaticFlowPusher(object):
2764 def __init__(self, server):
2765 self.server = server
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())
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())
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())
2800 #Build Pusher(REST/IN)
2801 pusher = StaticFlowPusher('127.0.0.1')
2803 net = Mininet(link=TCLink)
2806 customerA1 = net.addHost( 'A1' )
2807 customerA2 = net.addHost( 'A2' )
2808 customerB1 = net.addHost( 'B1' )
2809 customerB2 = net.addHost( 'B2' )
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' )
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 )
2835 floodlightController = net.addController(name='c0' , controller=RemoteController , ip='127.0.0.1', port=6653)
2839 if pusher.enableFirewall({})[0] == 200:
2840 print("Firewall enabled!")
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']
2854 result = net.pingAll(None)
2855 print("Network Simulation Complete")
2857 #Assume control and when finished "exit"
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())
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":
2945 Last updated 2020-04-03 16:04:24 IST
2948 .. |ONAP| image:: ../../../images/logos.png
2950 :target: http://www.onap.org/
2952 .. |VPN SLA Architecture| image:: images/pcvs/vpnsla-arch.png