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.system.PolicyEngine;
51 import org.onap.policy.drools.http.server.HttpServletServer;
52 import org.onap.policy.drools.impl.PolicyEngineJUnitImpl;
53 import org.onap.policy.guard.PolicyGuard;
54 import org.slf4j.Logger;
55 import org.slf4j.LoggerFactory;
59 public class ControlLoopXacmlGuardTest {
61 public static void setUpSimulator() {
64 } catch (Exception e) {
70 public static void tearDownSimulator() {
71 HttpServletServer.factory.destroy();
74 private static final Logger logger = LoggerFactory.getLogger(ControlLoopXacmlGuardTest.class);
75 private static final String OPSHISTPUPROP = "OperationsHistoryPU";
77 public static void setPUProp(){
78 System.setProperty(OPSHISTPUPROP, "TestOperationsHistoryPU");
79 PolicyEngine.manager.setEnvironmentProperty("guard.url", "http://127.0.0.1:8443/pdp");
82 public static void restorePUProp(){
83 System.setProperty(OPSHISTPUPROP, OPSHISTPUPROP);
90 this.runTest("src/main/resources/ControlLoop_Template_xacml_guard.drl",
91 "src/test/resources/yaml/policy_ControlLoop_Service123.yaml",
92 "service=Service123;resource=Res123;type=operational",
94 "org.onap.closed_loop.Service123:VNFS:0.0.1");
95 } catch (IOException e) {
101 public void runTest(String droolsTemplate,
105 String policyVersion) throws IOException {
107 // Pull info from the yaml
109 final Util.Pair<ControlLoopPolicy, String> pair = Util.loadYaml(yamlFile);
111 assertNotNull(pair.a);
112 assertNotNull(pair.a.getControlLoop());
113 assertNotNull(pair.a.getControlLoop().getControlLoopName());
114 assertTrue(pair.a.getControlLoop().getControlLoopName().length() > 0);
118 final KieSession kieSession = Util.buildContainer(droolsTemplate,
119 pair.a.getControlLoop().getControlLoopName(),
123 URLEncoder.encode(pair.b, "UTF-8"));
127 logger.debug("============");
128 logger.debug(URLEncoder.encode(pair.b, "UTF-8"));
129 logger.debug("============");
131 final PolicyEngineJUnitImpl engine = (PolicyEngineJUnitImpl) kieSession.getGlobal("Engine");
134 // Initial fire of rules
136 kieSession.fireAllRules();
138 // Kick a thread that starts testing
140 new Thread(new Runnable() {
149 // Let's use a unique ID for the request and
150 // a unique trigger source.
152 UUID requestID = UUID.randomUUID();
153 String triggerSourceName = "foobartriggersource36";
157 sendGoodEvents(kieSession, pair.a, requestID, triggerSourceName);
158 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
160 assertTrue(obj instanceof VirtualControlLoopNotification);
161 assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.ACTIVE));
163 // Give the control loop a little time to acquire the lock and publish the request
168 // "About to query Guard" notification (Querying about Restart)
169 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
171 logger.debug("\n\n####################### GOING TO QUERY GUARD about Restart!!!!!!");
172 logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message);
173 assertTrue(obj instanceof VirtualControlLoopNotification);
174 assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
176 Thread.sleep(2*4000);
177 // "Response from Guard" notification
178 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
180 logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message);
181 assertTrue(obj instanceof VirtualControlLoopNotification);
182 assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
185 if(true == ((VirtualControlLoopNotification)obj).message.contains("Guard result: Deny")){
187 // "About to query Guard" notification (Querying about Rebuild)
188 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
190 logger.debug("\n\n####################### GOING TO QUERY GUARD about Rebuild!!!!!!");
191 logger.debug("Rule: {} Message", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message);
192 assertTrue(obj instanceof VirtualControlLoopNotification);
193 assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
197 // "Response from Guard" notification
198 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
200 logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message);
201 assertTrue(obj instanceof VirtualControlLoopNotification);
202 assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
205 if(true == ((VirtualControlLoopNotification)obj).message.contains("Guard result: Deny")){
207 // "About to query Guard" notification (Querying about Migrate)
208 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
210 logger.debug("\n\n####################### GOING TO QUERY GUARD!!!!!!");
211 logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message);
212 assertTrue(obj instanceof VirtualControlLoopNotification);
213 assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
215 Thread.sleep(2*4000);
217 // "Response from Guard" notification
218 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
220 logger.debug("Rule: " + ((VirtualControlLoopNotification)obj).policyName +" Message: " + ((VirtualControlLoopNotification)obj).message);
221 assertTrue(obj instanceof VirtualControlLoopNotification);
222 assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
225 if(true == ((VirtualControlLoopNotification)obj).message.contains("Guard result: Deny")){
226 //All the 3 operations were Denied by Guard
234 // In case one of the operations was permitted by Guard
236 if(true == ((VirtualControlLoopNotification)obj).message.contains("Guard result: Permit")){
237 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
239 logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message);
240 assertTrue(obj instanceof VirtualControlLoopNotification);
241 assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
243 Thread.sleep(2*1000);
245 obj = engine.subscribe("UEB", "APPC-LCM-READ");
247 assertTrue(obj instanceof LCMRequestWrapper);
248 LCMRequestWrapper dmaapRequest = (LCMRequestWrapper) obj;
249 LCMRequest appcRequest = dmaapRequest.getBody();
250 assertTrue(appcRequest.getCommonHeader().getSubRequestId().equals("1"));
252 logger.debug("\n============ APP-C Got request!!! ===========\n");
254 // Ok - let's simulate ACCEPT
258 // now wait for it to finish
263 // Now we are going to success it
265 LCMResponseWrapper dmaapResponse = new LCMResponseWrapper();
266 LCMResponse appcResponse = new LCMResponse(appcRequest);
267 appcResponse.getStatus().setCode(400);
268 appcResponse.getStatus().setMessage("AppC success");
269 dmaapResponse.setBody(appcResponse);
270 kieSession.insert(dmaapResponse);
272 // Give it some time to process
276 // Insert the abatement event
278 sendAbatement(kieSession, pair.a, requestID, triggerSourceName);
280 // now wait for it to finish
282 Thread.sleep(2*15000);
284 // Ensure they released the lock
286 assertFalse(PolicyGuard.isLocked(TargetType.VM, triggerSourceName, requestID));
292 } catch (InterruptedException e) {
293 logger.error("Test thread got InterruptedException ", e.getLocalizedMessage());
294 } catch (AssertionError e) {
295 logger.error("Test thread got AssertionError ", e.getLocalizedMessage());
297 } catch (Exception e) {
298 logger.error("Test thread got Exception ", e.getLocalizedMessage());
306 // Start firing rules
308 kieSession.fireUntilHalt();
310 // Dump working memory
312 dumpFacts(kieSession);
314 // See if there is anything left in memory
316 assertEquals(1, kieSession.getFactCount());
318 for (FactHandle handle : kieSession.getFactHandles()) {
319 Object fact = kieSession.getObject(handle);
320 assertEquals("", "org.onap.policy.controlloop.Params", fact.getClass().getName());
322 kieSession.dispose();
328 public static void dumpFacts(KieSession kieSession) {
329 logger.debug("Fact Count: {}", kieSession.getFactCount());
330 for (FactHandle handle : kieSession.getFactHandles()) {
331 logger.debug("FACT: {}", handle);
335 protected void sendAbatement(KieSession kieSession, ControlLoopPolicy policy, UUID requestID, String triggerSourceName) throws InterruptedException {
336 VirtualControlLoopEvent event = new VirtualControlLoopEvent();
337 event.closedLoopControlName = policy.getControlLoop().getControlLoopName();
338 event.requestID = requestID;
339 event.target = "vserver.vserver-name";
340 event.closedLoopAlarmStart = Instant.now().minusSeconds(5);
341 event.closedLoopAlarmEnd = Instant.now();
342 event.AAI = new HashMap<>();
343 event.AAI.put("cloud-region.identity-url", "foo");
344 event.AAI.put("vserver.selflink", "bar");
345 event.AAI.put("vserver.is-closed-loop-disabled", "false");
346 event.AAI.put("generic-vnf.vnf-name", "testGenericVnfName");
347 event.closedLoopEventStatus = ControlLoopEventStatus.ABATED;
348 kieSession.insert(event);
351 protected void sendGoodEvents(KieSession kieSession, ControlLoopPolicy policy, UUID requestID, String triggerSourceName) throws InterruptedException {
352 VirtualControlLoopEvent event = new VirtualControlLoopEvent();
353 event.closedLoopControlName = policy.getControlLoop().getControlLoopName();
354 event.requestID = requestID;
355 event.target = "vserver.vserver-name";
356 event.closedLoopAlarmStart = Instant.now();
357 event.AAI = new HashMap<>();
358 event.AAI.put("cloud-region.identity-url", "foo");
359 event.AAI.put("vserver.selflink", "bar");
360 event.AAI.put("vserver.is-closed-loop-disabled", "false");
361 event.AAI.put("vserver.vserver-name", "testGenericVnfName");
362 event.closedLoopEventStatus = ControlLoopEventStatus.ONSET;
363 kieSession.insert(event);
368 protected void sendBadEvents(KieSession kieSession, ControlLoopPolicy policy, UUID requestID, String triggerSourceName) throws InterruptedException {
370 // Insert a bad Event
372 VirtualControlLoopEvent event = new VirtualControlLoopEvent();
373 event.closedLoopControlName = policy.getControlLoop().getControlLoopName();
374 kieSession.insert(event);
377 // add the request id
379 event.requestID = requestID;
380 kieSession.insert(event);
385 event.AAI = new HashMap<>();
386 event.AAI.put("cloud-region.identity-url", "foo");
387 event.AAI.put("vserver.selflink", "bar");
388 event.AAI.put("vserver.vserver-name", "vmfoo");
389 kieSession.insert(event);
392 // set a valid status
394 event.closedLoopEventStatus = ControlLoopEventStatus.ONSET;
395 kieSession.insert(event);
398 // add a trigger sourcename
400 kieSession.insert(event);
403 // add is closed-loop-disabled
405 event.AAI.put("vserver.is-closed-loop-disabled", "true");
406 kieSession.insert(event);
411 event.AAI.put("vserver.is-closed-loop-disabled", "false");
412 kieSession.insert(event);
415 // Add target, but bad.
417 event.target = "VM_BLAH";
418 kieSession.insert(event);