summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Mokry <michael.mokry@att.com>2019-02-27 07:42:20 -0600
committerMichael Mokry <michael.mokry@att.com>2019-03-11 14:13:38 -0500
commit4b2ef1a5a9bf92aeb7edc1512f7a6cd8e1be99d8 (patch)
treeba508d5273c39faff2b1ac046e3383a5f0a0aa70
parentc83093810cdfad0e3146ed937c11f7a61025b336 (diff)
Added HTTPS and CADI/AAF Support for PDP-X
- Yay I found the mysterious https issue that caused the junit to fail. Please don't laugh, it was a typo :) - Made changes per review comments 1) Added builder class for RestServer constructor 2) removed some try/catch blocks in junit 3) Other minor changes - More changes per review comments - Added changes per Ram's review comments (not lombrok yet) - Made changes for ONAP API CVS guidelines Change-Id: Ie1a6225459b3ce235cd73828ccddec04c690f5fd Issue-ID: POLICY-1436 Signed-off-by: Michael Mokry <michael.mokry@att.com>
-rw-r--r--main/src/main/java/org/onap/policy/pdpx/main/parameters/RestServerBuilder.java85
-rw-r--r--main/src/main/java/org/onap/policy/pdpx/main/parameters/RestServerParameters.java37
-rw-r--r--main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpAafFilter.java38
-rw-r--r--main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpRestController.java111
-rw-r--r--main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpRestServer.java8
-rw-r--r--main/src/main/java/org/onap/policy/pdpx/main/startstop/Main.java2
-rw-r--r--main/src/test/java/org/onap/policy/pdpx/main/parameters/CommonTestData.java13
-rw-r--r--main/src/test/java/org/onap/policy/pdpx/main/parameters/TestXacmlPdpParameterGroup.java2
-rw-r--r--main/src/test/java/org/onap/policy/pdpx/main/rest/TestXacmlPdpRestServer.java207
-rw-r--r--main/src/test/resources/parameters/XacmlPdpConfigParameters_Https.json10
-rw-r--r--main/src/test/resources/ssl/policy-keystorebin0 -> 4311 bytes
11 files changed, 445 insertions, 68 deletions
diff --git a/main/src/main/java/org/onap/policy/pdpx/main/parameters/RestServerBuilder.java b/main/src/main/java/org/onap/policy/pdpx/main/parameters/RestServerBuilder.java
new file mode 100644
index 00000000..90bc09f9
--- /dev/null
+++ b/main/src/main/java/org/onap/policy/pdpx/main/parameters/RestServerBuilder.java
@@ -0,0 +1,85 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.pdpx.main.parameters;
+
+public class RestServerBuilder {
+ private String host;
+ private int port;
+ private String userName;
+ private String password;
+ private boolean https;
+ private boolean aaf;
+
+
+ public String getHost() {
+ return host;
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public boolean isHttps() {
+ return https;
+ }
+
+ public boolean isAaf() {
+ return aaf;
+ }
+
+ public RestServerBuilder setHost(String host) {
+ this.host = host;
+ return this;
+ }
+
+ public RestServerBuilder setPort(int port) {
+ this.port = port;
+ return this;
+ }
+
+ public RestServerBuilder setUserName(String userName) {
+ this.userName = userName;
+ return this;
+ }
+
+ public RestServerBuilder setPassword(String password) {
+ this.password = password;
+ return this;
+ }
+
+ public RestServerBuilder setHttps(boolean https) {
+ this.https = https;
+ return this;
+ }
+
+ public RestServerBuilder setAaf(boolean aaf) {
+ this.aaf = aaf;
+ return this;
+ }
+}
diff --git a/main/src/main/java/org/onap/policy/pdpx/main/parameters/RestServerParameters.java b/main/src/main/java/org/onap/policy/pdpx/main/parameters/RestServerParameters.java
index e04a0f29..c452c758 100644
--- a/main/src/main/java/org/onap/policy/pdpx/main/parameters/RestServerParameters.java
+++ b/main/src/main/java/org/onap/policy/pdpx/main/parameters/RestServerParameters.java
@@ -35,21 +35,22 @@ public class RestServerParameters implements ParameterGroup {
private int port;
private String userName;
private String password;
+ private boolean https;
+ private boolean aaf;
/**
* Constructor for instantiating RestServerParameters.
*
- * @param host the host name
- * @param port the port
- * @param userName the user name
- * @param password the password
+ * @param builder the RestServer builder
*/
- public RestServerParameters(final String host, final int port, final String userName, final String password) {
+ public RestServerParameters(final RestServerBuilder builder) {
super();
- this.host = host;
- this.port = port;
- this.userName = userName;
- this.password = password;
+ this.host = builder.getHost();
+ this.port = builder.getPort();
+ this.userName = builder.getUserName();
+ this.password = builder.getPassword();
+ this.https = builder.isHttps();
+ this.aaf = builder.isAaf();
}
/**
@@ -99,6 +100,24 @@ public class RestServerParameters implements ParameterGroup {
}
/**
+ * Return the https flag of this RestServerParameters instance.
+ *
+ * @return the https flag
+ */
+ public boolean isHttps() {
+ return https;
+ }
+
+ /**
+ * Return the aaf flag of this RestServerParameters instance.
+ *
+ * @return the aaf flag
+ */
+ public boolean isAaf() {
+ return aaf;
+ }
+
+ /**
* Set the name of this RestServerParameters instance.
*
* @param name the name to set
diff --git a/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpAafFilter.java b/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpAafFilter.java
new file mode 100644
index 00000000..5a4c3bc6
--- /dev/null
+++ b/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpAafFilter.java
@@ -0,0 +1,38 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.pdpx.main.rest;
+
+import org.onap.policy.common.endpoints.http.server.aaf.AafGranularAuthFilter;
+
+/**
+ * Class to manage aaf filters for Xacml PDP component.
+ *
+ */
+public class XacmlPdpAafFilter extends AafGranularAuthFilter {
+
+ public static final String AAF_NODETYPE = "policy-pdpx";
+ public static final String AAF_ROOT_PERMISSION = DEFAULT_NAMESPACE + "." + AAF_NODETYPE;
+
+ @Override
+ public String getPermissionTypeRoot() {
+ return AAF_ROOT_PERMISSION;
+ }
+} \ No newline at end of file
diff --git a/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpRestController.java b/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpRestController.java
index dc091f03..965753ae 100644
--- a/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpRestController.java
+++ b/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpRestController.java
@@ -22,21 +22,27 @@ package org.onap.policy.pdpx.main.rest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.Authorization;
import io.swagger.annotations.BasicAuthDefinition;
+import io.swagger.annotations.Extension;
+import io.swagger.annotations.ExtensionProperty;
import io.swagger.annotations.Info;
+import io.swagger.annotations.ResponseHeader;
import io.swagger.annotations.SecurityDefinition;
import io.swagger.annotations.SwaggerDefinition;
-import io.swagger.annotations.Tag;
+import java.util.UUID;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.ResponseBuilder;
import org.onap.policy.common.endpoints.report.HealthCheckReport;
import org.onap.policy.pdpx.main.rest.model.Decision;
import org.onap.policy.pdpx.main.rest.model.StatisticsReport;
@@ -52,10 +58,10 @@ import org.onap.policy.pdpx.main.rest.provider.StatisticsProvider;
@Api
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
-@SwaggerDefinition(info = @Info(description = "Policy Xacml PDP Service", version = "v1.0", title = "Policy Xacml PDP"),
- consumes = {MediaType.APPLICATION_JSON}, produces = {MediaType.APPLICATION_JSON},
+@SwaggerDefinition(info = @Info(description = "Policy Xacml PDP Service", version = "1.0.0", title = "Policy Xacml PDP",
+ extensions = {@Extension(properties = {@ExtensionProperty(name = "planned-retirement-date", value = "tbd"),
+ @ExtensionProperty(name = "component", value = "Policy Framework")})}),
schemes = {SwaggerDefinition.Scheme.HTTP, SwaggerDefinition.Scheme.HTTPS},
- tags = {@Tag(name = "policy-pdpx", description = "Policy Xacml PDP Service Operations")},
securityDefinition = @SecurityDefinition(basicAuthDefinitions = {@BasicAuthDefinition(key = "basicAuth")}))
public class XacmlPdpRestController {
@@ -63,39 +69,108 @@ public class XacmlPdpRestController {
@Path("/healthcheck")
@ApiOperation(value = "Perform a system healthcheck",
notes = "Provides healthy status of the Policy Xacml PDP component", response = HealthCheckReport.class,
- authorizations = @Authorization(value = "basicAuth"))
- @ApiResponses(value = {
- @ApiResponse(code = 401, message = "Authentication Error"),
+ responseHeaders = {
+ @ResponseHeader(name = "X-MinorVersion",
+ description = "Used to request or communicate a MINOR version back from the client"
+ + " to the server, and from the server back to the client",
+ response = String.class),
+ @ResponseHeader(name = "X-PatchVersion",
+ description = "Used only to communicate a PATCH version in a response for"
+ + " troubleshooting purposes only, and will not be provided by"
+ + " the client on request",
+ response = String.class),
+ @ResponseHeader(name = "X-LatestVersion",
+ description = "Used only to communicate an API's latest version", response = String.class),
+ @ResponseHeader(name = "X-ONAP-RequestID",
+ description = "Used to track REST transactions for logging purpose",
+ response = UUID.class)},
+ authorizations = @Authorization(value = "basicAuth"), tags = {"HealthCheck",},
+ extensions = {@Extension(name = "interface info",
+ properties = {@ExtensionProperty(name = "pdpx-version", value = "1.0.0"),
+ @ExtensionProperty(name = "last-mod-release", value = "Dublin")})})
+ @ApiResponses(value = {@ApiResponse(code = 401, message = "Authentication Error"),
@ApiResponse(code = 403, message = "Authorization Error"),
@ApiResponse(code = 500, message = "Internal Server Error")})
- public Response healthcheck() {
- return Response.status(Response.Status.OK).entity(new HealthCheckProvider().performHealthCheck()).build();
+ public Response healthcheck(
+ @HeaderParam("X-ONAP-RequestID") @ApiParam("RequestID for http transaction") UUID requestId) {
+ return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
+ .entity(new HealthCheckProvider().performHealthCheck()).build();
}
@GET
@Path("/statistics")
@ApiOperation(value = "Fetch current statistics",
notes = "Provides current statistics of the Policy Xacml PDP component", response = StatisticsReport.class,
- authorizations = @Authorization(value = "basicAuth"))
- @ApiResponses(value = {
- @ApiResponse(code = 401, message = "Authentication Error"),
+ responseHeaders = {
+ @ResponseHeader(name = "X-MinorVersion",
+ description = "Used to request or communicate a MINOR version back from the client"
+ + " to the server, and from the server back to the client",
+ response = String.class),
+ @ResponseHeader(name = "X-PatchVersion",
+ description = "Used only to communicate a PATCH version in a response for"
+ + " troubleshooting purposes only, and will not be provided by"
+ + " the client on request",
+ response = String.class),
+ @ResponseHeader(name = "X-LatestVersion",
+ description = "Used only to communicate an API's latest version", response = String.class),
+ @ResponseHeader(name = "X-ONAP-RequestID",
+ description = "Used to track REST transactions for logging purpose",
+ response = UUID.class)},
+ authorizations = @Authorization(value = "basicAuth"), tags = {"Statistics",},
+ extensions = {@Extension(name = "interface info",
+ properties = {@ExtensionProperty(name = "pdpx-version", value = "1.0.0"),
+ @ExtensionProperty(name = "last-mod-release", value = "Dublin")})})
+ @ApiResponses(value = {@ApiResponse(code = 401, message = "Authentication Error"),
@ApiResponse(code = 403, message = "Authorization Error"),
@ApiResponse(code = 500, message = "Internal Server Error")})
- public Response statistics() {
- return Response.status(Response.Status.OK).entity(new StatisticsProvider().fetchCurrentStatistics()).build();
+ public Response statistics(
+ @HeaderParam("X-ONAP-RequestID") @ApiParam("RequestID for http transaction") UUID requestId) {
+ return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
+ .entity(new StatisticsProvider().fetchCurrentStatistics()).build();
}
@POST
@Path("/decision")
@ApiOperation(value = "Fetch the decision using specified decision parameters",
notes = "Returns the policy decision from Policy Xacml PDP", response = Decision.class,
- authorizations = @Authorization(value = "basicAuth"),
- tags = {"Decision",})
+ responseHeaders = {
+ @ResponseHeader(name = "X-MinorVersion",
+ description = "Used to request or communicate a MINOR version back from the client"
+ + " to the server, and from the server back to the client",
+ response = String.class),
+ @ResponseHeader(name = "X-PatchVersion",
+ description = "Used only to communicate a PATCH version in a response for"
+ + " troubleshooting purposes only, and will not be provided by"
+ + " the client on request",
+ response = String.class),
+ @ResponseHeader(name = "X-LatestVersion",
+ description = "Used only to communicate an API's latest version", response = String.class),
+ @ResponseHeader(name = "X-ONAP-RequestID",
+ description = "Used to track REST transactions for logging purpose",
+ response = UUID.class)},
+ authorizations = @Authorization(value = "basicAuth"), tags = {"Decision",},
+ extensions = {@Extension(name = "interface info",
+ properties = {@ExtensionProperty(name = "pdpx-version", value = "1.0.0"),
+ @ExtensionProperty(name = "last-mod-release", value = "Dublin")})})
@ApiResponses(value = {@ApiResponse(code = 400, message = "Bad Request"),
@ApiResponse(code = 401, message = "Authentication Error"),
@ApiResponse(code = 403, message = "Authorization Error"),
@ApiResponse(code = 500, message = "Internal Server Error")})
- public Response decision(Decision body) {
- return Response.status(Response.Status.OK).entity(new DecisionProvider().fetchDecision()).build();
+ public Response decision(Decision body,
+ @HeaderParam("X-ONAP-RequestID") @ApiParam("RequestID for http transaction") UUID requestId) {
+ return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
+ .entity(new DecisionProvider().fetchDecision()).build();
+ }
+
+ private ResponseBuilder addVersionControlHeaders(ResponseBuilder rb) {
+ return rb.header("X-MinorVersion", "0").header("X-PatchVersion", "0").header("X-LatestVersion", "1.0.0");
+ }
+
+ private ResponseBuilder addLoggingHeaders(ResponseBuilder rb, UUID requestId) {
+ if (requestId == null) {
+ // Generate a random uuid if client does not embed requestId in rest request
+ return rb.header("X-ONAP-RequestID", UUID.randomUUID());
+ }
+ return rb.header("X-ONAP-RequestID", requestId);
}
}
diff --git a/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpRestServer.java b/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpRestServer.java
index 90f0bfa1..eece1ffc 100644
--- a/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpRestServer.java
+++ b/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpRestServer.java
@@ -25,6 +25,7 @@ import java.util.List;
import java.util.Properties;
import org.onap.policy.common.capabilities.Startable;
import org.onap.policy.common.endpoints.http.server.HttpServletServer;
+import org.onap.policy.common.gson.JacksonHandler;
import org.onap.policy.pdpx.main.parameters.RestServerParameters;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -60,6 +61,9 @@ public class XacmlPdpRestServer implements Startable {
try {
servers = HttpServletServer.factory.build(getServerProperties());
for (final HttpServletServer server : servers) {
+ if (server.isAaf()) {
+ server.addFilterClass(null, XacmlPdpAafFilter.class.getCanonicalName());
+ }
server.start();
}
} catch (final Exception exp) {
@@ -89,6 +93,10 @@ public class XacmlPdpRestServer implements Startable {
restServerParameters.getUserName());
props.setProperty(HTTP_SERVER_SERVICES + SEPARATOR + restServerParameters.getName() + ".password",
restServerParameters.getPassword());
+ props.setProperty(HTTP_SERVER_SERVICES + SEPARATOR + restServerParameters.getName() + ".https",
+ String.valueOf(restServerParameters.isHttps()));
+ props.setProperty(HTTP_SERVER_SERVICES + SEPARATOR + restServerParameters.getName() + ".aaf",
+ String.valueOf(restServerParameters.isAaf()));
return props;
}
diff --git a/main/src/main/java/org/onap/policy/pdpx/main/startstop/Main.java b/main/src/main/java/org/onap/policy/pdpx/main/startstop/Main.java
index 91b38f9b..65e0a31e 100644
--- a/main/src/main/java/org/onap/policy/pdpx/main/startstop/Main.java
+++ b/main/src/main/java/org/onap/policy/pdpx/main/startstop/Main.java
@@ -51,7 +51,7 @@ public class Main {
*/
public Main(final String[] args) {
final String argumentString = Arrays.toString(args);
- LOGGER.info("Starting policy xacml pdp service with arguments - " + argumentString);
+ LOGGER.info("Starting policy xacml pdp service with arguments - {}", argumentString);
// Check the arguments
final XacmlPdpCommandLineArguments arguments = new XacmlPdpCommandLineArguments();
diff --git a/main/src/test/java/org/onap/policy/pdpx/main/parameters/CommonTestData.java b/main/src/test/java/org/onap/policy/pdpx/main/parameters/CommonTestData.java
index f50871ec..1bf2294c 100644
--- a/main/src/test/java/org/onap/policy/pdpx/main/parameters/CommonTestData.java
+++ b/main/src/test/java/org/onap/policy/pdpx/main/parameters/CommonTestData.java
@@ -30,6 +30,8 @@ public class CommonTestData {
private static final String REST_SERVER_USER = "healthcheck";
private static final int REST_SERVER_PORT = 6969;
private static final String REST_SERVER_HOST = "0.0.0.0";
+ private static final boolean REST_SERVER_HTTPS = false;
+ private static final boolean REST_SERVER_AAF = false;
public static final String PDPX_GROUP_NAME = "XacmlPdpGroup";
/**
@@ -39,13 +41,16 @@ public class CommonTestData {
* @return the restServerParameters object
*/
public RestServerParameters getRestServerParameters(final boolean isEmpty) {
- final RestServerParameters restServerParameters;
+ final RestServerBuilder builder;
if (!isEmpty) {
- restServerParameters = new RestServerParameters(REST_SERVER_HOST, REST_SERVER_PORT, REST_SERVER_USER,
- REST_SERVER_PASSWORD);
+ builder = new RestServerBuilder().setHost(REST_SERVER_HOST).setPort(REST_SERVER_PORT)
+ .setUserName(REST_SERVER_USER).setPassword(REST_SERVER_PASSWORD).setHttps(REST_SERVER_HTTPS)
+ .setAaf(REST_SERVER_AAF);
} else {
- restServerParameters = new RestServerParameters(null, 0, null, null);
+ builder = new RestServerBuilder().setHost(null).setPort(0).setUserName(null).setPassword(null)
+ .setHttps(REST_SERVER_HTTPS).setAaf(REST_SERVER_AAF);
}
+ final RestServerParameters restServerParameters = new RestServerParameters(builder);
return restServerParameters;
}
diff --git a/main/src/test/java/org/onap/policy/pdpx/main/parameters/TestXacmlPdpParameterGroup.java b/main/src/test/java/org/onap/policy/pdpx/main/parameters/TestXacmlPdpParameterGroup.java
index 4b9db99d..48606c98 100644
--- a/main/src/test/java/org/onap/policy/pdpx/main/parameters/TestXacmlPdpParameterGroup.java
+++ b/main/src/test/java/org/onap/policy/pdpx/main/parameters/TestXacmlPdpParameterGroup.java
@@ -47,6 +47,8 @@ public class TestXacmlPdpParameterGroup {
assertEquals(restServerParameters.getUserName(), pdpxParameters.getRestServerParameters().getUserName());
assertEquals(restServerParameters.getPassword(), pdpxParameters.getRestServerParameters().getPassword());
assertEquals(CommonTestData.PDPX_GROUP_NAME, pdpxParameters.getName());
+ assertFalse(pdpxParameters.getRestServerParameters().isHttps());
+ assertFalse(pdpxParameters.getRestServerParameters().isAaf());
}
@Test
diff --git a/main/src/test/java/org/onap/policy/pdpx/main/rest/TestXacmlPdpRestServer.java b/main/src/test/java/org/onap/policy/pdpx/main/rest/TestXacmlPdpRestServer.java
index 2170c8a3..0f608e29 100644
--- a/main/src/test/java/org/onap/policy/pdpx/main/rest/TestXacmlPdpRestServer.java
+++ b/main/src/test/java/org/onap/policy/pdpx/main/rest/TestXacmlPdpRestServer.java
@@ -18,7 +18,6 @@
* ============LICENSE_END=========================================================
*/
-
package org.onap.policy.pdpx.main.rest;
import static org.junit.Assert.assertEquals;
@@ -26,6 +25,14 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+import java.util.Properties;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
@@ -33,19 +40,20 @@ import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
+import org.junit.After;
import org.junit.Test;
import org.onap.policy.common.endpoints.report.HealthCheckReport;
import org.onap.policy.common.utils.network.NetworkUtil;
import org.onap.policy.pdpx.main.PolicyXacmlPdpException;
import org.onap.policy.pdpx.main.parameters.CommonTestData;
import org.onap.policy.pdpx.main.parameters.RestServerParameters;
+import org.onap.policy.pdpx.main.rest.model.StatisticsReport;
import org.onap.policy.pdpx.main.startstop.Main;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
/**
- * Class to perform unit test of HealthCheckMonitor.
+ * Class to perform unit test of {@link XacmlPdpRestServer}.
*
*/
public class TestXacmlPdpRestServer {
@@ -55,45 +63,124 @@ public class TestXacmlPdpRestServer {
private static final String ALIVE = "alive";
private static final String SELF = "self";
private static final String NAME = "Policy Xacml PDP";
+ private static final String HEALTHCHECK_ENDPOINT = "healthcheck";
+ private static final String STATISTICS_ENDPOINT = "statistics";
+ private static String KEYSTORE = System.getProperty("user.dir") + "/src/test/resources/ssl/policy-keystore";
+ private Main main;
+ private XacmlPdpRestServer restServer;
- @Test
- public void testHealthCheckSuccess() throws PolicyXacmlPdpException, InterruptedException {
- final String reportString = "Report [name=Policy Xacml PDP, url=self, healthy=true, code=200, message=alive]";
+ /**
+ * Method for cleanup after each test.
+ */
+ @After
+ public void teardown() {
try {
- final Main main = startXacmlPdpService();
- final HealthCheckReport report = performHealthCheck();
- validateReport(NAME, SELF, true, 200, ALIVE, reportString, report);
- stopXacmlPdpService(main);
- } catch (final Exception e) {
- LOGGER.error("testHealthCheckSuccess failed", e);
- fail("Test should not throw an exception");
+ if (NetworkUtil.isTcpPortOpen("localhost", 6969, 1, 1000L)) {
+ if (main != null) {
+ stopXacmlPdpService(main);
+ }
+
+ if (restServer != null) {
+ restServer.stop();
+ }
+ }
+ } catch (IOException | PolicyXacmlPdpException e) {
+ LOGGER.error("teardown failed", e);
+ } catch (InterruptedException ie) {
+ Thread.interrupted();
+ LOGGER.error("teardown failed", ie);
}
+ }
+ @Test
+ public void testHealthCheckSuccess() throws IOException, InterruptedException {
+ main = startXacmlPdpService(true);
+ final Invocation.Builder invocationBuilder = sendHttpRequest(HEALTHCHECK_ENDPOINT);
+ final HealthCheckReport report = invocationBuilder.get(HealthCheckReport.class);
+ validateHealthCheckReport(NAME, SELF, true, 200, ALIVE, report);
}
@Test
- public void testHealthCheckFailure() throws InterruptedException {
- final String reportString =
- "Report [name=Policy Xacml PDP, url=self, healthy=false, code=500, message=not alive]";
+ public void testHealthCheckFailure() throws InterruptedException, IOException {
final RestServerParameters restServerParams = new CommonTestData().getRestServerParameters(false);
restServerParams.setName(CommonTestData.PDPX_GROUP_NAME);
- final XacmlPdpRestServer restServer = new XacmlPdpRestServer(restServerParams);
+ restServer = new XacmlPdpRestServer(restServerParams);
+ restServer.start();
+ final Invocation.Builder invocationBuilder = sendHttpRequest(HEALTHCHECK_ENDPOINT);
+ final HealthCheckReport report = invocationBuilder.get(HealthCheckReport.class);
+ validateHealthCheckReport(NAME, SELF, false, 500, NOT_ALIVE, report);
+ assertTrue(restServer.isAlive());
+ assertTrue(restServer.toString().startsWith("XacmlPdpRestServer [servers="));
+ }
+
+ @Test
+ public void testHttpsHealthCheckSuccess() throws Exception {
+ main = startXacmlPdpService(false);
+ final Invocation.Builder invocationBuilder = sendHttpsRequest(HEALTHCHECK_ENDPOINT);
+ final HealthCheckReport report = invocationBuilder.get(HealthCheckReport.class);
+ validateHealthCheckReport(NAME, SELF, true, 200, ALIVE, report);
+ }
+
+ @Test
+ public void testStatistics_200() throws IOException, InterruptedException {
+ main = startXacmlPdpService(true);
+ Invocation.Builder invocationBuilder = sendHttpRequest(STATISTICS_ENDPOINT);
+ StatisticsReport report = invocationBuilder.get(StatisticsReport.class);
+ validateStatisticsReport(report, 0, 200);
+ updateXacmlPdpStatistics();
+ invocationBuilder = sendHttpRequest(STATISTICS_ENDPOINT);
+ report = invocationBuilder.get(StatisticsReport.class);
+ validateStatisticsReport(report, 1, 200);
+ XacmlPdpStatisticsManager.resetAllStatistics();
+ }
+
+ @Test
+ public void testStatistics_500() throws IOException, InterruptedException {
+ final RestServerParameters restServerParams = new CommonTestData().getRestServerParameters(false);
+ restServerParams.setName(CommonTestData.PDPX_GROUP_NAME);
+ restServer = new XacmlPdpRestServer(restServerParams);
+ restServer.start();
+ final Invocation.Builder invocationBuilder = sendHttpRequest(STATISTICS_ENDPOINT);
+ final StatisticsReport report = invocationBuilder.get(StatisticsReport.class);
+ validateStatisticsReport(report, 0, 500);
+ XacmlPdpStatisticsManager.resetAllStatistics();
+ }
+
+ @Test
+ public void testHttpsStatistic() throws Exception {
+ main = startXacmlPdpService(false);
+ final Invocation.Builder invocationBuilder = sendHttpsRequest(STATISTICS_ENDPOINT);
+ final StatisticsReport report = invocationBuilder.get(StatisticsReport.class);
+ validateStatisticsReport(report, 0, 200);
+ }
+ @Test
+ public void testStatisticsConstructorIsPrivate() {
try {
- restServer.start();
- final HealthCheckReport report = performHealthCheck();
- validateReport(NAME, SELF, false, 500, NOT_ALIVE, reportString, report);
- assertTrue(restServer.isAlive());
- assertTrue(restServer.toString().startsWith("XacmlPdpRestServer [servers="));
- restServer.shutdown();
- } catch (final Exception e) {
- LOGGER.error("testHealthCheckSuccess failed", e);
- fail("Test should not throw an exception");
+ final Constructor<XacmlPdpStatisticsManager> constructor =
+ XacmlPdpStatisticsManager.class.getDeclaredConstructor();
+ assertTrue(Modifier.isPrivate(constructor.getModifiers()));
+ constructor.setAccessible(true);
+ constructor.newInstance();
+ fail("Expected an InstantiationException to be thrown");
+ } catch (final Exception exp) {
+ assertTrue(exp.getCause().toString().contains("Instantiation of the class is not allowed"));
}
}
- private Main startXacmlPdpService() {
- final String[] xacmlPdpConfigParameters = {"-c", "parameters/XacmlPdpConfigParameters.json"};
+ private Main startXacmlPdpService(final boolean http) {
+ final String[] xacmlPdpConfigParameters = new String[2];
+ if (http) {
+ xacmlPdpConfigParameters[0] = "-c";
+ xacmlPdpConfigParameters[1] = "parameters/XacmlPdpConfigParameters.json";
+ } else {
+ final Properties systemProps = System.getProperties();
+ systemProps.put("javax.net.ssl.keyStore", KEYSTORE);
+ systemProps.put("javax.net.ssl.keyStorePassword", "Pol1cy_0nap");
+ System.setProperties(systemProps);
+ xacmlPdpConfigParameters[0] = "-c";
+ xacmlPdpConfigParameters[1] = "parameters/XacmlPdpConfigParameters_Https.json";
+ }
return new Main(xacmlPdpConfigParameters);
}
@@ -101,32 +188,80 @@ public class TestXacmlPdpRestServer {
main.shutdown();
}
- private HealthCheckReport performHealthCheck() throws InterruptedException, IOException {
-
+ private Invocation.Builder sendHttpRequest(final String endpoint) throws IOException, InterruptedException {
final ClientConfig clientConfig = new ClientConfig();
final HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic("healthcheck", "zb!XztG34");
clientConfig.register(feature);
final Client client = ClientBuilder.newClient(clientConfig);
- final WebTarget webTarget = client.target("http://localhost:6969/policy/pdpx/v1/healthcheck");
+ final WebTarget webTarget = client.target("http://localhost:6969/policy/pdpx/v1/" + endpoint);
final Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON);
if (!NetworkUtil.isTcpPortOpen("localhost", 6969, 6, 10000L)) {
- throw new IllegalStateException("Cannot connect to port 6969");
+ throw new IllegalStateException("cannot connect to port 6969");
}
+ return invocationBuilder;
+ }
+
+ private Invocation.Builder sendHttpsRequest(final String endpoint) throws Exception {
+
+ final TrustManager[] noopTrustManager = new TrustManager[] {new X509TrustManager() {
+
+ @Override
+ public X509Certificate[] getAcceptedIssuers() {
+ return new X509Certificate[0];
+ }
+
+ @Override
+ public void checkClientTrusted(final java.security.cert.X509Certificate[] certs, final String authType) {}
+
+ @Override
+ public void checkServerTrusted(final java.security.cert.X509Certificate[] certs, final String authType) {}
+ }};
+
+ final SSLContext sc = SSLContext.getInstance("TLSv1.2");
+ sc.init(null, noopTrustManager, new SecureRandom());
+ final ClientBuilder clientBuilder =
+ ClientBuilder.newBuilder().sslContext(sc).hostnameVerifier((host, session) -> true);
+ final Client client = clientBuilder.build();
+ final HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic("healthcheck", "zb!XztG34");
+ client.register(feature);
- return invocationBuilder.get(HealthCheckReport.class);
+ final WebTarget webTarget = client.target("https://localhost:6969/policy/pdpx/v1/" + endpoint);
+
+ final Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON);
+
+ if (!NetworkUtil.isTcpPortOpen("localhost", 6969, 6, 10000L)) {
+ throw new IllegalStateException("cannot connect to port 6969");
+ }
+ return invocationBuilder;
+ }
+
+ private void updateXacmlPdpStatistics() {
+ XacmlPdpStatisticsManager.updateTotalPoliciesCount();
+ XacmlPdpStatisticsManager.updatePermitDecisionsCount();
+ XacmlPdpStatisticsManager.updateDenyDecisionsCount();
+ XacmlPdpStatisticsManager.updateIndeterminantDecisionsCount();
+ XacmlPdpStatisticsManager.updateNotApplicableDecisionsCount();
+ }
+
+ private void validateStatisticsReport(final StatisticsReport report, final int count, final int code) {
+ assertEquals(code, report.getCode());
+ assertEquals(count, report.getTotalPoliciesCount());
+ assertEquals(count, report.getPermitDecisionsCount());
+ assertEquals(count, report.getDenyDecisionsCount());
+ assertEquals(count, report.getIndeterminantDecisionsCount());
+ assertEquals(count, report.getNotApplicableDecisionsCount());
}
- private void validateReport(final String name, final String url, final boolean healthy, final int code,
- final String message, final String reportString, final HealthCheckReport report) {
+ private void validateHealthCheckReport(final String name, final String url, final boolean healthy, final int code,
+ final String message, final HealthCheckReport report) {
assertEquals(name, report.getName());
assertEquals(url, report.getUrl());
assertEquals(healthy, report.isHealthy());
assertEquals(code, report.getCode());
assertEquals(message, report.getMessage());
- assertEquals(reportString, report.toString());
}
}
diff --git a/main/src/test/resources/parameters/XacmlPdpConfigParameters_Https.json b/main/src/test/resources/parameters/XacmlPdpConfigParameters_Https.json
new file mode 100644
index 00000000..b467fe4c
--- /dev/null
+++ b/main/src/test/resources/parameters/XacmlPdpConfigParameters_Https.json
@@ -0,0 +1,10 @@
+{
+ "name":"XacmlPdpGroup",
+ "restServerParameters":{
+ "host":"0.0.0.0",
+ "port":6969,
+ "userName":"healthcheck",
+ "password":"zb!XztG34",
+ "https":true
+ }
+} \ No newline at end of file
diff --git a/main/src/test/resources/ssl/policy-keystore b/main/src/test/resources/ssl/policy-keystore
new file mode 100644
index 00000000..7d2b1ecc
--- /dev/null
+++ b/main/src/test/resources/ssl/policy-keystore
Binary files differ