Fix JUnit Race Conditions
[policy/drools-applications.git] / controlloop / templates / template.demo / src / test / java / org / onap / policy / template / demo / VFCControlLoopTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * demo
4  * ================================================================================
5  * Copyright (C) 2017 Intel Corp. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.template.demo;
22
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertNotNull;
25 import static org.junit.Assert.assertTrue;
26 import static org.junit.Assert.fail;
27
28 import java.io.IOException;
29 import java.net.URLEncoder;
30 import java.time.Instant;
31 import java.util.HashMap;
32 import java.util.UUID;
33
34 import org.junit.AfterClass;
35 import org.junit.BeforeClass;
36 import org.junit.Test;
37 import org.kie.api.runtime.KieSession;
38 import org.kie.api.runtime.rule.FactHandle;
39 import org.onap.policy.controlloop.ControlLoopEventStatus;
40 import org.onap.policy.controlloop.ControlLoopNotificationType;
41 import org.onap.policy.controlloop.ControlLoopTargetType;
42 import org.onap.policy.controlloop.VirtualControlLoopEvent;
43 import org.onap.policy.controlloop.VirtualControlLoopNotification;
44 import org.onap.policy.controlloop.policy.ControlLoopPolicy;
45 import org.onap.policy.drools.PolicyEngineListener;
46 import org.onap.policy.drools.http.server.HttpServletServer;
47 import org.onap.policy.drools.impl.PolicyEngineJUnitImpl;
48 import org.onap.policy.vfc.VFCRequest;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51
52
53 public class VFCControlLoopTest implements PolicyEngineListener {
54
55         private static final Logger logger = LoggerFactory.getLogger(VFCControlLoopTest.class);
56         private KieSession kieSession;
57         private Util.Pair<ControlLoopPolicy, String> pair;
58         private PolicyEngineJUnitImpl engine;
59         private UUID requestID;
60
61         static {
62             /* Set environment properties */
63         Util.setAAIProps();
64         Util.setVFCProps();
65         Util.setGuardProps();
66         Util.setPUProp();
67         }
68         
69         @BeforeClass
70         public static void setUpSimulator() {
71                 try {
72                         Util.buildAaiSim();
73                         Util.buildVfcSim();
74                         Util.buildGuardSim();
75                 } catch (Exception e) {
76                         fail(e.getMessage());
77                 }
78         }
79
80         @AfterClass
81         public static void tearDownSimulator() {
82                 HttpServletServer.factory.destroy();
83         }
84
85         @Test
86         public void successTest() throws IOException {
87
88         /*
89          * Start the kie session
90          */
91         try {
92             kieSession = startSession("src/main/resources/ControlLoop_Template_xacml_guard.drl", 
93                         "src/test/resources/yaml/policy_ControlLoop_VFC.yaml",
94                         "type=operational", 
95                         "CL_VoLTE", 
96                         "v2.0");
97         } catch (IOException e) {
98             e.printStackTrace();
99             logger.debug("Could not create kieSession");
100             fail("Could not create kieSession");
101         }
102         
103         /*
104          * Allows the PolicyEngine to callback to this object to
105          * notify that there is an event ready to be pulled 
106          * from the queue
107          */
108         engine.addListener(this);
109         
110         /*
111          * Create a unique requestId
112          */
113         requestID = UUID.randomUUID();
114         
115         /* 
116          * Simulate an onset event the policy engine will 
117          * receive from DCAE to kick off processing through
118          * the rules
119          */
120         sendEvent(pair.a, requestID, ControlLoopEventStatus.ONSET);
121         
122         kieSession.fireUntilHalt();
123         
124         /*
125          * The only fact in memory should be Params
126          */
127         assertEquals(1, kieSession.getFactCount());
128         
129         /*
130          * Print what's left in memory
131          */
132         dumpFacts(kieSession);
133         
134         /*
135          * Gracefully shut down the kie session
136          */
137         kieSession.dispose();
138         }
139
140         /**
141          * This method will start a kie session and instantiate
142          * the Policy Engine.
143          *
144          * @param droolsTemplate
145          *          the DRL rules file
146          * @param yamlFile
147          *          the yaml file containing the policies
148          * @param policyScope
149          *          scope for policy
150          * @param policyName
151          *          name of the policy
152          * @param policyVersion
153          *          version of the policy
154          * @return the kieSession to be used to insert facts
155          * @throws IOException
156          */
157         private KieSession startSession(String droolsTemplate,
158                                         String yamlFile,
159                                         String policyScope,
160                                         String policyName,
161                                         String policyVersion) throws IOException {
162
163         /*
164          * Load policies from yaml
165          */
166                 pair = Util.loadYaml(yamlFile);
167                 assertNotNull(pair);
168                 assertNotNull(pair.a);
169                 assertNotNull(pair.a.getControlLoop());
170                 assertNotNull(pair.a.getControlLoop().getControlLoopName());
171                 assertTrue(pair.a.getControlLoop().getControlLoopName().length() > 0);
172
173         /*
174          * Construct a kie session
175          */
176                 final KieSession kieSession = Util.buildContainer(droolsTemplate,
177                                 pair.a.getControlLoop().getControlLoopName(),
178                                 policyScope,
179                                 policyName,
180                                 policyVersion,
181                                 URLEncoder.encode(pair.b, "UTF-8"));
182
183         /*
184          * Retrieve the Policy Engine
185          */
186                 engine = (PolicyEngineJUnitImpl) kieSession.getGlobal("Engine");
187
188                 logger.debug("============");
189                 logger.debug(URLEncoder.encode(pair.b, "UTF-8"));
190                 logger.debug("============");
191
192                 return kieSession;
193         }
194         
195         /*
196      * (non-Javadoc)
197      * @see org.onap.policy.drools.PolicyEngineListener#newEventNotification(java.lang.String)
198      */
199         public void newEventNotification(String topic) {
200         /*
201          * Pull the object that was sent out to DMAAP and make
202          * sure it is a ControlLoopNoticiation of type active
203          */
204         Object obj = engine.subscribe("UEB", topic);
205         assertNotNull(obj);
206         if (obj instanceof VirtualControlLoopNotification) {
207             VirtualControlLoopNotification notification = (VirtualControlLoopNotification) obj;
208             String policyName = notification.policyName;
209             if (policyName.endsWith("EVENT")) {
210                 logger.debug("Rule Fired: " + notification.policyName);
211                 assertTrue(ControlLoopNotificationType.ACTIVE.equals(notification.notification));
212             }
213             else if (policyName.endsWith("GUARD_NOT_YET_QUERIED")) {
214                 logger.debug("Rule Fired: " + notification.policyName);
215                 assertTrue(ControlLoopNotificationType.OPERATION.equals(notification.notification));
216                 assertNotNull(notification.message);
217                 assertTrue(notification.message.startsWith("Sending guard query"));
218             }
219             else if (policyName.endsWith("GUARD.RESPONSE")) {
220                 logger.debug("Rule Fired: " + notification.policyName);
221                 assertTrue(ControlLoopNotificationType.OPERATION.equals(notification.notification));
222                 assertNotNull(notification.message);
223                 assertTrue(notification.message.endsWith("PERMIT"));
224             }
225             else if (policyName.endsWith("GUARD_PERMITTED")) {
226                 logger.debug("Rule Fired: " + notification.policyName);
227                 assertTrue(ControlLoopNotificationType.OPERATION.equals(notification.notification));
228                 assertNotNull(notification.message);
229                 assertTrue(notification.message.startsWith("actor=VFC"));
230             }
231             else if (policyName.endsWith("OPERATION.TIMEOUT")) {
232                 logger.debug("Rule Fired: " + notification.policyName);
233                 kieSession.halt();
234                 logger.debug("The operation timed out");
235                 fail("Operation Timed Out");
236             }
237             else if (policyName.endsWith("VFC.RESPONSE")) {
238                 logger.debug("Rule Fired: " + notification.policyName);
239                 assertTrue(ControlLoopNotificationType.OPERATION_SUCCESS.equals(notification.notification));
240                 assertNotNull(notification.message);
241                 assertTrue(notification.message.startsWith("actor=VFC"));
242             }
243             else if (policyName.endsWith("EVENT.MANAGER")) {
244                 logger.debug("Rule Fired: " + notification.policyName);
245                 assertTrue(ControlLoopNotificationType.FINAL_SUCCESS.equals(notification.notification));
246                 kieSession.halt();
247             }
248             else if (policyName.endsWith("EVENT.MANAGER.TIMEOUT")) {
249                 logger.debug("Rule Fired: " + notification.policyName);
250                 kieSession.halt();
251                 logger.debug("The control loop timed out");
252                 fail("Control Loop Timed Out");
253             }
254         }
255         else if (obj instanceof VFCRequest) {
256             logger.debug("\n============ VFC received the request!!! ===========\n");
257         }        
258     }
259         
260         /**
261     * This method is used to simulate event messages from DCAE
262     * that start the control loop (onset message) or end the
263     * control loop (abatement message).
264     * 
265     * @param policy the controlLoopName comes from the policy 
266     * @param requestID the requestId for this event
267     * @param status could be onset or abated
268     */
269    protected void sendEvent(ControlLoopPolicy policy, UUID requestID, ControlLoopEventStatus status) {
270        VirtualControlLoopEvent event = new VirtualControlLoopEvent();
271        event.closedLoopControlName = policy.getControlLoop().getControlLoopName();
272        event.requestID = UUID.randomUUID();
273        event.closedLoopEventClient = "tca.instance00009";
274        event.target_type = ControlLoopTargetType.VM;
275        event.target = "VM_NAME";
276        event.from = "DCAE";
277        event.closedLoopAlarmStart = Instant.now();
278        event.AAI = new HashMap<String, String>();
279        event.AAI.put("vserver.vserver-name", "vserver-name-16102016-aai3255-data-11-1");
280        event.AAI.put("vserver.vserver-id", "vserver-id-16102016-aai3255-data-11-1");
281        event.AAI.put("generic-vnf.vnf-id", "vnf-id-16102016-aai3255-data-11-1");
282        event.AAI.put("service-instance.service-instance-id", "service-instance-id-16102016-aai3255-data-11-1");
283        event.AAI.put("vserver.is-closed-loop-disabled", "false");
284        event.closedLoopEventStatus = ControlLoopEventStatus.ONSET;
285        kieSession.insert(event);
286    }
287    
288    public static void dumpFacts(KieSession kieSession) {
289        logger.debug("Fact Count: " + kieSession.getFactCount());
290        for (FactHandle handle : kieSession.getFactHandles()) {
291            logger.debug("FACT: " + handle);
292        }
293    }
294
295 }
296