Test decision from main entry
[policy/xacml-pdp.git] / main / src / test / java / org / onap / policy / pdpx / main / rest / TestDecision.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.pdpx.main.rest;
22
23 import static org.assertj.core.api.Assertions.assertThat;
24 import static org.junit.Assert.assertEquals;
25
26 import com.google.gson.Gson;
27 import com.google.gson.GsonBuilder;
28
29 import java.io.File;
30 import java.io.IOException;
31 import java.nio.file.Files;
32 import java.nio.file.Path;
33 import java.nio.file.Paths;
34 import java.nio.file.StandardCopyOption;
35 import java.security.KeyManagementException;
36 import java.security.NoSuchAlgorithmException;
37 import java.util.Collections;
38 import java.util.HashMap;
39 import java.util.Map;
40
41 import javax.ws.rs.client.Client;
42 import javax.ws.rs.client.ClientBuilder;
43 import javax.ws.rs.client.Entity;
44 import javax.ws.rs.client.Invocation;
45 import javax.ws.rs.client.WebTarget;
46 import javax.ws.rs.core.MediaType;
47 import javax.ws.rs.core.Response;
48 import javax.ws.rs.core.Response.Status;
49
50 import org.glassfish.jersey.client.ClientConfig;
51 import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
52 import org.junit.AfterClass;
53 import org.junit.BeforeClass;
54 import org.junit.ClassRule;
55 import org.junit.Test;
56 import org.junit.rules.TemporaryFolder;
57 import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams;
58 import org.onap.policy.common.endpoints.http.client.HttpClient;
59 import org.onap.policy.common.gson.GsonMessageBodyHandler;
60 import org.onap.policy.common.utils.network.NetworkUtil;
61 import org.onap.policy.models.decisions.concepts.DecisionRequest;
62 import org.onap.policy.models.decisions.concepts.DecisionResponse;
63 import org.onap.policy.models.errors.concepts.ErrorResponse;
64 import org.onap.policy.pdpx.main.PolicyXacmlPdpException;
65 import org.onap.policy.pdpx.main.parameters.RestServerBuilder;
66 import org.onap.policy.pdpx.main.parameters.RestServerParameters;
67 import org.onap.policy.pdpx.main.parameters.XacmlPdpParameterGroup;
68 import org.onap.policy.pdpx.main.startstop.Main;
69 import org.slf4j.Logger;
70 import org.slf4j.LoggerFactory;
71
72 public class TestDecision {
73
74     private static final Logger LOGGER = LoggerFactory.getLogger(TestDecision.class);
75
76     private static Main main;
77
78     @ClassRule
79     public static final TemporaryFolder appsFolder = new TemporaryFolder();
80
81     /**
82      * BeforeClass setup environment.
83      * @throws IOException Cannot create temp apps folder
84      */
85     @BeforeClass
86     public static void beforeClass() throws IOException {
87         System.setProperty("org.eclipse.jetty.util.log.class", "org.eclipse.jetty.util.log.StdErrLog");
88         System.setProperty("org.eclipse.jetty.LEVEL", "OFF");
89         //
90         // Copy test directory over of the application directories
91         //
92         Path src = Paths.get("../packages/policy-xacmlpdp-tarball/src/main/resources/apps");
93         File apps = appsFolder.newFolder("apps");
94         Files.walk(src).forEach(source -> {
95             copy(source, apps.toPath().resolve(src.relativize(source)));
96         });
97         //
98         // Get the parameters file correct.
99         //
100         RestServerParameters rest = new RestServerParameters(new RestServerBuilder()
101                 .setHost("0.0.0.0").setPort(6969).setUserName("healthcheck").setPassword("zb!XztG34"));
102         XacmlPdpParameterGroup params = new XacmlPdpParameterGroup("XacmlPdpGroup", rest, apps.getAbsolutePath());
103         final Gson gson = new GsonBuilder().create();
104         File fileParams = appsFolder.newFile("params.json");
105         String jsonParams = gson.toJson(params);
106         LOGGER.info("Creating new params: {}", jsonParams);
107         Files.write(fileParams.toPath(), jsonParams.getBytes());
108         //
109         // Start the service
110         //
111         main = startXacmlPdpService(fileParams);
112     }
113
114     @AfterClass
115     public static void after() throws PolicyXacmlPdpException {
116         stopXacmlPdpService(main);
117     }
118
119     @Test
120     public void testDecision_UnsupportedAction() throws KeyManagementException, NoSuchAlgorithmException,
121         ClassNotFoundException {
122
123         LOGGER.info("Running test testDecision_UnsupportedAction");
124
125         DecisionRequest request = new DecisionRequest();
126         request.setOnapName("DROOLS");
127         request.setAction("foo");
128         Map<String, Object> guard = new HashMap<String, Object>();
129         guard.put("actor", "foo");
130         guard.put("recipe", "bar");
131         guard.put("target", "somevnf");
132         guard.put("clname", "phoneyloop");
133         request.setResource(guard);
134
135         ErrorResponse response = getErrorDecision(request);
136         LOGGER.info("Response {}", response);
137         assertThat(response.getResponseCode()).isEqualTo(Status.BAD_REQUEST);
138         assertThat(response.getErrorMessage()).isEqualToIgnoringCase("No application for action foo");
139     }
140
141     @Test
142     public void testDecision_Guard() throws InterruptedException, IOException {
143         LOGGER.info("Running test testDecision_Guard");
144
145         DecisionRequest request = new DecisionRequest();
146         request.setOnapName("DROOLS");
147         request.setAction("guard");
148         Map<String, Object> guard = new HashMap<String, Object>();
149         guard.put("actor", "foo");
150         guard.put("recipe", "bar");
151         guard.put("target", "somevnf");
152         guard.put("clname", "phoneyloop");
153         request.setResource(guard);
154
155         DecisionResponse response = getDecision(request);
156         LOGGER.info("Response {}", response);
157         assertThat(response.getStatus()).isEqualTo("Permit");
158     }
159
160     private static Main startXacmlPdpService(File params) {
161         final String[] XacmlPdpConfigParameters = {"-c", params.getAbsolutePath(), "-p",
162             "parameters/topic.properties"};
163         return new Main(XacmlPdpConfigParameters);
164     }
165
166     private static void stopXacmlPdpService(final Main main) throws PolicyXacmlPdpException {
167         main.shutdown();
168     }
169
170     private DecisionResponse getDecision(DecisionRequest request) throws InterruptedException, IOException {
171         final ClientConfig clientConfig = new ClientConfig();
172
173         final HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic("healthcheck", "zb!XztG34");
174         clientConfig.register(feature);
175
176         final Client client = ClientBuilder.newClient(clientConfig);
177         final WebTarget webTarget = client.target("http://localhost:6969/policy/pdpx/v1/decision");
178
179         final Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON);
180
181         if (!NetworkUtil.isTcpPortOpen("localhost", 6969, 6, 10000L)) {
182             throw new IllegalStateException("Cannot connect to port 6969");
183         }
184
185         return invocationBuilder.post(Entity.json(request), DecisionResponse.class);
186     }
187
188     private ErrorResponse getErrorDecision(DecisionRequest request) throws KeyManagementException,
189         NoSuchAlgorithmException, ClassNotFoundException {
190
191         HttpClient client = getNoAuthHttpClient();
192
193         Entity<DecisionRequest> entityRequest = Entity.entity(request, MediaType.APPLICATION_JSON);
194         Response response = client.post("", entityRequest, Collections.emptyMap());
195
196         assertEquals(400, response.getStatus());
197
198         return HttpClient.getBody(response, ErrorResponse.class);
199     }
200
201     private HttpClient getNoAuthHttpClient()
202             throws KeyManagementException, NoSuchAlgorithmException, ClassNotFoundException {
203         return HttpClient.factory.build(BusTopicParams.builder()
204                 .clientName("testDecisionClient")
205                 .serializationProvider(GsonMessageBodyHandler.class.getName())
206                 .useHttps(false).allowSelfSignedCerts(false).hostname("localhost").port(6969)
207                 .basePath("policy/pdpx/v1/decision")
208                 .userName("healthcheck").password("zb!XztG34").managed(true).build());
209     }
210
211     private static void copy(Path source, Path dest) {
212         try {
213             LOGGER.info("Copying {} to {}", source, dest);
214             Files.copy(source, dest, StandardCopyOption.REPLACE_EXISTING);
215         } catch (IOException e) {
216             LOGGER.error("Failed to copy {} to {}", source, dest);
217         }
218     }
219
220 }