3859b740514ff190376f16badfd410618c6d9f5b
[policy/drools-applications.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * demo
4  * ================================================================================
5  * Copyright (C) 2019 Wipro Limited Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.template.demo;
23
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertNotNull;
26 import static org.junit.Assert.assertTrue;
27 import static org.junit.Assert.fail;
28
29 import java.io.IOException;
30 import java.net.URLEncoder;
31 import java.time.Instant;
32 import java.util.HashMap;
33 import java.util.List;
34 import java.util.Properties;
35 import java.util.UUID;
36 import org.junit.AfterClass;
37 import org.junit.BeforeClass;
38 import org.junit.Test;
39 import org.kie.api.runtime.KieSession;
40 import org.kie.api.runtime.rule.FactHandle;
41 import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
42 import org.onap.policy.common.endpoints.event.comm.TopicEndpointManager;
43 import org.onap.policy.common.endpoints.event.comm.TopicListener;
44 import org.onap.policy.common.endpoints.event.comm.TopicSink;
45 import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInstance;
46 import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties;
47 import org.onap.policy.controlloop.ControlLoopEventStatus;
48 import org.onap.policy.controlloop.ControlLoopNotificationType;
49 import org.onap.policy.controlloop.ControlLoopTargetType;
50 import org.onap.policy.controlloop.VirtualControlLoopEvent;
51 import org.onap.policy.controlloop.VirtualControlLoopNotification;
52 import org.onap.policy.controlloop.policy.ControlLoopPolicy;
53 import org.onap.policy.drools.protocol.coders.EventProtocolCoder;
54 import org.onap.policy.drools.protocol.coders.EventProtocolParams;
55 import org.onap.policy.drools.protocol.coders.JsonProtocolFilter;
56 import org.onap.policy.drools.system.PolicyController;
57 import org.onap.policy.drools.system.PolicyEngine;
58 import org.onap.policy.drools.utils.logging.LoggerUtil;
59 import org.onap.policy.sdnr.PciRequest;
60 import org.onap.policy.sdnr.PciRequestWrapper;
61 import org.onap.policy.sdnr.PciResponse;
62 import org.onap.policy.sdnr.PciResponseWrapper;
63 import org.slf4j.Logger;
64 import org.slf4j.LoggerFactory;
65
66 public class VsonhControlLoopTest implements TopicListener {
67
68     private static final Logger logger = LoggerFactory.getLogger(VsonhControlLoopTest.class);
69
70     private static List<? extends TopicSink> noopTopics;
71
72     private static KieSession kieSession;
73     private static SupportUtil.Pair<ControlLoopPolicy, String> pair;
74     private UUID requestId;
75
76     static {
77         /* Set environment properties */
78         SupportUtil.setAaiProps();
79         SupportUtil.setGuardProps();
80         SupportUtil.setPuProp();
81         LoggerUtil.setLevel(LoggerUtil.ROOT_LOGGER, "DEBUG");
82     }
83
84     /**
85      * Setup the simulator.
86      */
87     @BeforeClass
88     public static void setUpSimulator() {
89         PolicyEngine.manager.configure(new Properties());
90         assertTrue(PolicyEngine.manager.start());
91         Properties noopSinkProperties = new Properties();
92         noopSinkProperties.put(PolicyEndPointProperties.PROPERTY_NOOP_SINK_TOPICS, "SDNR-CL,POLICY-CL-MGT");
93         noopSinkProperties.put("noop.sink.topics.SDNR-CL.events", "org.onap.policy.sdnr.PciRequestWrapper");
94         noopSinkProperties.put("noop.sink.topics.SDNR-CL.events.custom.gson",
95                 "org.onap.policy.sdnr.util.Serialization,gson");
96         noopSinkProperties.put("noop.sink.topics.POLICY-CL-MGT.events",
97                 "org.onap.policy.controlloop.VirtualControlLoopNotification");
98         noopSinkProperties.put("noop.sink.topics.POLICY-CL-MGT.events.custom.gson",
99                 "org.onap.policy.controlloop.util.Serialization,gsonPretty");
100         noopTopics = TopicEndpointManager.getManager().addTopicSinks(noopSinkProperties);
101
102         EventProtocolCoder.manager.addEncoder(EventProtocolParams.builder()
103                 .groupId("junit.groupId")
104                 .artifactId("junit.artifactId")
105                 .topic("POLICY-CL-MGT")
106                 .eventClass("org.onap.policy.controlloop.VirtualControlLoopNotification")
107                 .protocolFilter(new JsonProtocolFilter())
108                 .modelClassLoaderHash(1111));
109         EventProtocolCoder.manager.addEncoder(EventProtocolParams.builder()
110                 .groupId("junit.groupId")
111                 .artifactId("junit.artifactId")
112                 .topic("SDNR-CL")
113                 .eventClass("org.onap.policy.sdnr.PciRequestWrapper")
114                 .protocolFilter(new JsonProtocolFilter())
115                 .modelClassLoaderHash(1111));
116         try {
117             SupportUtil.buildAaiSim();
118             SupportUtil.buildGuardSim();
119         } catch (Exception e) {
120             fail(e.getMessage());
121         }
122         /*
123          * Start the kie session
124          */
125         try {
126             kieSession = startSession(
127                     "../archetype-cl-amsterdam/src/main/resources/archetype-resources"
128                             + "/src/main/resources/__closedLoopControlName__.drl",
129                     "src/test/resources/yaml/policy_ControlLoop_vSONH.yaml", "type=operational", "CL_vSONH", "v4.0.0");
130         } catch (IOException e) {
131             e.printStackTrace();
132             logger.debug("Could not create kieSession");
133             fail("Could not create kieSession");
134         }
135     }
136
137     /**
138      * Tear down the simulator.
139      */
140     @AfterClass
141     public static void tearDownSimulator() {
142         /*
143          * Gracefully shut down the kie session
144          */
145         kieSession.dispose();
146
147         PolicyEngine.manager.stop();
148         HttpServletServerFactoryInstance.getServerFactory().destroy();
149         PolicyController.factory.shutdown();
150         TopicEndpointManager.getManager().shutdown();
151     }
152
153     @Test
154     public void successTest() {
155
156         /*
157          * Allows the PolicyEngine to callback to this object to notify that there is an
158          * event ready to be pulled from the queue
159          */
160         for (TopicSink sink : noopTopics) {
161             assertTrue(sink.start());
162             sink.register(this);
163         }
164
165         /*
166          * Create a unique requestId
167          */
168         requestId = UUID.randomUUID();
169
170         /*
171          * Simulate an onset event the policy engine will receive from DCAE to kick off
172          * processing through the rules
173          */
174         sendEvent(pair.first, requestId, ControlLoopEventStatus.ONSET, true);
175
176         kieSession.fireUntilHalt();
177
178         // allow object clean-up
179         kieSession.fireAllRules();
180
181         /*
182          * The only fact in memory should be Params
183          */
184         assertEquals(1, kieSession.getFactCount());
185
186         /*
187          * Print what's left in memory
188          */
189         dumpFacts(kieSession);
190
191     }
192
193     @Test
194     public void aaiGetFailTest() {
195
196         /*
197          * Allows the PolicyEngine to callback to this object to notify that there is an
198          * event ready to be pulled from the queue
199          */
200         for (TopicSink sink : noopTopics) {
201             assertTrue(sink.start());
202             sink.register(this);
203         }
204
205         /*
206          * Create a unique requestId
207          */
208         requestId = UUID.randomUUID();
209
210         /*
211          * Simulate an onset event the policy engine will receive from DCAE to kick off
212          * processing through the rules
213          */
214         sendEvent(pair.first, requestId, ControlLoopEventStatus.ONSET, false);
215
216         kieSession.fireUntilHalt();
217
218         // allow object clean-up
219         kieSession.fireAllRules();
220
221         /*
222          * The only fact in memory should be Params
223          */
224         assertEquals(1, kieSession.getFactCount());
225
226         /*
227          * Print what's left in memory
228          */
229         dumpFacts(kieSession);
230
231     }
232
233     /**
234      * This method will start a kie session and instantiate the Policy Engine.
235      *
236      * @param droolsTemplate
237      *            the DRL rules file
238      * @param yamlFile
239      *            the yaml file containing the policies
240      * @param policyScope
241      *            scope for policy
242      * @param policyName
243      *            name of the policy
244      * @param policyVersion
245      *            version of the policy
246      * @return the kieSession to be used to insert facts
247      * @throws IOException
248      *             IO exception
249      */
250     private static KieSession startSession(String droolsTemplate, String yamlFile, String policyScope,
251             String policyName, String policyVersion) throws IOException {
252
253         /*
254          * Load policies from yaml
255          */
256         pair = SupportUtil.loadYaml(yamlFile);
257         assertNotNull(pair);
258         assertNotNull(pair.first);
259         assertNotNull(pair.first.getControlLoop());
260         assertNotNull(pair.first.getControlLoop().getControlLoopName());
261         assertTrue(pair.first.getControlLoop().getControlLoopName().length() > 0);
262
263         /*
264          * Construct a kie session
265          */
266         final KieSession kieSession = SupportUtil.buildContainer(droolsTemplate,
267                 pair.first.getControlLoop().getControlLoopName(), policyScope, policyName, policyVersion,
268                 URLEncoder.encode(pair.second, "UTF-8"));
269
270         /*
271          * Retrieve the Policy Engine
272          */
273
274         logger.debug("======controlloop======");
275         logger.debug(((ControlLoopPolicy) pair.first).toString());
276         logger.debug("======policies======");
277         logger.debug(URLEncoder.encode(pair.second, "UTF-8"));
278         logger.debug("============");
279
280         return kieSession;
281     }
282
283     /*
284      * (non-Javadoc)
285      *
286      * @see
287      * org.onap.policy.drools.PolicyEngineListener#newEventNotification(java.lang.
288      * String)
289      */
290     @Override
291     public void onTopicEvent(CommInfrastructure commType, String topic, String event) {
292         logger.debug("\n============ onTopicEvent!!! ===========\n");
293         logger.debug("topic: {}, event: {}", topic, event);
294         /*
295          * Pull the object that was sent out to DMAAP and make sure it is a
296          * ControlLoopNoticiation of type active
297          */
298         Object obj = null;
299         if ("POLICY-CL-MGT".equals(topic)) {
300             obj = org.onap.policy.controlloop.util.Serialization.gsonJunit.fromJson(event,
301                     org.onap.policy.controlloop.VirtualControlLoopNotification.class);
302         } else if ("SDNR-CL".equals(topic)) {
303             obj = org.onap.policy.sdnr.util.Serialization.gsonJunit.fromJson(event,
304                     org.onap.policy.sdnr.PciRequestWrapper.class);
305         }
306         assertNotNull(obj);
307         if (obj instanceof VirtualControlLoopNotification) {
308             VirtualControlLoopNotification notification = (VirtualControlLoopNotification) obj;
309             String policyName = notification.getPolicyName();
310             logger.debug("Rule Fired: {}", policyName);
311             if (policyName.endsWith("EVENT")) {
312                 assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification());
313             } else if (policyName.endsWith("GUARD_NOT_YET_QUERIED")) {
314                 assertEquals(ControlLoopNotificationType.OPERATION, notification.getNotification());
315                 assertNotNull(notification.getMessage());
316                 assertTrue(notification.getMessage().startsWith("Sending guard query"));
317             } else if (policyName.endsWith("GUARD.RESPONSE")) {
318                 assertEquals(ControlLoopNotificationType.OPERATION, notification.getNotification());
319                 assertNotNull(notification.getMessage());
320                 assertTrue(notification.getMessage().toLowerCase().endsWith("permit"));
321             } else if (policyName.endsWith("GUARD_PERMITTED")) {
322                 assertEquals(ControlLoopNotificationType.OPERATION, notification.getNotification());
323                 assertNotNull(notification.getMessage());
324                 assertTrue(notification.getMessage().startsWith("actor=SDNR"));
325             } else if (policyName.endsWith("OPERATION.TIMEOUT")) {
326                 kieSession.halt();
327                 logger.debug("The operation timed out");
328                 fail("Operation Timed Out");
329             } else if (policyName.endsWith("SDNR.RESPONSE")) {
330                 assertEquals(ControlLoopNotificationType.OPERATION_SUCCESS, notification.getNotification());
331                 assertNotNull(notification.getMessage());
332                 assertTrue(notification.getMessage().startsWith("actor=SDNR"));
333             } else if (policyName.endsWith("EVENT.MANAGER")) {
334                 if ("getFail".equals(notification.getAai().get("generic-vnf.vnf-id"))) {
335                     assertEquals(ControlLoopNotificationType.FINAL_FAILURE, notification.getNotification());
336                     kieSession.halt();
337                 } else {
338                     assertEquals(ControlLoopNotificationType.FINAL_SUCCESS, notification.getNotification());
339                     kieSession.halt();
340                 }
341             } else if (policyName.endsWith("EVENT.MANAGER.TIMEOUT")) {
342                 kieSession.halt();
343                 logger.debug("The control loop timed out");
344                 fail("Control Loop Timed Out");
345             }
346         } else if (obj instanceof PciRequestWrapper) {
347             /*
348              * The request should be of type PciRequestWrapper and the subrequestid should
349              * be 1
350              */
351             PciRequestWrapper dmaapRequest = (PciRequestWrapper) obj;
352             PciRequest pciRequest = dmaapRequest.getBody();
353             assertEquals("1", pciRequest.getCommonHeader().getSubRequestId());
354
355             logger.debug("\n============ SDNR received the request!!! ===========\n");
356             logger.debug("\n============ dmaapRequest ===========\n {} ", dmaapRequest);
357             logger.debug("\n============ pciRequest ===========\n {}", pciRequest);
358
359             /*
360              * Simulate a success response from SDNR and insert the response into the
361              * working memory
362              */
363             PciResponse pciResponse = new PciResponse(pciRequest);
364             pciResponse.getStatus().setCode(200);
365             pciResponse.getStatus().setValue("SUCCESS");
366             StringBuilder sb = new StringBuilder();
367             sb.append("{ \"Configurations\":[ { \"Status\": { \"Code\": 200, \"Value\":"
368                     + " \"SUCCESS\" }, \"data\":{ \"FAPService\":{ \"alias\":"
369                     + "\"Network1\", \"CellConfig\":{ \"LTE\":{ \"RAN\":{ \"Common\":"
370                                         + "{ \"CellIdentity\":\"1\" }, \"NeighborListInUse\" : "
371                                         + "{ \"LTECellNumberOfEntries\" : \"1\" , \"LTECell\" : "
372                                         + "[ { \"PLMNID\" :\"plmnid1\", \"CID\":\"Chn0001\", \"PhyCellID\":"
373                                         + "\"3\", \"PNFName\":\"ncserver01\", \"Blacklisted\":\"false\" "
374                                         + "} ] } } } } } } } ] }");
375
376             pciResponse.setPayload(sb.toString());
377             PciResponseWrapper dmaapResponse = new PciResponseWrapper();
378             dmaapResponse.setBody(pciResponse);
379             dmaapResponse.setType("response");
380             logger.debug("\n============ SDNR sending response!!! ===========\n");
381             logger.debug("\n============ dmaapResponse ===========\n {}", dmaapResponse);
382             logger.debug("\n============ pciResponse ===========\n {}", pciResponse);
383             kieSession.insert(dmaapResponse);
384         }
385     }
386
387     /**
388      * This method is used to simulate event messages from DCAE that start the
389      * control loop (onset message).
390      *
391      * @param policy
392      *            the controlLoopName comes from the policy
393      * @param requestId
394      *            the requestId for this event
395      * @param status
396      *            could be onset
397      */
398     protected void sendEvent(ControlLoopPolicy policy, UUID requestId, ControlLoopEventStatus status,
399             boolean isEnriched) {
400         VirtualControlLoopEvent event = new VirtualControlLoopEvent();
401         event.setClosedLoopControlName(policy.getControlLoop().getControlLoopName());
402         event.setRequestId(requestId);
403         event.setTarget("generic-vnf.vnf-id");
404         event.setTargetType(ControlLoopTargetType.VNF);
405         event.setClosedLoopAlarmStart(Instant.now());
406         event.setAai(new HashMap<>());
407         if (isEnriched) {
408             event.getAai().put("generic-vnf.is-closed-loop-disabled", "false");
409             event.getAai().put("generic-vnf.prov-status", "ACTIVE");
410             event.getAai().put("generic-vnf.vnf-id", "notused");
411         } else {
412             event.getAai().put("generic-vnf.vnf-id", "getFail");
413         }
414         event.setClosedLoopEventStatus(status);
415         StringBuilder sb = new StringBuilder();
416         sb.append("{ \"Configurations\":[ { \"data\":{ \"FAPService\":"
417                 + " { \"alias\":\"Cell1\", \"CellConfig\":{ \"LTE\":{ \"RAN\":{ \"Common\":"
418                                         + "{ \"CellIdentity\":\"1\" }, \"NeighborListInUse\" : "
419                                         + "{ \"LTECellNumberOfEntries\" : \"1\" , \"LTECell\" : "
420                                         + "[ { \"PLMNID\" :\"plmnid1\", \"CID\":\"Chn0001\", \"PhyCellID\":"
421                                         + "\"3\", \"PNFName\":\"ncserver01\", \"Blacklisted\":\"false\" "
422                                         + "} ] } } } } } } } ] }");
423
424         event.setPayload(sb.toString());
425         logger.debug("\n============ Policy receiving ONSET event !!! ===========\n");
426         logger.debug("\n============ event ===========\n {}", event);
427         kieSession.insert(event);
428     }
429
430     /**
431      * This method will dump all the facts in the working memory.
432      *
433      * @param kieSession
434      *            the session containing the facts
435      */
436     public void dumpFacts(KieSession kieSession) {
437         logger.debug("Fact Count: {}", kieSession.getFactCount());
438         for (FactHandle handle : kieSession.getFactHandles()) {
439             logger.debug("FACT: {}", handle);
440         }
441     }
442
443 }