add rest serve and distribution framework 73/82773/1
authorliboNet <libo.zhu@intel.com>
Thu, 21 Mar 2019 00:01:55 +0000 (08:01 +0800)
committerliboNet <libo.zhu@intel.com>
Thu, 21 Mar 2019 00:05:09 +0000 (08:05 +0800)
. update the pom.xml to include a submodule main
. add all common necessnary package into pom.xml
. add rest server and test case
. port the distribution framework
. which supports both http and https

Change-Id: I5ccc712342fc8929d11e553f3e09f36e93a80935
Issue-ID: MULTICLOUD-546
Signed-off-by: liboNet <libo.zhu@intel.com>
24 files changed:
artifactbroker/main/pom.xml [new file with mode: 0644]
artifactbroker/main/src/main/java/org/onap/policy/distribution/main/PolicyDistributionException.java [new file with mode: 0644]
artifactbroker/main/src/main/java/org/onap/policy/distribution/main/PolicyDistributionRuntimeException.java [new file with mode: 0644]
artifactbroker/main/src/main/java/org/onap/policy/distribution/main/parameters/DistributionParameterGroup.java [new file with mode: 0644]
artifactbroker/main/src/main/java/org/onap/policy/distribution/main/parameters/DistributionParameterHandler.java [new file with mode: 0644]
artifactbroker/main/src/main/java/org/onap/policy/distribution/main/parameters/RestServerParameters.java [new file with mode: 0644]
artifactbroker/main/src/main/java/org/onap/policy/distribution/main/rest/DistributionRestController.java [new file with mode: 0644]
artifactbroker/main/src/main/java/org/onap/policy/distribution/main/rest/DistributionRestServer.java [new file with mode: 0644]
artifactbroker/main/src/main/java/org/onap/policy/distribution/main/rest/HealthCheckProvider.java [new file with mode: 0644]
artifactbroker/main/src/main/java/org/onap/policy/distribution/main/rest/StatisticsProvider.java [new file with mode: 0644]
artifactbroker/main/src/main/java/org/onap/policy/distribution/main/rest/StatisticsReport.java [new file with mode: 0644]
artifactbroker/main/src/main/java/org/onap/policy/distribution/main/startstop/DistributionActivator.java [new file with mode: 0644]
artifactbroker/main/src/main/java/org/onap/policy/distribution/main/startstop/DistributionCommandLineArguments.java [new file with mode: 0644]
artifactbroker/main/src/main/java/org/onap/policy/distribution/main/startstop/Main.java [new file with mode: 0644]
artifactbroker/main/src/main/resources/version.txt [new file with mode: 0644]
artifactbroker/main/src/test/java/org/onap/policy/distribution/main/TestExceptions.java [new file with mode: 0644]
artifactbroker/main/src/test/java/org/onap/policy/distribution/main/rest/TestDistributionRestServer.java [new file with mode: 0644]
artifactbroker/main/src/test/java/org/onap/policy/distribution/main/rest/TestHttpsDistributionRestServer.backup [new file with mode: 0644]
artifactbroker/main/src/test/java/org/onap/policy/distribution/main/rest/TestHttpsStatisticDistributionRestServer.backup [new file with mode: 0644]
artifactbroker/main/src/test/java/org/onap/policy/distribution/main/rest/TestStatisticsReport.java [new file with mode: 0644]
artifactbroker/main/src/test/resources/parameters/DistributionConfigParameters.json [new file with mode: 0644]
artifactbroker/main/src/test/resources/parameters/DistributionConfigParameters_Https.json [new file with mode: 0644]
artifactbroker/main/src/test/resources/ssl/policy-keystore [new file with mode: 0644]
artifactbroker/pom.xml

