2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved.
6 * Modifications Copyright (C) 2023, 2024 Nordix Foundation.
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.policy.controlloop.actor.xacml;
24 import static org.assertj.core.api.Assertions.assertThat;
25 import static org.junit.jupiter.api.Assertions.assertEquals;
26 import static org.junit.jupiter.api.Assertions.assertFalse;
27 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
28 import static org.junit.jupiter.api.Assertions.assertNotNull;
29 import static org.junit.jupiter.api.Assertions.assertNull;
30 import static org.junit.jupiter.api.Assertions.assertTrue;
31 import static org.mockito.ArgumentMatchers.any;
32 import static org.mockito.Mockito.mock;
33 import static org.mockito.Mockito.never;
34 import static org.mockito.Mockito.verify;
35 import static org.mockito.Mockito.when;
37 import java.util.List;
39 import java.util.concurrent.CompletableFuture;
40 import java.util.function.Consumer;
41 import org.junit.jupiter.api.AfterAll;
42 import org.junit.jupiter.api.BeforeAll;
43 import org.junit.jupiter.api.BeforeEach;
44 import org.junit.jupiter.api.Test;
45 import org.junit.jupiter.api.extension.ExtendWith;
46 import org.mockito.Mock;
47 import org.mockito.Mockito;
48 import org.mockito.junit.jupiter.MockitoExtension;
49 import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams;
50 import org.onap.policy.common.endpoints.http.client.HttpClientFactoryInstance;
51 import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInstance;
52 import org.onap.policy.controlloop.actor.test.BasicHttpOperation;
53 import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
54 import org.onap.policy.controlloop.actorserviceprovider.OperationResult;
55 import org.onap.policy.controlloop.actorserviceprovider.Util;
56 import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams;
57 import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpConfig;
58 import org.onap.policy.models.decisions.concepts.DecisionRequest;
59 import org.onap.policy.models.decisions.concepts.DecisionResponse;
60 import org.onap.policy.simulators.XacmlSimulatorJaxRs;
62 @ExtendWith(MockitoExtension.class)
63 class DecisionOperationTest extends BasicHttpOperation {
64 private static final List<String> PROPERTY_NAMES = List.of("prop-A", "prop-B");
67 private Consumer<OperationOutcome> started;
69 private Consumer<OperationOutcome> completed;
71 private DecisionConfig guardConfig;
75 * Starts the simulator.
78 static void setUpBeforeClass() throws Exception {
79 org.onap.policy.simulators.Util.buildXacmlSim();
81 BusTopicParams clientParams = BusTopicParams.builder().clientName(MY_CLIENT).basePath("policy/pdpx/v1/")
82 .hostname("localhost").managed(true).port(org.onap.policy.simulators.Util.XACMLSIM_SERVER_PORT)
84 HttpClientFactoryInstance.getClientFactory().build(clientParams);
88 static void tearDownAfterClass() {
89 HttpClientFactoryInstance.getClientFactory().destroy();
90 HttpServletServerFactoryInstance.getServerFactory().destroy();
97 void setUp() throws Exception {
100 guardConfig = mock(DecisionConfig.class);
101 Mockito.lenient().when(guardConfig.makeRequest()).thenAnswer(args -> {
102 DecisionRequest req = new DecisionRequest();
103 req.setAction("guard");
104 req.setOnapComponent("my-onap-component");
105 req.setOnapInstance("my-onap-instance");
106 req.setOnapName("my-onap-name");
110 config = guardConfig;
113 params = params.toBuilder().startCallback(started).completeCallback(completed).build();
115 oper = new MyOper(params, config);
119 * Tests with simulator.
122 void testSimulator() throws Exception {
123 DecisionParams opParams = DecisionParams.builder().clientName(MY_CLIENT).path("decision").build();
124 config = new DecisionConfig(blockingExecutor, opParams, HttpClientFactoryInstance.getClientFactory());
126 params = params.toBuilder().retry(0).timeoutSec(5).executor(blockingExecutor)
127 .payload(Map.of("clname", XacmlSimulatorJaxRs.DENY_CLNAME)).build();
128 oper = new MyOper(params, config);
130 outcome = oper.start().get();
131 assertEquals(OperationResult.FAILURE, outcome.getResult());
132 assertInstanceOf(DecisionResponse.class, outcome.getResponse());
136 void testConstructor() {
137 assertEquals(DEFAULT_ACTOR, oper.getActorName());
138 assertEquals(DEFAULT_OPERATION, oper.getName());
142 void testGetPropertyNames() {
143 assertThat(oper.getPropertyNames()).isEqualTo(PROPERTY_NAMES);
147 void testStartOperationAsync() throws Exception {
148 CompletableFuture<OperationOutcome> future2 = oper.start();
149 executor.runAll(100);
150 assertFalse(future2.isDone());
152 DecisionResponse resp = new DecisionResponse();
153 resp.setStatus(GuardOperation.PERMIT);
154 when(rawResponse.readEntity(String.class)).thenReturn(Util.translate("", resp, String.class));
156 verify(client).post(callbackCaptor.capture(), any(), requestCaptor.capture(), any());
157 callbackCaptor.getValue().completed(rawResponse);
159 executor.runAll(100);
160 assertTrue(future2.isDone());
162 outcome = future2.get();
163 assertEquals(OperationResult.SUCCESS, outcome.getResult());
164 assertEquals(resp, outcome.getResponse());
166 assertNotNull(oper.getSubRequestId());
167 assertEquals(oper.getSubRequestId(), future2.get().getSubRequestId());
171 * Tests startOperationAsync() when the guard is disabled.
174 void testStartOperationAsyncDisabled() throws Exception {
175 // indicate that it's disabled
176 when(guardConfig.isDisabled()).thenReturn(true);
178 CompletableFuture<OperationOutcome> future2 = oper.start();
179 executor.runAll(100);
181 verify(client, never()).post(any(), any(), any(), any());
183 // should already be done
184 assertTrue(future2.isDone());
186 outcome = future2.get();
187 assertEquals(OperationResult.SUCCESS, outcome.getResult());
188 assertNull(outcome.getResponse());
190 // ensure callbacks were invoked
191 verify(started).accept(any());
192 verify(completed).accept(any());
195 private class MyOper extends DecisionOperation {
197 MyOper(ControlLoopOperationParams params, HttpConfig config) {
198 super(params, config, PROPERTY_NAMES);
202 protected DecisionRequest makeRequest() {
203 return guardConfig.makeRequest();