2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. 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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.onap.policy.template.demo;
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertFalse;
25 import static org.junit.Assert.assertNotNull;
26 import static org.junit.Assert.assertTrue;
27 import static org.junit.Assert.fail;
29 import java.io.IOException;
30 import java.net.URLEncoder;
31 import java.time.Instant;
32 import java.util.HashMap;
33 import java.util.UUID;
35 import org.junit.AfterClass;
36 import org.junit.BeforeClass;
37 import org.junit.Test;
38 import org.kie.api.runtime.KieSession;
39 import org.kie.api.runtime.rule.FactHandle;
40 import org.onap.policy.appclcm.LCMRequest;
41 import org.onap.policy.appclcm.LCMRequestWrapper;
42 import org.onap.policy.appclcm.LCMResponse;
43 import org.onap.policy.appclcm.LCMResponseWrapper;
44 import org.onap.policy.controlloop.ControlLoopEventStatus;
45 import org.onap.policy.controlloop.ControlLoopNotificationType;
46 import org.onap.policy.controlloop.VirtualControlLoopEvent;
47 import org.onap.policy.controlloop.VirtualControlLoopNotification;
48 import org.onap.policy.controlloop.policy.ControlLoopPolicy;
49 import org.onap.policy.controlloop.policy.TargetType;
50 import org.onap.policy.drools.http.server.HttpServletServer;
51 import org.onap.policy.drools.impl.PolicyEngineJUnitImpl;
52 import org.onap.policy.guard.PolicyGuard;
53 import org.slf4j.Logger;
54 import org.slf4j.LoggerFactory;
58 public class ControlLoopXacmlGuardTest {
60 public static void setUpSimulator() {
63 } catch (InterruptedException e) {
69 public static void tearDownSimulator() {
70 HttpServletServer.factory.destroy();
73 private static final Logger logger = LoggerFactory.getLogger(ControlLoopXacmlGuardTest.class);
74 private static final String OPSHISTPUPROP = "OperationsHistoryPU";
76 public static void setPUProp(){
77 System.setProperty(OPSHISTPUPROP, "TestOperationsHistoryPU");
80 public static void restorePUProp(){
81 System.setProperty(OPSHISTPUPROP, OPSHISTPUPROP);
88 this.runTest("src/main/resources/ControlLoop_Template_xacml_guard.drl",
89 "src/test/resources/yaml/policy_ControlLoop_Service123.yaml",
90 "service=Service123;resource=Res123;type=operational",
92 "org.onap.closed_loop.Service123:VNFS:0.0.1");
93 } catch (IOException e) {
99 public void runTest(String droolsTemplate,
103 String policyVersion) throws IOException {
105 // Pull info from the yaml
107 final Util.Pair<ControlLoopPolicy, String> pair = Util.loadYaml(yamlFile);
109 assertNotNull(pair.a);
110 assertNotNull(pair.a.getControlLoop());
111 assertNotNull(pair.a.getControlLoop().getControlLoopName());
112 assertTrue(pair.a.getControlLoop().getControlLoopName().length() > 0);
116 final KieSession kieSession = Util.buildContainer(droolsTemplate,
117 pair.a.getControlLoop().getControlLoopName(),
121 URLEncoder.encode(pair.b, "UTF-8"));
125 logger.debug("============");
126 logger.debug(URLEncoder.encode(pair.b, "UTF-8"));
127 logger.debug("============");
129 final PolicyEngineJUnitImpl engine = (PolicyEngineJUnitImpl) kieSession.getGlobal("Engine");
132 // Initial fire of rules
134 kieSession.fireAllRules();
136 // Kick a thread that starts testing
138 new Thread(new Runnable() {
147 // Let's use a unique ID for the request and
148 // a unique trigger source.
150 UUID requestID = UUID.randomUUID();
151 String triggerSourceName = "foobartriggersource36";
155 sendGoodEvents(kieSession, pair.a, requestID, triggerSourceName);
156 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
158 assertTrue(obj instanceof VirtualControlLoopNotification);
159 assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.ACTIVE));
161 // Give the control loop a little time to acquire the lock and publish the request
166 // "About to query Guard" notification (Querying about Restart)
167 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
169 logger.debug("\n\n####################### GOING TO QUERY GUARD about Restart!!!!!!");
170 logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message);
171 assertTrue(obj instanceof VirtualControlLoopNotification);
172 assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
175 // "Response from Guard" notification
176 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
178 logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message);
179 assertTrue(obj instanceof VirtualControlLoopNotification);
180 assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
183 if(true == ((VirtualControlLoopNotification)obj).message.contains("Guard result: Deny")){
185 // "About to query Guard" notification (Querying about Rebuild)
186 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
188 logger.debug("\n\n####################### GOING TO QUERY GUARD about Rebuild!!!!!!");
189 logger.debug("Rule: {} Message", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message);
190 assertTrue(obj instanceof VirtualControlLoopNotification);
191 assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
195 // "Response from Guard" notification
196 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
198 logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message);
199 assertTrue(obj instanceof VirtualControlLoopNotification);
200 assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
203 if(true == ((VirtualControlLoopNotification)obj).message.contains("Guard result: Deny")){
205 // "About to query Guard" notification (Querying about Migrate)
206 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
208 logger.debug("\n\n####################### GOING TO QUERY GUARD!!!!!!");
209 logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message);
210 assertTrue(obj instanceof VirtualControlLoopNotification);
211 assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
215 // "Response from Guard" notification
216 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
218 logger.debug("Rule: " + ((VirtualControlLoopNotification)obj).policyName +" Message: " + ((VirtualControlLoopNotification)obj).message);
219 assertTrue(obj instanceof VirtualControlLoopNotification);
220 assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
223 if(true == ((VirtualControlLoopNotification)obj).message.contains("Guard result: Deny")){
224 //All the 3 operations were Denied by Guard
232 // In case one of the operations was permitted by Guard
234 if(true == ((VirtualControlLoopNotification)obj).message.contains("Guard result: Permit")){
235 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
237 logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message);
238 assertTrue(obj instanceof VirtualControlLoopNotification);
239 assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
243 obj = engine.subscribe("UEB", "APPC-CL");
245 assertTrue(obj instanceof LCMRequestWrapper);
246 LCMRequestWrapper dmaapRequest = (LCMRequestWrapper) obj;
247 LCMRequest appcRequest = dmaapRequest.getBody();
248 assertTrue(appcRequest.getCommonHeader().getSubRequestId().equals("1"));
250 logger.debug("\n============ APP-C Got request!!! ===========\n");
252 // Ok - let's simulate ACCEPT
256 // now wait for it to finish
261 // Now we are going to success it
263 LCMResponseWrapper dmaapResponse = new LCMResponseWrapper();
264 LCMResponse appcResponse = new LCMResponse(appcRequest);
265 appcResponse.getStatus().setCode(400);
266 appcResponse.getStatus().setMessage("AppC success");
267 dmaapResponse.setBody(appcResponse);
268 kieSession.insert(dmaapResponse);
270 // Give it some time to process
274 // Insert the abatement event
276 sendAbatement(kieSession, pair.a, requestID, triggerSourceName);
278 // now wait for it to finish
282 // Ensure they released the lock
284 assertFalse(PolicyGuard.isLocked(TargetType.VM, triggerSourceName, requestID));
290 } catch (InterruptedException e) {
291 logger.error("Test thread got InterruptedException ", e.getLocalizedMessage());
292 } catch (AssertionError e) {
293 logger.error("Test thread got AssertionError ", e.getLocalizedMessage());
295 } catch (Exception e) {
296 logger.error("Test thread got Exception ", e.getLocalizedMessage());
304 // Start firing rules
306 kieSession.fireUntilHalt();
308 // Dump working memory
310 dumpFacts(kieSession);
312 // See if there is anything left in memory
314 assertEquals(1, kieSession.getFactCount());
316 for (FactHandle handle : kieSession.getFactHandles()) {
317 Object fact = kieSession.getObject(handle);
318 assertEquals("", "org.onap.policy.controlloop.Params", fact.getClass().getName());
320 kieSession.dispose();
326 public static void dumpFacts(KieSession kieSession) {
327 logger.debug("Fact Count: {}", kieSession.getFactCount());
328 for (FactHandle handle : kieSession.getFactHandles()) {
329 logger.debug("FACT: {}", handle);
333 protected void sendAbatement(KieSession kieSession, ControlLoopPolicy policy, UUID requestID, String triggerSourceName) throws InterruptedException {
334 VirtualControlLoopEvent event = new VirtualControlLoopEvent();
335 event.closedLoopControlName = policy.getControlLoop().getControlLoopName();
336 event.requestID = requestID;
337 event.target = "vserver.vserver-name";
338 event.closedLoopAlarmStart = Instant.now().minusSeconds(5);
339 event.closedLoopAlarmEnd = Instant.now();
340 event.AAI = new HashMap<>();
341 event.AAI.put("cloud-region.identity-url", "foo");
342 event.AAI.put("vserver.selflink", "bar");
343 event.AAI.put("vserver.is-closed-loop-disabled", "false");
344 event.AAI.put("generic-vnf.vnf-name", "testGenericVnfName");
345 event.closedLoopEventStatus = ControlLoopEventStatus.ABATED;
346 kieSession.insert(event);
349 protected void sendGoodEvents(KieSession kieSession, ControlLoopPolicy policy, UUID requestID, String triggerSourceName) throws InterruptedException {
350 VirtualControlLoopEvent event = new VirtualControlLoopEvent();
351 event.closedLoopControlName = policy.getControlLoop().getControlLoopName();
352 event.requestID = requestID;
353 event.target = "vserver.vserver-name";
354 event.closedLoopAlarmStart = Instant.now();
355 event.AAI = new HashMap<>();
356 event.AAI.put("cloud-region.identity-url", "foo");
357 event.AAI.put("vserver.selflink", "bar");
358 event.AAI.put("vserver.is-closed-loop-disabled", "false");
359 event.AAI.put("vserver.vserver-name", "testGenericVnfName");
360 event.closedLoopEventStatus = ControlLoopEventStatus.ONSET;
361 kieSession.insert(event);
366 protected void sendBadEvents(KieSession kieSession, ControlLoopPolicy policy, UUID requestID, String triggerSourceName) throws InterruptedException {
368 // Insert a bad Event
370 VirtualControlLoopEvent event = new VirtualControlLoopEvent();
371 event.closedLoopControlName = policy.getControlLoop().getControlLoopName();
372 kieSession.insert(event);
375 // add the request id
377 event.requestID = requestID;
378 kieSession.insert(event);
383 event.AAI = new HashMap<>();
384 event.AAI.put("cloud-region.identity-url", "foo");
385 event.AAI.put("vserver.selflink", "bar");
386 event.AAI.put("vserver.vserver-name", "vmfoo");
387 kieSession.insert(event);
390 // set a valid status
392 event.closedLoopEventStatus = ControlLoopEventStatus.ONSET;
393 kieSession.insert(event);
396 // add a trigger sourcename
398 kieSession.insert(event);
401 // add is closed-loop-disabled
403 event.AAI.put("vserver.is-closed-loop-disabled", "true");
404 kieSession.insert(event);
409 event.AAI.put("vserver.is-closed-loop-disabled", "false");
410 kieSession.insert(event);
413 // Add target, but bad.
415 event.target = "VM_BLAH";
416 kieSession.insert(event);