From 9bf471abe906598ffd2cd280d372e7cb9474a418 Mon Sep 17 00:00:00 2001 From: Pamela Dragosh Date: Tue, 2 Apr 2019 14:48:38 -0700 Subject: [PATCH] Tie XACML REST Decision Ties the decision API to the applications. Adds a static application manager class to manager the applications. Added applicationPath as a parameter to be supported in the Json parameter group. Issue-ID: POLICY-1440 Change-Id: I43cb44b3e308aadcf258fd987f3b53944c2edb72 Signed-off-by: Pamela Dragosh --- .../pdpx/main/parameters/RestServerBuilder.java | 1 - .../main/parameters/XacmlPdpParameterGroup.java | 27 +++- .../pdpx/main/rest/XacmlPdpApplicationManager.java | 122 +++++++++++++++ .../pdpx/main/rest/XacmlPdpRestController.java | 31 +++- .../policy/pdpx/main/rest/XacmlPdpRestServer.java | 47 ++---- .../onap/policy/pdpx/main/rest/model/Decision.java | 37 ----- .../pdpx/main/rest/provider/DecisionProvider.java | 33 +++- .../pdpx/main/startstop/XacmlPdpActivator.java | 3 +- .../parameters/TestXacmlPdpParameterGroup.java | 30 +++- .../parameters/TestXacmlPdpParameterHandler.java | 13 +- .../onap/policy/pdpx/main/rest/TestDecision.java | 172 +++++++++++++++++++++ .../pdpx/main/rest/TestXacmlPdpRestServer.java | 17 +- .../pdpx/main/rest/TestXacmlPdpStatistics.java | 19 ++- .../resources/parameters/MinimumParameters.json | 3 +- .../parameters/XacmlPdpConfigParameters.json | 3 +- .../parameters/XacmlPdpConfigParameters_Https.json | 3 +- 16 files changed, 456 insertions(+), 105 deletions(-) create mode 100644 main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpApplicationManager.java delete mode 100644 main/src/main/java/org/onap/policy/pdpx/main/rest/model/Decision.java create mode 100644 main/src/test/java/org/onap/policy/pdpx/main/rest/TestDecision.java 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 index 90bc09f9..6c729f21 100644 --- 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 @@ -28,7 +28,6 @@ public class RestServerBuilder { private boolean https; private boolean aaf; - public String getHost() { return host; } diff --git a/main/src/main/java/org/onap/policy/pdpx/main/parameters/XacmlPdpParameterGroup.java b/main/src/main/java/org/onap/policy/pdpx/main/parameters/XacmlPdpParameterGroup.java index 2c972641..e442a087 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/parameters/XacmlPdpParameterGroup.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/parameters/XacmlPdpParameterGroup.java @@ -30,17 +30,22 @@ import org.onap.policy.common.utils.validation.ParameterValidationUtils; * */ public class XacmlPdpParameterGroup implements ParameterGroup { + private static final String PARAM_REST_SERVER = "restServerParameters"; + private static final String PARAM_APPLICATION_PATH = "applicationPath"; private String name; private RestServerParameters restServerParameters; + private String applicationPath; /** * Create the xacml pdp parameter group. * * @param name the parameter group name */ - public XacmlPdpParameterGroup(final String name, final RestServerParameters restServerParameters) { + public XacmlPdpParameterGroup(final String name, final RestServerParameters restServerParameters, + final String applicationPath) { this.name = name; this.restServerParameters = restServerParameters; + this.applicationPath = applicationPath; } /** @@ -72,6 +77,15 @@ public class XacmlPdpParameterGroup implements ParameterGroup { return restServerParameters; } + /** + * Returns the path where applications will store their data. + * + * @return String to the path + */ + public String getApplicationPath() { + return applicationPath; + } + /** * Validate the parameter group. * @@ -84,10 +98,17 @@ public class XacmlPdpParameterGroup implements ParameterGroup { validationResult.setResult("name", ValidationStatus.INVALID, "must be a non-blank string"); } if (restServerParameters == null) { - validationResult.setResult("restServerParameters", ValidationStatus.INVALID, + validationResult.setResult(PARAM_REST_SERVER, ValidationStatus.INVALID, "must have restServerParameters to configure xacml pdp rest server"); } else { - validationResult.setResult("restServerParameters", restServerParameters.validate()); + validationResult.setResult(PARAM_REST_SERVER, restServerParameters.validate()); + } + // + // Validate the application path directory + // + if (applicationPath == null || applicationPath.isEmpty()) { + validationResult.setResult(PARAM_APPLICATION_PATH, ValidationStatus.INVALID, + "must have application path for applications to store policies and data."); } return validationResult; } diff --git a/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpApplicationManager.java b/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpApplicationManager.java new file mode 100644 index 00000000..c97166c1 --- /dev/null +++ b/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpApplicationManager.java @@ -0,0 +1,122 @@ +/*- + * ============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 java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.ServiceLoader; + +import org.onap.policy.models.decisions.concepts.DecisionRequest; +import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class XacmlPdpApplicationManager { + private static final Logger LOGGER = LoggerFactory.getLogger(XacmlPdpApplicationManager.class); + + private static boolean needsInit = true; + private static ServiceLoader applicationLoader; + private static Map providerActionMap = new HashMap<>(); + + private XacmlPdpApplicationManager() { + super(); + } + + /** + * One time to initialize the applications upon startup. + */ + public static void initializeApplications(Path applicationPath) { + // + // If we have already done this + // + if (! needsInit) { + LOGGER.error("Already initialized the applications"); + return; + } + // + // Load service + // + applicationLoader = ServiceLoader.load(XacmlApplicationServiceProvider.class); + // + // Iterate through them + // + Iterator iterator = applicationLoader.iterator(); + while (iterator.hasNext()) { + // + // Get the application + // + XacmlApplicationServiceProvider application = iterator.next(); + LOGGER.info("Application {} supports {}", application.applicationName(), + application.supportedPolicyTypes()); + // + // Iterate each application + // + int pathCount = 1; + for (String action : application.actionDecisionsSupported()) { + // + // Save the actions that it supports + // + providerActionMap.put(action, application); + // + // Create a unique path for the application to store its data + // May need to scan this name to remove unsafe characters etc. + // But for debugging purposes, its good to use the application name + // + // + Path path = Paths.get(applicationPath.toAbsolutePath().toString(), + application.applicationName(), Integer.toString(pathCount++)); + // + // Have the application initialize + // + application.initialize(path); + } + } + // + // we have initialized + // + needsInit = false; + } + + public static XacmlApplicationServiceProvider findApplication(DecisionRequest request) { + return providerActionMap.get(request.getAction()); + } + + /** + * Returns the current count of policy types supported. This could be misleading a bit + * as some applications can support wildcard of policy types. Eg. onap.Monitoring.* as + * well as individual types/versions. Nevertheless useful for debugging and testing. + * + * @return Total count added from all applications + */ + public static long getPolicyTypeCount() { + Iterator iterator = applicationLoader.iterator(); + long types = 0; + while (iterator.hasNext()) { + XacmlApplicationServiceProvider application = iterator.next(); + types += application.supportedPolicyTypes().size(); + } + return types; + } + +} 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 965753ae..c61bef24 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 @@ -33,7 +33,9 @@ import io.swagger.annotations.Info; import io.swagger.annotations.ResponseHeader; import io.swagger.annotations.SecurityDefinition; import io.swagger.annotations.SwaggerDefinition; + import java.util.UUID; + import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; @@ -43,8 +45,12 @@ 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.models.decisions.concepts.DecisionException; +import org.onap.policy.models.decisions.concepts.DecisionRequest; +import org.onap.policy.models.decisions.concepts.DecisionResponse; +import org.onap.policy.models.errors.concepts.ErrorResponse; import org.onap.policy.pdpx.main.rest.model.StatisticsReport; import org.onap.policy.pdpx.main.rest.provider.DecisionProvider; import org.onap.policy.pdpx.main.rest.provider.HealthCheckProvider; @@ -129,10 +135,17 @@ public class XacmlPdpRestController { .entity(new StatisticsProvider().fetchCurrentStatistics()).build(); } + /** + * Our decision entry point. + * + * @param body Should be a DecisionRequest object + * @param requestId Unique request id + * @return DecisionResponse or ErrorResponse object + */ @POST @Path("/decision") @ApiOperation(value = "Fetch the decision using specified decision parameters", - notes = "Returns the policy decision from Policy Xacml PDP", response = Decision.class, + notes = "Returns the policy decision from Policy Xacml PDP", response = DecisionResponse.class, responseHeaders = { @ResponseHeader(name = "X-MinorVersion", description = "Used to request or communicate a MINOR version back from the client" @@ -152,14 +165,20 @@ public class XacmlPdpRestController { 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"), + @ApiResponses(value = {@ApiResponse(code = 400, message = "Bad Request", response = ErrorResponse.class), @ApiResponse(code = 401, message = "Authentication Error"), @ApiResponse(code = 403, message = "Authorization Error"), @ApiResponse(code = 500, message = "Internal Server Error")}) - public Response decision(Decision body, + public Response decision(DecisionRequest 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(); + try { + return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId) + .entity(new DecisionProvider().fetchDecision(body)).build(); + } catch (DecisionException e) { + return addLoggingHeaders( + addVersionControlHeaders(Response.status((e.getErrorResponse().getResponseCode()))), requestId) + .entity(e.getErrorResponse()).build(); + } } private ResponseBuilder addVersionControlHeaders(ResponseBuilder rb) { 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 f3b7a54e..67bbccaa 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 @@ -20,15 +20,14 @@ package org.onap.policy.pdpx.main.rest; +import java.nio.file.Paths; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import java.util.Properties; -import java.util.ServiceLoader; import org.onap.policy.common.capabilities.Startable; import org.onap.policy.common.endpoints.http.server.HttpServletServer; -import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider; +import org.onap.policy.common.gson.GsonMessageBodyHandler; import org.onap.policy.pdpx.main.parameters.RestServerParameters; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,16 +45,16 @@ public class XacmlPdpRestServer implements Startable { private List servers = new ArrayList<>(); private RestServerParameters restServerParameters; - - private ServiceLoader applicationLoader; + private String applicationPath; /** * Constructor for instantiating XacmlPdpRestServer. * * @param restServerParameters the rest server parameters */ - public XacmlPdpRestServer(final RestServerParameters restServerParameters) { + public XacmlPdpRestServer(final RestServerParameters restServerParameters, final String applicationPath) { this.restServerParameters = restServerParameters; + this.applicationPath = applicationPath; } /** @@ -65,9 +64,13 @@ public class XacmlPdpRestServer implements Startable { public boolean start() { try { // - // Look for existing policy types loaded into the system + // Initialize the applications - SEND PROPERTIES + // + XacmlPdpApplicationManager.initializeApplications(Paths.get(applicationPath)); + // + // Update statistics manager on the policy types // - locateExistingPolicyTypes(); + XacmlPdpStatisticsManager.setTotalPolicyTypesCount(XacmlPdpApplicationManager.getPolicyTypeCount()); // // Get the server properties // @@ -112,35 +115,11 @@ public class XacmlPdpRestServer implements Startable { String.valueOf(restServerParameters.isHttps())); props.setProperty(HTTP_SERVER_SERVICES + SEPARATOR + restServerParameters.getName() + ".aaf", String.valueOf(restServerParameters.isAaf())); + props.setProperty(HTTP_SERVER_SERVICES + SEPARATOR + restServerParameters.getName() + ".serialization.provider", + GsonMessageBodyHandler.class.getName()); return props; } - private void locateExistingPolicyTypes() { - // - // Load service - // - applicationLoader = ServiceLoader.load(XacmlApplicationServiceProvider.class); - // - // Iterate through them - // - StringBuilder strDump = new StringBuilder("Loaded applications:" + System.lineSeparator()); - Iterator iterator = applicationLoader.iterator(); - long types = 0; - while (iterator.hasNext()) { - XacmlApplicationServiceProvider application = iterator.next(); - strDump.append(application.applicationName()); - strDump.append(" supports "); - strDump.append(application.supportedPolicyTypes()); - types += application.supportedPolicyTypes().size(); - strDump.append(System.lineSeparator()); - } - LOGGER.debug("{}", strDump); - // - // Update statistics manager - // - XacmlPdpStatisticsManager.setTotalPolicyTypesCount(types); - } - /** * {@inheritDoc}. */ diff --git a/main/src/main/java/org/onap/policy/pdpx/main/rest/model/Decision.java b/main/src/main/java/org/onap/policy/pdpx/main/rest/model/Decision.java deleted file mode 100644 index f5c9a4d8..00000000 --- a/main/src/main/java/org/onap/policy/pdpx/main/rest/model/Decision.java +++ /dev/null @@ -1,37 +0,0 @@ -/*- - * ============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.model; - -import java.util.List; -import java.util.Map; - -public class Decision { - - String onapName; - - String onapComponent; - - String onapInstance; - - String action; - - List> resource; -} diff --git a/main/src/main/java/org/onap/policy/pdpx/main/rest/provider/DecisionProvider.java b/main/src/main/java/org/onap/policy/pdpx/main/rest/provider/DecisionProvider.java index 62190043..33178533 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/rest/provider/DecisionProvider.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/rest/provider/DecisionProvider.java @@ -20,19 +20,44 @@ package org.onap.policy.pdpx.main.rest.provider; -import org.onap.policy.pdpx.main.rest.model.Decision; +import javax.ws.rs.core.Response.Status; + +import org.onap.policy.models.decisions.concepts.DecisionException; +import org.onap.policy.models.decisions.concepts.DecisionRequest; +import org.onap.policy.models.decisions.concepts.DecisionResponse; +import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider; +import org.onap.policy.pdpx.main.rest.XacmlPdpApplicationManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class DecisionProvider { + private static final Logger LOGGER = LoggerFactory.getLogger(DecisionProvider.class); /** * Retrieves the policy decision for the specified parameters. + * @param body * * @return the Decision object */ - public Decision fetchDecision() { - // placeholder - return new Decision(); + public DecisionResponse fetchDecision(DecisionRequest request) { + LOGGER.debug("Fetching decision {}", request); + // + // Find application for this decision + // + XacmlApplicationServiceProvider application = findApplication(request); + // + // Cannot find application for action + // + return application.makeDecision(request); + } + + private XacmlApplicationServiceProvider findApplication(DecisionRequest request) { + XacmlApplicationServiceProvider application = XacmlPdpApplicationManager.findApplication(request); + if (application != null) { + return application; + } + throw new DecisionException(Status.BAD_REQUEST, "No application for action " + request.getAction()); } } diff --git a/main/src/main/java/org/onap/policy/pdpx/main/startstop/XacmlPdpActivator.java b/main/src/main/java/org/onap/policy/pdpx/main/startstop/XacmlPdpActivator.java index d50c4f13..42ad7bb0 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/startstop/XacmlPdpActivator.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/startstop/XacmlPdpActivator.java @@ -71,7 +71,8 @@ public class XacmlPdpActivator { */ private void startXacmlPdpRestServer() throws PolicyXacmlPdpException { xacmlPdpParameterGroup.getRestServerParameters().setName(xacmlPdpParameterGroup.getName()); - restServer = new XacmlPdpRestServer(xacmlPdpParameterGroup.getRestServerParameters()); + restServer = new XacmlPdpRestServer(xacmlPdpParameterGroup.getRestServerParameters(), + xacmlPdpParameterGroup.getApplicationPath()); if (!restServer.start()) { throw new PolicyXacmlPdpException("Failed to start xacml pdp rest server. Check log for more details..."); } 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 48606c98..2bf6fd81 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 @@ -25,7 +25,13 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import java.io.File; +import java.io.IOException; + +import org.junit.Before; +import org.junit.ClassRule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.onap.policy.common.parameters.GroupValidationResult; /** @@ -34,12 +40,23 @@ import org.onap.policy.common.parameters.GroupValidationResult; */ public class TestXacmlPdpParameterGroup { CommonTestData commonTestData = new CommonTestData(); + private static File applicationPath; + + @ClassRule + public static final TemporaryFolder applicationFolder = new TemporaryFolder(); + + @Before + public void setupPath() throws IOException { + applicationPath = applicationFolder.newFolder(); + } @Test - public void testXacmlPdpParameterGroup() { + public void testXacmlPdpParameterGroup() throws IOException { final RestServerParameters restServerParameters = commonTestData.getRestServerParameters(false); final XacmlPdpParameterGroup pdpxParameters = - new XacmlPdpParameterGroup(CommonTestData.PDPX_GROUP_NAME, restServerParameters); + new XacmlPdpParameterGroup(CommonTestData.PDPX_GROUP_NAME, + restServerParameters, + applicationPath.getAbsolutePath()); final GroupValidationResult validationResult = pdpxParameters.validate(); assertTrue(validationResult.isValid()); assertEquals(restServerParameters.getHost(), pdpxParameters.getRestServerParameters().getHost()); @@ -54,7 +71,8 @@ public class TestXacmlPdpParameterGroup { @Test public void testXacmlPdpParameterGroup_NullName() { final RestServerParameters restServerParameters = commonTestData.getRestServerParameters(false); - final XacmlPdpParameterGroup pdpxParameters = new XacmlPdpParameterGroup(null, restServerParameters); + final XacmlPdpParameterGroup pdpxParameters = new XacmlPdpParameterGroup(null, restServerParameters, + applicationPath.getAbsolutePath()); final GroupValidationResult validationResult = pdpxParameters.validate(); assertFalse(validationResult.isValid()); assertEquals(null, pdpxParameters.getName()); @@ -66,7 +84,8 @@ public class TestXacmlPdpParameterGroup { public void testXacmlPdpParameterGroup_EmptyName() { final RestServerParameters restServerParameters = commonTestData.getRestServerParameters(false); - final XacmlPdpParameterGroup pdpxParameters = new XacmlPdpParameterGroup("", restServerParameters); + final XacmlPdpParameterGroup pdpxParameters = new XacmlPdpParameterGroup("", restServerParameters, + applicationPath.getAbsolutePath()); final GroupValidationResult validationResult = pdpxParameters.validate(); assertFalse(validationResult.isValid()); assertEquals("", pdpxParameters.getName()); @@ -79,7 +98,8 @@ public class TestXacmlPdpParameterGroup { final RestServerParameters restServerParameters = commonTestData.getRestServerParameters(true); final XacmlPdpParameterGroup pdpxParameters = - new XacmlPdpParameterGroup(CommonTestData.PDPX_GROUP_NAME, restServerParameters); + new XacmlPdpParameterGroup(CommonTestData.PDPX_GROUP_NAME, restServerParameters, + applicationPath.getAbsolutePath()); final GroupValidationResult validationResult = pdpxParameters.validate(); assertFalse(validationResult.isValid()); assertTrue(validationResult.getResult() diff --git a/main/src/test/java/org/onap/policy/pdpx/main/parameters/TestXacmlPdpParameterHandler.java b/main/src/test/java/org/onap/policy/pdpx/main/parameters/TestXacmlPdpParameterHandler.java index ef85a762..de55282e 100644 --- a/main/src/test/java/org/onap/policy/pdpx/main/parameters/TestXacmlPdpParameterHandler.java +++ b/main/src/test/java/org/onap/policy/pdpx/main/parameters/TestXacmlPdpParameterHandler.java @@ -93,11 +93,14 @@ public class TestXacmlPdpParameterHandler { noArguments.parse(noArgumentString); assertThatThrownBy(() -> new XacmlPdpParameterHandler().getParameters(noArguments)) - .hasMessage("validation error(s) on parameters from \"parameters/NoParameters.json\"\nparameter group " - + "\"null\" type \"org.onap.policy.pdpx.main.parameters.XacmlPdpParameterGroup\" INVALID, " - + "parameter group has status INVALID\n" - + " field \"name\" type \"java.lang.String\" value \"null\" " - + "INVALID, must be a non-blank string\n"); + .hasMessage("validation error(s) on parameters from \"parameters/NoParameters.json\"\n" + + "parameter group \"null\" type " + + "\"org.onap.policy.pdpx.main.parameters.XacmlPdpParameterGroup\"" + + " INVALID, parameter group has status INVALID\n" + + " field \"name\" type \"java.lang.String\" value \"null\" INVALID, " + + "must be a non-blank string\n" + + " field \"applicationPath\" type \"java.lang.String\" value \"null\" INVALID, " + + "must have application path for applications to store policies and data.\n"); } @Test diff --git a/main/src/test/java/org/onap/policy/pdpx/main/rest/TestDecision.java b/main/src/test/java/org/onap/policy/pdpx/main/rest/TestDecision.java new file mode 100644 index 00000000..fe307e4f --- /dev/null +++ b/main/src/test/java/org/onap/policy/pdpx/main/rest/TestDecision.java @@ -0,0 +1,172 @@ +/*- + * ============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 static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.glassfish.jersey.client.ClientConfig; +import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams; +import org.onap.policy.common.endpoints.http.client.HttpClient; +import org.onap.policy.common.gson.GsonMessageBodyHandler; +import org.onap.policy.common.utils.network.NetworkUtil; +import org.onap.policy.models.decisions.concepts.DecisionRequest; +import org.onap.policy.models.decisions.concepts.DecisionResponse; +import org.onap.policy.models.errors.concepts.ErrorResponse; +import org.onap.policy.pdpx.main.PolicyXacmlPdpException; +import org.onap.policy.pdpx.main.startstop.Main; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TestDecision { + + private static final Logger LOGGER = LoggerFactory.getLogger(TestDecision.class); + + private static Main main; + + /** + * BeforeClass setup environment. + */ + @BeforeClass + public static void beforeClass() { + System.setProperty("org.eclipse.jetty.util.log.class", "org.eclipse.jetty.util.log.StdErrLog"); + System.setProperty("org.eclipse.jetty.LEVEL", "OFF"); + main = startXacmlPdpService(); + } + + @AfterClass + public static void after() throws PolicyXacmlPdpException { + stopXacmlPdpService(main); + } + + @Test + public void testDecision_UnsupportedAction() throws KeyManagementException, NoSuchAlgorithmException, + ClassNotFoundException { + + LOGGER.info("Running test testDecision_UnsupportedAction"); + + DecisionRequest request = new DecisionRequest(); + request.setOnapName("DROOLS"); + request.setAction("foo"); + Map guard = new HashMap(); + guard.put("actor", "foo"); + guard.put("recipe", "bar"); + guard.put("target", "somevnf"); + guard.put("clname", "phoneyloop"); + request.setResource(guard); + + ErrorResponse response = getErrorDecision(request); + LOGGER.info("Response {}", response); + assertThat(response.getResponseCode()).isEqualTo(Status.BAD_REQUEST); + assertThat(response.getErrorMessage()).isEqualToIgnoringCase("No application for action foo"); + } + + @Test + public void testDecision_Guard() throws InterruptedException, IOException { + LOGGER.info("Running test testDecision_Guard"); + + DecisionRequest request = new DecisionRequest(); + request.setOnapName("DROOLS"); + request.setAction("guard"); + Map guard = new HashMap(); + guard.put("actor", "foo"); + guard.put("recipe", "bar"); + guard.put("target", "somevnf"); + guard.put("clname", "phoneyloop"); + request.setResource(guard); + + DecisionResponse response = getDecision(request); + LOGGER.info("Response {}", response); + //assertThat(response.getErrorMessage()).isEqualToIgnoringCase("No application for action foo"); + } + + private static Main startXacmlPdpService() { + final String[] XacmlPdpConfigParameters = {"-c", "parameters/XacmlPdpConfigParameters.json"}; + return new Main(XacmlPdpConfigParameters); + } + + private static void stopXacmlPdpService(final Main main) throws PolicyXacmlPdpException { + main.shutdown(); + } + + private DecisionResponse getDecision(DecisionRequest request) throws InterruptedException, IOException { + 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/decision"); + + 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.post(Entity.json(request), DecisionResponse.class); + } + + private ErrorResponse getErrorDecision(DecisionRequest request) throws KeyManagementException, + NoSuchAlgorithmException, ClassNotFoundException { + + HttpClient client = getNoAuthHttpClient(); + + Entity entityRequest = Entity.entity(request, MediaType.APPLICATION_JSON); + Response response = client.post("", entityRequest, Collections.emptyMap()); + + assertEquals(400, response.getStatus()); + + return HttpClient.getBody(response, ErrorResponse.class); + } + + private HttpClient getNoAuthHttpClient() + throws KeyManagementException, NoSuchAlgorithmException, ClassNotFoundException { + return HttpClient.factory.build(BusTopicParams.builder() + .clientName("testDecisionClient") + .serializationProvider(GsonMessageBodyHandler.class.getName()) + .useHttps(false).allowSelfSignedCerts(false).hostname("localhost").port(6969) + .basePath("policy/pdpx/v1/decision") + .userName("healthcheck").password("zb!XztG34").managed(true).build()); + } + + +} \ No newline at end of file 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 316abac7..fc3edd73 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 @@ -24,6 +24,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.io.File; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.Modifier; @@ -42,7 +43,9 @@ import org.glassfish.jersey.client.ClientConfig; import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; import org.junit.After; import org.junit.BeforeClass; +import org.junit.ClassRule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.onap.policy.common.endpoints.report.HealthCheckReport; import org.onap.policy.common.utils.network.NetworkUtil; import org.onap.policy.pdpx.main.PolicyXacmlPdpException; @@ -69,15 +72,21 @@ public class TestXacmlPdpRestServer { private static String KEYSTORE = System.getProperty("user.dir") + "/src/test/resources/ssl/policy-keystore"; private Main main; private XacmlPdpRestServer restServer; + private static File applicationPath; + + @ClassRule + public static final TemporaryFolder applicationFolder = new TemporaryFolder(); /** * setup. + * + * @throws IOException exception if cannot create temporary folder */ @BeforeClass - public static void setUp() { + public static void setUp() throws IOException { System.setProperty("org.eclipse.jetty.util.log.class", "org.eclipse.jetty.util.log.StdErrLog"); System.setProperty("org.eclipse.jetty.LEVEL", "OFF"); - + applicationPath = applicationFolder.newFolder(); } /** @@ -115,7 +124,7 @@ public class TestXacmlPdpRestServer { public void testHealthCheckFailure() throws InterruptedException, IOException { final RestServerParameters restServerParams = new CommonTestData().getRestServerParameters(false); restServerParams.setName(CommonTestData.PDPX_GROUP_NAME); - restServer = new XacmlPdpRestServer(restServerParams); + restServer = new XacmlPdpRestServer(restServerParams, applicationPath.getAbsolutePath()); restServer.start(); final Invocation.Builder invocationBuilder = sendHttpRequest(HEALTHCHECK_ENDPOINT); final HealthCheckReport report = invocationBuilder.get(HealthCheckReport.class); @@ -149,7 +158,7 @@ public class TestXacmlPdpRestServer { 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 = new XacmlPdpRestServer(restServerParams, applicationPath.getAbsolutePath()); restServer.start(); final Invocation.Builder invocationBuilder = sendHttpRequest(STATISTICS_ENDPOINT); final StatisticsReport report = invocationBuilder.get(StatisticsReport.class); diff --git a/main/src/test/java/org/onap/policy/pdpx/main/rest/TestXacmlPdpStatistics.java b/main/src/test/java/org/onap/policy/pdpx/main/rest/TestXacmlPdpStatistics.java index 595301de..8d2f7ce4 100644 --- a/main/src/test/java/org/onap/policy/pdpx/main/rest/TestXacmlPdpStatistics.java +++ b/main/src/test/java/org/onap/policy/pdpx/main/rest/TestXacmlPdpStatistics.java @@ -25,6 +25,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; +import java.io.File; import java.io.IOException; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; @@ -33,8 +34,11 @@ 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.Before; import org.junit.BeforeClass; +import org.junit.ClassRule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.onap.policy.common.utils.network.NetworkUtil; import org.onap.policy.pdpx.main.PolicyXacmlPdpException; import org.onap.policy.pdpx.main.parameters.CommonTestData; @@ -52,11 +56,21 @@ import org.slf4j.LoggerFactory; public class TestXacmlPdpStatistics { private static final Logger LOGGER = LoggerFactory.getLogger(TestXacmlPdpStatistics.class); + private static File applicationPath; + @ClassRule + public static final TemporaryFolder applicationFolder = new TemporaryFolder(); + + /** + * Turn off some debugging and create temporary folder for applications. + * + * @throws IOException If temporary folder fails + */ @BeforeClass - public static void beforeClass() { + public static void beforeClass() throws IOException { System.setProperty("org.eclipse.jetty.util.log.class", "org.eclipse.jetty.util.log.StdErrLog"); System.setProperty("org.eclipse.jetty.LEVEL", "OFF"); + applicationPath = applicationFolder.newFolder(); } @Test @@ -81,7 +95,8 @@ public class TestXacmlPdpStatistics { public void testXacmlPdpStatistics_500() throws InterruptedException { final RestServerParameters restServerParams = new CommonTestData().getRestServerParameters(false); restServerParams.setName(CommonTestData.PDPX_GROUP_NAME); - final XacmlPdpRestServer restServer = new XacmlPdpRestServer(restServerParams); + final XacmlPdpRestServer restServer = new XacmlPdpRestServer(restServerParams, + applicationPath.getAbsolutePath()); try { restServer.start(); diff --git a/main/src/test/resources/parameters/MinimumParameters.json b/main/src/test/resources/parameters/MinimumParameters.json index 798731ae..ab52cc85 100644 --- a/main/src/test/resources/parameters/MinimumParameters.json +++ b/main/src/test/resources/parameters/MinimumParameters.json @@ -5,5 +5,6 @@ "port": 6969, "userName": "healthcheck", "password": "zb!XztG34" - } + }, + "applicationPath": "apps.test" } diff --git a/main/src/test/resources/parameters/XacmlPdpConfigParameters.json b/main/src/test/resources/parameters/XacmlPdpConfigParameters.json index 798731ae..ab52cc85 100644 --- a/main/src/test/resources/parameters/XacmlPdpConfigParameters.json +++ b/main/src/test/resources/parameters/XacmlPdpConfigParameters.json @@ -5,5 +5,6 @@ "port": 6969, "userName": "healthcheck", "password": "zb!XztG34" - } + }, + "applicationPath": "apps.test" } diff --git a/main/src/test/resources/parameters/XacmlPdpConfigParameters_Https.json b/main/src/test/resources/parameters/XacmlPdpConfigParameters_Https.json index b467fe4c..92e6e908 100644 --- a/main/src/test/resources/parameters/XacmlPdpConfigParameters_Https.json +++ b/main/src/test/resources/parameters/XacmlPdpConfigParameters_Https.json @@ -6,5 +6,6 @@ "userName":"healthcheck", "password":"zb!XztG34", "https":true - } + }, + "applicationPath": "apps.test" } \ No newline at end of file -- 2.16.6