2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2019-2022 AT&T Intellectual Property. All rights reserved.
4 * Modifications Copyright (C) 2019, 2023-2024 Nordix Foundation.
5 * ================================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
22 package org.onap.policy.pdpx.main.rest;
24 import static org.assertj.core.api.Assertions.assertThat;
25 import static org.junit.jupiter.api.Assertions.assertEquals;
27 import com.google.gson.Gson;
28 import com.google.gson.GsonBuilder;
29 import jakarta.ws.rs.client.Entity;
30 import jakarta.ws.rs.core.MediaType;
31 import jakarta.ws.rs.core.Response;
32 import jakarta.ws.rs.core.Response.Status;
34 import java.io.IOException;
35 import java.nio.file.Files;
36 import java.nio.file.Path;
37 import java.nio.file.Paths;
38 import java.nio.file.StandardCopyOption;
39 import java.util.Collections;
40 import java.util.HashMap;
42 import org.junit.jupiter.api.AfterAll;
43 import org.junit.jupiter.api.BeforeAll;
44 import org.junit.jupiter.api.Test;
45 import org.junit.jupiter.api.io.TempDir;
46 import org.onap.policy.common.endpoints.http.client.HttpClient;
47 import org.onap.policy.common.endpoints.http.client.HttpClientConfigException;
48 import org.onap.policy.common.endpoints.http.client.HttpClientFactoryInstance;
49 import org.onap.policy.common.endpoints.parameters.RestClientParameters;
50 import org.onap.policy.common.endpoints.parameters.RestServerParameters;
51 import org.onap.policy.common.endpoints.parameters.TopicParameterGroup;
52 import org.onap.policy.common.utils.network.NetworkUtil;
53 import org.onap.policy.common.utils.resources.ResourceUtils;
54 import org.onap.policy.models.decisions.concepts.DecisionRequest;
55 import org.onap.policy.models.decisions.concepts.DecisionResponse;
56 import org.onap.policy.models.errors.concepts.ErrorResponse;
57 import org.onap.policy.pdpx.main.PolicyXacmlPdpException;
58 import org.onap.policy.pdpx.main.parameters.CommonTestData;
59 import org.onap.policy.pdpx.main.parameters.XacmlApplicationParameters;
60 import org.onap.policy.pdpx.main.parameters.XacmlPdpParameterGroup;
61 import org.onap.policy.pdpx.main.startstop.Main;
62 import org.onap.policy.pdpx.main.startstop.XacmlPdpActivator;
63 import org.slf4j.Logger;
64 import org.slf4j.LoggerFactory;
68 private static final Logger LOGGER = LoggerFactory.getLogger(TestDecision.class);
70 private static int port;
71 private static Main main;
72 private static HttpClient client;
73 private static final CommonTestData testData = new CommonTestData();
74 private static final String APPLICATION_XACML_XML = "application/xacml+xml";
75 private static final String APPLICATION_XACML_JSON = "application/xacml+json";
78 static Path appsFolder;
81 * BeforeClass setup environment.
83 * @throws IOException Cannot create temp apps folder
84 * @throws Exception exception if service does not start
87 static void beforeClass() throws Exception {
88 System.setProperty("org.eclipse.jetty.util.log.class", "org.eclipse.jetty.util.log.StdErrLog");
89 System.setProperty("org.eclipse.jetty.LEVEL", "OFF");
91 port = NetworkUtil.allocPort();
94 // Copy test directory over of the application directories
96 Path src = Paths.get("src/test/resources/apps");
97 File apps = appsFolder.resolve("apps").toFile();
98 Files.walk(src).forEach(source -> {
99 copy(source, apps.toPath().resolve(src.relativize(source)));
102 // Get the parameters file correct.
104 RestServerParameters rest =
105 testData.toObject(testData.getRestServerParametersMap(port), RestServerParameters.class);
106 RestClientParameters policyApiParameters =
107 testData.toObject(testData.getPolicyApiParametersMap(false), RestClientParameters.class);
108 TopicParameterGroup topicParameterGroup =
109 testData.toObject(testData.getTopicParametersMap(false), TopicParameterGroup.class);
110 final XacmlApplicationParameters xacmlApplicationParameters =
111 testData.toObject(testData.getXacmlapplicationParametersMap(false,
112 apps.getAbsolutePath()), XacmlApplicationParameters.class);
113 XacmlPdpParameterGroup params =
114 new XacmlPdpParameterGroup("XacmlPdpParameters", "XacmlPdpGroup", "xacml", rest, policyApiParameters,
115 topicParameterGroup, xacmlApplicationParameters);
116 final Gson gson = new GsonBuilder().create();
117 File fileParams = appsFolder.resolve("params.json").toFile();
118 String jsonParams = gson.toJson(params);
119 LOGGER.info("Creating new params: {}", jsonParams);
120 Files.write(fileParams.toPath(), jsonParams.getBytes());
124 main = startXacmlPdpService(fileParams);
125 XacmlPdpActivator.getCurrent().enableApi();
127 // Make sure it is running
129 if (!NetworkUtil.isTcpPortOpen("localhost", port, 20, 1000L)) {
130 throw new IllegalStateException("Cannot connect to port " + port);
135 client = getNoAuthHttpClient();
139 static void after() {
140 stopXacmlPdpService(main);
145 void testDecision_UnsupportedAction() {
146 LOGGER.info("Running test testDecision_UnsupportedAction");
148 DecisionRequest request = new DecisionRequest();
149 request.setOnapName("DROOLS");
150 request.setAction("foo");
151 Map<String, Object> guard = new HashMap<String, Object>();
152 guard.put("actor", "foo");
153 guard.put("recipe", "bar");
154 guard.put("target", "somevnf");
155 guard.put("clname", "phoneyloop");
156 request.setResource(guard);
158 ErrorResponse response = getErrorDecision(request);
159 LOGGER.info("Response {}", response);
160 assertThat(response.getResponseCode()).isEqualTo(Status.BAD_REQUEST);
161 assertThat(response.getErrorMessage()).isEqualToIgnoringCase("No application for action foo");
165 void testDecision_Guard() {
166 LOGGER.info("Running test testDecision_Guard");
168 DecisionRequest request = new DecisionRequest();
169 request.setOnapName("DROOLS");
170 request.setAction("guard");
171 Map<String, Object> guard = new HashMap<String, Object>();
172 guard.put("actor", "foo");
173 guard.put("recipe", "bar");
174 guard.put("target", "somevnf");
175 guard.put("clname", "phoneyloop");
176 request.setResource(guard);
178 DecisionResponse response = getDecision(request);
179 LOGGER.info("Response {}", response);
180 assertThat(response.getStatus()).isEqualTo("Permit");
184 void testDecision_Native() throws IOException {
185 LOGGER.info("Running test testDecision_Native");
187 String xmlRequestAsString = ResourceUtils.getResourceAsString(
188 "src/test/resources/decisions/decision.native.request.xml");
189 if (xmlRequestAsString == null) {
190 throw new IOException("failed to read the xml request");
193 String jsonRequestAsString = ResourceUtils.getResourceAsString(
194 "src/test/resources/decisions/decision.native.request.json");
195 if (jsonRequestAsString == null) {
196 throw new IOException("failed to read the json request");
199 String responseFromXmlRequest = getNativeDecision(xmlRequestAsString, APPLICATION_XACML_XML);
200 LOGGER.info("Response from xml request {}", responseFromXmlRequest);
201 assertThat(responseFromXmlRequest).contains("<Response xmlns=").contains("NotApplicable");
203 String responseFromJsonRequest = getNativeDecision(jsonRequestAsString, APPLICATION_XACML_JSON);
204 LOGGER.info("Response from json request {}", responseFromJsonRequest);
205 assertThat(responseFromJsonRequest).contains("\"Response\":").contains("NotApplicable");
208 private static Main startXacmlPdpService(File params) throws PolicyXacmlPdpException {
209 final String[] xacmlPdpConfigParameters = {"-c", params.getAbsolutePath()};
210 return new Main(xacmlPdpConfigParameters);
213 private static void stopXacmlPdpService(final Main main) {
217 private DecisionResponse getDecision(DecisionRequest request) {
218 Entity<DecisionRequest> entityRequest = Entity.entity(request, MediaType.APPLICATION_JSON);
219 Response response = client.post("/decision", entityRequest, Collections.emptyMap());
221 assertEquals(200, response.getStatus());
223 return HttpClient.getBody(response, DecisionResponse.class);
226 private String getNativeDecision(String request, String mediaType) {
227 Entity<String> entityRequest = Entity.entity(request, mediaType);
228 Response response = client.post("/xacml", entityRequest, Map.of("Accept", mediaType));
230 assertEquals(200, response.getStatus());
232 return HttpClient.getBody(response, String.class);
235 private ErrorResponse getErrorDecision(DecisionRequest request) {
236 Entity<DecisionRequest> entityRequest = Entity.entity(request, MediaType.APPLICATION_JSON);
237 Response response = client.post("/decision", entityRequest, Collections.emptyMap());
239 assertEquals(400, response.getStatus());
241 return HttpClient.getBody(response, ErrorResponse.class);
244 private static HttpClient getNoAuthHttpClient() throws HttpClientConfigException {
245 return HttpClientFactoryInstance.getClientFactory().build(RestClientParameters.builder()
246 .clientName("testDecisionClient")
247 .useHttps(false).allowSelfSignedCerts(false).hostname("localhost").port(port)
248 .basePath("policy/pdpx/v1")
249 .userName("healthcheck").password("zb!XztG34").managed(true).build());
252 private static void copy(Path source, Path dest) {
254 LOGGER.info("Copying {} to {}", source, dest);
255 Files.copy(source, dest, StandardCopyOption.REPLACE_EXISTING);
256 } catch (IOException e) {
257 LOGGER.error("Failed to copy {} to {}", source, dest);