a6a4d3fc6df6b82d0b546b10fde079801858870b
[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.assertFalse;
24 import static org.junit.Assert.assertNotNull;
25 import static org.junit.Assert.assertTrue;
26 import static org.junit.Assert.fail;
27
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;
33
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;
55
56
57
58 public class ControlLoopXacmlGuardTest {
59     @BeforeClass
60     public static void setUpSimulator() {
61         try {
62             Util.buildAaiSim();
63             Util.buildGuardSim();
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                 Util.setTestGuardProps();
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-LCM-READ");
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             if (kieSession.getFactCount() != 1L) {
318               logger.error("FACT count mismatch: 1 expected but there are {}", kieSession.getFactCount());
319             }
320
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());
325             }
326                 kieSession.dispose();
327         }
328
329
330
331
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);
336                 }
337         }
338
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);
353         }
354
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);
368                 Thread.sleep(2000);
369
370         }
371
372         protected void sendBadEvents(KieSession kieSession, ControlLoopPolicy policy, UUID requestID, String triggerSourceName) throws InterruptedException {
373                 //
374                 // Insert a bad Event
375                 //
376                 VirtualControlLoopEvent event = new VirtualControlLoopEvent();
377                 event.closedLoopControlName = policy.getControlLoop().getControlLoopName();
378                 kieSession.insert(event);
379                 Thread.sleep(500);
380                 //
381                 // add the request id
382                 //
383                 event.requestID = requestID;
384                 kieSession.insert(event);
385                 Thread.sleep(500);
386                 //
387                 // add some aai
388                 //
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);
394                 Thread.sleep(500);
395                 //
396                 // set a valid status
397                 //
398                 event.closedLoopEventStatus = ControlLoopEventStatus.ONSET;
399                 kieSession.insert(event);
400                 Thread.sleep(500);
401                 //
402                 // add a trigger sourcename
403                 //
404                 kieSession.insert(event);
405                 Thread.sleep(500);
406                 //
407                 // add is closed-loop-disabled
408                 //
409                 event.AAI.put("vserver.is-closed-loop-disabled", "true");
410                 kieSession.insert(event);
411                 Thread.sleep(500);
412                 //
413                 // now enable
414                 //
415                 event.AAI.put("vserver.is-closed-loop-disabled", "false");
416                 kieSession.insert(event);
417                 Thread.sleep(500);
418                 //
419                 // Add target, but bad.
420                 //
421                 event.target = "VM_BLAH";
422                 kieSession.insert(event);
423                 Thread.sleep(500);
424         }
425 }