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