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