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() {
63 } catch (Exception 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");
78 PolicyEngine.manager.setEnvironmentProperty("guard.url", "http://127.0.0.1:8443/pdp");
81 public static void restorePUProp(){
82 System.setProperty(OPSHISTPUPROP, OPSHISTPUPROP);
89 this.runTest("src/main/resources/ControlLoop_Template_xacml_guard.drl",
90 "src/test/resources/yaml/policy_ControlLoop_Service123.yaml",
91 "service=Service123;resource=Res123;type=operational",
93 "org.onap.closed_loop.Service123:VNFS:0.0.1");
94 } catch (IOException e) {
100 public void runTest(String droolsTemplate,
104 String policyVersion) throws IOException {
106 // Pull info from the yaml
108 final Util.Pair<ControlLoopPolicy, String> pair = Util.loadYaml(yamlFile);
110 assertNotNull(pair.a);
111 assertNotNull(pair.a.getControlLoop());
112 assertNotNull(pair.a.getControlLoop().getControlLoopName());
113 assertTrue(pair.a.getControlLoop().getControlLoopName().length() > 0);
117 final KieSession kieSession = Util.buildContainer(droolsTemplate,
118 pair.a.getControlLoop().getControlLoopName(),
122 URLEncoder.encode(pair.b, "UTF-8"));
126 logger.debug("============");
127 logger.debug(URLEncoder.encode(pair.b, "UTF-8"));
128 logger.debug("============");
130 final PolicyEngineJUnitImpl engine = (PolicyEngineJUnitImpl) kieSession.getGlobal("Engine");
133 // Initial fire of rules
135 kieSession.fireAllRules();
137 // Kick a thread that starts testing
139 new Thread(new Runnable() {
148 // Let's use a unique ID for the request and
149 // a unique trigger source.
151 UUID requestID = UUID.randomUUID();
152 String triggerSourceName = "foobartriggersource36";
156 sendGoodEvents(kieSession, pair.a, requestID, triggerSourceName);
157 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
159 assertTrue(obj instanceof VirtualControlLoopNotification);
160 assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.ACTIVE));
162 // Give the control loop a little time to acquire the lock and publish the request
167 // "About to query Guard" notification (Querying about Restart)
168 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
170 logger.debug("\n\n####################### GOING TO QUERY GUARD about Restart!!!!!!");
171 logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message);
172 assertTrue(obj instanceof VirtualControlLoopNotification);
173 assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
175 Thread.sleep(2*4000);
176 // "Response from Guard" notification
177 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
179 logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message);
180 assertTrue(obj instanceof VirtualControlLoopNotification);
181 assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
184 if(true == ((VirtualControlLoopNotification)obj).message.contains("Guard result: Deny")){
186 // "About to query Guard" notification (Querying about Rebuild)
187 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
189 logger.debug("\n\n####################### GOING TO QUERY GUARD about Rebuild!!!!!!");
190 logger.debug("Rule: {} Message", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message);
191 assertTrue(obj instanceof VirtualControlLoopNotification);
192 assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
196 // "Response from Guard" notification
197 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
199 logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message);
200 assertTrue(obj instanceof VirtualControlLoopNotification);
201 assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
204 if(true == ((VirtualControlLoopNotification)obj).message.contains("Guard result: Deny")){
206 // "About to query Guard" notification (Querying about Migrate)
207 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
209 logger.debug("\n\n####################### GOING TO QUERY GUARD!!!!!!");
210 logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message);
211 assertTrue(obj instanceof VirtualControlLoopNotification);
212 assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
214 Thread.sleep(2*4000);
216 // "Response from Guard" notification
217 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
219 logger.debug("Rule: " + ((VirtualControlLoopNotification)obj).policyName +" Message: " + ((VirtualControlLoopNotification)obj).message);
220 assertTrue(obj instanceof VirtualControlLoopNotification);
221 assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
224 if(true == ((VirtualControlLoopNotification)obj).message.contains("Guard result: Deny")){
225 //All the 3 operations were Denied by Guard
233 // In case one of the operations was permitted by Guard
235 if(true == ((VirtualControlLoopNotification)obj).message.contains("Guard result: Permit")){
236 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
238 logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message);
239 assertTrue(obj instanceof VirtualControlLoopNotification);
240 assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
242 Thread.sleep(2*1000);
244 obj = engine.subscribe("UEB", "APPC-LCM-READ");
246 assertTrue(obj instanceof LCMRequestWrapper);
247 LCMRequestWrapper dmaapRequest = (LCMRequestWrapper) obj;
248 LCMRequest appcRequest = dmaapRequest.getBody();
249 assertTrue(appcRequest.getCommonHeader().getSubRequestId().equals("1"));
251 logger.debug("\n============ APP-C Got request!!! ===========\n");
253 // Ok - let's simulate ACCEPT
257 // now wait for it to finish
262 // Now we are going to success it
264 LCMResponseWrapper dmaapResponse = new LCMResponseWrapper();
265 LCMResponse appcResponse = new LCMResponse(appcRequest);
266 appcResponse.getStatus().setCode(400);
267 appcResponse.getStatus().setMessage("AppC success");
268 dmaapResponse.setBody(appcResponse);
269 kieSession.insert(dmaapResponse);
271 // Give it some time to process
275 // Insert the abatement event
277 sendAbatement(kieSession, pair.a, requestID, triggerSourceName);
279 // now wait for it to finish
281 Thread.sleep(2*15000);
283 // Ensure they released the lock
285 assertFalse(PolicyGuard.isLocked(TargetType.VM, triggerSourceName, requestID));
291 } catch (InterruptedException e) {
292 logger.error("Test thread got InterruptedException ", e.getLocalizedMessage());
293 } catch (AssertionError e) {
294 logger.error("Test thread got AssertionError ", e.getLocalizedMessage());
296 } catch (Exception e) {
297 logger.error("Test thread got Exception ", e.getLocalizedMessage());
305 // Start firing rules
307 kieSession.fireUntilHalt();
309 // Dump working memory
311 dumpFacts(kieSession);
313 // See if there is anything left in memory
315 // assertEquals(1, kieSession.getFactCount());
316 if (kieSession.getFactCount() != 1L) {
317 logger.error("FACT count mismatch: 1 expected but there are {}", kieSession.getFactCount());
320 for (final FactHandle handle : kieSession.getFactHandles()) {
321 final Object fact = kieSession.getObject(handle);
322 // assertEquals("", "org.onap.policy.controlloop.Params", fact.getClass().getName());
323 logger.info("Working Memory FACT: {}", fact.getClass().getName());
325 kieSession.dispose();
331 public static void dumpFacts(KieSession kieSession) {
332 logger.debug("Fact Count: {}", kieSession.getFactCount());
333 for (FactHandle handle : kieSession.getFactHandles()) {
334 logger.debug("FACT: {}", handle);
338 protected void sendAbatement(KieSession kieSession, ControlLoopPolicy policy, UUID requestID, String triggerSourceName) throws InterruptedException {
339 VirtualControlLoopEvent event = new VirtualControlLoopEvent();
340 event.closedLoopControlName = policy.getControlLoop().getControlLoopName();
341 event.requestID = requestID;
342 event.target = "vserver.vserver-name";
343 event.closedLoopAlarmStart = Instant.now().minusSeconds(5);
344 event.closedLoopAlarmEnd = Instant.now();
345 event.AAI = new HashMap<>();
346 event.AAI.put("cloud-region.identity-url", "foo");
347 event.AAI.put("vserver.selflink", "bar");
348 event.AAI.put("vserver.is-closed-loop-disabled", "false");
349 event.AAI.put("generic-vnf.vnf-name", "testGenericVnfName");
350 event.closedLoopEventStatus = ControlLoopEventStatus.ABATED;
351 kieSession.insert(event);
354 protected void sendGoodEvents(KieSession kieSession, ControlLoopPolicy policy, UUID requestID, String triggerSourceName) throws InterruptedException {
355 VirtualControlLoopEvent event = new VirtualControlLoopEvent();
356 event.closedLoopControlName = policy.getControlLoop().getControlLoopName();
357 event.requestID = requestID;
358 event.target = "vserver.vserver-name";
359 event.closedLoopAlarmStart = Instant.now();
360 event.AAI = new HashMap<>();
361 event.AAI.put("cloud-region.identity-url", "foo");
362 event.AAI.put("vserver.selflink", "bar");
363 event.AAI.put("vserver.is-closed-loop-disabled", "false");
364 event.AAI.put("vserver.vserver-name", "testGenericVnfName");
365 event.closedLoopEventStatus = ControlLoopEventStatus.ONSET;
366 kieSession.insert(event);
371 protected void sendBadEvents(KieSession kieSession, ControlLoopPolicy policy, UUID requestID, String triggerSourceName) throws InterruptedException {
373 // Insert a bad Event
375 VirtualControlLoopEvent event = new VirtualControlLoopEvent();
376 event.closedLoopControlName = policy.getControlLoop().getControlLoopName();
377 kieSession.insert(event);
380 // add the request id
382 event.requestID = requestID;
383 kieSession.insert(event);
388 event.AAI = new HashMap<>();
389 event.AAI.put("cloud-region.identity-url", "foo");
390 event.AAI.put("vserver.selflink", "bar");
391 event.AAI.put("vserver.vserver-name", "vmfoo");
392 kieSession.insert(event);
395 // set a valid status
397 event.closedLoopEventStatus = ControlLoopEventStatus.ONSET;
398 kieSession.insert(event);
401 // add a trigger sourcename
403 kieSession.insert(event);
406 // add is closed-loop-disabled
408 event.AAI.put("vserver.is-closed-loop-disabled", "true");
409 kieSession.insert(event);
414 event.AAI.put("vserver.is-closed-loop-disabled", "false");
415 kieSession.insert(event);
418 // Add target, but bad.
420 event.target = "VM_BLAH";
421 kieSession.insert(event);