diff options
author | liboNet <libo.zhu@intel.com> | 2019-03-21 08:01:55 +0800 |
---|---|---|
committer | liboNet <libo.zhu@intel.com> | 2019-03-21 08:05:09 +0800 |
commit | 94d7d990ac85143fd3605c9a094082592d554e2a (patch) | |
tree | 01af85a5d39416a72366ee3dcc09a6dbce76d580 /artifactbroker/main | |
parent | 20cc990e09f61a75375b2f39a0b7d9b790f37ccd (diff) |
add rest serve and distribution framework
. 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>
Diffstat (limited to 'artifactbroker/main')
23 files changed, 2009 insertions, 0 deletions
diff --git a/artifactbroker/main/pom.xml b/artifactbroker/main/pom.xml new file mode 100644 index 0000000..875a14f --- /dev/null +++ b/artifactbroker/main/pom.xml @@ -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 index 0000000..041f87c --- /dev/null +++ b/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/PolicyDistributionException.java @@ -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 index 0000000..385505a --- /dev/null +++ b/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/PolicyDistributionRuntimeException.java @@ -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 index 0000000..d034e5e --- /dev/null +++ b/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/parameters/DistributionParameterGroup.java @@ -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 index 0000000..dc72978 --- /dev/null +++ b/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/parameters/DistributionParameterHandler.java @@ -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 index 0000000..4685b7d --- /dev/null +++ b/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/parameters/RestServerParameters.java @@ -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 index 0000000..d7e0f9f --- /dev/null +++ b/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/rest/DistributionRestController.java @@ -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 index 0000000..748d516 --- /dev/null +++ b/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/rest/DistributionRestServer.java @@ -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 index 0000000..a22d085 --- /dev/null +++ b/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/rest/HealthCheckProvider.java @@ -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 index 0000000..6d1f511 --- /dev/null +++ b/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/rest/StatisticsProvider.java @@ -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 index 0000000..4cbbcd7 --- /dev/null +++ b/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/rest/StatisticsReport.java @@ -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 index 0000000..2a5dd88 --- /dev/null +++ b/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/startstop/DistributionActivator.java @@ -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 index 0000000..b805456 --- /dev/null +++ b/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/startstop/DistributionCommandLineArguments.java @@ -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 index 0000000..3ff85b8 --- /dev/null +++ b/artifactbroker/main/src/main/java/org/onap/policy/distribution/main/startstop/Main.java @@ -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 index 0000000..c617841 --- /dev/null +++ b/artifactbroker/main/src/main/resources/version.txt @@ -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 index 0000000..b314097 --- /dev/null +++ b/artifactbroker/main/src/test/java/org/onap/policy/distribution/main/TestExceptions.java @@ -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 index 0000000..f9e790c --- /dev/null +++ b/artifactbroker/main/src/test/java/org/onap/policy/distribution/main/rest/TestDistributionRestServer.java @@ -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 index 0000000..6667d7f --- /dev/null +++ b/artifactbroker/main/src/test/java/org/onap/policy/distribution/main/rest/TestHttpsDistributionRestServer.backup @@ -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 index 0000000..5aadb6e --- /dev/null +++ b/artifactbroker/main/src/test/java/org/onap/policy/distribution/main/rest/TestHttpsStatisticDistributionRestServer.backup @@ -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 index 0000000..64d2e5c --- /dev/null +++ b/artifactbroker/main/src/test/java/org/onap/policy/distribution/main/rest/TestStatisticsReport.java @@ -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 index 0000000..9e20224 --- /dev/null +++ b/artifactbroker/main/src/test/resources/parameters/DistributionConfigParameters.json @@ -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 index 0000000..6aa6116 --- /dev/null +++ b/artifactbroker/main/src/test/resources/parameters/DistributionConfigParameters_Https.json @@ -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 Binary files differnew file mode 100644 index 0000000..7d2b1ec --- /dev/null +++ b/artifactbroker/main/src/test/resources/ssl/policy-keystore |