diff --git a/artifactbroker/main/pom.xml b/artifactbroker/main/pom.xml
new file mode 100644 (file)
index 0000000..875a14f
--- /dev/null
@@ -0,0 +1,52 @@
+<!--
+  ============LICENSE_START=======================================================
+   Copyright (C) 2018 Ericsson. 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=========================================================
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.onap.multicloud.framework.broker</groupId>
+        <artifactId>multicloud-framework-artifactbroker</artifactId>
+        <version>1.3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>main</artifactId>
+
+    <name>${project.artifactId}</name>
+    <description>The main module of Policy Distribution that handles startup, lifecycle management, and parameters.</description>
+
+    <build>
+        <resources>
+            <!-- Output the version of the distribution service -->
+            <resource>
+                <directory>src/main/resources</directory>
+                <filtering>true</filtering>
+                <includes>
+                    <include>**/version.txt</include>
+                </includes>
+            </resource>
+            <resource>
+                <directory>src/main/resources</directory>
+                <filtering>false</filtering>
+                <excludes>
+                    <exclude>**/version.txt</exclude>
+                </excludes>
+            </resource>
+        </resources>
+    </build>
+
+</project>
diff --git a/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/PolicyDistributionException.java b/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/PolicyDistributionException.java
new file mode 100644 (file)
index 0000000..041f87c
--- /dev/null
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2018 Ericsson. 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.distribution.main;
+
+/**
+ * This exception will be called if an error occurs in policy distribution service.
+ */
+public class PolicyDistributionException extends Exception {
+    private static final long serialVersionUID = -8507246953751956974L;
+
+    /**
+     * Instantiates a new policy distribution exception with a message.
+     *
+     * @param message the message
+     */
+    public PolicyDistributionException(final String message) {
+        super(message);
+    }
+
+    /**
+     * Instantiates a new policy distribution exception with a message and a caused by exception.
+     *
+     * @param message the message
+     * @param exp the exception that caused this exception to be thrown
+     */
+    public PolicyDistributionException(final String message, final Exception exp) {
+        super(message, exp);
+    }
+}
diff --git a/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/PolicyDistributionRuntimeException.java b/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/PolicyDistributionRuntimeException.java
new file mode 100644 (file)
index 0000000..385505a
--- /dev/null
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2018 Ericsson. 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.distribution.main;
+
+/**
+ * This runtime exception will be called if a runtime error occurs when using policy distribution.
+ */
+public class PolicyDistributionRuntimeException extends RuntimeException {
+    private static final long serialVersionUID = -8507246953751956974L;
+
+    /**
+     * Instantiates a new policy distribution runtime exception with a message.
+     *
+     * @param message the message
+     */
+    public PolicyDistributionRuntimeException(final String message) {
+        super(message);
+    }
+
+    /**
+     * Instantiates a new policy distribution runtime exception with a message and a caused by exception.
+     *
+     * @param message the message
+     * @param exp the exception that caused this exception to be thrown
+     */
+    public PolicyDistributionRuntimeException(final String message, final Exception exp) {
+        super(message, exp);
+    }
+}
diff --git a/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/parameters/DistributionParameterGroup.java b/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/parameters/DistributionParameterGroup.java
new file mode 100644 (file)
index 0000000..d034e5e
--- /dev/null
@@ -0,0 +1,102 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2018 Ericsson. 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.distribution.main.parameters;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.onap.policy.common.parameters.GroupValidationResult;
+import org.onap.policy.common.parameters.ParameterGroup;
+import org.onap.policy.common.parameters.ValidationStatus;
+import org.onap.policy.common.utils.validation.ParameterValidationUtils;
+
+/**
+ * Class to hold all parameters needed for Distribution component.
+ *
+ * @author Ram Krishna Verma (ram.krishna.verma@ericsson.com)
+ */
+public class DistributionParameterGroup implements ParameterGroup {
+    // @formatter:off
+    private String name;
+    private RestServerParameters restServerParameters;
+    // @formatter:on
+
+    /**
+     * Create the distribution parameter group.
+     *
+     * @param name the parameter group name
+     */
+    public DistributionParameterGroup(final String name, final RestServerParameters restServerParameters) {
+        this.name = name;
+        this.restServerParameters = restServerParameters;
+    }
+
+    /**
+     * Return the name of this parameter group instance.
+     *
+     * @return name the parameter group name
+     */
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Set the name of this parameter group instance.
+     *
+     * @param name the parameter group name
+     */
+    @Override
+    public void setName(final String name) {
+        this.name = name;
+    }
+
+    /**
+     * Return the restServerParameters of this parameter group instance.
+     *
+     * @return the restServerParameters
+     */
+    public RestServerParameters getRestServerParameters() {
+        return restServerParameters;
+    }
+
+    /**
+     * Validate the parameter group.
+     *
+     * @return the result of the validation
+     */
+    @Override
+    public GroupValidationResult validate() {
+        final GroupValidationResult validationResult = new GroupValidationResult(this);
+        if (!ParameterValidationUtils.validateStringParameter(name)) {
+            validationResult.setResult("name", ValidationStatus.INVALID, "must be a non-blank string");
+        }
+        if (restServerParameters == null) {
+            validationResult.setResult("restServerParameters", ValidationStatus.INVALID,
+                "must have restServerParameters to configure distribution rest server");
+        } else {
+            validationResult.setResult("restServerParameters", restServerParameters.validate());
+        }
+        return validationResult;
+    }
+
+}
diff --git a/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/parameters/DistributionParameterHandler.java b/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/parameters/DistributionParameterHandler.java
new file mode 100644 (file)
index 0000000..dc72978
--- /dev/null
@@ -0,0 +1,85 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2018 Ericsson. 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.distribution.main.parameters;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+import java.io.FileReader;
+
+import org.onap.policy.common.logging.flexlogger.FlexLogger;
+import org.onap.policy.common.logging.flexlogger.Logger;
+import org.onap.policy.common.parameters.GroupValidationResult;
+import org.onap.policy.distribution.main.PolicyDistributionException;
+import org.onap.policy.distribution.main.startstop.DistributionCommandLineArguments;
+
+/**
+ * This class handles reading, parsing and validating of policy distribution parameters from JSON files.
+ */
+public class DistributionParameterHandler {
+    private static final Logger LOGGER = FlexLogger.getLogger(DistributionParameterHandler.class);
+
+    /**
+     * Read the parameters from the parameter file.
+     *
+     * @param arguments the arguments passed to policy distribution
+     * @return the parameters read from the configuration file
+     * @throws PolicyDistributionException on parameter exceptions
+     */
+    public DistributionParameterGroup getParameters(final DistributionCommandLineArguments arguments)
+            throws PolicyDistributionException {
+        DistributionParameterGroup distributionParameterGroup = null;
+
+        // Read the parameters
+        try {
+            // Read the parameters from JSON using Gson
+            final Gson gson = new GsonBuilder()
+                    .create();
+            distributionParameterGroup = gson.fromJson(new FileReader(arguments.getFullConfigurationFilePath()),
+                    DistributionParameterGroup.class);
+        } catch (final Exception e) {
+            final String errorMessage = "error reading parameters from \"" + arguments.getConfigurationFilePath()
+                    + "\"\n" + "(" + e.getClass().getSimpleName() + "):" + e.getMessage();
+            LOGGER.error(errorMessage, e);
+            throw new PolicyDistributionException(errorMessage, e);
+        }
+
+        // The JSON processing returns null if there is an empty file
+        if (distributionParameterGroup == null) {
+            final String errorMessage = "no parameters found in \"" + arguments.getConfigurationFilePath() + "\"";
+            LOGGER.error(errorMessage);
+            throw new PolicyDistributionException(errorMessage);
+        }
+
+        // validate the parameters
+        final GroupValidationResult validationResult = distributionParameterGroup.validate();
+        if (!validationResult.isValid()) {
+            String returnMessage =
+                    "validation error(s) on parameters from \"" + arguments.getConfigurationFilePath() + "\"\n";
+            returnMessage += validationResult.getResult();
+
+            LOGGER.error(returnMessage);
+            throw new PolicyDistributionException(returnMessage);
+        }
+
+        return distributionParameterGroup;
+    }
+}
diff --git a/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/parameters/RestServerParameters.java b/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/parameters/RestServerParameters.java
new file mode 100644 (file)
index 0000000..4685b7d
--- /dev/null
@@ -0,0 +1,150 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2018 Ericsson. 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.distribution.main.parameters;
+
+import org.onap.policy.common.parameters.GroupValidationResult;
+import org.onap.policy.common.parameters.ParameterGroup;
+import org.onap.policy.common.parameters.ValidationStatus;
+import org.onap.policy.common.utils.validation.ParameterValidationUtils;
+
+/**
+ * Class to hold all parameters needed for distribution rest server.
+ *
+ * @author Ram Krishna Verma (ram.krishna.verma@ericsson.com)
+ */
+public class RestServerParameters implements ParameterGroup {
+    private String name;
+    private String host;
+    private int port;
+    private String userName;
+    private String password;
+    private boolean https;
+
+    /**
+     * Constructor for instantiating RestServerParameters.
+     *
+     * @param host the host name
+     * @param port the port
+     * @param userName the user name
+     * @param password the password
+     * @param https the https
+     */
+    public RestServerParameters(final String host, final int port, final String userName, final String password,
+                                final boolean https) {
+        super();
+        this.host = host;
+        this.port = port;
+        this.userName = userName;
+        this.password = password;
+        this.https = https;
+    }
+
+    /**
+     * Return the name of this RestServerParameters instance.
+     *
+     * @return name the name of this RestServerParameters
+     */
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Return the host of this RestServerParameters instance.
+     *
+     * @return the host
+     */
+    public String getHost() {
+        return host;
+    }
+
+    /**
+     * Return the port of this RestServerParameters instance.
+     *
+     * @return the port
+     */
+    public int getPort() {
+        return port;
+    }
+
+    /**
+     * Return the user name of this RestServerParameters instance.
+     *
+     * @return the userName
+     */
+    public String getUserName() {
+        return userName;
+    }
+
+    /**
+     * Return the password of this RestServerParameters instance.
+     *
+     * @return the password
+     */
+    public String getPassword() {
+        return password;
+    }
+
+    /**
+     * Return the https of this RestServerParameters instance.
+     *
+     * @return the password
+     */
+    public boolean isHttps() {
+        return https;
+    }
+
+    /**
+     * Set the name of this RestServerParameters instance.
+     *
+     * @param name the name to set
+     */
+    public void setName(final String name) {
+        this.name = name;
+    }
+
+    /**
+     * Validate the rest server parameters.
+     *
+     * @return the result of the validation
+     */
+    @Override
+    public GroupValidationResult validate() {
+        final GroupValidationResult validationResult = new GroupValidationResult(this);
+        if (!ParameterValidationUtils.validateStringParameter(host)) {
+            validationResult.setResult("host", ValidationStatus.INVALID,
+                    "must be a non-blank string containing hostname/ipaddress of the distribution rest server");
+        }
+        if (!ParameterValidationUtils.validateStringParameter(userName)) {
+            validationResult.setResult("userName", ValidationStatus.INVALID,
+                    "must be a non-blank string containing userName for distribution rest server credentials");
+        }
+        if (!ParameterValidationUtils.validateStringParameter(password)) {
+            validationResult.setResult("password", ValidationStatus.INVALID,
+                    "must be a non-blank string containing password for distribution rest server credentials");
+        }
+        if (!ParameterValidationUtils.validateIntParameter(port)) {
+            validationResult.setResult("port", ValidationStatus.INVALID,
+                    "must be a positive integer containing port of the distribution rest server");
+        }
+        return validationResult;
+    }
+}
diff --git a/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/rest/DistributionRestController.java b/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/rest/DistributionRestController.java
new file mode 100644 (file)
index 0000000..d7e0f9f
--- /dev/null
@@ -0,0 +1,70 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2018 Ericsson. 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.distribution.main.rest;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.Info;
+import io.swagger.annotations.SwaggerDefinition;
+import io.swagger.annotations.Tag;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.onap.policy.common.endpoints.report.HealthCheckReport;
+
+/**
+ * Class to provide distribution REST services.
+ *
+ * @author Ram Krishna Verma (ram.krishna.verma@ericsson.com)
+ */
+@Path("/")
+@Api
+@Produces(MediaType.APPLICATION_JSON)
+@SwaggerDefinition(
+        info = @Info(description = "Policy Distribution Service", version = "v1.0", title = "Policy Distribution"),
+        consumes = { MediaType.APPLICATION_JSON }, produces = { MediaType.APPLICATION_JSON },
+        schemes = { SwaggerDefinition.Scheme.HTTP },
+        tags = { @Tag(name = "policy-distribution", description = "Policy Distribution Service Operations") })
+public class DistributionRestController {
+
+    @GET
+    @Path("healthcheck")
+    @Produces(MediaType.APPLICATION_JSON)
+    @ApiOperation(value = "Perform a system healthcheck",
+            notes = "Provides healthy status of the Policy Distribution component", response = HealthCheckReport.class)
+    public Response healthcheck() {
+        return Response.status(Response.Status.OK).entity(new HealthCheckProvider().performHealthCheck()).build();
+    }
+
+    @GET
+    @Path("statistics")
+    @Produces(MediaType.APPLICATION_JSON)
+    @ApiOperation(value = "Fetch current statistics",
+            notes = "Provides current statistics of the Policy Distribution component",
+            response = StatisticsReport.class)
+    public Response statistics() {
+        return Response.status(Response.Status.OK).entity(new StatisticsProvider().fetchCurrentStatistics()).build();
+    }
+}
diff --git a/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/rest/DistributionRestServer.java b/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/rest/DistributionRestServer.java
new file mode 100644 (file)
index 0000000..748d516
--- /dev/null
@@ -0,0 +1,142 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2018 Ericsson. 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.distribution.main.rest;
+
+import java.util.ArrayList;
+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.logging.flexlogger.FlexLogger;
+import org.onap.policy.common.logging.flexlogger.Logger;
+import org.onap.policy.distribution.main.parameters.RestServerParameters;
+
+/**
+ * Class to manage life cycle of distribution rest server.
+ *
+ * @author Ram Krishna Verma (ram.krishna.verma@ericsson.com)
+ */
+public class DistributionRestServer implements Startable {
+
+    private static final String SEPARATOR = ".";
+    private static final String HTTP_SERVER_SERVICES = "http.server.services";
+    private static final Logger LOGGER = FlexLogger.getLogger(DistributionRestServer.class);
+
+    private List<HttpServletServer> servers = new ArrayList<>();
+
+    private RestServerParameters restServerParameters;
+
+    /**
+     * Constructor for instantiating DistributionRestServer.
+     *
+     * @param restServerParameters the rest server parameters
+     */
+    public DistributionRestServer(final RestServerParameters restServerParameters) {
+        this.restServerParameters = restServerParameters;
+    }
+
+    /**
+     * {@inheritDoc}.
+     */
+    @Override
+    public boolean start() {
+        try {
+            servers = HttpServletServer.factory.build(getServerProperties());
+            for (final HttpServletServer server : servers) {
+                server.start();
+            }
+        } catch (final Exception exp) {
+            LOGGER.error("Failed to start distribution http server", exp);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Creates the server properties object using restServerParameters.
+     *
+     * @return the properties object
+     */
+    private Properties getServerProperties() {
+        final Properties props = new Properties();
+        props.setProperty(HTTP_SERVER_SERVICES, restServerParameters.getName());
+        props.setProperty(HTTP_SERVER_SERVICES + SEPARATOR + restServerParameters.getName() + ".host",
+                restServerParameters.getHost());
+        props.setProperty(HTTP_SERVER_SERVICES + SEPARATOR + restServerParameters.getName() + ".port",
+                Integer.toString(restServerParameters.getPort()));
+        props.setProperty(HTTP_SERVER_SERVICES + SEPARATOR + restServerParameters.getName() + ".restClasses",
+                DistributionRestController.class.getCanonicalName());
+        props.setProperty(HTTP_SERVER_SERVICES + SEPARATOR + restServerParameters.getName() + ".managed", "false");
+        props.setProperty(HTTP_SERVER_SERVICES + SEPARATOR + restServerParameters.getName() + ".swagger", "true");
+        props.setProperty(HTTP_SERVER_SERVICES + SEPARATOR + restServerParameters.getName() + ".userName",
+                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()));
+        return props;
+    }
+
+    /**
+     * {@inheritDoc}.
+     */
+    @Override
+    public boolean stop() {
+        for (final HttpServletServer server : servers) {
+            try {
+                server.stop();
+            } catch (final Exception exp) {
+                LOGGER.error("Failed to stop distribution http server", exp);
+            }
+        }
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}.
+     */
+    @Override
+    public void shutdown() {
+        stop();
+    }
+
+    /**
+     * {@inheritDoc}.
+     */
+    @Override
+    public boolean isAlive() {
+        return !servers.isEmpty();
+    }
+
+    /**
+     * {@inheritDoc}.
+     */
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("DistributionRestServer [servers=");
+        builder.append(servers);
+        builder.append("]");
+        return builder.toString();
+    }
+
+}
diff --git a/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/rest/HealthCheckProvider.java b/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/rest/HealthCheckProvider.java
new file mode 100644 (file)
index 0000000..a22d085
--- /dev/null
@@ -0,0 +1,52 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2018 Ericsson. 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.distribution.main.rest;
+
+import org.onap.policy.common.endpoints.report.HealthCheckReport;
+import org.onap.policy.distribution.main.startstop.DistributionActivator;
+
+/**
+ * Class to fetch health check of distribution service.
+ *
+ * @author Ram Krishna Verma (ram.krishna.verma@ericsson.com)
+ */
+public class HealthCheckProvider {
+
+    private static final String NOT_ALIVE = "not alive";
+    private static final String ALIVE = "alive";
+    private static final String URL = "self";
+    private static final String NAME = "Policy SSD";
+
+    /**
+     * Performs the health check of distribution service.
+     *
+     * @return Report containing health check status
+     */
+    public HealthCheckReport performHealthCheck() {
+        final HealthCheckReport report = new HealthCheckReport();
+        report.setName(NAME);
+        report.setUrl(URL);
+        report.setHealthy(DistributionActivator.isAlive());
+        report.setCode(DistributionActivator.isAlive() ? 200 : 500);
+        report.setMessage(DistributionActivator.isAlive() ? ALIVE : NOT_ALIVE);
+        return report;
+    }
+}
diff --git a/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/rest/StatisticsProvider.java b/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/rest/StatisticsProvider.java
new file mode 100644 (file)
index 0000000..6d1f511
--- /dev/null
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2018 Ericsson. 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.distribution.main.rest;
+
+import org.onap.policy.distribution.main.startstop.DistributionActivator;
+
+/**
+ * Class to fetch statistics of distribution service.
+ *
+ * @author Ram Krishna Verma (ram.krishna.verma@ericsson.com)
+ */
+public class StatisticsProvider {
+
+    /**
+     * Returns the current statistics of distribution service.
+     *
+     * @return Report containing statistics of distribution service
+     */
+    public StatisticsReport fetchCurrentStatistics() {
+        final StatisticsReport report = new StatisticsReport();
+        report.setCode(DistributionActivator.isAlive() ? 200 : 500);
+        return report;
+    }
+}
diff --git a/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/rest/StatisticsReport.java b/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/rest/StatisticsReport.java
new file mode 100644 (file)
index 0000000..4cbbcd7
--- /dev/null
@@ -0,0 +1,188 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2018 Ericsson. 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.distribution.main.rest;
+
+/**
+ * Class to represent statistics report of distribution service.
+ *
+ * @author Ram Krishna Verma (ram.krishna.verma@ericsson.com)
+ */
+public class StatisticsReport {
+
+    private int code;
+    private long totalDistributionCount;
+    private long distributionSuccessCount;
+    private long distributionFailureCount;
+    private long totalDownloadCount;
+    private long downloadSuccessCount;
+    private long downloadFailureCount;
+
+    /**
+     * Returns the code of this {@link StatisticsReport} instance.
+     *
+     * @return the code
+     */
+    public int getCode() {
+        return code;
+    }
+
+    /**
+     * Set code in this {@link StatisticsReport} instance.
+     *
+     * @param code the code to set
+     */
+    public void setCode(final int code) {
+        this.code = code;
+    }
+
+    /**
+     * Returns the totalDistributionCount of this {@link StatisticsReport} instance.
+     *
+     * @return the totalDistributionCount
+     */
+    public long getTotalDistributionCount() {
+        return totalDistributionCount;
+    }
+
+    /**
+     * Set totalDistributionCount in this {@link StatisticsReport} instance.
+     *
+     * @param totalDistributionCount the totalDistributionCount to set
+     */
+    public void setTotalDistributionCount(final long totalDistributionCount) {
+        this.totalDistributionCount = totalDistributionCount;
+    }
+
+    /**
+     * Returns the distributionSuccessCount of this {@link StatisticsReport} instance.
+     *
+     * @return the distributionSuccessCount
+     */
+    public long getDistributionSuccessCount() {
+        return distributionSuccessCount;
+    }
+
+    /**
+     * Set distributionSuccessCount in this {@link StatisticsReport} instance.
+     *
+     * @param distributionSuccessCount the distributionSuccessCount to set
+     */
+    public void setDistributionSuccessCount(final long distributionSuccessCount) {
+        this.distributionSuccessCount = distributionSuccessCount;
+    }
+
+    /**
+     * Returns the distributionFailureCount of this {@link StatisticsReport} instance.
+     *
+     * @return the distributionFailureCount
+     */
+    public long getDistributionFailureCount() {
+        return distributionFailureCount;
+    }
+
+    /**
+     * Set distributionFailureCount in this {@link StatisticsReport} instance.
+     *
+     * @param distributionFailureCount the distributionFailureCount to set
+     */
+    public void setDistributionFailureCount(final long distributionFailureCount) {
+        this.distributionFailureCount = distributionFailureCount;
+    }
+
+    /**
+     * Returns the totalDownloadCount of this {@link StatisticsReport} instance.
+     *
+     * @return the totalDownloadCount
+     */
+    public long getTotalDownloadCount() {
+        return totalDownloadCount;
+    }
+
+    /**
+     * Set totalDownloadCount in this {@link StatisticsReport} instance.
+     *
+     * @param totalDownloadCount the totalDownloadCount to set
+     */
+    public void setTotalDownloadCount(final long totalDownloadCount) {
+        this.totalDownloadCount = totalDownloadCount;
+    }
+
+    /**
+     * Returns the downloadSuccessCount of this {@link StatisticsReport} instance.
+     *
+     * @return the downloadSuccessCount
+     */
+    public long getDownloadSuccessCount() {
+        return downloadSuccessCount;
+    }
+
+    /**
+     * Set downloadSuccessCount in this {@link StatisticsReport} instance.
+     *
+     * @param downloadSuccessCount the downloadSuccessCount to set
+     */
+    public void setDownloadSuccessCount(final long downloadSuccessCount) {
+        this.downloadSuccessCount = downloadSuccessCount;
+    }
+
+    /**
+     * Returns the downloadFailureCount of this {@link StatisticsReport} instance.
+     *
+     * @return the downloadFailureCount
+     */
+    public long getDownloadFailureCount() {
+        return downloadFailureCount;
+    }
+
+    /**
+     * Set downloadFailureCount in this {@link StatisticsReport} instance.
+     *
+     * @param downloadFailureCount the downloadFailureCount to set
+     */
+    public void setDownloadFailureCount(final long downloadFailureCount) {
+        this.downloadFailureCount = downloadFailureCount;
+    }
+
+
+    /**
+     * {@inheritDoc}.
+     */
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("StatisticsReport [code=");
+        builder.append(getCode());
+        builder.append(", totalDistributionCount=");
+        builder.append(getTotalDistributionCount());
+        builder.append(", distributionSuccessCount=");
+        builder.append(getDistributionSuccessCount());
+        builder.append(", distributionFailureCount=");
+        builder.append(getDistributionFailureCount());
+        builder.append(", totalDownloadCount=");
+        builder.append(getTotalDownloadCount());
+        builder.append(", downloadSuccessCount=");
+        builder.append(getDownloadSuccessCount());
+        builder.append(", downloadFailureCount=");
+        builder.append(getDownloadFailureCount());
+        builder.append("]");
+        return builder.toString();
+    }
+}
diff --git a/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/startstop/DistributionActivator.java b/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/startstop/DistributionActivator.java
new file mode 100644 (file)
index 0000000..2a5dd88
--- /dev/null
@@ -0,0 +1,153 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2018 Ericsson. 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.distribution.main.startstop;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.onap.policy.common.logging.flexlogger.FlexLogger;
+import org.onap.policy.common.logging.flexlogger.Logger;
+import org.onap.policy.common.parameters.ParameterService;
+import org.onap.policy.distribution.main.PolicyDistributionException;
+import org.onap.policy.distribution.main.parameters.DistributionParameterGroup;
+import org.onap.policy.distribution.main.rest.DistributionRestServer;
+
+/**
+ * This class wraps a distributor so that it can be activated as a complete service together with all its distribution
+ * and forwarding handlers.
+ */
+public class DistributionActivator {
+    // The logger for this class
+    private static final Logger LOGGER = FlexLogger.getLogger(DistributionActivator.class);
+
+    // The parameters of this policy distribution activator
+    private final DistributionParameterGroup distributionParameterGroup;
+
+    // The map of reception handlers initialized by this distribution activator
+
+    private static boolean alive = false;
+
+    private DistributionRestServer restServer;
+
+    /**
+     * Instantiate the activator for policy distribution as a complete service.
+     *
+     * @param distributionParameterGroup the parameters for the distribution service
+     */
+    public DistributionActivator(final DistributionParameterGroup distributionParameterGroup) {
+        this.distributionParameterGroup = distributionParameterGroup;
+    }
+
+    /**
+     * Initialize distribution as a complete service.
+     *
+     * @throws PolicyDistributionException on errors in initializing the service
+     */
+    @SuppressWarnings("unchecked")
+    public void initialize() throws PolicyDistributionException {
+        LOGGER.debug("Policy distribution starting as a service . . .");
+        startDistributionRestServer();
+        registerToParameterService(distributionParameterGroup);
+        DistributionActivator.setAlive(true);
+        LOGGER.debug("Policy distribution started as a service");
+    }
+
+    /**
+     * Starts the distribution rest server using configuration parameters.
+     *
+     * @throws PolicyDistributionException if server start fails
+     */
+    private void startDistributionRestServer() throws PolicyDistributionException {
+        distributionParameterGroup.getRestServerParameters().setName(distributionParameterGroup.getName());
+        restServer = new DistributionRestServer(distributionParameterGroup.getRestServerParameters());
+        if (!restServer.start()) {
+            throw new PolicyDistributionException(
+                    "Failed to start distribution rest server. Check log for more details...");
+        }
+    }
+
+    /**
+     * Terminate policy distribution.
+     *
+     * @throws PolicyDistributionException on termination errors
+     */
+    public void terminate() throws PolicyDistributionException {
+        try {
+            deregisterToParameterService(distributionParameterGroup);
+            DistributionActivator.setAlive(false);
+
+            // Stop the distribution rest server
+            restServer.stop();
+        } catch (final Exception exp) {
+            LOGGER.error("Policy distribution service termination failed", exp);
+            throw new PolicyDistributionException(exp.getMessage(), exp);
+        }
+    }
+
+    /**
+     * Get the parameters used by the activator.
+     *
+     * @return the parameters of the activator
+     */
+    public DistributionParameterGroup getParameterGroup() {
+        return distributionParameterGroup;
+    }
+
+    /**
+     * Method to register the parameters to Common Parameter Service.
+     *
+     * @param distributionParameterGroup the distribution parameter group
+     */
+    public void registerToParameterService(final DistributionParameterGroup distributionParameterGroup) {
+        ParameterService.register(distributionParameterGroup);
+        //@formatter:off
+        //@formatter:on
+    }
+
+    /**
+     * Method to deregister the parameters from Common Parameter Service.
+     *
+     * @param distributionParameterGroup the distribution parameter group
+     */
+    public void deregisterToParameterService(final DistributionParameterGroup distributionParameterGroup) {
+        ParameterService.deregister(distributionParameterGroup.getName());
+        //@formatter:on
+    }
+
+    /**
+     * Returns the alive status of distribution service.
+     *
+     * @return the alive
+     */
+    public static boolean isAlive() {
+        return alive;
+    }
+
+    /**
+     * Change the alive status of distribution service.
+     *
+     * @param status the status
+     */
+    public static void setAlive(final boolean status) {
+        alive = status;
+    }
+}
diff --git a/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/startstop/DistributionCommandLineArguments.java b/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/startstop/DistributionCommandLineArguments.java
new file mode 100644 (file)
index 0000000..b805456
--- /dev/null
@@ -0,0 +1,246 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2018 Ericsson. 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.distribution.main.startstop;
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.URL;
+import java.util.Arrays;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.onap.policy.common.utils.resources.ResourceUtils;
+import org.onap.policy.distribution.main.PolicyDistributionException;
+import org.onap.policy.distribution.main.PolicyDistributionRuntimeException;
+
+/**
+ * This class reads and handles command line parameters for the policy distribution main program.
+ */
+public class DistributionCommandLineArguments {
+    private static final String FILE_MESSAGE_PREAMBLE = " file \"";
+    private static final int HELP_LINE_LENGTH = 120;
+
+    // Apache Commons CLI options
+    private final Options options;
+
+    // The command line options
+    private String configurationFilePath = null;
+
+    /**
+     * Construct the options for the CLI editor.
+     */
+    public DistributionCommandLineArguments() {
+        //@formatter:off
+        options = new Options();
+        options.addOption(Option.builder("h")
+                .longOpt("help")
+                .desc("outputs the usage of this command")
+                .required(false)
+                .type(Boolean.class)
+                .build());
+        options.addOption(Option.builder("v")
+                .longOpt("version")
+                .desc("outputs the version of policy distribution")
+                .required(false)
+                .type(Boolean.class)
+                .build());
+        options.addOption(Option.builder("c")
+                .longOpt("config-file")
+                .desc("the full path to the configuration file to use, "
+                        + "the configuration file must be a Json file containing the policy distribution parameters")
+                .hasArg()
+                .argName("CONFIG_FILE")
+                .required(false)
+                .type(String.class)
+                .build());
+        //@formatter:on
+    }
+
+    /**
+     * Construct the options for the CLI editor and parse in the given arguments.
+     *
+     * @param args The command line arguments
+     */
+    public DistributionCommandLineArguments(final String[] args) {
+        // Set up the options with the default constructor
+        this();
+
+        // Parse the arguments
+        try {
+            parse(args);
+        } catch (final PolicyDistributionException e) {
+            throw new PolicyDistributionRuntimeException("parse error on policy distribution parameters", e);
+        }
+    }
+
+    /**
+     * Parse the command line options.
+     *
+     * @param args The command line arguments
+     * @return a string with a message for help and version, or null if there is no message
+     * @throws PolicyDistributionException on command argument errors
+     */
+    public String parse(final String[] args) throws PolicyDistributionException {
+        // Clear all our arguments
+        setConfigurationFilePath(null);
+
+        CommandLine commandLine = null;
+        try {
+            commandLine = new DefaultParser().parse(options, args);
+        } catch (final ParseException e) {
+            throw new PolicyDistributionException("invalid command line arguments specified : " + e.getMessage());
+        }
+
+        // Arguments left over after Commons CLI does its stuff
+        final String[] remainingArgs = commandLine.getArgs();
+
+        if (remainingArgs.length > 0 && commandLine.hasOption('c') || remainingArgs.length > 0) {
+            throw new PolicyDistributionException(
+                    "too many command line arguments specified : " + Arrays.toString(args));
+        }
+
+        if (remainingArgs.length == 1) {
+            configurationFilePath = remainingArgs[0];
+        }
+
+        if (commandLine.hasOption('h')) {
+            return help(Main.class.getCanonicalName());
+        }
+
+        if (commandLine.hasOption('v')) {
+            return version();
+        }
+
+        if (commandLine.hasOption('c')) {
+            setConfigurationFilePath(commandLine.getOptionValue('c'));
+        }
+
+        return null;
+    }
+
+    /**
+     * Validate the command line options.
+     *
+     * @throws PolicyDistributionException on command argument validation errors
+     */
+    public void validate() throws PolicyDistributionException {
+        validateReadableFile("policy distribution configuration", configurationFilePath);
+    }
+
+    /**
+     * Print version information for policy distribution.
+     *
+     * @return the version string
+     */
+    public String version() {
+        return ResourceUtils.getResourceAsString("version.txt");
+    }
+
+    /**
+     * Print help information for policy distribution.
+     *
+     * @param mainClassName the main class name
+     * @return the help string
+     */
+    public String help(final String mainClassName) {
+        final HelpFormatter helpFormatter = new HelpFormatter();
+        final StringWriter stringWriter = new StringWriter();
+        final PrintWriter printWriter = new PrintWriter(stringWriter);
+
+        helpFormatter.printHelp(printWriter, HELP_LINE_LENGTH, mainClassName + " [options...]", "options", options, 0,
+                0, "");
+
+        return stringWriter.toString();
+    }
+
+    /**
+     * Gets the configuration file path.
+     *
+     * @return the configuration file path
+     */
+    public String getConfigurationFilePath() {
+        return configurationFilePath;
+    }
+
+    /**
+     * Gets the full expanded configuration file path.
+     *
+     * @return the configuration file path
+     */
+    public String getFullConfigurationFilePath() {
+        return ResourceUtils.getFilePath4Resource(getConfigurationFilePath());
+    }
+
+    /**
+     * Sets the configuration file path.
+     *
+     * @param configurationFilePath the configuration file path
+     */
+    public void setConfigurationFilePath(final String configurationFilePath) {
+        this.configurationFilePath = configurationFilePath;
+
+    }
+
+    /**
+     * Check set configuration file path.
+     *
+     * @return true, if check set configuration file path
+     */
+    public boolean checkSetConfigurationFilePath() {
+        return configurationFilePath != null && configurationFilePath.length() > 0;
+    }
+
+    /**
+     * Validate readable file.
+     *
+     * @param fileTag the file tag
+     * @param fileName the file name
+     * @throws PolicyDistributionException on the file name passed as a parameter
+     */
+    private void validateReadableFile(final String fileTag, final String fileName) throws PolicyDistributionException {
+        if (fileName == null || fileName.length() == 0) {
+            throw new PolicyDistributionException(fileTag + " file was not specified as an argument");
+        }
+
+        // The file name refers to a resource on the local file system
+        final URL fileUrl = ResourceUtils.getUrl4Resource(fileName);
+        if (fileUrl == null) {
+            throw new PolicyDistributionException(fileTag + FILE_MESSAGE_PREAMBLE + fileName + "\" does not exist");
+        }
+
+        final File theFile = new File(fileUrl.getPath());
+        if (!theFile.exists()) {
+            throw new PolicyDistributionException(fileTag + FILE_MESSAGE_PREAMBLE + fileName + "\" does not exist");
+        }
+        if (!theFile.isFile()) {
+            throw new PolicyDistributionException(
+                    fileTag + FILE_MESSAGE_PREAMBLE + fileName + "\" is not a normal file");
+        }
+        if (!theFile.canRead()) {
+            throw new PolicyDistributionException(fileTag + FILE_MESSAGE_PREAMBLE + fileName + "\" is ureadable");
+        }
+    }
+}
diff --git a/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/startstop/Main.java b/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/startstop/Main.java
new file mode 100644 (file)
index 0000000..3ff85b8
--- /dev/null
@@ -0,0 +1,149 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2018 Ericsson. 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.distribution.main.startstop;
+
+import java.util.Arrays;
+
+import org.onap.policy.common.logging.flexlogger.FlexLogger;
+import org.onap.policy.common.logging.flexlogger.Logger;
+import org.onap.policy.distribution.main.PolicyDistributionException;
+import org.onap.policy.distribution.main.parameters.DistributionParameterGroup;
+import org.onap.policy.distribution.main.parameters.DistributionParameterHandler;
+
+/**
+ * This class initiates ONAP Policy Framework policy distribution.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class Main {
+    private static final Logger LOGGER = FlexLogger.getLogger(Main.class);
+
+    // The policy distribution Activator that activates the policy distribution service
+    private DistributionActivator activator;
+
+    // The parameters read in from JSON
+    private DistributionParameterGroup parameterGroup;
+
+    /**
+     * Instantiates the policy distribution service.
+     *
+     * @param args the command line arguments
+     */
+    public Main(final String[] args) {
+        final String argumentString = Arrays.toString(args);
+        LOGGER.info("Starting policy distribution service with arguments - " + argumentString);
+
+        // Check the arguments
+        final DistributionCommandLineArguments arguments = new DistributionCommandLineArguments();
+        try {
+            // The arguments return a string if there is a message to print and we should exit
+            final String argumentMessage = arguments.parse(args);
+            if (argumentMessage != null) {
+                LOGGER.info(argumentMessage);
+                return;
+            }
+
+            // Validate that the arguments are sane
+            arguments.validate();
+        } catch (final PolicyDistributionException e) {
+            LOGGER.error("start of policy distribution service failed", e);
+            return;
+        }
+
+        // Read the parameters
+        try {
+            parameterGroup = new DistributionParameterHandler().getParameters(arguments);
+        } catch (final Exception e) {
+            LOGGER.error("start of policy distribution service failed", e);
+            return;
+        }
+
+        // Now, create the activator for the policy distribution service
+        activator = new DistributionActivator(parameterGroup);
+
+        // Start the activator
+        try {
+            activator.initialize();
+        } catch (final PolicyDistributionException e) {
+            LOGGER.error("start of policy distribution service failed, used parameters are " + Arrays.toString(args),
+                    e);
+            return;
+        }
+
+        // Add a shutdown hook to shut everything down in an orderly manner
+        Runtime.getRuntime().addShutdownHook(new PolicyDistributionShutdownHookClass());
+        LOGGER.info("Started policy distribution service");
+    }
+
+    /**
+     * Get the parameters specified in JSON.
+     *
+     * @return the parameters
+     */
+    public DistributionParameterGroup getParameters() {
+        return parameterGroup;
+    }
+
+    /**
+     * Shut down Execution.
+     *
+     * @throws PolicyDistributionException on shutdown errors
+     */
+    public void shutdown() throws PolicyDistributionException {
+        // clear the parameterGroup variable
+        parameterGroup = null;
+
+        // clear the distribution activator
+        if (activator != null) {
+            activator.terminate();
+        }
+    }
+
+    /**
+     * The Class PolicyDistributionShutdownHookClass terminates the policy distribution service when its run method is
+     * called.
+     */
+    private class PolicyDistributionShutdownHookClass extends Thread {
+        /*
+         * (non-Javadoc)
+         *
+         * @see java.lang.Runnable#run()
+         */
+        @Override
+        public void run() {
+            try {
+                // Shutdown the policy distribution service and wait for everything to stop
+                activator.terminate();
+            } catch (final PolicyDistributionException e) {
+                LOGGER.warn("error occured during shut down of the policy distribution service", e);
+            }
+        }
+    }
+
+    /**
+     * The main method.
+     *
+     * @param args the arguments
+     */
+    public static void main(final String[] args) {
+        new Main(args);
+    }
+}
diff --git a/artifactbroker/main/src/main/resources/version.txt b/artifactbroker/main/src/main/resources/version.txt
new file mode 100644 (file)
index 0000000..c617841
--- /dev/null
@@ -0,0 +1,4 @@
+ONAP Policy Framework Distribution Service
+Version: ${project.version}
+Built (UTC): ${maven.build.timestamp}
+ONAP https://wiki.onap.org
\ No newline at end of file
diff --git a/artifactbroker/main/src/test/java/org/onap/policy/distribution/main/TestExceptions.java b/artifactbroker/main/src/test/java/org/onap/policy/distribution/main/TestExceptions.java
new file mode 100644 (file)
index 0000000..b314097
--- /dev/null
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2018 Ericsson. 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.distribution.main;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+
+import org.junit.Test;
+
+public class TestExceptions {
+
+    @Test
+    public void test() {
+        assertNotNull(new PolicyDistributionException("Message"));
+        assertNotNull(new PolicyDistributionException("Message", new IOException()));
+        
+        assertNotNull(new PolicyDistributionRuntimeException("Message"));
+        assertNotNull(new PolicyDistributionRuntimeException("Message", new IOException()));
+    }
+}
diff --git a/artifactbroker/main/src/test/java/org/onap/policy/distribution/main/rest/TestDistributionRestServer.java b/artifactbroker/main/src/test/java/org/onap/policy/distribution/main/rest/TestDistributionRestServer.java
new file mode 100644 (file)
index 0000000..f9e790c
--- /dev/null
@@ -0,0 +1,103 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2018 Ericsson. 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.distribution.main.rest;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Invocation;
+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.Test;
+import org.onap.policy.common.endpoints.report.HealthCheckReport;
+import org.onap.policy.common.logging.flexlogger.FlexLogger;
+import org.onap.policy.common.logging.flexlogger.Logger;
+import org.onap.policy.distribution.main.PolicyDistributionException;
+import org.onap.policy.distribution.main.parameters.RestServerParameters;
+import org.onap.policy.distribution.main.startstop.Main;
+
+/**
+ * Class to perform unit test of HealthCheckMonitor.
+ *
+ * @author Ram Krishna Verma (ram.krishna.verma@ericsson.com)
+ */
+public class TestDistributionRestServer {
+
+    private static final Logger LOGGER = FlexLogger.getLogger(TestDistributionRestServer.class);
+    private static final String NOT_ALIVE = "not alive";
+    private static final String ALIVE = "alive";
+    private static final String SELF = "self";
+    private static final String NAME = "Policy SSD";
+
+    @Test
+    public void testHealthCheckSuccess() throws PolicyDistributionException, InterruptedException {
+        final String reportString = "Report [name=Policy SSD, url=self, healthy=true, code=200, message=alive]";
+        final Main main = startDistributionService();
+        final HealthCheckReport report = performHealthCheck();
+        validateReport(NAME, SELF, true, 200, ALIVE, reportString, report);
+        stopDistributionService(main);
+    }
+
+    private Main startDistributionService() {
+        final String[] distributionConfigParameters = { "-c", "parameters/DistributionConfigParameters.json" };
+        return new Main(distributionConfigParameters);
+    }
+
+    private void stopDistributionService(final Main main) throws PolicyDistributionException {
+        main.shutdown();
+    }
+
+    private HealthCheckReport performHealthCheck() throws InterruptedException {
+        HealthCheckReport response = null;
+        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 Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON);
+        while (response == null) {
+            try {
+                response = invocationBuilder.get(HealthCheckReport.class);
+            } catch (final Exception exp) {
+                LOGGER.info("the server is not started yet. We will retry again");
+            }
+        }
+        return response;
+    }
+
+    private void validateReport(final String name, final String url, final boolean healthy, final int code,
+            final String message, final String reportString, 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/artifactbroker/main/src/test/java/org/onap/policy/distribution/main/rest/TestHttpsDistributionRestServer.backup b/artifactbroker/main/src/test/java/org/onap/policy/distribution/main/rest/TestHttpsDistributionRestServer.backup
new file mode 100644 (file)
index 0000000..6667d7f
--- /dev/null
@@ -0,0 +1,136 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2018 Intel. 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.distribution.main.rest;
+
+import static org.junit.Assert.assertEquals;
+
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+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;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+
+import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
+import org.junit.Test;
+import org.onap.policy.common.endpoints.report.HealthCheckReport;
+import org.onap.policy.common.logging.flexlogger.FlexLogger;
+import org.onap.policy.common.logging.flexlogger.Logger;
+import org.onap.policy.distribution.main.PolicyDistributionException;
+import org.onap.policy.distribution.main.startstop.Main;
+
+/**
+ * Class to perform unit test of HealthCheckMonitor.
+ *
+ * @author Libo Zhu (libo.zhu@intel.com)
+ */
+public class TestHttpsDistributionRestServer {
+
+    private static final Logger LOGGER = FlexLogger.getLogger(TestDistributionRestServer.class);
+    private static final String ALIVE = "alive";
+    private static final String SELF = "self";
+    private static final String NAME = "Policy SSD";
+    private static String KEYSTORE = System.getProperty("user.dir") + "/src/test/resources/ssl/policy-keystore";
+
+    @Test
+    public void testHealthCheckSuccess()
+        throws PolicyDistributionException, InterruptedException, KeyManagementException, NoSuchAlgorithmException {
+        final String reportString = "Report [name=Policy SSD, url=self, healthy=true, code=200, message=alive]";
+        final Main main = startDistributionService();
+        final HealthCheckReport report = performHealthCheck();
+        validateReport(NAME, SELF, true, 200, ALIVE, reportString, report);
+        stopDistributionService(main);
+    }
+
+    private Main startDistributionService() {
+        Properties systemProps = System.getProperties();
+        systemProps.put("javax.net.ssl.keyStore", KEYSTORE);
+        systemProps.put("javax.net.ssl.keyStorePassword", "Pol1cy_0nap");
+        System.setProperties(systemProps);
+
+        final String[] distributionConfigParameters = { "-c", "parameters/DistributionConfigParameters_Https.json" };
+        return new Main(distributionConfigParameters);
+    }
+
+    private void stopDistributionService(final Main main) throws PolicyDistributionException {
+        main.shutdown();
+    }
+
+    private HealthCheckReport performHealthCheck()
+        throws InterruptedException, KeyManagementException, NoSuchAlgorithmException {
+        HealthCheckReport response = null;
+
+        TrustManager[] noopTrustManager = new TrustManager[] { new X509TrustManager() {
+
+            @Override
+            public X509Certificate[] getAcceptedIssuers() {
+                return new X509Certificate[0];
+            }
+
+            @Override
+            public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
+            }
+
+            @Override
+            public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
+            }
+        } };
+
+        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/healthcheck");
+
+        final Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON);
+        while (response == null) {
+            try {
+                response = invocationBuilder.get(HealthCheckReport.class);
+            } catch (final Exception exp) {
+                LOGGER.error("the server is not started yet. We will retry again", exp);
+            }
+        }
+        return response;
+    }
+
+    private void validateReport(final String name, final String url, final boolean healthy, final int code,
+        final String message, final String reportString, 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/artifactbroker/main/src/test/java/org/onap/policy/distribution/main/rest/TestHttpsStatisticDistributionRestServer.backup b/artifactbroker/main/src/test/java/org/onap/policy/distribution/main/rest/TestHttpsStatisticDistributionRestServer.backup
new file mode 100644 (file)
index 0000000..5aadb6e
--- /dev/null
@@ -0,0 +1,136 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2018 Intel. 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.distribution.main.rest;
+
+import static org.junit.Assert.assertEquals;
+
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+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;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+
+import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
+import org.junit.Test;
+import org.onap.policy.common.logging.flexlogger.FlexLogger;
+import org.onap.policy.common.logging.flexlogger.Logger;
+import org.onap.policy.distribution.main.PolicyDistributionException;
+import org.onap.policy.distribution.main.startstop.Main;
+
+/**
+ * Class to perform unit test of HealthCheckMonitor.
+ *
+ * @author Libo Zhu (libo.zhu@intel.com)
+ */
+public class TestHttpsStatisticDistributionRestServer {
+
+    private static final Logger LOGGER = FlexLogger.getLogger(TestHttpsStatisticDistributionRestServer.class);
+    private static String KEYSTORE = System.getProperty("user.dir") + "/src/test/resources/ssl/policy-keystore";
+
+    @Test
+    public void testDistributionStatistic()
+        throws PolicyDistributionException, InterruptedException, KeyManagementException, NoSuchAlgorithmException {
+        final String reportString = "StatisticsReport [code=200, totalDistributionCount=0, distributionSuccessCount=0, "
+            + "distributionFailureCount=0, totalDownloadCount=0, " + "downloadSuccessCount=0, downloadFailureCount=0]";
+        final Main main = startDistributionService();
+        final StatisticsReport report = performStatisticCheck();
+        validateReport(200, 0, 0, 0, 0, 0, 0, reportString, report);
+        stopDistributionService(main);
+    }
+
+    private Main startDistributionService() {
+        Properties systemProps = System.getProperties();
+        systemProps.put("javax.net.ssl.keyStore", KEYSTORE);
+        systemProps.put("javax.net.ssl.keyStorePassword", "Pol1cy_0nap");
+        System.setProperties(systemProps);
+
+        final String[] distributionConfigParameters = { "-c", "parameters/DistributionConfigParameters_Https.json" };
+        return new Main(distributionConfigParameters);
+    }
+
+    private void stopDistributionService(final Main main) throws PolicyDistributionException {
+        main.shutdown();
+    }
+
+    private StatisticsReport performStatisticCheck()
+        throws InterruptedException, KeyManagementException, NoSuchAlgorithmException {
+        StatisticsReport response = null;
+
+        TrustManager[] noopTrustManager = new TrustManager[] { new X509TrustManager() {
+
+            @Override
+            public X509Certificate[] getAcceptedIssuers() {
+                return new X509Certificate[0];
+            }
+
+            @Override
+            public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
+            }
+
+            @Override
+            public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
+            }
+        } };
+
+        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/statistics");
+
+        final Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON);
+        while (response == null) {
+            try {
+                response = invocationBuilder.get(StatisticsReport.class);
+            } catch (final Exception exp) {
+                LOGGER.error("the server is not started yet. We will retry again", exp);
+            }
+        }
+        return response;
+    }
+
+    private void validateReport(final int code, final int total, final int successCount, final int failureCount,
+        final int download, final int downloadSuccess, final int downloadFailure, final String reportString,
+        final StatisticsReport report) {
+        assertEquals(code, report.getCode());
+        assertEquals(total, report.getTotalDistributionCount());
+        assertEquals(successCount, report.getDistributionSuccessCount());
+        assertEquals(failureCount, report.getDistributionFailureCount());
+        assertEquals(download, report.getTotalDownloadCount());
+        assertEquals(downloadSuccess, report.getDownloadSuccessCount());
+        assertEquals(downloadFailure, report.getDownloadFailureCount());
+        assertEquals(reportString, report.toString());
+    }
+}
diff --git a/artifactbroker/main/src/test/java/org/onap/policy/distribution/main/rest/TestStatisticsReport.java b/artifactbroker/main/src/test/java/org/onap/policy/distribution/main/rest/TestStatisticsReport.java
new file mode 100644 (file)
index 0000000..64d2e5c
--- /dev/null
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2018 Ericsson. 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.distribution.main.rest;
+
+import com.openpojo.reflection.filters.FilterClassName;
+import com.openpojo.validation.Validator;
+import com.openpojo.validation.ValidatorBuilder;
+import com.openpojo.validation.rule.impl.SetterMustExistRule;
+import com.openpojo.validation.test.impl.GetterTester;
+import com.openpojo.validation.test.impl.SetterTester;
+
+import org.junit.Test;
+import org.onap.policy.common.utils.validation.ToStringTester;
+
+/**
+ * Class to perform unit testing of {@link StatisticsReport}.
+ *
+ * @author Ram Krishna Verma (ram.krishna.verma@ericsson.com)
+ */
+public class TestStatisticsReport {
+
+    @Test
+    public void testStatisticsReport() {
+        final Validator validator = ValidatorBuilder.create().with(new ToStringTester()).with(new SetterMustExistRule())
+                .with(new SetterTester()).with(new GetterTester()).build();
+        validator.validate(StatisticsReport.class.getPackage().getName(),
+                new FilterClassName(StatisticsReport.class.getName()));
+    }
+}
diff --git a/artifactbroker/main/src/test/resources/parameters/DistributionConfigParameters.json b/artifactbroker/main/src/test/resources/parameters/DistributionConfigParameters.json
new file mode 100644 (file)
index 0000000..9e20224
--- /dev/null
@@ -0,0 +1,9 @@
+{
+    "name":"SDCDistributionGroup",
+    "restServerParameters":{
+        "host":"0.0.0.0",
+        "port":6969,
+        "userName":"healthcheck",
+        "password":"zb!XztG34"
+    }
+}
diff --git a/artifactbroker/main/src/test/resources/parameters/DistributionConfigParameters_Https.json b/artifactbroker/main/src/test/resources/parameters/DistributionConfigParameters_Https.json
new file mode 100644 (file)
index 0000000..6aa6116
--- /dev/null
@@ -0,0 +1,10 @@
+{
+    "name":"SDCDistributionGroup",
+    "restServerParameters":{
+        "host":"0.0.0.0",
+        "port":6969,
+        "userName":"healthcheck",
+        "password":"zb!XztG34",
+        "https":true
+    }
+}
diff --git a/artifactbroker/main/src/test/resources/ssl/policy-keystore b/artifactbroker/main/src/test/resources/ssl/policy-keystore
new file mode 100644 (file)
index 0000000..7d2b1ec
Binary files /dev/null and b/artifactbroker/main/src/test/resources/ssl/policy-keystore differ
index a49dbc4..971eac7 100644 (file)
         <groupId>org.onap.multicloud.framework</groupId>
         <artifactId>multicloud-framework</artifactId>
         <version>1.3.0-SNAPSHOT</version>
