From 9ff68b1ed845e94944f99c32eef209eb63c6469d Mon Sep 17 00:00:00 2001 From: HOCKLA Date: Mon, 14 Oct 2019 14:25:29 -0500 Subject: Modified Decision API to accept query parameters and abbreviate Monitor decision results Issue-ID: POLICY-2126 Change-Id: I18d50a8746ede792ec9507ab98125383c5914ba1 Signed-off-by: HOCKLA --- main/pom.xml | 6 + .../pdpx/main/rest/XacmlPdpRestController.java | 10 +- .../pdpx/main/rest/provider/DecisionProvider.java | 6 +- .../main/rest/TestAbbreviateDecisionResults.java | 295 +++++++++++++++++++++ .../onap/policy/pdpx/main/rest/TestDecision.java | 1 + 5 files changed, 310 insertions(+), 8 deletions(-) create mode 100644 main/src/test/java/org/onap/policy/pdpx/main/rest/TestAbbreviateDecisionResults.java (limited to 'main') diff --git a/main/pom.xml b/main/pom.xml index 581463a3..f8508335 100644 --- a/main/pom.xml +++ b/main/pom.xml @@ -87,6 +87,12 @@ policy-models-pdp ${policy.models.version} + + org.onap.policy.xacml-pdp + xacml-test + ${project.version} + test + org.powermock powermock-api-mockito 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 5b17c34e..f668411b 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,19 +33,18 @@ 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.servlet.http.HttpServletRequest; 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.Context; 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.models.decisions.concepts.DecisionException; import org.onap.policy.models.decisions.concepts.DecisionRequest; @@ -175,10 +174,11 @@ public class XacmlPdpRestController { @ApiResponse(code = 403, message = "Authorization Error"), @ApiResponse(code = 500, message = "Internal Server Error")}) public Response decision(DecisionRequest body, - @HeaderParam("X-ONAP-RequestID") @ApiParam("RequestID for http transaction") UUID requestId) { + @HeaderParam("X-ONAP-RequestID") @ApiParam("RequestID for http transaction") UUID requestId, + @Context HttpServletRequest request) { try { return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId) - .entity(new DecisionProvider().fetchDecision(body)).build(); + .entity(new DecisionProvider().fetchDecision(body, request.getParameterMap())).build(); } catch (DecisionException e) { LOGGER.error("Decision exception", e); XacmlPdpStatisticsManager.getCurrent().updateErrorCount(); 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 ec687957..a5141b90 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 @@ -22,7 +22,7 @@ package org.onap.policy.pdpx.main.rest.provider; import com.att.research.xacml.api.Response; import com.att.research.xacml.api.Result; - +import java.util.Map; import org.apache.commons.lang3.tuple.Pair; import org.onap.policy.models.decisions.concepts.DecisionException; import org.onap.policy.models.decisions.concepts.DecisionRequest; @@ -43,7 +43,7 @@ public class DecisionProvider { * * @return the Decision object */ - public DecisionResponse fetchDecision(DecisionRequest request) { + public DecisionResponse fetchDecision(DecisionRequest request, Map queryParams) { LOGGER.debug("Fetching decision {}", request); // // Find application for this decision @@ -52,7 +52,7 @@ public class DecisionProvider { // // Found application for action // - Pair decision = application.makeDecision(request); + Pair decision = application.makeDecision(request, queryParams); // // Calculate statistics // diff --git a/main/src/test/java/org/onap/policy/pdpx/main/rest/TestAbbreviateDecisionResults.java b/main/src/test/java/org/onap/policy/pdpx/main/rest/TestAbbreviateDecisionResults.java new file mode 100644 index 00000000..716e6412 --- /dev/null +++ b/main/src/test/java/org/onap/policy/pdpx/main/rest/TestAbbreviateDecisionResults.java @@ -0,0 +1,295 @@ +/*- + * ============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 static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.ServiceLoader; +import javax.ws.rs.client.Entity; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +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.endpoints.http.client.HttpClientConfigException; +import org.onap.policy.common.endpoints.http.client.internal.JerseyClient; +import org.onap.policy.common.endpoints.parameters.RestServerParameters; +import org.onap.policy.common.endpoints.parameters.TopicParameterGroup; +import org.onap.policy.common.gson.GsonMessageBodyHandler; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +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.pdp.xacml.application.common.XacmlApplicationException; +import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider; +import org.onap.policy.pdp.xacml.application.common.XacmlPolicyUtils; +import org.onap.policy.pdp.xacml.xacmltest.TestUtils; +import org.onap.policy.pdpx.main.PolicyXacmlPdpException; +import org.onap.policy.pdpx.main.parameters.CommonTestData; +import org.onap.policy.pdpx.main.parameters.XacmlPdpParameterGroup; +import org.onap.policy.pdpx.main.startstop.Main; +import org.onap.policy.xacml.pdp.application.monitoring.MonitoringPdpApplication; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TestAbbreviateDecisionResults { + + private static final Logger LOGGER = LoggerFactory.getLogger(TestDecision.class); + + private static int port; + private static Main main; + private static HttpClient client; + private static CommonTestData testData = new CommonTestData(); + + private static Properties properties = new Properties(); + private static File propertiesFile; + private static XacmlApplicationServiceProvider service; + + private static RestServerParameters policyApiParameters; + + @ClassRule + public static final TemporaryFolder appsFolder = new TemporaryFolder(); + + /** + * BeforeClass setup environment. + * + * @throws IOException Cannot create temp apps folder + * @throws Exception exception if service does not start + */ + @BeforeClass + public static void beforeClass() throws Exception { + port = NetworkUtil.allocPort(); + // + // Copy test directory over of the application directories + // + Path src = Paths.get("src/test/resources/apps"); + File apps = appsFolder.newFolder("apps"); + Files.walk(src).forEach(source -> { + copy(source, apps.toPath().resolve(src.relativize(source))); + }); + + // Start the Monitoring Application + startXacmlApplicationService(apps); + + // Load monitoring policy + TestUtils.loadPolicies("../applications/monitoring/src/test/resources/vDNS.policy.input.yaml", service); + + // Create parameters for XacmlPdPService + RestServerParameters rest = testData.toObject(testData.getRestServerParametersMap(port), + RestServerParameters.class); + policyApiParameters = testData.toObject(testData.getPolicyApiParametersMap(false), RestServerParameters.class); + TopicParameterGroup topicParameterGroup = testData.toObject(testData.getTopicParametersMap(false), + TopicParameterGroup.class); + XacmlPdpParameterGroup params = new XacmlPdpParameterGroup("XacmlPdpGroup", rest, policyApiParameters, + topicParameterGroup, apps.getAbsolutePath()); + StandardCoder gson = new StandardCoder(); + File fileParams = appsFolder.newFile("params.json"); + String jsonParams = gson.encode(params); + LOGGER.info("Creating new params: {}", jsonParams); + Files.write(fileParams.toPath(), jsonParams.getBytes()); + // + // Start the service + // + main = startXacmlPdpService(fileParams); + // + // Make sure it is running + // + if (!NetworkUtil.isTcpPortOpen("localhost", port, 20, 1000L)) { + throw new IllegalStateException("Cannot connect to port " + port); + } + // + // Create a client + // + client = getNoAuthHttpClient(); + } + + /** + * Clean up. + */ + @AfterClass + public static void after() throws PolicyXacmlPdpException { + stopXacmlPdpService(main); + client.shutdown(); + } + + /** + * Tests if the Decision Response contains abbreviated results. Specifically, "properties", "name" and "version" + * should have been removed from the response. + */ + @Test + public void testAbbreviateDecisionResult() { + + LOGGER.info("Running testAbbreviateDecisionResult"); + + try { + // Create DecisionRequest + DecisionRequest request = new DecisionRequest(); + request.setOnapName("DCAE"); + request.setOnapComponent("PolicyHandler"); + request.setOnapInstance("622431a4-9dea-4eae-b443-3b2164639c64"); + request.setAction("configure"); + Map resource = new HashMap(); + resource.put("policy-id", "onap.scaleout.tca"); + request.setResource(resource); + + // Query decision API + DecisionResponse response = getDecision(request); + LOGGER.info("Decision Response {}", response); + + assertFalse(response.getPolicies().isEmpty()); + + @SuppressWarnings("unchecked") + Map policy = (Map) response.getPolicies().get("onap.scaleout.tca"); + assertTrue(policy.containsKey("type")); + assertFalse(policy.containsKey("properties")); + assertFalse(policy.containsKey("name")); + assertFalse(policy.containsKey("version")); + assertTrue(policy.containsKey("metadata")); + + } catch (Exception e) { + LOGGER.error("Exception {}", e); + fail("testAbbreviateDecisionResult failed due to: " + e.getLocalizedMessage()); + } + } + + private static Main startXacmlPdpService(File params) throws PolicyXacmlPdpException { + final String[] XacmlPdpConfigParameters = { "-c", params.getAbsolutePath() }; + return new Main(XacmlPdpConfigParameters); + } + + private static void stopXacmlPdpService(final Main main) throws PolicyXacmlPdpException { + main.shutdown(); + } + + /** + * Performs the POST request to Decision API. + * + */ + private DecisionResponse getDecision(DecisionRequest request) throws HttpClientConfigException { + + Entity entityRequest = Entity.entity(request, MediaType.APPLICATION_JSON); + Response response = client.post("", entityRequest, Collections.emptyMap()); + + assertEquals(200, response.getStatus()); + return HttpClient.getBody(response, DecisionResponse.class); + } + + /** + * Create HttpClient. + * + */ + private static HttpClient getNoAuthHttpClient() + throws HttpClientConfigException, KeyManagementException, NoSuchAlgorithmException, ClassNotFoundException { + BusTopicParams clientParams = new BusTopicParams(); + clientParams.setClientName("testName"); + clientParams.setSerializationProvider(GsonMessageBodyHandler.class.getName()); + clientParams.setUseHttps(false); + clientParams.setAllowSelfSignedCerts(false); + clientParams.setHostname("localhost"); + clientParams.setPort(port); + clientParams.setBasePath("policy/pdpx/v1/decision?abbrev=true"); + clientParams.setUserName("healthcheck"); + clientParams.setPassword("zb!XztG34"); + clientParams.setManaged(true); + client = new JerseyClient(clientParams); + return client; + } + + private static void copy(Path source, Path dest) { + try { + LOGGER.info("Copying {} to {}", source, dest); + Files.copy(source, dest, StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + LOGGER.error("Failed to copy {} to {}", source, dest); + } + } + + /** + * Initializes the Monitoring application service + * + * @param apps - the path to xacml.properties file + */ + private static void startXacmlApplicationService(File apps) + throws XacmlApplicationException, CoderException, IOException { + LOGGER.info("****** Starting Xacml Application Service ******"); + // + // Setup our temporary folder + // + XacmlPolicyUtils.FileCreator myCreator = (String filename) -> { + new File(apps, "monitoring/" + filename).delete(); + return appsFolder.newFile("apps/monitoring/" + filename); + }; + propertiesFile = XacmlPolicyUtils.copyXacmlPropertiesContents( + "../applications/monitoring/src/test/resources/xacml.properties", properties, myCreator); + // + // Load XacmlApplicationServiceProvider service + // + ServiceLoader applicationLoader = ServiceLoader + .load(XacmlApplicationServiceProvider.class); + // + // Look for our class instance and save it + // + StringBuilder strDump = new StringBuilder("Loaded applications:" + System.lineSeparator()); + for (XacmlApplicationServiceProvider application : applicationLoader) { + // + // Is it our service? + // + if (application instanceof MonitoringPdpApplication) { + // + // Should be the first and only one + // + assertThat(service).isNull(); + service = application; + } + strDump.append(application.applicationName()); + strDump.append(" supports "); + strDump.append(application.supportedPolicyTypes()); + strDump.append(System.lineSeparator()); + } + LOGGER.debug("{}", strDump); + // + // Tell it to initialize based on the properties file + // we just built for it. + // + service.initialize(propertiesFile.toPath().getParent(), policyApiParameters); + } +} 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 index 5f75e6dd..042180b4 100644 --- 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 @@ -131,6 +131,7 @@ public class TestDecision { @AfterClass public static void after() throws PolicyXacmlPdpException { stopXacmlPdpService(main); + client.shutdown(); } @Test -- cgit 1.2.3-korg