2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2020-2021 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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.onap.policy.drools.apps.controller.usecases;
23 import static org.assertj.core.api.Assertions.assertThat;
24 import static org.assertj.core.api.Assertions.assertThatCode;
25 import static org.assertj.core.api.Assertions.assertThatThrownBy;
26 import static org.junit.Assert.assertEquals;
27 import static org.junit.Assert.assertFalse;
28 import static org.junit.Assert.assertNotNull;
29 import static org.junit.Assert.assertSame;
30 import static org.junit.Assert.assertTrue;
31 import static org.mockito.ArgumentMatchers.any;
32 import static org.mockito.Mockito.verify;
33 import static org.mockito.Mockito.when;
35 import java.time.Instant;
36 import java.util.ArrayList;
37 import java.util.Arrays;
38 import java.util.Deque;
39 import java.util.List;
41 import java.util.TreeMap;
42 import java.util.UUID;
43 import java.util.concurrent.ExecutorService;
44 import org.drools.core.WorkingMemory;
45 import org.junit.Before;
46 import org.junit.Test;
47 import org.junit.runner.RunWith;
48 import org.kie.api.runtime.rule.FactHandle;
49 import org.mockito.Mock;
50 import org.mockito.junit.MockitoJUnitRunner;
51 import org.onap.policy.common.utils.coder.Coder;
52 import org.onap.policy.common.utils.coder.CoderException;
53 import org.onap.policy.common.utils.coder.StandardYamlCoder;
54 import org.onap.policy.common.utils.resources.ResourceUtils;
55 import org.onap.policy.controlloop.ControlLoopEventStatus;
56 import org.onap.policy.controlloop.ControlLoopException;
57 import org.onap.policy.controlloop.ControlLoopResponse;
58 import org.onap.policy.controlloop.ControlLoopTargetType;
59 import org.onap.policy.controlloop.VirtualControlLoopEvent;
60 import org.onap.policy.controlloop.actorserviceprovider.Operation;
61 import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
62 import org.onap.policy.controlloop.actorserviceprovider.OperationProperties;
63 import org.onap.policy.controlloop.actorserviceprovider.OperationResult;
64 import org.onap.policy.controlloop.actorserviceprovider.Operator;
65 import org.onap.policy.controlloop.actorserviceprovider.TargetType;
66 import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams;
67 import org.onap.policy.controlloop.actorserviceprovider.spi.Actor;
68 import org.onap.policy.controlloop.drl.legacy.ControlLoopParams;
69 import org.onap.policy.controlloop.eventmanager.ActorConstants;
70 import org.onap.policy.controlloop.eventmanager.EventManagerServices;
71 import org.onap.policy.controlloop.ophistory.OperationHistoryDataManager;
72 import org.onap.policy.drools.apps.controller.usecases.step.AaiCqStep2;
73 import org.onap.policy.drools.apps.controller.usecases.step.AaiGetPnfStep2;
74 import org.onap.policy.drools.apps.controller.usecases.step.AaiGetTenantStep2;
75 import org.onap.policy.drools.apps.controller.usecases.step.GetTargetEntityStep2;
76 import org.onap.policy.drools.apps.controller.usecases.step.GuardStep2;
77 import org.onap.policy.drools.apps.controller.usecases.step.Step2;
78 import org.onap.policy.drools.core.lock.LockCallback;
79 import org.onap.policy.drools.core.lock.LockImpl;
80 import org.onap.policy.drools.core.lock.LockState;
81 import org.onap.policy.drools.system.PolicyEngine;
82 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
83 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
84 import org.onap.policy.sdnr.PciBody;
85 import org.onap.policy.sdnr.PciMessage;
86 import org.onap.policy.sdnr.PciResponse;
88 @RunWith(MockitoJUnitRunner.class)
89 public class UsecasesEventManagerTest {
90 private static final UUID REQ_ID = UUID.randomUUID();
91 private static final String CL_NAME = "my-closed-loop-name";
92 private static final String POLICY_NAME = "my-policy-name";
93 private static final String POLICY_SCOPE = "my-scope";
94 private static final String POLICY_VERSION = "1.2.3";
95 private static final String SIMPLE_ACTOR = "First";
96 private static final String SIMPLE_OPERATION = "OperationA";
97 private static final String MY_TARGET = "my-target";
98 private static final String EVENT_MGR_SIMPLE_YAML =
99 "../eventmanager/src/test/resources/eventManager/event-mgr-simple.yaml";
100 private static final Coder yamlCoder = new StandardYamlCoder();
101 private static final String OUTCOME_MSG = "my outcome message";
104 private PolicyEngine engineMgr;
106 private WorkingMemory workMem;
108 private FactHandle factHandle;
110 private Operator policyOperator;
112 private Operation policyOperation;
114 private Actor policyActor;
116 private EventManagerServices services;
118 private OperationHistoryDataManager dataMgr;
120 private ExecutorService executor;
126 private List<LockImpl> locks;
127 private ToscaPolicy tosca;
128 private ControlLoopParams params;
129 private VirtualControlLoopEvent event;
130 private UsecasesEventManager mgr;
136 public void setUp() throws ControlLoopException, CoderException {
137 when(services.getDataManager()).thenReturn(dataMgr);
139 when(workMem.getFactHandle(any())).thenReturn(factHandle);
141 event = new VirtualControlLoopEvent();
142 event.setRequestId(REQ_ID);
143 event.setTarget(UsecasesConstants.VSERVER_VSERVER_NAME);
144 event.setAai(new TreeMap<>(Map.of(UsecasesConstants.VSERVER_VSERVER_NAME, MY_TARGET)));
145 event.setClosedLoopEventStatus(ControlLoopEventStatus.ONSET);
146 event.setClosedLoopControlName(CL_NAME);
147 event.setTargetType(ControlLoopTargetType.VNF);
149 params = new ControlLoopParams();
150 params.setClosedLoopControlName(CL_NAME);
151 params.setPolicyName(POLICY_NAME);
152 params.setPolicyScope(POLICY_SCOPE);
153 params.setPolicyVersion(POLICY_VERSION);
155 loadPolicy(EVENT_MGR_SIMPLE_YAML);
157 locks = new ArrayList<>();
159 mgr = new MyManager(services, params, event, workMem);
163 public void testConstructor() {
164 assertEquals(POLICY_NAME, mgr.getPolicyName());
165 assertSame(event, mgr.getEvent());
167 Map<String, String> orig = event.getAai();
169 event.setAai(addAai(orig, UsecasesConstants.VSERVER_IS_CLOSED_LOOP_DISABLED, "true"));
170 assertThatThrownBy(() -> new UsecasesEventManager(services, params, event, workMem))
171 .hasMessage("is-closed-loop-disabled is set to true on VServer or VNF");
174 event.setAai(addAai(orig, UsecasesConstants.VSERVER_PROV_STATUS,
175 UsecasesConstants.PROV_STATUS_ACTIVE.toUpperCase()));
176 assertThatCode(() -> new UsecasesEventManager(services, params, event, workMem)).doesNotThrowAnyException();
179 event.setAai(addAai(orig, UsecasesConstants.VSERVER_PROV_STATUS,
180 UsecasesConstants.PROV_STATUS_ACTIVE.toLowerCase()));
181 assertThatCode(() -> new UsecasesEventManager(services, params, event, workMem)).doesNotThrowAnyException();
184 event.setAai(addAai(orig, UsecasesConstants.VSERVER_PROV_STATUS, "inactive"));
185 assertThatThrownBy(() -> new UsecasesEventManager(services, params, event, workMem))
186 .hasMessage("prov-status is not ACTIVE on VServer or VNF");
189 event.setAai(addAai(orig, UsecasesConstants.GENERIC_VNF_PROV_STATUS,
190 UsecasesConstants.PROV_STATUS_ACTIVE.toUpperCase()));
191 assertThatCode(() -> new UsecasesEventManager(services, params, event, workMem)).doesNotThrowAnyException();
194 event.setAai(addAai(orig, UsecasesConstants.GENERIC_VNF_PROV_STATUS,
195 UsecasesConstants.PROV_STATUS_ACTIVE.toLowerCase()));
196 assertThatCode(() -> new UsecasesEventManager(services, params, event, workMem)).doesNotThrowAnyException();
199 event.setAai(addAai(orig, UsecasesConstants.GENERIC_VNF_PROV_STATUS, "inactive"));
200 assertThatThrownBy(() -> new UsecasesEventManager(services, params, event, workMem))
201 .hasMessage("prov-status is not ACTIVE on VServer or VNF");
205 assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
208 event.setTarget("unknown-target");
209 assertThatThrownBy(() -> new UsecasesEventManager(services, params, event, workMem))
210 .isInstanceOf(ControlLoopException.class);
214 public void testLoadPreprocessorSteps() {
215 stepa = new Step2(mgr, ControlLoopOperationParams.builder().build(), event) {
217 public List<String> getPropertyNames() {
218 return List.of(OperationProperties.AAI_DEFAULT_CLOUD_REGION);
222 protected Operation buildOperation() {
223 return policyOperation;
227 mgr.getSteps().add(stepa);
228 mgr.getSteps().add(stepb);
230 mgr.loadPreprocessorSteps();
232 Deque<Step2> steps = mgr.getSteps();
234 Step2 lockStep = steps.poll();
235 assertNotNull(lockStep);
236 assertEquals(ActorConstants.LOCK_ACTOR, lockStep.getActorName());
237 assertThat(steps.poll()).isInstanceOf(AaiCqStep2.class);
238 assertThat(steps.poll()).isInstanceOf(GuardStep2.class);
239 assertSame(stepa, steps.poll());
240 assertSame(stepb, steps.poll());
241 assertThat(steps).isEmpty();
245 * Tests loadPreprocessorSteps() when no additional steps are needed.
248 public void testLoadPreprocessorStepsNothingToLoad() {
249 when(stepa.isPolicyStep()).thenReturn(false);
250 when(stepa.getPropertyNames()).thenReturn(List.of("unknown-property"));
252 Deque<Step2> steps = mgr.getSteps();
257 mgr.loadPreprocessorSteps();
259 assertSame(stepa, steps.poll());
260 assertSame(stepb, steps.poll());
261 assertThat(steps).isEmpty();
265 * Tests loadPreprocessorSteps() when an A&AI custom query is needed.
268 public void testLoadPreprocessorStepsCq() {
269 loadStepsWithProperties(OperationProperties.AAI_DEFAULT_CLOUD_REGION, OperationProperties.AAI_DEFAULT_TENANT);
272 mgr.loadPreprocessorSteps();
274 Deque<Step2> steps = mgr.getSteps();
276 assertThat(steps.poll()).isInstanceOf(AaiCqStep2.class);
277 assertSame(stepa, steps.poll());
278 assertSame(stepb, steps.poll());
279 assertThat(steps).isEmpty();
283 * Tests loadPreprocessorSteps() when an A&AI PNF query is needed.
286 public void testLoadPreprocessorStepsPnf() {
287 // doubling up the property to check both branches
288 loadStepsWithProperties(OperationProperties.AAI_PNF, OperationProperties.AAI_PNF);
291 mgr.loadPreprocessorSteps();
293 Deque<Step2> steps = mgr.getSteps();
295 assertThat(steps.poll()).isInstanceOf(AaiGetPnfStep2.class);
296 assertSame(stepa, steps.poll());
297 assertSame(stepb, steps.poll());
298 assertThat(steps).isEmpty();
302 * Tests loadPreprocessorSteps() when an A&AI Tenant query is needed.
305 public void testLoadPreprocessorStepsTenant() {
306 // doubling up the property to check both branches
307 event.getAai().put(Step2.VSERVER_VSERVER_NAME, "my-vserver");
308 loadStepsWithProperties(OperationProperties.AAI_VSERVER_LINK, OperationProperties.AAI_VSERVER_LINK);
311 mgr.loadPreprocessorSteps();
313 Deque<Step2> steps = mgr.getSteps();
315 assertThat(steps.poll()).isInstanceOf(AaiGetTenantStep2.class);
316 assertSame(stepa, steps.poll());
317 assertSame(stepb, steps.poll());
318 assertThat(steps).isEmpty();
322 * Tests loadPreprocessorSteps() when the target entity is unset.
325 public void testLoadPreprocessorStepsNeedTargetEntity() {
326 stepa = new Step2(mgr, ControlLoopOperationParams.builder()
327 .targetType(TargetType.toTargetType(event.getTargetType())).targetEntityIds(Map.of()).build(),
330 public List<String> getPropertyNames() {
331 return List.of(OperationProperties.AAI_TARGET_ENTITY);
335 protected Operation buildOperation() {
336 return policyOperation;
340 public boolean isPolicyStep() {
345 Deque<Step2> steps = mgr.getSteps();
349 mgr.loadPreprocessorSteps();
351 Step2 entityStep = steps.poll();
353 assertThat(entityStep).isInstanceOf(GetTargetEntityStep2.class);
354 assertSame(stepa, steps.poll());
355 assertSame(stepb, steps.poll());
356 assertThat(steps).isEmpty();
358 // put get-target-entity back onto the queue and ensure nothing else is added
359 steps.add(entityStep);
360 mgr.loadPreprocessorSteps();
361 assertSame(entityStep, steps.poll());
362 assertThat(steps).isEmpty();
366 public void testIsAbort() {
367 OperationOutcome outcome = makeCompletedOutcome();
368 outcome.setResult(OperationResult.FAILURE);
370 // closed loop timeout
371 outcome.setActor(ActorConstants.CL_TIMEOUT_ACTOR);
372 assertTrue(mgr.isAbort(outcome));
375 outcome.setActor(ActorConstants.LOCK_ACTOR);
376 assertTrue(mgr.isAbort(outcome));
378 // no effect for success
379 outcome.setResult(OperationResult.SUCCESS);
380 assertFalse(mgr.isAbort(outcome));
384 public void testStoreInDataBase() throws ControlLoopException {
386 OperationOutcome outcome = makeOutcome();
387 mgr.addToHistory(outcome);
389 mgr.storeInDataBase(mgr.getPartialHistory().peekLast());
391 verify(dataMgr).store(REQ_ID.toString(), event.getClosedLoopControlName(), event, null,
392 mgr.getPartialHistory().peekLast().getClOperation());
396 public void testMakeControlLoopResponse() {
397 final OperationOutcome outcome = new OperationOutcome();
399 // no message - should return null
400 checkResp(outcome, null);
402 // not a PciMessage - should return null
403 outcome.setResponse("not-a-pci-message");
404 checkResp(outcome, null);
407 * now work with a PciMessage
409 PciMessage msg = new PciMessage();
410 outcome.setResponse(msg);
412 PciBody body = new PciBody();
415 PciResponse output = new PciResponse();
416 body.setOutput(output);
418 output.setPayload("my-payload");
420 // should generate a response, with a payload
421 checkResp(outcome, "my-payload");
424 * these should generate a response, with null payload
426 output.setPayload(null);
427 checkResp(outcome, null);
429 body.setOutput(null);
430 checkResp(outcome, null);
433 checkResp(outcome, null);
435 outcome.setResponse(null);
436 checkResp(outcome, null);
440 public void testCheckEventSyntax() {
442 * only need to check one success and one failure from the super class method
445 // initially, it's valid
446 assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
448 event.setTarget("unknown-target");
449 assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class)
450 .hasMessage("target field invalid");
452 event.setTarget(null);
453 assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class)
454 .hasMessage("No target field");
456 event.setRequestId(null);
457 assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class)
458 .hasMessage("No request ID");
462 public void testValidateStatus() {
464 * only need to check one success and one failure from the super class method
466 event.setClosedLoopEventStatus(ControlLoopEventStatus.ONSET);
467 assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
469 event.setClosedLoopEventStatus(null);
470 assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class)
471 .hasMessage("Invalid value in closedLoopEventStatus");
475 public void testValidateAaiData() {
476 event.setTargetType("unknown-target-type");
477 assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class)
478 .hasMessage("The target type is not supported");
480 event.setTargetType(null);
481 assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class)
482 .hasMessage("The Target type is null");
485 assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class)
486 .hasMessage("AAI is null");
489 event.setTargetType(ControlLoopTargetType.VM);
490 event.setAai(Map.of(UsecasesConstants.GENERIC_VNF_VNF_ID, MY_TARGET));
491 assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
493 event.setAai(Map.of());
494 assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class);
497 event.setTargetType(ControlLoopTargetType.VNF);
498 event.setAai(Map.of(UsecasesConstants.GENERIC_VNF_VNF_ID, MY_TARGET));
499 assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
501 event.setAai(Map.of());
502 assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class);
505 event.setTargetType(ControlLoopTargetType.PNF);
506 event.setAai(Map.of(UsecasesConstants.PNF_NAME, MY_TARGET));
507 assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
509 event.setAai(Map.of());
510 assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class);
514 public void testValidateAaiVmVnfData() {
515 event.setTargetType(ControlLoopTargetType.VM);
516 event.setAai(Map.of(UsecasesConstants.GENERIC_VNF_VNF_ID, MY_TARGET));
517 assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
519 event.setAai(Map.of(UsecasesConstants.VSERVER_VSERVER_NAME, MY_TARGET));
520 assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
522 event.setAai(Map.of(UsecasesConstants.GENERIC_VNF_VNF_NAME, MY_TARGET));
523 assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
525 event.setAai(Map.of());
526 assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class).hasMessage(
527 "generic-vnf.vnf-id or generic-vnf.vnf-name or vserver.vserver-name information missing");
531 public void testValidateAaiPnfData() {
532 event.setTargetType(ControlLoopTargetType.PNF);
533 event.setAai(Map.of(UsecasesConstants.PNF_NAME, MY_TARGET));
534 assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
536 event.setAai(Map.of());
537 assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class)
538 .hasMessage("AAI PNF object key pnf-name is missing");
542 public void testIsClosedLoopDisabled() {
543 Map<String, String> orig = event.getAai();
545 event.setAai(addAai(orig, UsecasesConstants.VSERVER_IS_CLOSED_LOOP_DISABLED, "true"));
546 assertThatThrownBy(() -> new UsecasesEventManager(services, params, event, workMem))
547 .isInstanceOf(IllegalStateException.class);
549 event.setAai(addAai(orig, UsecasesConstants.GENERIC_VNF_IS_CLOSED_LOOP_DISABLED, "true"));
550 assertThatThrownBy(() -> new UsecasesEventManager(services, params, event, workMem))
551 .isInstanceOf(IllegalStateException.class);
553 event.setAai(addAai(orig, UsecasesConstants.PNF_IS_IN_MAINT, "true"));
554 assertThatThrownBy(() -> new UsecasesEventManager(services, params, event, workMem))
555 .isInstanceOf(IllegalStateException.class);
559 public void testIsProvStatusInactive() {
560 Map<String, String> orig = event.getAai();
562 event.setAai(addAai(orig, UsecasesConstants.VSERVER_PROV_STATUS, "ACTIVE"));
563 assertThatCode(() -> new UsecasesEventManager(services, params, event, workMem)).doesNotThrowAnyException();
565 event.setAai(addAai(orig, UsecasesConstants.VSERVER_PROV_STATUS, "inactive"));
566 assertThatThrownBy(() -> new UsecasesEventManager(services, params, event, workMem))
567 .isInstanceOf(IllegalStateException.class);
569 event.setAai(addAai(orig, UsecasesConstants.GENERIC_VNF_PROV_STATUS, "ACTIVE"));
570 assertThatCode(() -> new UsecasesEventManager(services, params, event, workMem)).doesNotThrowAnyException();
572 event.setAai(addAai(orig, UsecasesConstants.GENERIC_VNF_PROV_STATUS, "inactive"));
573 assertThatThrownBy(() -> new UsecasesEventManager(services, params, event, workMem))
574 .isInstanceOf(IllegalStateException.class);
578 public void testIsAaiTrue() {
579 Map<String, String> orig = event.getAai();
581 for (String value : Arrays.asList("yes", "y", "true", "t", "yEs", "trUe")) {
582 event.setAai(addAai(orig, UsecasesConstants.VSERVER_IS_CLOSED_LOOP_DISABLED, value));
583 assertThatThrownBy(() -> new UsecasesEventManager(services, params, event, workMem))
584 .isInstanceOf(IllegalStateException.class);
587 event.setAai(addAai(orig, UsecasesConstants.VSERVER_IS_CLOSED_LOOP_DISABLED, "false"));
588 assertThatCode(() -> new UsecasesEventManager(services, params, event, workMem)).doesNotThrowAnyException();
590 event.setAai(addAai(orig, UsecasesConstants.VSERVER_IS_CLOSED_LOOP_DISABLED, "no"));
591 assertThatCode(() -> new UsecasesEventManager(services, params, event, workMem)).doesNotThrowAnyException();
596 private Map<String, String> addAai(Map<String, String> original, String key, String value) {
597 Map<String, String> map = new TreeMap<>(original);
602 private void loadPolicy(String fileName) throws CoderException {
603 ToscaServiceTemplate template =
604 yamlCoder.decode(ResourceUtils.getResourceAsString(fileName), ToscaServiceTemplate.class);
605 tosca = template.getToscaTopologyTemplate().getPolicies().get(0).values().iterator().next();
607 params.setToscaPolicy(tosca);
610 private void loadStepsWithProperties(String... properties) {
611 stepa = new Step2(mgr, ControlLoopOperationParams.builder().build(), event) {
614 public boolean isPolicyStep() {
619 public List<String> getPropertyNames() {
620 return List.of(properties);
624 protected Operation buildOperation() {
625 return policyOperation;
629 mgr.getSteps().add(stepa);
630 mgr.getSteps().add(stepb);
633 private OperationOutcome makeCompletedOutcome() {
634 OperationOutcome outcome = makeOutcome();
635 outcome.setEnd(outcome.getStart());
640 private OperationOutcome makeOutcome() {
641 OperationOutcome outcome = new OperationOutcome();
642 outcome.setActor(SIMPLE_ACTOR);
643 outcome.setOperation(SIMPLE_OPERATION);
644 outcome.setMessage(OUTCOME_MSG);
645 outcome.setResult(OperationResult.SUCCESS);
646 outcome.setStart(Instant.now());
647 outcome.setTarget(MY_TARGET);
652 private void checkResp(OperationOutcome outcome, String expectedPayload) {
653 ControlLoopResponse resp = mgr.makeControlLoopResponse(outcome);
655 assertEquals(REQ_ID, resp.getRequestId());
656 assertEquals(expectedPayload, resp.getPayload());
660 * Sets the target entity so a step doesn't have to be added to set it.
662 private void setTargetEntity() {
663 mgr.setProperty(OperationProperties.AAI_TARGET_ENTITY, MY_TARGET);
667 private class MyManager extends UsecasesEventManager {
668 private static final long serialVersionUID = 1L;
670 public MyManager(EventManagerServices services, ControlLoopParams params, VirtualControlLoopEvent event,
671 WorkingMemory workMem) throws ControlLoopException {
673 super(services, params, event, workMem);
677 protected ExecutorService getBlockingExecutor() {
682 protected void makeLock(String targetEntity, String requestId, int holdSec, LockCallback callback) {
683 LockImpl lock = new LockImpl(LockState.ACTIVE, targetEntity, requestId, holdSec, callback);
685 callback.lockAvailable(lock);
689 protected PolicyEngine getPolicyEngineManager() {