diff options
author | 2018-08-31 20:01:30 +0900 | |
---|---|---|
committer | 2018-09-03 08:17:36 +0900 | |
commit | da9e01a78e3205ee7238196a574adcf11c041797 (patch) | |
tree | b3e9baf1e0087b95f5b4ba54ce93ef3f1b59a471 /main/src/main | |
parent | 293600297e604c9a8d5487cd281044becdf9c405 (diff) |
Add basic main structure for policy-api
Define main pom xml and update to include main.
Add the main exception parameters rest
startstop classes. Add test cases. Modify comments
Issue-ID: POLICY-1066
Change-Id: I2e878a58eef4f021e3a9a991738194127edf4d16
Signed-off-by: krisjinka <kris.jinka@samsung.com>
Signed-off-by: krishnajinka <kris.jinka@samsung.com>
Diffstat (limited to 'main/src/main')
12 files changed, 1197 insertions, 0 deletions
diff --git a/main/src/main/java/org/onap/policy/api/main/PolicyApiException.java b/main/src/main/java/org/onap/policy/api/main/PolicyApiException.java new file mode 100644 index 00000000..8dedc8ad --- /dev/null +++ b/main/src/main/java/org/onap/policy/api/main/PolicyApiException.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Samsung Electronics Co., Ltd. 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.api.main; + +/** + * This exception will be called if an error occurs in policy api external service. + */ +public class PolicyApiException extends Exception { + private static final long serialVersionUID = -8507246953751956974L; + + /** + * Instantiates a new policy api exception with a message. + * + * @param message the message + */ + public PolicyApiException(final String message) { + super(message); + } + + /** + * Instantiates a new policy api 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 PolicyApiException(final String message, final Exception exp) { + super(message, exp); + } +} diff --git a/main/src/main/java/org/onap/policy/api/main/PolicyApiRuntimeException.java b/main/src/main/java/org/onap/policy/api/main/PolicyApiRuntimeException.java new file mode 100644 index 00000000..a9ec07db --- /dev/null +++ b/main/src/main/java/org/onap/policy/api/main/PolicyApiRuntimeException.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Samsung Electronics Co., Ltd. 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.api.main; + +/** + * This runtime exception will be called if a runtime error occurs when using policy api. + */ +public class PolicyApiRuntimeException extends RuntimeException { + private static final long serialVersionUID = -8507246953751956974L; + + /** + * Instantiates a new policy api runtime exception with a message. + * + * @param message the message + */ + public PolicyApiRuntimeException(final String message) { + super(message); + } + + /** + * Instantiates a new policy api 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 PolicyApiRuntimeException(final String message, final Exception exp) { + super(message, exp); + } +} diff --git a/main/src/main/java/org/onap/policy/api/main/parameters/ApiParameterGroup.java b/main/src/main/java/org/onap/policy/api/main/parameters/ApiParameterGroup.java new file mode 100644 index 00000000..1b149d03 --- /dev/null +++ b/main/src/main/java/org/onap/policy/api/main/parameters/ApiParameterGroup.java @@ -0,0 +1,94 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Samsung Electronics Co., Ltd. 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.api.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 Api component. + * + */ +public class ApiParameterGroup implements ParameterGroup { + private String name; + private RestServerParameters restServerParameters; + + /** + * Create the api parameter group. + * + * @param name the parameter group name + */ + public ApiParameterGroup(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(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 api rest server"); + } else { + validationResult.setResult("restServerParameters", restServerParameters.validate()); + } + return validationResult; + } +} diff --git a/main/src/main/java/org/onap/policy/api/main/parameters/ApiParameterHandler.java b/main/src/main/java/org/onap/policy/api/main/parameters/ApiParameterHandler.java new file mode 100644 index 00000000..4cee10a1 --- /dev/null +++ b/main/src/main/java/org/onap/policy/api/main/parameters/ApiParameterHandler.java @@ -0,0 +1,83 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Samsung Electronics Co., Ltd. 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.api.main.parameters; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +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.api.main.PolicyApiException; +import org.onap.policy.api.main.startstop.ApiCommandLineArguments; + +import java.io.FileReader; + +/** + * This class handles reading, parsing and validating of policy api parameters from JSON files. + */ +public class ApiParameterHandler { + private static final Logger LOGGER = FlexLogger.getLogger(ApiParameterHandler.class); + + /** + * Read the parameters from the parameter file. + * + * @param arguments the arguments passed to policy api + * @return the parameters read from the configuration file + * @throws PolicyApiException on parameter exceptions + */ + public ApiParameterGroup getParameters(final ApiCommandLineArguments arguments) + throws PolicyApiException { + ApiParameterGroup apiParameterGroup = null; + + // Read the parameters + try { + // Read the parameters from JSON using Gson + final Gson gson = new GsonBuilder().create(); + apiParameterGroup = gson.fromJson(new FileReader(arguments.getFullConfigurationFilePath()), + ApiParameterGroup.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 PolicyApiException(errorMessage, e); + } + + // The JSON processing returns null if there is an empty file + if (apiParameterGroup == null) { + final String errorMessage = "no parameters found in \"" + arguments.getConfigurationFilePath() + "\""; + LOGGER.error(errorMessage); + throw new PolicyApiException(errorMessage); + } + + // validate the parameters + final GroupValidationResult validationResult = apiParameterGroup.validate(); + if (!validationResult.isValid()) { + String returnMessage = + "validation error(s) on parameters from \"" + arguments.getConfigurationFilePath() + "\"\n"; + returnMessage += validationResult.getResult(); + + LOGGER.error(returnMessage); + throw new PolicyApiException(returnMessage); + } + + return apiParameterGroup; + } +} diff --git a/main/src/main/java/org/onap/policy/api/main/parameters/RestServerParameters.java b/main/src/main/java/org/onap/policy/api/main/parameters/RestServerParameters.java new file mode 100644 index 00000000..33ecff37 --- /dev/null +++ b/main/src/main/java/org/onap/policy/api/main/parameters/RestServerParameters.java @@ -0,0 +1,136 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Samsung Electronics Co., Ltd. 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.api.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 api rest server. + * + */ +public class RestServerParameters implements ParameterGroup { + private String name; + private String host; + private int port; + private String userName; + private String password; + + /** + * Constructor for instantiating RestServerParameters. + * + * @param host the host name + * @param port the port + * @param userName the user name + * @param password the password + */ + public RestServerParameters(final String host, final int port, final String userName, final String password) { + super(); + this.host = host; + this.port = port; + this.userName = userName; + this.password = password; + } + + /** + * 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; + } + + /** + * 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 api rest server"); + } + if (!ParameterValidationUtils.validateStringParameter(userName)) { + validationResult.setResult("userName", ValidationStatus.INVALID, + "must be a non-blank string containing userName for api rest server credentials"); + } + if (!ParameterValidationUtils.validateStringParameter(password)) { + validationResult.setResult("password", ValidationStatus.INVALID, + "must be a non-blank string containing password for api rest server credentials"); + } + if (!ParameterValidationUtils.validateIntParameter(port)) { + validationResult.setResult("port", ValidationStatus.INVALID, + "must be a positive integer containing port of the api rest server"); + } + return validationResult; + } +} diff --git a/main/src/main/java/org/onap/policy/api/main/rest/ApiRestController.java b/main/src/main/java/org/onap/policy/api/main/rest/ApiRestController.java new file mode 100644 index 00000000..1dd01a32 --- /dev/null +++ b/main/src/main/java/org/onap/policy/api/main/rest/ApiRestController.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Samsung Electronics Co., Ltd. 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.api.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 org.onap.policy.common.endpoints.report.HealthCheckReport; + +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; + +/** + * Class to provide api REST services. + * + */ +@Path("/") +@Api +@Produces(MediaType.APPLICATION_JSON) +@SwaggerDefinition( + info = @Info(description = "Policy Api Service", version = "v1.0", title = "Policy Api"), + consumes = { MediaType.APPLICATION_JSON }, produces = { MediaType.APPLICATION_JSON }, + schemes = { SwaggerDefinition.Scheme.HTTP }, + tags = { @Tag(name = "policy-api", description = "Policy Api Service Operations") }) +public class ApiRestController { + + @GET + @Path("healthcheck") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Perform a system healthcheck", + notes = "Provides healthy status of the Policy Api component", response = HealthCheckReport.class) + public Response healthcheck() { + return Response.status(Response.Status.OK).entity(new HealthCheckProvider().performHealthCheck()).build(); + } +} diff --git a/main/src/main/java/org/onap/policy/api/main/rest/ApiRestServer.java b/main/src/main/java/org/onap/policy/api/main/rest/ApiRestServer.java new file mode 100644 index 00000000..1050dbf6 --- /dev/null +++ b/main/src/main/java/org/onap/policy/api/main/rest/ApiRestServer.java @@ -0,0 +1,139 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Samsung Electronics Co., Ltd. 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.api.main.rest; + +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.api.main.parameters.RestServerParameters; + +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +/** + * Class to manage life cycle of api rest server. + * + */ +public class ApiRestServer implements Startable { + + private static final String SEPARATOR = "."; + private static final String HTTP_SERVER_SERVICES = "http.server.services"; + private static final Logger LOGGER = FlexLogger.getLogger(ApiRestServer.class); + + private List<HttpServletServer> servers = new ArrayList<>(); + + private RestServerParameters restServerParameters; + + /** + * Constructor for instantiating ApiRestServer. + * + * @param restServerParameters the rest server parameters + */ + public ApiRestServer(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 api 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", + ApiRestController.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()); + return props; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean stop() { + for (final HttpServletServer server : servers) { + try { + server.stop(); + } catch (final Exception exp) { + LOGGER.error("Failed to stop api 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("ApiRestServer [servers="); + builder.append(servers); + builder.append("]"); + return builder.toString(); + } + +} diff --git a/main/src/main/java/org/onap/policy/api/main/rest/HealthCheckProvider.java b/main/src/main/java/org/onap/policy/api/main/rest/HealthCheckProvider.java new file mode 100644 index 00000000..33eda9dc --- /dev/null +++ b/main/src/main/java/org/onap/policy/api/main/rest/HealthCheckProvider.java @@ -0,0 +1,51 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Samsung Electronics Co., Ltd. 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.api.main.rest; + +import org.onap.policy.common.endpoints.report.HealthCheckReport; +import org.onap.policy.api.main.startstop.ApiActivator; + +/** + * Class to fetch health check of api service. + * + */ +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 API"; + + /** + * Performs the health check of api service. + * + * @return Report containing health check status + */ + public HealthCheckReport performHealthCheck() { + final HealthCheckReport report = new HealthCheckReport(); + report.setName(NAME); + report.setUrl(URL); + report.setHealthy(ApiActivator.isAlive()); + report.setCode(ApiActivator.isAlive() ? 200 : 500); + report.setMessage(ApiActivator.isAlive() ? ALIVE : NOT_ALIVE); + return report; + } +} diff --git a/main/src/main/java/org/onap/policy/api/main/startstop/ApiActivator.java b/main/src/main/java/org/onap/policy/api/main/startstop/ApiActivator.java new file mode 100644 index 00000000..2173ef3a --- /dev/null +++ b/main/src/main/java/org/onap/policy/api/main/startstop/ApiActivator.java @@ -0,0 +1,144 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Samsung Electronics Co., Ltd. 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.api.main.startstop; + +import org.onap.policy.api.main.rest.ApiRestServer; +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.api.main.PolicyApiException; +import org.onap.policy.api.main.parameters.ApiParameterGroup; + +/** + * This class wraps a distributor so that it can be activated as a complete service together with all its api + * and forwarding handlers. + */ +public class ApiActivator { + // The logger for this class + private static final Logger LOGGER = FlexLogger.getLogger(ApiActivator.class); + + // The parameters of this policy api activator + private final ApiParameterGroup apiParameterGroup; + + private static boolean alive = false; + + private ApiRestServer restServer; + + /** + * Instantiate the activator for policy api as a complete service. + * + * @param apiParameterGroup the parameters for the api service + */ + public ApiActivator(final ApiParameterGroup apiParameterGroup) { + this.apiParameterGroup = apiParameterGroup; + } + + /** + * Initialize api as a complete service. + * + * @throws PolicyApiException on errors in initializing the service + */ + @SuppressWarnings("unchecked") + public void initialize() throws PolicyApiException { + LOGGER.debug("Policy api starting as a service . . ."); + startApiRestServer(); + registerToParameterService(apiParameterGroup); + ApiActivator.setAlive(true); + LOGGER.debug("Policy api started as a service"); + } + + /** + * Starts the api rest server using configuration parameters. + * + * @throws PolicyApiException if server start fails + */ + private void startApiRestServer() throws PolicyApiException { + apiParameterGroup.getRestServerParameters().setName(apiParameterGroup.getName()); + restServer = new ApiRestServer(apiParameterGroup.getRestServerParameters()); + if (!restServer.start()) { + throw new PolicyApiException( + "Failed to start api rest server. Check log for more details..."); + } + } + + /** + * Terminate policy api. + * + * @throws PolicyApiException on termination errors + */ + public void terminate() throws PolicyApiException { + try { + deregisterToParameterService(apiParameterGroup); + ApiActivator.setAlive(false); + + // Stop the api rest server + restServer.stop(); + } catch (final Exception exp) { + LOGGER.error("Policy api service termination failed", exp); + throw new PolicyApiException(exp.getMessage(), exp); + } + } + + /** + * Get the parameters used by the activator. + * + * @return the parameters of the activator + */ + public ApiParameterGroup getParameterGroup() { + return apiParameterGroup; + } + + /** + * Method to register the parameters to Common Parameter Service. + * + * @param apiParameterGroup the api parameter group + */ + public void registerToParameterService(final ApiParameterGroup apiParameterGroup) { + ParameterService.register(apiParameterGroup); + } + + /** + * Method to deregister the parameters from Common Parameter Service. + * + * @param apiParameterGroup the api parameter group + */ + public void deregisterToParameterService(final ApiParameterGroup apiParameterGroup) { + ParameterService.deregister(apiParameterGroup.getName()); + } + + /** + * Returns the alive status of api service. + * + * @return the alive + */ + public static boolean isAlive() { + return alive; + } + + /** + * Change the alive status of api service. + * + * @param status the status + */ + public static void setAlive(final boolean status) { + alive = status; + } +} diff --git a/main/src/main/java/org/onap/policy/api/main/startstop/ApiCommandLineArguments.java b/main/src/main/java/org/onap/policy/api/main/startstop/ApiCommandLineArguments.java new file mode 100644 index 00000000..4306ef30 --- /dev/null +++ b/main/src/main/java/org/onap/policy/api/main/startstop/ApiCommandLineArguments.java @@ -0,0 +1,246 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Samsung Electronics Co., Ltd. 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.api.main.startstop; + +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.api.main.PolicyApiException; +import org.onap.policy.api.main.PolicyApiRuntimeException; + +import java.io.File; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.net.URL; +import java.util.Arrays; + +/** + * This class reads and handles command line parameters for the policy api main program. + */ +public class ApiCommandLineArguments { + 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 ApiCommandLineArguments() { + //@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 api") + .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 api 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 ApiCommandLineArguments(final String[] args) { + // Set up the options with the default constructor + this(); + + // Parse the arguments + try { + parse(args); + } catch (final PolicyApiException e) { + throw new PolicyApiRuntimeException("parse error on policy api 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 PolicyApiException on command argument errors + */ + public String parse(final String[] args) throws PolicyApiException { + // Clear all our arguments + setConfigurationFilePath(null); + + CommandLine commandLine = null; + try { + commandLine = new DefaultParser().parse(options, args); + } catch (final ParseException e) { + throw new PolicyApiException("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 PolicyApiException( + "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 PolicyApiException on command argument validation errors + */ + public void validate() throws PolicyApiException { + validateReadableFile("policy api configuration", configurationFilePath); + } + + /** + * Print version information for policy api. + * + * @return the version string + */ + public String version() { + return ResourceUtils.getResourceAsString("version.txt"); + } + + /** + * Print help information for policy api. + * + * @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 PolicyApiException on the file name passed as a parameter + */ + private void validateReadableFile(final String fileTag, final String fileName) throws PolicyApiException { + if (fileName == null || fileName.length() == 0) { + throw new PolicyApiException(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 PolicyApiException(fileTag + FILE_MESSAGE_PREAMBLE + fileName + "\" does not exist"); + } + + final File theFile = new File(fileUrl.getPath()); + if (!theFile.exists()) { + throw new PolicyApiException(fileTag + FILE_MESSAGE_PREAMBLE + fileName + "\" does not exist"); + } + if (!theFile.isFile()) { + throw new PolicyApiException( + fileTag + FILE_MESSAGE_PREAMBLE + fileName + "\" is not a normal file"); + } + if (!theFile.canRead()) { + throw new PolicyApiException(fileTag + FILE_MESSAGE_PREAMBLE + fileName + "\" is ureadable"); + } + } +} diff --git a/main/src/main/java/org/onap/policy/api/main/startstop/Main.java b/main/src/main/java/org/onap/policy/api/main/startstop/Main.java new file mode 100644 index 00000000..a533bed5 --- /dev/null +++ b/main/src/main/java/org/onap/policy/api/main/startstop/Main.java @@ -0,0 +1,148 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Samsung Electronics Co., Ltd. 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.api.main.startstop; + +import org.onap.policy.api.main.PolicyApiException; +import org.onap.policy.common.logging.flexlogger.FlexLogger; +import org.onap.policy.common.logging.flexlogger.Logger; +import org.onap.policy.api.main.parameters.ApiParameterGroup; +import org.onap.policy.api.main.parameters.ApiParameterHandler; + +import java.util.Arrays; + +/** + * This class initiates ONAP Policy Framework policy api. + * + */ +public class Main { + private static final Logger LOGGER = FlexLogger.getLogger(Main.class); + + // The policy api Activator that activates the policy api service + private ApiActivator activator; + + // The parameters read in from JSON + private ApiParameterGroup parameterGroup; + + /** + * Instantiates the policy api service. + * + * @param args the command line arguments + */ + public Main(final String[] args) { + final String argumentString = Arrays.toString(args); + LOGGER.info("Starting policy api service with arguments - " + argumentString); + + // Check the arguments + final ApiCommandLineArguments arguments = new ApiCommandLineArguments(); + 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 PolicyApiException e) { + LOGGER.error("start of policy api service failed", e); + return; + } + + // Read the parameters + try { + parameterGroup = new ApiParameterHandler().getParameters(arguments); + } catch (final Exception e) { + LOGGER.error("start of policy api service failed", e); + return; + } + + // Now, create the activator for the policy api service + activator = new ApiActivator(parameterGroup); + + // Start the activator + try { + activator.initialize(); + } catch (final PolicyApiException e) { + LOGGER.error("start of policy api 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 PolicyApiShutdownHookClass()); + LOGGER.info("Started policy api service"); + } + + /** + * Get the parameters specified in JSON. + * + * @return the parameters + */ + public ApiParameterGroup getParameters() { + return parameterGroup; + } + + /** + * Shut down Execution. + * + * @throws PolicyApiException on shutdown errors + */ + public void shutdown() throws PolicyApiException { + // clear the parameterGroup variable + parameterGroup = null; + + // clear the api activator + if (activator != null) { + activator.terminate(); + } + } + + /** + * The Class PolicyApiShutdownHookClass terminates the policy api service when its run method is + * called. + */ + private class PolicyApiShutdownHookClass extends Thread { + /* + * (non-Javadoc) + * + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + try { + // Shutdown the policy api service and wait for everything to stop + activator.terminate(); + } catch (final PolicyApiException e) { + LOGGER.warn("error occured during shut down of the policy api service", e); + } + } + } + + /** + * The main method. + * + * @param args the arguments + */ + public static void main(final String[] args) { + new Main(args); + } +} diff --git a/main/src/main/resources/version.txt b/main/src/main/resources/version.txt new file mode 100644 index 00000000..ad413fcd --- /dev/null +++ b/main/src/main/resources/version.txt @@ -0,0 +1,4 @@ +ONAP Policy Framework Api Service +Version: ${project.version} +Built (UTC): ${maven.build.timestamp} +ONAP https://wiki.onap.org
\ No newline at end of file |