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.assertFalse;
24 import static org.junit.Assert.assertNotNull;
25 import static org.junit.Assert.assertTrue;
26 import static org.junit.Assert.fail;
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;
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.appclcm.LCMRequest;
40 import org.onap.policy.appclcm.LCMRequestWrapper;
41 import org.onap.policy.appclcm.LCMResponse;
42 import org.onap.policy.appclcm.LCMResponseWrapper;
43 import org.onap.policy.controlloop.ControlLoopEventStatus;
44 import org.onap.policy.controlloop.ControlLoopNotificationType;
45 import org.onap.policy.controlloop.VirtualControlLoopEvent;
46 import org.onap.policy.controlloop.VirtualControlLoopNotification;
47 import org.onap.policy.controlloop.policy.ControlLoopPolicy;
48 import org.onap.policy.controlloop.policy.TargetType;
49 import org.onap.policy.drools.http.server.HttpServletServer;
50 import org.onap.policy.drools.impl.PolicyEngineJUnitImpl;
51 import org.onap.policy.drools.system.PolicyEngine;
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() {
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 Util.setTestGuardProps();
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());
317 if (kieSession.getFactCount() != 1L) {
318 logger.error("FACT count mismatch: 1 expected but there are {}", kieSession.getFactCount());
321 for (final FactHandle handle : kieSession.getFactHandles()) {
322 final Object fact = kieSession.getObject(handle);
323 // assertEquals("", "org.onap.policy.controlloop.Params", fact.getClass().getName());
324 logger.info("Working Memory FACT: {}", fact.getClass().getName());
326 kieSession.dispose();
332 public static void dumpFacts(KieSession kieSession) {
333 logger.debug("Fact Count: {}", kieSession.getFactCount());
334 for (FactHandle handle : kieSession.getFactHandles()) {
335 logger.debug("FACT: {}", handle);
339 protected void sendAbatement(KieSession kieSession, ControlLoopPolicy policy, UUID requestID, String triggerSourceName) throws InterruptedException {
340 VirtualControlLoopEvent event = new VirtualControlLoopEvent();
341 event.closedLoopControlName = policy.getControlLoop().getControlLoopName();
342 event.requestID = requestID;
343 event.target = "vserver.vserver-name";
344 event.closedLoopAlarmStart = Instant.now().minusSeconds(5);
345 event.closedLoopAlarmEnd = Instant.now();
346 event.AAI = new HashMap<>();
347 event.AAI.put("cloud-region.identity-url", "foo");
348 event.AAI.put("vserver.selflink", "bar");
349 event.AAI.put("vserver.is-closed-loop-disabled", "false");
350 event.AAI.put("generic-vnf.vnf-name", "testGenericVnfName");
351 event.closedLoopEventStatus = ControlLoopEventStatus.ABATED;
352 kieSession.insert(event);
355 protected void sendGoodEvents(KieSession kieSession, ControlLoopPolicy policy, UUID requestID, String triggerSourceName) throws InterruptedException {
356 VirtualControlLoopEvent event = new VirtualControlLoopEvent();
357 event.closedLoopControlName = policy.getControlLoop().getControlLoopName();
358 event.requestID = requestID;
359 event.target = "vserver.vserver-name";
360 event.closedLoopAlarmStart = Instant.now();
361 event.AAI = new HashMap<>();
362 event.AAI.put("cloud-region.identity-url", "foo");
363 event.AAI.put("vserver.selflink", "bar");
364 event.AAI.put("vserver.is-closed-loop-disabled", "false");
365 event.AAI.put("vserver.vserver-name", "testGenericVnfName");
366 event.closedLoopEventStatus = ControlLoopEventStatus.ONSET;
367 kieSession.insert(event);
372 protected void sendBadEvents(KieSession kieSession, ControlLoopPolicy policy, UUID requestID, String triggerSourceName) throws InterruptedException {
374 // Insert a bad Event
376 VirtualControlLoopEvent event = new VirtualControlLoopEvent();
377 event.closedLoopControlName = policy.getControlLoop().getControlLoopName();
378 kieSession.insert(event);
381 // add the request id
383 event.requestID = requestID;
384 kieSession.insert(event);
389 event.AAI = new HashMap<>();
390 event.AAI.put("cloud-region.identity-url", "foo");
391 event.AAI.put("vserver.selflink", "bar");
392 event.AAI.put("vserver.vserver-name", "vmfoo");
393 kieSession.insert(event);
396 // set a valid status
398 event.closedLoopEventStatus = ControlLoopEventStatus.ONSET;
399 kieSession.insert(event);
402 // add a trigger sourcename
404 kieSession.insert(event);
407 // add is closed-loop-disabled
409 event.AAI.put("vserver.is-closed-loop-disabled", "true");
410 kieSession.insert(event);
415 event.AAI.put("vserver.is-closed-loop-disabled", "false");
416 kieSession.insert(event);
419 // Add target, but bad.
421 event.target = "VM_BLAH";
422 kieSession.insert(event);