+        <relativePath />
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>org.onap.multicloud.framework.broker</groupId>
-    <artifactId>multicloud-framework-artifact-broker</artifactId>
+    <artifactId>multicloud-framework-artifactbroker</artifactId>
     <version>1.3.0-SNAPSHOT</version>
     <packaging>pom</packaging>
-    <name>multicloud-framework-artifact-broker</name>
+    <name>multicloud-framework-artifactbroker</name>
     <description>artifact  broker</description>
     <properties>
         <encoding>UTF-8</encoding>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
         <nexusproxy>https://nexus.onap.org</nexusproxy>
+        <version.logback>1.2.3</version.logback>
+        <policy.common.version>1.3.4</policy.common.version>
+        <policy.engine.version>1.3.5</policy.engine.version>
     </properties>
+
+    <modules>
+        <module>main</module>
+    </modules>
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.12</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-ext</artifactId>
+            <version>1.8.0-beta2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.7.25</version>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-core</artifactId>
+            <version>${version.logback}</version>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <version>${version.logback}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.policy.common</groupId>
+            <artifactId>common-parameters</artifactId>
+            <version>${policy.common.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.policy.common</groupId>
+            <artifactId>ONAP-Logging</artifactId>
+            <version>${policy.common.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.policy.common</groupId>
+            <artifactId>capabilities</artifactId>
+            <version>${policy.common.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.policy.common</groupId>
+            <artifactId>policy-endpoints</artifactId>
+            <version>${policy.common.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.policy.common</groupId>
+            <artifactId>utils</artifactId>
+            <version>${policy.common.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-cli</groupId>
+            <artifactId>commons-cli</artifactId>
+            <version>1.4</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+            <version>2.8.4</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.jacoco</groupId>
+                <artifactId>jacoco-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>pre-unit-test</id>
+                        <goals>
+                            <goal>prepare-agent</goal>
+                        </goals>
+                        <configuration>
+                            <destFile>${sonar.jacoco.reportPath}</destFile>
+                            <append>true</append>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>post-unit-test</id>
+                        <phase>test</phase>
+                        <goals>
+                            <goal>report</goal>
+                        </goals>
+                        <configuration>
+                            <dataFile>${sonar.jacoco.reportPath}</dataFile>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>onap-java-style</id>
+                        <goals>
+                            <goal>check</goal>
+                        </goals>
+                        <phase>process-sources</phase>
+                        <configuration>
+                            <!-- Use Google Java Style Guide:
+                            https://github.com/checkstyle/checkstyle/blob/master/src/main/resources/google_checks.xml
+                            with minor changes -->
+                            <configLocation>onap-checkstyle/onap-java-style.xml</configLocation>
+                            <!-- <sourceDirectory> is needed so that checkstyle ignores the generated sources directory -->
+                            <sourceDirectory>${project.build.sourceDirectory}</sourceDirectory>
+                            <includeResources>true</includeResources>
+                            <includeTestSourceDirectory>true</includeTestSourceDirectory>
+                            <includeTestResources>true</includeTestResources>
+                            <excludes>
+                            </excludes>
+                            <consoleOutput>true</consoleOutput>
+                            <failOnViolation>true</failOnViolation>
+                            <violationSeverity>warning</violationSeverity>
+                        </configuration>
+                    </execution>
+                </executions>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.onap.oparent</groupId>
+                        <artifactId>checkstyle</artifactId>
+                        <version>1.2.0</version>
+                        <scope>compile</scope>
+                    </dependency>
+                </dependencies>
+            </plugin>
+        </plugins>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.jacoco</groupId>
+                    <artifactId>jacoco-maven-plugin</artifactId>
+                    <version>${jacoco.version}</version>
+                    <configuration>
+                        <!-- Note: This exclusion list should match <sonar.exclusions> property
+                            above -->
+                        <excludes>
+                            <exclude>**/gen/**</exclude>
+                            <exclude>**/generated-sources/**</exclude>
+                            <exclude>**/yang-gen/**</exclude>
+                            <exclude>**/pax/**</exclude>
+                        </excludes>
+                    </configuration>
+                    <executions>
+                        <!-- Prepares the property pointing to the JaCoCo runtime agent which
+                            is passed as VM argument when Maven the Surefire plugin is executed. -->
+                        <execution>
+                            <id>pre-unit-test</id>
+                            <goals>
+                                <goal>prepare-agent</goal>
+                            </goals>
+                            <configuration>
+                                <destFile>${sonar.jacoco.reportPath}</destFile>
+                            </configuration>
+                        </execution>
+                        <!-- Ensures that the code coverage report for unit tests is created
+                            after unit tests have been run. -->
+                        <execution>
+                            <id>post-unit-test</id>
+                            <phase>test</phase>
+                            <goals>
+                                <goal>report</goal>
+                            </goals>
+                            <configuration>
+                                <dataFile>${sonar.jacoco.reportPath}</dataFile>
+                            </configuration>
+                        </execution>
+                    </executions>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+</project>
 </project>