Xacml PDP Register/Unregister Changes
[policy/xacml-pdp.git] / main / src / test / java / org / onap / policy / pdpx / main / rest / TestXacmlPdpRestServer.java
index ce0671a..0deab9d 100644 (file)
  * ============LICENSE_END=========================================================
  */
 
-
 package org.onap.policy.pdpx.main.rest;
 
 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;
+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;
@@ -31,18 +41,24 @@ 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.BeforeClass;
+import org.junit.ClassRule;
 import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClientException;
 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 {
@@ -52,33 +68,144 @@ 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;
+    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() 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();
+    }
+
+    /**
+     * Method for cleanup after each test.
+     */
+    @After
+    public void teardown() {
+        try {
+            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 PolicyXacmlPdpException, InterruptedException {
-        final String reportString = "Report [name=Policy Xacml PDP, url=self, healthy=true, code=200, message=alive]";
-        final Main main = startXacmlPdpService();
-        final HealthCheckReport report = performHealthCheck();
-        validateReport(NAME, SELF, true, 200, ALIVE, reportString, report);
-        stopXacmlPdpService(main);
+    public void testHealthCheckSuccess() throws IOException, InterruptedException, TopicSinkClientException {
+        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, applicationPath.getAbsolutePath());
         restServer.start();
-        final HealthCheckReport report = performHealthCheck();
-        validateReport(NAME, SELF, false, 500, NOT_ALIVE, reportString, report);
+        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="));
-        restServer.shutdown();
     }
 
-    private Main startXacmlPdpService() {
-        final String[] xacmlPdpConfigParameters = {"-c", "parameters/XacmlPdpConfigParameters.json"};
+    @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, TopicSinkClientException {
+        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, applicationPath.getAbsolutePath());
+        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 {
+            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 boolean http) throws TopicSinkClientException {
+        final String[] xacmlPdpConfigParameters = new String[4];
+        if (http) {
+            xacmlPdpConfigParameters[0] = "-c";
+            xacmlPdpConfigParameters[1] = "parameters/XacmlPdpConfigParameters.json";
+            xacmlPdpConfigParameters[2] = "-p";
+            xacmlPdpConfigParameters[3] = "parameters/topic.properties";
+        } 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";
+            xacmlPdpConfigParameters[2] = "-p";
+            xacmlPdpConfigParameters[3] = "parameters/topic.properties";
+        }
         return new Main(xacmlPdpConfigParameters);
     }
 
@@ -86,36 +213,80 @@ public class TestXacmlPdpRestServer {
         main.shutdown();
     }
 
-    private HealthCheckReport performHealthCheck() throws InterruptedException {
-        HealthCheckReport response = null;
+    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/healthcheck");
+        final WebTarget webTarget = client.target("http://localhost:6969/policy/pdpx/v1/" + endpoint);
 
         final Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON);
 
-        final long startTime = System.currentTimeMillis();
-        while (response == null && (System.currentTimeMillis() - startTime) < 120000) {
-            try {
-                response = invocationBuilder.get(HealthCheckReport.class);
-            } catch (final Exception exp) {
-                LOGGER.info("the server is not started yet. We will retry again");
+        if (!NetworkUtil.isTcpPortOpen("localhost", 6969, 6, 10000L)) {
+            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);
+
+        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 response;
+        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());
     }
 }