266ad1ac9c3dc8e584dd164ee2d122af83d50ff6
[policy/drools-applications.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP
4  * ================================================================================
5  * Copyright (C) 2017-2020 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.controlloop.eventmanager;
22
23 import static org.assertj.core.api.Assertions.assertThatThrownBy;
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertFalse;
26 import static org.junit.Assert.assertNotNull;
27 import static org.junit.Assert.assertNull;
28 import static org.junit.Assert.assertSame;
29 import static org.junit.Assert.assertTrue;
30 import static org.mockito.Matchers.any;
31 import static org.mockito.Mockito.mock;
32 import static org.mockito.Mockito.never;
33 import static org.mockito.Mockito.verify;
34 import static org.mockito.Mockito.when;
35
36 import java.io.File;
37 import java.io.FileInputStream;
38 import java.io.IOException;
39 import java.io.InputStream;
40 import java.io.Serializable;
41 import java.nio.charset.StandardCharsets;
42 import java.nio.file.Files;
43 import java.nio.file.Paths;
44 import java.time.Instant;
45 import java.util.HashMap;
46 import java.util.Map;
47 import java.util.UUID;
48 import org.apache.commons.io.IOUtils;
49 import org.jetbrains.annotations.NotNull;
50 import org.junit.AfterClass;
51 import org.junit.Before;
52 import org.junit.BeforeClass;
53 import org.junit.Rule;
54 import org.junit.Test;
55 import org.junit.rules.ExpectedException;
56 import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInstance;
57 import org.onap.policy.common.utils.coder.CoderException;
58 import org.onap.policy.common.utils.coder.StandardCoder;
59 import org.onap.policy.common.utils.io.Serializer;
60 import org.onap.policy.controlloop.ControlLoopEventStatus;
61 import org.onap.policy.controlloop.ControlLoopException;
62 import org.onap.policy.controlloop.ControlLoopNotificationType;
63 import org.onap.policy.controlloop.ControlLoopTargetType;
64 import org.onap.policy.controlloop.VirtualControlLoopEvent;
65 import org.onap.policy.controlloop.VirtualControlLoopNotification;
66 import org.onap.policy.controlloop.eventmanager.ControlLoopEventManager.NewEventStatus;
67 import org.onap.policy.controlloop.policy.PolicyResult;
68 import org.onap.policy.drools.core.lock.Lock;
69 import org.onap.policy.drools.core.lock.LockCallback;
70 import org.onap.policy.drools.system.PolicyEngineConstants;
71 import org.onap.policy.drools.utils.Pair;
72 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
73 import org.powermock.reflect.Whitebox;
74
75 public class ControlLoopEventManagerTest {
76     private static final String TARGET_LOCK_FIELD = "targetLock";
77     private static final String ONSET_ONE = "onsetOne";
78     private static final String VSERVER_NAME = "vserver.vserver-name";
79     private static final String TEST_YAML = "src/test/resources/test.yaml";
80     private static final String VNF_NAME = "generic-vnf.vnf-name";
81     private static final String VNF_ID = "generic-vnf.vnf-id";
82     private static final String AAI_USERNAME = "aai.username";
83     private static final String AAI_URL = "aai.url";
84     private static final String AAI_PASS = "aai.password";
85     private static final String TWO_ONSET_TEST = "TwoOnsetTest";
86     private static final String VNF_UUID = "83f674e8-7555-44d7-9a39-bdc3770b0491";
87
88
89     @Rule
90     public ExpectedException thrown = ExpectedException.none();
91
92     private VirtualControlLoopEvent onset;
93     private LockCallback callback;
94
95     /**
96      * Set up test class.
97      */
98     @BeforeClass
99     public static void setUpSimulator() throws Exception {
100         org.onap.policy.simulators.Util.buildAaiSim();
101
102         PolicyEngineConstants.getManager().setEnvironmentProperty(AAI_USERNAME, "AAI");
103         PolicyEngineConstants.getManager().setEnvironmentProperty(AAI_PASS, "AAI");
104         PolicyEngineConstants.getManager().setEnvironmentProperty(AAI_URL, "http://localhost:6666");
105         PolicyEngineConstants.getManager().setEnvironmentProperty("aai.customQuery", "false");
106     }
107
108     @AfterClass
109     public static void tearDownSimulator() {
110         HttpServletServerFactoryInstance.getServerFactory().destroy();
111     }
112
113     /**
114      * Setup.
115      */
116     @Before
117     public void setUp() {
118         callback = mock(LockCallback.class);
119
120         onset = new VirtualControlLoopEvent();
121         onset.setClosedLoopControlName("ControlLoop-vUSP");
122         onset.setRequestId(UUID.randomUUID());
123         onset.setTarget("VM_NAME");
124         onset.setClosedLoopAlarmStart(Instant.now());
125         onset.setAai(new HashMap<>());
126         onset.getAai().put("cloud-region.identity-url", "foo");
127         onset.getAai().put("vserver.selflink", "bar");
128         onset.getAai().put(VNF_ID, VNF_UUID);
129         onset.setClosedLoopEventStatus(ControlLoopEventStatus.ONSET);
130         onset.setTargetType(ControlLoopTargetType.VNF);
131
132         PolicyEngineConstants.getManager().setEnvironmentProperty(AAI_URL, "http://localhost:6666");
133     }
134
135     @Test
136     public void testMethods() {
137         UUID requestId = UUID.randomUUID();
138         ControlLoopEventManager clem = new ControlLoopEventManager("MyClosedLoopName", requestId);
139
140         assertEquals("MyClosedLoopName", clem.getClosedLoopControlName());
141         assertEquals(requestId, clem.getRequestId());
142
143         clem.setActivated(true);
144         assertEquals(true, clem.isActivated());
145
146         clem.setControlLoopResult("SUCCESS");
147         assertEquals("SUCCESS", clem.getControlLoopResult());
148
149         clem.setControlLoopTimedOut();
150         assertEquals(true, clem.isControlLoopTimedOut());
151
152         clem.setNumAbatements(12345);
153         assertEquals(Integer.valueOf(12345), clem.getNumAbatements());
154
155         clem.setNumOnsets(54321);
156         assertEquals(Integer.valueOf(54321), clem.getNumOnsets());
157
158         assertNull(clem.getOnsetEvent());
159         assertNull(clem.getAbatementEvent());
160         assertNull(clem.getProcessor());
161
162         assertEquals(true, clem.isControlLoopTimedOut());
163
164         assertNull(clem.unlockCurrentOperation());
165     }
166
167     @Test
168     public void testAlreadyActivated() {
169         VirtualControlLoopEvent event = getOnsetEvent();
170
171         ControlLoopEventManager manager = makeManager(event);
172         manager.setActivated(true);
173         VirtualControlLoopNotification notification = manager.activate(event);
174         assertEquals(ControlLoopNotificationType.REJECTED, notification.getNotification());
175     }
176
177     @Test
178     public void testActivationYaml() throws IOException, CoderException {
179
180         VirtualControlLoopEvent event = getOnsetEvent();
181         ControlLoopEventManager manager = makeManager(event);
182
183         // Null YAML should fail
184         VirtualControlLoopNotification notificationNull = manager.activate((String) null, event);
185         assertNotNull(notificationNull);
186         assertEquals(ControlLoopNotificationType.REJECTED, notificationNull.getNotification());
187
188         // Empty YAML should fail
189         VirtualControlLoopNotification notificationEmpty = manager.activate("", event);
190         assertNotNull(notificationEmpty);
191         assertEquals(ControlLoopNotificationType.REJECTED, notificationEmpty.getNotification());
192
193         // Bad YAML should fail
194         InputStream isBad = new FileInputStream(new File("src/test/resources/notutf8.yaml"));
195         final String yamlStringBad = IOUtils.toString(isBad, StandardCharsets.UTF_8);
196
197         VirtualControlLoopNotification notificationBad = manager.activate(yamlStringBad, event);
198         assertNotNull(notificationBad);
199         assertEquals(ControlLoopNotificationType.REJECTED, notificationBad.getNotification());
200
201
202         InputStream is = new FileInputStream(new File(TEST_YAML));
203         final String yamlString = IOUtils.toString(is, StandardCharsets.UTF_8);
204
205         VirtualControlLoopNotification notification = manager.activate(yamlString, event);
206         assertNotNull(notification);
207         assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification());
208
209         // Another activate should fail
210         VirtualControlLoopNotification notificationActive = manager.activate(yamlString, event);
211         assertNotNull(notificationActive);
212         assertEquals(ControlLoopNotificationType.REJECTED, notificationActive.getNotification());
213     }
214
215     @Test
216     public void testActivateToscaLegacy() throws IOException, CoderException {
217         String policy =
218                 new String(Files.readAllBytes(Paths.get("src/test/resources/tosca-policy-legacy-vcpe.json")));
219         ToscaPolicy toscaPolicy = new StandardCoder().decode(policy, ToscaPolicy.class);
220
221         VirtualControlLoopEvent event = getOnsetEvent();
222         ControlLoopEventManager manager = makeManager(event);
223
224         // trigger a reject by passing the wrong policy type
225         toscaPolicy.setType("onap.policies.controlloop.operational.common.Drools");
226         VirtualControlLoopNotification notification = manager.activate(toscaPolicy, event);
227         assertEquals(ControlLoopNotificationType.REJECTED, notification.getNotification());
228
229         // place back correct policy type
230         toscaPolicy.setType("onap.policies.controlloop.Operational");
231         notification = manager.activate(toscaPolicy, event);
232         assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification());
233
234         // another activate should fail
235         notification = manager.activate(toscaPolicy, event);
236         assertEquals(ControlLoopNotificationType.REJECTED, notification.getNotification());
237     }
238
239     @Test
240     public void testControlLoopFinal() throws Exception {
241         VirtualControlLoopEvent event = getOnsetEvent();
242
243         ControlLoopEventManager manager = makeManager(event);
244         ControlLoopEventManager manager2 = manager;
245         assertThatThrownBy(manager2::isControlLoopFinal).isInstanceOf(ControlLoopException.class)
246                         .hasMessage("ControlLoopEventManager MUST be activated first.");
247
248         manager.setActivated(true);
249         assertThatThrownBy(manager2::isControlLoopFinal).isInstanceOf(ControlLoopException.class)
250                         .hasMessage("No onset event for ControlLoopEventManager.");
251
252         manager.setActivated(false);
253
254         InputStream is = new FileInputStream(new File(TEST_YAML));
255         final String yamlString = IOUtils.toString(is, StandardCharsets.UTF_8);
256
257         VirtualControlLoopNotification notification = manager.activate(yamlString, event);
258         assertNotNull(notification);
259         assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification());
260
261         VirtualControlLoopNotification clfNotification = manager.isControlLoopFinal();
262         assertNull(clfNotification);
263
264         // serialize and de-serialize manager
265         manager = Serializer.roundTrip(manager);
266
267         manager.getProcessor().nextPolicyForResult(PolicyResult.SUCCESS);
268         clfNotification = manager.isControlLoopFinal();
269         assertNotNull(clfNotification);
270         assertEquals(ControlLoopNotificationType.FINAL_SUCCESS, clfNotification.getNotification());
271
272         manager = new ControlLoopEventManager(event.getClosedLoopControlName(), event.getRequestId());
273         notification = manager.activate(yamlString, event);
274         assertNotNull(notification);
275         assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification());
276
277         manager.getProcessor().nextPolicyForResult(PolicyResult.FAILURE_EXCEPTION);
278         clfNotification = manager.isControlLoopFinal();
279         assertNotNull(clfNotification);
280         assertEquals(ControlLoopNotificationType.FINAL_FAILURE, clfNotification.getNotification());
281
282         manager = new ControlLoopEventManager(event.getClosedLoopControlName(), event.getRequestId());
283         notification = manager.activate(yamlString, event);
284         assertNotNull(notification);
285         assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification());
286
287         manager.getProcessor().nextPolicyForResult(PolicyResult.FAILURE_GUARD);
288         clfNotification = manager.isControlLoopFinal();
289         assertNotNull(clfNotification);
290         assertEquals(ControlLoopNotificationType.FINAL_FAILURE, clfNotification.getNotification());
291
292         manager.setControlLoopTimedOut();
293         clfNotification = manager.isControlLoopFinal();
294         assertNotNull(clfNotification);
295         assertEquals(ControlLoopNotificationType.FINAL_FAILURE, clfNotification.getNotification());
296     }
297
298     @NotNull
299     private VirtualControlLoopEvent getOnsetEvent() {
300         UUID requestId = UUID.randomUUID();
301         VirtualControlLoopEvent event = new VirtualControlLoopEvent();
302         event.setClosedLoopControlName(TWO_ONSET_TEST);
303         event.setRequestId(requestId);
304         event.setTarget(VNF_ID);
305         event.setClosedLoopAlarmStart(Instant.now());
306         event.setClosedLoopEventStatus(ControlLoopEventStatus.ONSET);
307         event.setAai(new HashMap<>());
308         event.getAai().put(VNF_NAME, ONSET_ONE);
309         event.setTargetType(ControlLoopTargetType.VNF);
310         return event;
311     }
312
313     @Test
314     public void testProcessControlLoop() throws Exception {
315         UUID requestId = UUID.randomUUID();
316         VirtualControlLoopEvent event = new VirtualControlLoopEvent();
317         event.setClosedLoopControlName(TWO_ONSET_TEST);
318         event.setRequestId(requestId);
319         event.setTarget(VNF_ID);
320         event.setClosedLoopAlarmStart(Instant.now());
321         event.setClosedLoopEventStatus(ControlLoopEventStatus.ONSET);
322         event.setAai(new HashMap<>());
323         event.getAai().put(VNF_NAME, ONSET_ONE);
324         event.getAai().put(VSERVER_NAME, "testVserverName");
325         event.setTargetType(ControlLoopTargetType.VNF);
326
327         ControlLoopEventManager manager = makeManager(event);
328         ControlLoopEventManager manager2 = manager;
329         assertThatThrownBy(manager2::processControlLoop).isInstanceOf(ControlLoopException.class)
330                         .hasMessage("ControlLoopEventManager MUST be activated first.");
331
332         manager.setActivated(true);
333         assertThatThrownBy(manager2::processControlLoop).isInstanceOf(ControlLoopException.class)
334                         .hasMessage("No onset event for ControlLoopEventManager.");
335
336         manager.setActivated(false);
337
338         InputStream is = new FileInputStream(new File(TEST_YAML));
339         final String yamlString = IOUtils.toString(is, StandardCharsets.UTF_8);
340
341         VirtualControlLoopNotification notification = manager.activate(yamlString, event);
342         assertNotNull(notification);
343         assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification());
344
345         ControlLoopOperationManager clom = manager.processControlLoop();
346         assertNotNull(clom);
347         assertNull(clom.getOperationResult());
348
349         // serialize and de-serialize manager
350         manager = Serializer.roundTrip(manager);
351
352         // Test operation in progress
353         ControlLoopEventManager manager3 = manager;
354         assertThatThrownBy(manager3::processControlLoop).isInstanceOf(ControlLoopException.class)
355                         .hasMessage("Already working an Operation, do not call this method.");
356
357         manager = new ControlLoopEventManager(event.getClosedLoopControlName(), event.getRequestId());
358         notification = manager.activate(yamlString, event);
359         assertNotNull(notification);
360         assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification());
361
362         manager.getProcessor().nextPolicyForResult(PolicyResult.FAILURE_GUARD);
363         VirtualControlLoopNotification clfNotification = manager.isControlLoopFinal();
364         assertNotNull(clfNotification);
365         assertEquals(ControlLoopNotificationType.FINAL_FAILURE, clfNotification.getNotification());
366
367         // Test operation completed
368         ControlLoopEventManager manager4 = manager;
369         assertThatThrownBy(manager4::processControlLoop).isInstanceOf(ControlLoopException.class)
370                         .hasMessage("Control Loop is in FINAL state, do not call this method.");
371
372         manager = new ControlLoopEventManager(event.getClosedLoopControlName(), event.getRequestId());
373         notification = manager.activate(yamlString, event);
374         assertNotNull(notification);
375         assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification());
376         manager.getProcessor().nextPolicyForResult(PolicyResult.FAILURE);
377
378         // Test operation with no next policy defined
379         ControlLoopEventManager manager5 = manager;
380         assertThatThrownBy(manager5::processControlLoop).isInstanceOf(ControlLoopException.class)
381                         .hasMessage("The target type is null");
382     }
383
384     @Test
385     public void testFinishOperation() throws Exception {
386         InputStream isStd = new FileInputStream(new File(TEST_YAML));
387         final String yamlStringStd = IOUtils.toString(isStd, StandardCharsets.UTF_8);
388
389         VirtualControlLoopEvent event = makeEvent();
390
391         ControlLoopEventManager manager = makeManager(event);
392         ControlLoopEventManager manager2 = manager;
393         assertThatThrownBy(() -> manager2.finishOperation(null)).isInstanceOf(ControlLoopException.class)
394                         .hasMessage("No operation to finish.");
395
396         manager.setActivated(true);
397         assertThatThrownBy(() -> manager2.finishOperation(null)).isInstanceOf(ControlLoopException.class)
398                         .hasMessage("No operation to finish.");
399
400         manager.setActivated(false);
401
402         InputStream is = new FileInputStream(new File("src/test/resources/testSOactor.yaml"));
403         final String yamlString = IOUtils.toString(is, StandardCharsets.UTF_8);
404
405         VirtualControlLoopNotification notification = manager.activate(yamlString, event);
406         assertNotNull(notification);
407         assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification());
408         
409         event.getAai().put(VSERVER_NAME, "testVserverName");
410
411         // serialize and de-serialize manager
412         manager = Serializer.roundTrip(manager);
413
414         ControlLoopOperationManager clom = manager.processControlLoop();
415         assertNotNull(clom);
416         assertNull(clom.getOperationResult());
417
418         clom.startOperation(event);
419
420         // This call should be exception free
421         manager.finishOperation(clom);
422
423         ControlLoopEventManager otherManager = makeManager(event);
424         VirtualControlLoopNotification otherNotification = otherManager.activate(yamlStringStd, event);
425         assertNotNull(otherNotification);
426         assertEquals(ControlLoopNotificationType.ACTIVE, otherNotification.getNotification());
427
428         ControlLoopOperationManager otherClom = otherManager.processControlLoop();
429         assertNotNull(otherClom);
430         assertNull(otherClom.getOperationResult());
431
432         otherManager.finishOperation(clom);
433     }
434
435     @Test
436     public void testLockCurrentOperation_testUnlockCurrentOperation() throws Exception {
437         VirtualControlLoopEvent event = makeEvent();
438
439         ControlLoopEventManager manager = makeManager(event);
440
441         manager.setActivated(false);
442
443         InputStream is = new FileInputStream(new File("src/test/resources/testSOactor.yaml"));
444         final String yamlString = IOUtils.toString(is, StandardCharsets.UTF_8);
445
446         VirtualControlLoopNotification notification = manager.activate(yamlString, event);
447         assertNotNull(notification);
448         assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification());
449
450         ControlLoopEventManager manager2 = manager;
451         assertThatThrownBy(() -> manager2.lockCurrentOperation(callback)).isInstanceOf(ControlLoopException.class)
452                         .hasMessage("Do not have a current operation.");
453
454         assertNull(manager.unlockCurrentOperation());
455         
456         event.getAai().put(VSERVER_NAME, "testVserverName");
457
458         ControlLoopOperationManager clom = manager.processControlLoop();
459         assertNotNull(clom);
460         assertNull(clom.getOperationResult());
461
462         Pair<Lock, Lock> lockPair = manager.lockCurrentOperation(callback);
463         assertNull(lockPair.first());
464         assertNotNull(lockPair.second());
465
466         // pseudo lock - session should NOT have been notified of the change
467         verify(callback, never()).lockAvailable(any());
468         verify(callback, never()).lockUnavailable(any());
469
470         // repeat - should cause an extension
471         Lock lock = lockPair.second();
472         lockPair = manager.lockCurrentOperation(callback);
473
474         /*
475          * even with a pseudo lock, the session should have been notified that it was
476          * extended
477          */
478
479         verify(callback).lockAvailable(lock);
480
481         assertSame(lock, manager.unlockCurrentOperation());
482
483         assertNull(lockPair.first());
484         assertNull(lockPair.second());
485
486         // force it to use a pseudo lock
487         manager.setUseTargetLock(false);
488         lockPair = manager.lockCurrentOperation(callback);
489         assertNull(lockPair.first());
490         assertNotNull(lockPair.second());
491
492         lock = lockPair.second();
493
494         lockPair = manager.lockCurrentOperation(callback);
495         assertNull(lockPair.first());
496         assertNull(lockPair.second());
497
498         // first lock uses a pseudo lock, so it will only update when extended
499         verify(callback).lockAvailable(lock);
500
501         // force it to re-create the lock due to change in resource ID
502         lock = mock(Lock.class);
503         when(lock.getResourceId()).thenReturn("different");
504         Whitebox.setInternalState(manager, TARGET_LOCK_FIELD, lock);
505
506         lockPair = manager.lockCurrentOperation(callback);
507         assertSame(lock, lockPair.first());
508         assertNotNull(lockPair.second());
509
510         lock = lockPair.second();
511
512         lockPair = manager.lockCurrentOperation(callback);
513         assertNull(lockPair.first());
514         assertNull(lockPair.second());
515
516         // first lock uses a pseudo lock, so it won't do an update
517         verify(callback).lockAvailable(lock);
518
519         assertSame(lock, manager.unlockCurrentOperation());
520         assertNull(manager.unlockCurrentOperation());
521
522         // try again - this time don't return the fact handle- no change in count
523         lockPair = manager.lockCurrentOperation(callback);
524         assertNull(lockPair.first());
525         assertNotNull(lockPair.second());
526     }
527
528     @Test
529     public void testOnNewEvent() throws Exception {
530         UUID requestId = UUID.randomUUID();
531         VirtualControlLoopEvent onsetEvent = new VirtualControlLoopEvent();
532         onsetEvent.setClosedLoopControlName(TWO_ONSET_TEST);
533         onsetEvent.setRequestId(requestId);
534         onsetEvent.setTarget(VNF_ID);
535         onsetEvent.setClosedLoopAlarmStart(Instant.now());
536         onsetEvent.setClosedLoopEventStatus(ControlLoopEventStatus.ONSET);
537         onsetEvent.setAai(new HashMap<>());
538         onsetEvent.getAai().put(VNF_NAME, ONSET_ONE);
539         onsetEvent.setTargetType(ControlLoopTargetType.VNF);
540
541         VirtualControlLoopEvent abatedEvent = new VirtualControlLoopEvent();
542         abatedEvent.setClosedLoopControlName(TWO_ONSET_TEST);
543         abatedEvent.setRequestId(requestId);
544         abatedEvent.setTarget(VNF_ID);
545         abatedEvent.setClosedLoopAlarmStart(Instant.now());
546         abatedEvent.setClosedLoopEventStatus(ControlLoopEventStatus.ABATED);
547         abatedEvent.setAai(new HashMap<>());
548         abatedEvent.getAai().put(VNF_NAME, ONSET_ONE);
549
550         ControlLoopEventManager manager = makeManager(onsetEvent);
551
552         InputStream is = new FileInputStream(new File(TEST_YAML));
553         final String yamlString = IOUtils.toString(is, StandardCharsets.UTF_8);
554
555         VirtualControlLoopNotification notification = manager.activate(yamlString, onsetEvent);
556         assertNotNull(notification);
557         assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification());
558
559         assertEquals(NewEventStatus.FIRST_ONSET, manager.onNewEvent(onsetEvent));
560         assertEquals(NewEventStatus.FIRST_ABATEMENT, manager.onNewEvent(abatedEvent));
561         assertEquals(NewEventStatus.SUBSEQUENT_ABATEMENT, manager.onNewEvent(abatedEvent));
562
563         VirtualControlLoopEvent checkSyntaxEvent = new VirtualControlLoopEvent();
564         checkSyntaxEvent.setAai(null);
565         checkSyntaxEvent.setClosedLoopAlarmEnd(null);
566         checkSyntaxEvent.setClosedLoopAlarmStart(null);
567         checkSyntaxEvent.setClosedLoopControlName(null);
568         checkSyntaxEvent.setClosedLoopEventClient(null);
569         checkSyntaxEvent.setClosedLoopEventStatus(null);
570         checkSyntaxEvent.setFrom(null);
571         checkSyntaxEvent.setPolicyName(null);
572         checkSyntaxEvent.setPolicyScope(null);
573         checkSyntaxEvent.setPolicyVersion(null);
574         checkSyntaxEvent.setRequestId(null);
575         checkSyntaxEvent.setTarget(null);
576         checkSyntaxEvent.setTargetType(null);
577         checkSyntaxEvent.setVersion(null);
578
579         assertEquals(NewEventStatus.SYNTAX_ERROR, manager.onNewEvent(checkSyntaxEvent));
580
581         checkSyntaxEvent.setClosedLoopEventStatus(ControlLoopEventStatus.ONSET);
582         assertEquals(NewEventStatus.SYNTAX_ERROR, manager.onNewEvent(checkSyntaxEvent));
583
584         checkSyntaxEvent.setClosedLoopControlName(null);
585         assertEquals(NewEventStatus.SYNTAX_ERROR, manager.onNewEvent(checkSyntaxEvent));
586
587         checkSyntaxEvent.setClosedLoopControlName("");
588         assertEquals(NewEventStatus.SYNTAX_ERROR, manager.onNewEvent(checkSyntaxEvent));
589
590         checkSyntaxEvent.setClosedLoopControlName(TWO_ONSET_TEST);
591         assertEquals(NewEventStatus.SYNTAX_ERROR, manager.onNewEvent(checkSyntaxEvent));
592
593         checkSyntaxEvent.setRequestId(null);
594         assertEquals(NewEventStatus.SYNTAX_ERROR, manager.onNewEvent(checkSyntaxEvent));
595
596         checkSyntaxEvent.setRequestId(requestId);
597         assertEquals(NewEventStatus.SYNTAX_ERROR, manager.onNewEvent(checkSyntaxEvent));
598
599         checkSyntaxEvent.setAai(null);
600         assertEquals(NewEventStatus.SYNTAX_ERROR, manager.onNewEvent(checkSyntaxEvent));
601
602         checkSyntaxEvent.setAai(new HashMap<>());
603         assertEquals(NewEventStatus.SYNTAX_ERROR, manager.onNewEvent(checkSyntaxEvent));
604
605         checkSyntaxEvent.setTargetType("");
606         assertEquals(NewEventStatus.SYNTAX_ERROR, manager.onNewEvent(checkSyntaxEvent));
607
608         checkSyntaxEvent.setTarget("");
609         assertEquals(NewEventStatus.SYNTAX_ERROR, manager.onNewEvent(checkSyntaxEvent));
610
611         checkSyntaxEvent.setTarget(null);
612         assertEquals(NewEventStatus.SYNTAX_ERROR, manager.onNewEvent(checkSyntaxEvent));
613
614         checkSyntaxEvent.setTarget("");
615         assertEquals(NewEventStatus.SYNTAX_ERROR, manager.onNewEvent(checkSyntaxEvent));
616
617         checkSyntaxEvent.setTarget("OZ");
618         assertEquals(NewEventStatus.SYNTAX_ERROR, manager.onNewEvent(checkSyntaxEvent));
619
620         checkSyntaxEvent.setTarget("VM_NAME");
621         assertEquals(NewEventStatus.SYNTAX_ERROR, manager.onNewEvent(checkSyntaxEvent));
622
623         checkSyntaxEvent.setTarget("VNF_NAME");
624         assertEquals(NewEventStatus.SYNTAX_ERROR, manager.onNewEvent(checkSyntaxEvent));
625
626         checkSyntaxEvent.setTarget(VSERVER_NAME);
627         assertEquals(NewEventStatus.SYNTAX_ERROR, manager.onNewEvent(checkSyntaxEvent));
628
629         checkSyntaxEvent.setTarget(VNF_ID);
630         assertEquals(NewEventStatus.SYNTAX_ERROR, manager.onNewEvent(checkSyntaxEvent));
631
632         checkSyntaxEvent.setTarget(VNF_NAME);
633         assertEquals(NewEventStatus.SYNTAX_ERROR, manager.onNewEvent(checkSyntaxEvent));
634
635         checkSyntaxEvent.setAai(null);
636         assertEquals(NewEventStatus.SYNTAX_ERROR, manager.onNewEvent(checkSyntaxEvent));
637
638         checkSyntaxEvent.setAai(new HashMap<>());
639         assertEquals(NewEventStatus.SYNTAX_ERROR, manager.onNewEvent(checkSyntaxEvent));
640
641         checkSyntaxEvent.getAai().put(VNF_NAME, ONSET_ONE);
642         assertEquals(NewEventStatus.SUBSEQUENT_ABATEMENT, manager.onNewEvent(abatedEvent));
643
644         checkSyntaxEvent.getAai().put(VSERVER_NAME, ONSET_ONE);
645         assertEquals(NewEventStatus.SUBSEQUENT_ABATEMENT, manager.onNewEvent(abatedEvent));
646
647         checkSyntaxEvent.getAai().put(VNF_ID, ONSET_ONE);
648         assertEquals(NewEventStatus.SUBSEQUENT_ABATEMENT, manager.onNewEvent(abatedEvent));
649     }
650
651     @Test
652     public void testControlLoopTimeout() throws IOException {
653         VirtualControlLoopEvent onsetEvent = getOnsetEvent();
654
655         ControlLoopEventManager manager = makeManager(onsetEvent);
656         assertTrue(0 == manager.getControlLoopTimeout(null));
657         assertTrue(120 == manager.getControlLoopTimeout(120));
658
659         InputStream is = new FileInputStream(new File(TEST_YAML));
660         final String yamlString = IOUtils.toString(is, StandardCharsets.UTF_8);
661
662         VirtualControlLoopNotification notification = manager.activate(yamlString, onsetEvent);
663         assertNotNull(notification);
664         assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification());
665
666         assertEquals(60, manager.getControlLoopTimeout(null));
667     }
668
669     @Test
670     public void testControlLoopTimeout_ZeroTimeout() throws IOException {
671         VirtualControlLoopEvent onsetEvent = getOnsetEvent();
672
673         ControlLoopEventManager manager = makeManager(onsetEvent);
674
675         InputStream is = new FileInputStream(new File("src/test/resources/test-zero-timeout.yaml"));
676         final String yamlString = IOUtils.toString(is, StandardCharsets.UTF_8);
677
678         VirtualControlLoopNotification notification = manager.activate(yamlString, onsetEvent);
679         assertNotNull(notification);
680         assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification());
681
682         assertTrue(0 == manager.getControlLoopTimeout(null));
683         assertTrue(120 == manager.getControlLoopTimeout(120));
684     }
685
686     @Test
687     public void testControlLoopTimeout_NullTimeout() throws IOException {
688         VirtualControlLoopEvent onsetEvent = getOnsetEvent();
689
690         ControlLoopEventManager manager = makeManager(onsetEvent);
691
692         InputStream is = new FileInputStream(new File("src/test/resources/test-null-timeout.yaml"));
693         final String yamlString = IOUtils.toString(is, StandardCharsets.UTF_8);
694
695         VirtualControlLoopNotification notification = manager.activate(yamlString, onsetEvent);
696         assertNotNull(notification);
697         assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification());
698
699         assertTrue(0 == manager.getControlLoopTimeout(null));
700         assertTrue(120 == manager.getControlLoopTimeout(120));
701     }
702
703     @Test
704     public void testIsClosedLoopDisabled() {
705         Map<String, String> aai = onset.getAai();
706
707         // null, null
708         aai.remove(ControlLoopEventManager.GENERIC_VNF_IS_CLOSED_LOOP_DISABLED);
709         aai.remove(ControlLoopEventManager.VSERVER_IS_CLOSED_LOOP_DISABLED);
710         assertFalse(ControlLoopEventManager.isClosedLoopDisabled(onset));
711
712         // null, false
713         aai.remove(ControlLoopEventManager.GENERIC_VNF_IS_CLOSED_LOOP_DISABLED);
714         aai.put(ControlLoopEventManager.VSERVER_IS_CLOSED_LOOP_DISABLED, Boolean.FALSE.toString());
715         assertFalse(ControlLoopEventManager.isClosedLoopDisabled(onset));
716
717         // false, null
718         aai.put(ControlLoopEventManager.GENERIC_VNF_IS_CLOSED_LOOP_DISABLED, Boolean.FALSE.toString());
719         aai.remove(ControlLoopEventManager.VSERVER_IS_CLOSED_LOOP_DISABLED);
720         assertFalse(ControlLoopEventManager.isClosedLoopDisabled(onset));
721
722         // null, true
723         aai.remove(ControlLoopEventManager.GENERIC_VNF_IS_CLOSED_LOOP_DISABLED);
724         aai.put(ControlLoopEventManager.VSERVER_IS_CLOSED_LOOP_DISABLED, Boolean.TRUE.toString());
725         assertTrue(ControlLoopEventManager.isClosedLoopDisabled(onset));
726
727         // true, null
728         aai.put(ControlLoopEventManager.GENERIC_VNF_IS_CLOSED_LOOP_DISABLED, Boolean.TRUE.toString());
729         aai.remove(ControlLoopEventManager.VSERVER_IS_CLOSED_LOOP_DISABLED);
730         assertTrue(ControlLoopEventManager.isClosedLoopDisabled(onset));
731     }
732
733     @Test
734     public void testIsProvStatusInactive() {
735         Map<String, String> aai = onset.getAai();
736
737         // null, null
738         aai.remove(ControlLoopEventManager.GENERIC_VNF_PROV_STATUS);
739         aai.remove(ControlLoopEventManager.VSERVER_PROV_STATUS);
740         assertFalse(ControlLoopEventManager.isProvStatusInactive(onset));
741
742         // null, active
743         aai.remove(ControlLoopEventManager.GENERIC_VNF_PROV_STATUS);
744         aai.put(ControlLoopEventManager.VSERVER_PROV_STATUS, ControlLoopEventManager.PROV_STATUS_ACTIVE);
745         assertFalse(ControlLoopEventManager.isProvStatusInactive(onset));
746
747         // active, null
748         aai.put(ControlLoopEventManager.GENERIC_VNF_PROV_STATUS, ControlLoopEventManager.PROV_STATUS_ACTIVE);
749         aai.remove(ControlLoopEventManager.VSERVER_PROV_STATUS);
750         assertFalse(ControlLoopEventManager.isProvStatusInactive(onset));
751
752         // null, inactive
753         aai.remove(ControlLoopEventManager.GENERIC_VNF_PROV_STATUS);
754         aai.put(ControlLoopEventManager.VSERVER_PROV_STATUS, "other1");
755         assertTrue(ControlLoopEventManager.isProvStatusInactive(onset));
756
757         // inactive, null
758         aai.put(ControlLoopEventManager.GENERIC_VNF_PROV_STATUS, "other2");
759         aai.remove(ControlLoopEventManager.VSERVER_PROV_STATUS);
760         assertTrue(ControlLoopEventManager.isProvStatusInactive(onset));
761     }
762
763     @Test
764     public void testIsAaiTrue() {
765         assertTrue(ControlLoopEventManager.isAaiTrue("tRuE"));
766         assertTrue(ControlLoopEventManager.isAaiTrue("T"));
767         assertTrue(ControlLoopEventManager.isAaiTrue("t"));
768         assertTrue(ControlLoopEventManager.isAaiTrue("yES"));
769         assertTrue(ControlLoopEventManager.isAaiTrue("Y"));
770         assertTrue(ControlLoopEventManager.isAaiTrue("y"));
771
772         assertFalse(ControlLoopEventManager.isAaiTrue("no"));
773         assertFalse(ControlLoopEventManager.isAaiTrue(null));
774     }
775
776
777     private VirtualControlLoopEvent makeEvent() {
778         UUID requestId = UUID.randomUUID();
779         VirtualControlLoopEvent event = new VirtualControlLoopEvent();
780         event.setClosedLoopControlName(TWO_ONSET_TEST);
781         event.setRequestId(requestId);
782         event.setTarget(VNF_ID);
783         event.setClosedLoopAlarmStart(Instant.now());
784         event.setClosedLoopEventStatus(ControlLoopEventStatus.ONSET);
785         event.setAai(new HashMap<>());
786         event.getAai().put(VNF_ID, ONSET_ONE);
787         event.getAai().put(VSERVER_NAME, "test-vserver");
788         event.setTargetType(ControlLoopTargetType.VNF);
789         return event;
790     }
791
792     private ControlLoopEventManager makeManager(VirtualControlLoopEvent event) {
793         return new MyManager(event.getClosedLoopControlName(), event.getRequestId());
794     }
795
796     private static class MyManager extends ControlLoopEventManager implements Serializable {
797         private static final long serialVersionUID = 1L;
798
799         public MyManager(String closedLoopControlName, UUID requestId) {
800             super(closedLoopControlName, requestId);
801         }
802
803         @Override
804         protected Lock createRealLock(String targetEntity, UUID requestId, int holdSec, LockCallback callback) {
805             return createPseudoLock(targetEntity, requestId, holdSec, callback);
806         }
807     }
808 }