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