5fe2f6222d93f3bbe01330895512e0fef00ae6ea
[policy/drools-applications.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * demo
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
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.assertFalse;
25 import static org.junit.Assert.assertNotNull;
26 import static org.junit.Assert.assertTrue;
27 import static org.junit.Assert.fail;
28
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;
34
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;
56
57
58
59 public class ControlLoopXacmlGuardTest {
60     @BeforeClass
61     public static void setUpSimulator() {
62         try {
63             Util.buildAaiSim();
64         } catch (Exception e) {
65             fail(e.getMessage());
66         }
67     }
68
69     @AfterClass
70     public static void tearDownSimulator() {
71         HttpServletServer.factory.destroy();
72     }
73
74         private static final Logger logger = LoggerFactory.getLogger(ControlLoopXacmlGuardTest.class);
75         private static final String OPSHISTPUPROP = "OperationsHistoryPU";
76         @BeforeClass
77         public static void setPUProp(){
78                 System.setProperty(OPSHISTPUPROP, "TestOperationsHistoryPU");
79                 PolicyEngine.manager.setEnvironmentProperty("guard.url", "http://127.0.0.1:8443/pdp");
80         }
81         @AfterClass
82         public static void restorePUProp(){
83                 System.setProperty(OPSHISTPUPROP, OPSHISTPUPROP);
84         }
85
86
87         @Test
88         public void test() {
89                 try {
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",
93                                         "CL_SERV123_8888",
94                                         "org.onap.closed_loop.Service123:VNFS:0.0.1");
95                 } catch (IOException e) {
96                         e.printStackTrace();
97                         fail(e.getMessage());
98                 }
99         }
100
101         public void runTest(String droolsTemplate,
102                         String yamlFile,
103                         String policyScope,
104                         String policyName,
105                         String policyVersion) throws IOException {
106                 //
107                 // Pull info from the yaml
108                 //
109                 final Util.Pair<ControlLoopPolicy, String> pair = Util.loadYaml(yamlFile);
110                 assertNotNull(pair);
111                 assertNotNull(pair.a);
112                 assertNotNull(pair.a.getControlLoop());
113                 assertNotNull(pair.a.getControlLoop().getControlLoopName());
114                 assertTrue(pair.a.getControlLoop().getControlLoopName().length() > 0);
115                 //
116                 // Build a container
117                 //
118                 final KieSession kieSession = Util.buildContainer(droolsTemplate,
119                                 pair.a.getControlLoop().getControlLoopName(),
120                                 policyScope,
121                                 policyName,
122                                 policyVersion,
123                                 URLEncoder.encode(pair.b, "UTF-8"));
124
125
126
127                 logger.debug("============");
128                 logger.debug(URLEncoder.encode(pair.b, "UTF-8"));
129                 logger.debug("============");
130
131                 final PolicyEngineJUnitImpl engine = (PolicyEngineJUnitImpl) kieSession.getGlobal("Engine");
132
133                 //
134                 // Initial fire of rules
135                 //
136                 kieSession.fireAllRules();
137                 //
138                 // Kick a thread that starts testing
139                 //
140                 new Thread(new Runnable() {
141
142
143                         @Override
144                         public void run() {
145                                 try {
146
147
148                                         //
149                                         // Let's use a unique ID for the request and
150                                         // a unique trigger source.
151                                         //
152                                         UUID requestID = UUID.randomUUID();
153                                         String triggerSourceName = "foobartriggersource36";
154
155                                         Object obj = null;
156
157                                         sendGoodEvents(kieSession, pair.a, requestID, triggerSourceName);
158                                         obj = engine.subscribe("UEB", "POLICY-CL-MGT");
159                                         assertNotNull(obj);
160                                         assertTrue(obj instanceof VirtualControlLoopNotification);
161                                         assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.ACTIVE));
162                                         //
163                                         // Give the control loop a little time to acquire the lock and publish the request
164                                         //
165                                         Thread.sleep(4000);
166
167
168                                         // "About to query Guard" notification (Querying about Restart)
169                                         obj = engine.subscribe("UEB", "POLICY-CL-MGT");
170                                         assertNotNull(obj);
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));
175
176                                         Thread.sleep(2*4000);
177                                         // "Response from Guard" notification
178                                         obj = engine.subscribe("UEB", "POLICY-CL-MGT");
179                                         assertNotNull(obj);
180                                         logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message);
181                                         assertTrue(obj instanceof VirtualControlLoopNotification);
182                                         assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
183
184
185                                         if(true == ((VirtualControlLoopNotification)obj).message.contains("Guard result: Deny")){
186
187                                                 // "About to query Guard" notification (Querying about Rebuild)
188                                                 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
189                                                 assertNotNull(obj);
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));
194
195                                                 Thread.sleep(4000);
196
197                                                 // "Response from Guard" notification
198                                                 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
199                                                 assertNotNull(obj);
200                                                 logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message);
201                                                 assertTrue(obj instanceof VirtualControlLoopNotification);
202                                                 assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
203
204
205                                                 if(true == ((VirtualControlLoopNotification)obj).message.contains("Guard result: Deny")){
206
207                                                         // "About to query Guard" notification (Querying about Migrate)
208                                                         obj = engine.subscribe("UEB", "POLICY-CL-MGT");
209                                                         assertNotNull(obj);
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));
214
215                                                         Thread.sleep(2*4000);
216
217                                                         // "Response from Guard" notification
218                                                         obj = engine.subscribe("UEB", "POLICY-CL-MGT");
219                                                         assertNotNull(obj);
220                                                         logger.debug("Rule: " + ((VirtualControlLoopNotification)obj).policyName +" Message: " + ((VirtualControlLoopNotification)obj).message);
221                                                         assertTrue(obj instanceof VirtualControlLoopNotification);
222                                                         assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
223
224
225                                                         if(true == ((VirtualControlLoopNotification)obj).message.contains("Guard result: Deny")){
226                                                                 //All the 3 operations were Denied by Guard
227                                                                 Thread.sleep(60000);
228
229                                                         }
230                                                 }
231                                         }
232
233                                         //
234                                         // In case one of the operations was permitted by Guard
235                                         //
236                                         if(true == ((VirtualControlLoopNotification)obj).message.contains("Guard result: Permit")){
237                                                 obj = engine.subscribe("UEB", "POLICY-CL-MGT");
238                                                 assertNotNull(obj);
239                                                 logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message);
240                                                 assertTrue(obj instanceof VirtualControlLoopNotification);
241                                                 assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
242
243                                                 Thread.sleep(2*1000);
244
245                                                 obj = engine.subscribe("UEB", "APPC-CL");
246                                                 assertNotNull(obj);
247                                                 assertTrue(obj instanceof LCMRequestWrapper);
248                                                 LCMRequestWrapper dmaapRequest = (LCMRequestWrapper) obj;
249                                                 LCMRequest appcRequest = dmaapRequest.getBody();
250                                                 assertTrue(appcRequest.getCommonHeader().getSubRequestId().equals("1"));
251
252                                                 logger.debug("\n============ APP-C Got request!!! ===========\n");
253                                                 //
254                                                 // Ok - let's simulate ACCEPT
255                                                 //
256
257                                                 //
258                                                 // now wait for it to finish
259                                                 //
260                                                 Thread.sleep(1000);
261
262                                                 //
263                                                 // Now we are going to success it
264                                                 //
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);
271                                                 //
272                                                 // Give it some time to process
273                                                 //
274                                                 Thread.sleep(4000);
275                                                 //
276                                                 // Insert the abatement event
277                                                 //
278                                                 sendAbatement(kieSession, pair.a, requestID, triggerSourceName);
279                                                 //
280                                                 // now wait for it to finish
281                                                 //
282                                                 Thread.sleep(2*15000);
283                                                 //
284                                                 // Ensure they released the lock
285                                                 //
286                                                 assertFalse(PolicyGuard.isLocked(TargetType.VM, triggerSourceName, requestID));
287
288                                         }
289
290
291
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());
296                                         e.printStackTrace();
297                                 } catch (Exception e) {
298                                         logger.error("Test thread got Exception ", e.getLocalizedMessage());
299                                         e.printStackTrace();
300                                 }
301                                 kieSession.halt();
302                         }
303
304                 }).start();
305                 //
306                 // Start firing rules
307                 //
308                 kieSession.fireUntilHalt();
309                 //
310                 // Dump working memory
311                 //
312                 dumpFacts(kieSession);
313                 //
314                 // See if there is anything left in memory
315                 //
316                 assertEquals(1, kieSession.getFactCount());
317
318                 for (FactHandle handle : kieSession.getFactHandles()) {
319                         Object fact = kieSession.getObject(handle);
320                         assertEquals("", "org.onap.policy.controlloop.Params", fact.getClass().getName());
321                 }
322                 kieSession.dispose();
323         }
324
325
326
327
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);
332                 }
333         }
334
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);
349         }
350
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);
364                 Thread.sleep(2000);
365
366         }
367
368         protected void sendBadEvents(KieSession kieSession, ControlLoopPolicy policy, UUID requestID, String triggerSourceName) throws InterruptedException {
369                 //
370                 // Insert a bad Event
371                 //
372                 VirtualControlLoopEvent event = new VirtualControlLoopEvent();
373                 event.closedLoopControlName = policy.getControlLoop().getControlLoopName();
374                 kieSession.insert(event);
375                 Thread.sleep(500);
376                 //
377                 // add the request id
378                 //
379                 event.requestID = requestID;
380                 kieSession.insert(event);
381                 Thread.sleep(500);
382                 //
383                 // add some aai
384                 //
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);
390                 Thread.sleep(500);
391                 //
392                 // set a valid status
393                 //
394                 event.closedLoopEventStatus = ControlLoopEventStatus.ONSET;
395                 kieSession.insert(event);
396                 Thread.sleep(500);
397                 //
398                 // add a trigger sourcename
399                 //
400                 kieSession.insert(event);
401                 Thread.sleep(500);
402                 //
403                 // add is closed-loop-disabled
404                 //
405                 event.AAI.put("vserver.is-closed-loop-disabled", "true");
406                 kieSession.insert(event);
407                 Thread.sleep(500);
408                 //
409                 // now enable
410                 //
411                 event.AAI.put("vserver.is-closed-loop-disabled", "false");
412                 kieSession.insert(event);
413                 Thread.sleep(500);
414                 //
415                 // Add target, but bad.
416                 //
417                 event.target = "VM_BLAH";
418                 kieSession.insert(event);
419                 Thread.sleep(500);
420         }
421 }