diff options
Diffstat (limited to 'runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main')
10 files changed, 944 insertions, 0 deletions
diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/parameters/ClRuntimeParameterGroup.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/parameters/ClRuntimeParameterGroup.java new file mode 100644 index 000000000..4c99b8e57 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/parameters/ClRuntimeParameterGroup.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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.clamp.controlloop.runtime.main.parameters; + +import java.util.List; +import javax.validation.constraints.NotBlank; +import lombok.Getter; +import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams; +import org.onap.policy.common.endpoints.parameters.RestServerParameters; +import org.onap.policy.common.endpoints.parameters.TopicParameterGroup; +import org.onap.policy.common.parameters.ParameterGroupImpl; +import org.onap.policy.common.parameters.annotations.NotNull; +import org.onap.policy.models.provider.PolicyModelsProviderParameters; + +/** + * Class to hold all parameters needed for the Control Loop runtime component. + * + */ +@NotNull +@NotBlank +@Getter +public class ClRuntimeParameterGroup extends ParameterGroupImpl { + private RestServerParameters restServerParameters; + private PolicyModelsProviderParameters databaseProviderParameters; + private ParticipantParameters participantParameters; + private TopicParameterGroup topicParameterGroup; + private List<BusTopicParams> healthCheckRestClientParameters; + + /** + * Create the Control Loop parameter group. + * + * @param name the parameter group name + */ + public ClRuntimeParameterGroup(final String name) { + super(name); + } +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/parameters/ClRuntimeParameterHandler.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/parameters/ClRuntimeParameterHandler.java new file mode 100644 index 000000000..a463ad171 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/parameters/ClRuntimeParameterHandler.java @@ -0,0 +1,77 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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.clamp.controlloop.runtime.main.parameters; + +import java.io.File; +import javax.ws.rs.core.Response; +import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; +import org.onap.policy.clamp.controlloop.runtime.main.startstop.ClRuntimeCommandLineArguments; +import org.onap.policy.common.parameters.ValidationResult; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; + +/** + * This class handles reading, parsing and validating of control loop runtime parameters from JSON files. + */ +public class ClRuntimeParameterHandler { + + private static final Coder CODER = new StandardCoder(); + + /** + * Read the parameters from the parameter file. + * + * @param arguments the arguments passed to control loop runtime + * @return the parameters read from the configuration file + * @throws ControlLoopException on parameter exceptions + */ + public ClRuntimeParameterGroup getParameters(final ClRuntimeCommandLineArguments arguments) + throws ControlLoopException { + ClRuntimeParameterGroup clRuntimeParameterGroup = null; + + // Read the parameters + try { + // Read the parameters from JSON + File file = new File(arguments.getFullConfigurationFilePath()); + clRuntimeParameterGroup = CODER.decode(file, ClRuntimeParameterGroup.class); + } catch (final CoderException e) { + throw new ControlLoopException( + Response.Status.NOT_ACCEPTABLE, "error reading parameters from \"" + + arguments.getConfigurationFilePath() + "\"\n" + "(" + e.getClass().getSimpleName() + ")", + e); + } + + // The JSON processing returns null if there is an empty file + if (clRuntimeParameterGroup == null) { + throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, + "no parameters found in \"" + arguments.getConfigurationFilePath() + "\""); + } + + // validate the parameters + final ValidationResult validationResult = clRuntimeParameterGroup.validate(); + if (!validationResult.isValid()) { + throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, "validation error(s) on parameters from \"" + + arguments.getConfigurationFilePath() + "\"\n" + validationResult.getResult()); + } + + return clRuntimeParameterGroup; + } +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/parameters/ParticipantParameters.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/parameters/ParticipantParameters.java new file mode 100644 index 000000000..dfc1b2806 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/parameters/ParticipantParameters.java @@ -0,0 +1,59 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime.main.parameters; + +import java.util.concurrent.TimeUnit; +import lombok.Getter; +import org.onap.policy.common.parameters.ParameterGroupImpl; +import org.onap.policy.common.parameters.annotations.Min; +import org.onap.policy.common.parameters.annotations.NotBlank; +import org.onap.policy.common.parameters.annotations.NotNull; + +/** + * Parameters for communicating with participants. + */ +@NotNull +@NotBlank +@Getter +public class ParticipantParameters extends ParameterGroupImpl { + + /** + * Default maximum message age, in milliseconds, that should be examined. Any message + * older than this is discarded. + */ + public static final long DEFAULT_MAX_AGE_MS = TimeUnit.MILLISECONDS.convert(10, TimeUnit.MINUTES); + + + @Min(1) + private long heartBeatMs; + + @Min(1) + private long maxMessageAgeMs = DEFAULT_MAX_AGE_MS; + + private ParticipantUpdateParameters updateParameters; + private ParticipantStateChangeParameters stateChangeParameters; + + + /** + * Constructs the object. + */ + public ParticipantParameters() { + super(ParticipantParameters.class.getSimpleName()); + } +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/parameters/ParticipantStateChangeParameters.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/parameters/ParticipantStateChangeParameters.java new file mode 100644 index 000000000..2eea4ab51 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/parameters/ParticipantStateChangeParameters.java @@ -0,0 +1,53 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime.main.parameters; + +import lombok.Getter; +import org.onap.policy.common.parameters.ParameterGroupImpl; +import org.onap.policy.common.parameters.annotations.Min; +import org.onap.policy.common.parameters.annotations.NotBlank; +import org.onap.policy.common.parameters.annotations.NotNull; + +/** + * Parameters for Participant STATE-CHANGE requests. + */ +@NotNull +@NotBlank +@Getter +public class ParticipantStateChangeParameters extends ParameterGroupImpl { + + /** + * Maximum number of times to re-send a request to a PDP. + */ + @Min(value = 0) + private int maxRetryCount; + + /** + * Maximum time to wait, in milliseconds, for a PDP response. + */ + @Min(value = 0) + private long maxWaitMs; + + /** + * Constructs the object. + */ + public ParticipantStateChangeParameters() { + super(ParticipantStateChangeParameters.class.getSimpleName()); + } +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/parameters/ParticipantUpdateParameters.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/parameters/ParticipantUpdateParameters.java new file mode 100644 index 000000000..2af5be534 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/parameters/ParticipantUpdateParameters.java @@ -0,0 +1,54 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime.main.parameters; + +import lombok.Getter; +import org.onap.policy.common.parameters.ParameterGroupImpl; +import org.onap.policy.common.parameters.annotations.Min; +import org.onap.policy.common.parameters.annotations.NotBlank; +import org.onap.policy.common.parameters.annotations.NotNull; + +/** + * Parameters for Participant UPDATE requests. + */ +@NotNull +@NotBlank +@Getter +public class ParticipantUpdateParameters extends ParameterGroupImpl { + + /** + * Maximum number of times to re-send a request to a PDP. + */ + @Min(value = 0) + private int maxRetryCount; + + /** + * Maximum time to wait, in milliseconds, for a PDP response. + */ + @Min(value = 0) + private long maxWaitMs; + + /** + * Constructs the object. + */ + public ParticipantUpdateParameters() { + super(ParticipantUpdateParameters.class.getSimpleName()); + } +} + diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/ControlLoopAafFilter.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/ControlLoopAafFilter.java new file mode 100644 index 000000000..f166de5d6 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/ControlLoopAafFilter.java @@ -0,0 +1,38 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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.clamp.controlloop.runtime.main.rest; + +import org.onap.policy.common.endpoints.http.server.aaf.AafGranularAuthFilter; +import org.onap.policy.common.utils.resources.MessageConstants; + +/** + * Class to manage AAF filters for the control loop runtime component. + */ +public class ControlLoopAafFilter extends AafGranularAuthFilter { + + public static final String AAF_NODETYPE = MessageConstants.POLICY_CLAMP; + public static final String AAF_ROOT_PERMISSION = DEFAULT_NAMESPACE + "." + AAF_NODETYPE; + + @Override + public String getPermissionTypeRoot() { + return AAF_ROOT_PERMISSION; + } +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/RestController.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/RestController.java new file mode 100644 index 000000000..dd3fa30fc --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/RestController.java @@ -0,0 +1,115 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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.clamp.controlloop.runtime.main.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.BasicAuthDefinition; +import io.swagger.annotations.Info; +import io.swagger.annotations.SecurityDefinition; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import java.net.HttpURLConnection; +import java.util.UUID; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response.ResponseBuilder; + +/** + * Common superclass to provide REST endpoints for the control loop service. + */ +// @formatter:off +@Path("/onap/controlloop/v2") +@Api(value = "Control Loop API") +@Produces({MediaType.APPLICATION_JSON, RestController.APPLICATION_YAML}) +@SwaggerDefinition( + info = @Info(description = + "Control Loop Service", version = "v1.0", + title = "Control Loop"), + consumes = {MediaType.APPLICATION_JSON, RestController.APPLICATION_YAML}, + produces = {MediaType.APPLICATION_JSON, RestController.APPLICATION_YAML}, + schemes = {SwaggerDefinition.Scheme.HTTP, SwaggerDefinition.Scheme.HTTPS}, + tags = {@Tag(name = "controlloop", description = "Control Loop Service")}, + securityDefinition = @SecurityDefinition(basicAuthDefinitions = {@BasicAuthDefinition(key = "basicAuth")})) +// @formatter:on +public class RestController { + public static final String APPLICATION_YAML = "application/yaml"; + + public static final String EXTENSION_NAME = "interface info"; + + public static final String API_VERSION_NAME = "api-version"; + public static final String API_VERSION = "1.0.0"; + + public static final String LAST_MOD_NAME = "last-mod-release"; + public static final String LAST_MOD_RELEASE = "Dublin"; + + public static final String VERSION_MINOR_NAME = "X-MinorVersion"; + public static final String VERSION_MINOR_DESCRIPTION = + "Used to request or communicate a MINOR version back from the client" + + " to the server, and from the server back to the client"; + + public static final String VERSION_PATCH_NAME = "X-PatchVersion"; + public static final String VERSION_PATCH_DESCRIPTION = "Used only to communicate a PATCH version in a response for" + + " troubleshooting purposes only, and will not be provided by" + " the client on request"; + + public static final String VERSION_LATEST_NAME = "X-LatestVersion"; + public static final String VERSION_LATEST_DESCRIPTION = "Used only to communicate an API's latest version"; + + public static final String REQUEST_ID_NAME = "X-ONAP-RequestID"; + public static final String REQUEST_ID_HDR_DESCRIPTION = "Used to track REST transactions for logging purpose"; + public static final String REQUEST_ID_PARAM_DESCRIPTION = "RequestID for http transaction"; + + public static final String AUTHORIZATION_TYPE = "basicAuth"; + + public static final int AUTHENTICATION_ERROR_CODE = HttpURLConnection.HTTP_UNAUTHORIZED; + public static final int AUTHORIZATION_ERROR_CODE = HttpURLConnection.HTTP_FORBIDDEN; + public static final int SERVER_ERROR_CODE = HttpURLConnection.HTTP_INTERNAL_ERROR; + + public static final String AUTHENTICATION_ERROR_MESSAGE = "Authentication Error"; + public static final String AUTHORIZATION_ERROR_MESSAGE = "Authorization Error"; + public static final String SERVER_ERROR_MESSAGE = "Internal Server Error"; + + /** + * Adds version headers to the response. + * + * @param respBuilder response builder + * @return the response builder, with version headers + */ + public ResponseBuilder addVersionControlHeaders(ResponseBuilder respBuilder) { + return respBuilder.header(VERSION_MINOR_NAME, "0").header(VERSION_PATCH_NAME, "0").header(VERSION_LATEST_NAME, + API_VERSION); + } + + /** + * Adds logging headers to the response. + * + * @param respBuilder response builder + * @return the response builder, with version logging + */ + public ResponseBuilder addLoggingHeaders(ResponseBuilder respBuilder, UUID requestId) { + if (requestId == null) { + // Generate a random uuid if client does not embed requestId in rest request + return respBuilder.header(REQUEST_ID_NAME, UUID.randomUUID()); + } + + return respBuilder.header(REQUEST_ID_NAME, requestId); + } +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeActivator.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeActivator.java new file mode 100644 index 000000000..a4238a9c4 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeActivator.java @@ -0,0 +1,186 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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.clamp.controlloop.runtime.main.startstop; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; +import javax.ws.rs.core.Response.Status; +import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; +import org.onap.policy.clamp.controlloop.common.handler.ControlLoopHandler; +import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningHandler; +import org.onap.policy.clamp.controlloop.runtime.instantiation.InstantiationHandler; +import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; +import org.onap.policy.clamp.controlloop.runtime.main.rest.ControlLoopAafFilter; +import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringHandler; +import org.onap.policy.clamp.controlloop.runtime.supervision.SupervisionHandler; +import org.onap.policy.common.endpoints.event.comm.TopicEndpointManager; +import org.onap.policy.common.endpoints.event.comm.TopicSink; +import org.onap.policy.common.endpoints.event.comm.TopicSource; +import org.onap.policy.common.endpoints.http.server.RestServer; +import org.onap.policy.common.endpoints.listeners.MessageTypeDispatcher; +import org.onap.policy.common.parameters.ParameterService; +import org.onap.policy.common.utils.services.ServiceManagerContainer; + +/** + * This class activates the control loop runtime component as a complete service together with all its controllers, + * listeners & handlers. + */ +public class ClRuntimeActivator extends ServiceManagerContainer { + // Name of the message type for messages on topics + private static final String[] MSG_TYPE_NAMES = {"messageType"}; + + private final ClRuntimeParameterGroup clRuntimeParameterGroup; + + // Topics from which the application receives and to which the application sends messages + private List<TopicSink> topicSinks; + private List<TopicSource> topicSources; + + /** + * Listens for messages on the topic, decodes them into a message, and then dispatches them. + */ + private final MessageTypeDispatcher msgDispatcher; + + /** + * Instantiate the activator for the control loop runtime as a complete service. + * + * @param clRuntimeParameterGroup the parameters for the control loop runtime service + */ + public ClRuntimeActivator(final ClRuntimeParameterGroup clRuntimeParameterGroup) { + + if (clRuntimeParameterGroup == null || !clRuntimeParameterGroup.isValid()) { + throw new ControlLoopRuntimeException(Status.INTERNAL_SERVER_ERROR, "ParameterGroup not valid"); + } + + this.clRuntimeParameterGroup = clRuntimeParameterGroup; + + topicSinks = TopicEndpointManager.getManager() + .addTopicSinks(clRuntimeParameterGroup.getTopicParameterGroup().getTopicSinks()); + + topicSources = TopicEndpointManager.getManager() + .addTopicSources(clRuntimeParameterGroup.getTopicParameterGroup().getTopicSources()); + + try { + msgDispatcher = new MessageTypeDispatcher(MSG_TYPE_NAMES); + } catch (final RuntimeException e) { + throw new ControlLoopRuntimeException(Status.INTERNAL_SERVER_ERROR, + "topic message dispatcher failed to start", e); + } + + final AtomicReference<ControlLoopHandler> commissioningHandler = new AtomicReference<>(); + final AtomicReference<ControlLoopHandler> instantiationHandler = new AtomicReference<>(); + final AtomicReference<ControlLoopHandler> supervisionHandler = new AtomicReference<>(); + final AtomicReference<ControlLoopHandler> monitoringHandler = new AtomicReference<>(); + final AtomicReference<RestServer> restServer = new AtomicReference<>(); + + // @formatter:off + addAction("Control loop runtime parameters", + () -> ParameterService.register(clRuntimeParameterGroup), + () -> ParameterService.deregister(clRuntimeParameterGroup.getName())); + + addAction("Topic endpoint management", + () -> TopicEndpointManager.getManager().start(), + () -> TopicEndpointManager.getManager().shutdown()); + + addAction("Commissioning Handler", + () -> commissioningHandler.set(new CommissioningHandler(clRuntimeParameterGroup)), + () -> commissioningHandler.get().close()); + + addAction("Instantiation Handler", + () -> instantiationHandler.set(new InstantiationHandler(clRuntimeParameterGroup)), + () -> instantiationHandler.get().close()); + + addAction("Supervision Handler", + () -> supervisionHandler.set(new SupervisionHandler(clRuntimeParameterGroup)), + () -> supervisionHandler.get().close()); + + addAction("Monitoring Handler", + () -> monitoringHandler.set(new MonitoringHandler(clRuntimeParameterGroup)), + () -> monitoringHandler.get().close()); + + addHandlerActions("Commissioning", commissioningHandler); + addHandlerActions("Instantiation", instantiationHandler); + addHandlerActions("Supervision", supervisionHandler); + addHandlerActions("Monitoring", monitoringHandler); + + addAction("Topic Message Dispatcher", this::registerMsgDispatcher, this::unregisterMsgDispatcher); + + clRuntimeParameterGroup.getRestServerParameters().setName(clRuntimeParameterGroup.getName()); + + addAction("REST server", + () -> { + Set<Class<?>> providerClasses = new HashSet<>(); + providerClasses.addAll(commissioningHandler.get().getProviderClasses()); + providerClasses.addAll(instantiationHandler.get().getProviderClasses()); + providerClasses.addAll(supervisionHandler.get().getProviderClasses()); + providerClasses.addAll(monitoringHandler.get().getProviderClasses()); + + RestServer server = new RestServer(clRuntimeParameterGroup.getRestServerParameters(), + ControlLoopAafFilter.class, + providerClasses.toArray(new Class<?>[providerClasses.size()])); + + restServer.set(server); + restServer.get().start(); + }, + () -> restServer.get().stop()); + // @formatter:on + } + + private void addHandlerActions(final String name, final AtomicReference<ControlLoopHandler> handler) { + addAction(name + " Providers", + () -> handler.get().startProviders(), + () -> handler.get().stopProviders()); + addAction(name + " Listeners", + () -> handler.get().startAndRegisterListeners(msgDispatcher), + () -> handler.get().stopAndUnregisterListeners(msgDispatcher)); + addAction(name + " Publishers", + () -> handler.get().startAndRegisterPublishers(topicSinks), + () -> handler.get().stopAndUnregisterPublishers()); + } + + /** + * Registers the dispatcher with the topic source(s). + */ + private void registerMsgDispatcher() { + for (final TopicSource source : topicSources) { + source.register(msgDispatcher); + } + } + + /** + * Unregisters the dispatcher from the topic source(s). + */ + private void unregisterMsgDispatcher() { + for (final TopicSource source : topicSources) { + source.unregister(msgDispatcher); + } + } + + /** + * Get the parameters used by the activator. + * + * @return the parameters of the activator + */ + public ClRuntimeParameterGroup getParameterGroup() { + return clRuntimeParameterGroup; + } +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeCommandLineArguments.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeCommandLineArguments.java new file mode 100644 index 000000000..f36bb858b --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeCommandLineArguments.java @@ -0,0 +1,151 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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.clamp.controlloop.runtime.main.startstop; + +import java.io.File; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.net.URL; +import java.util.Arrays; +import javax.ws.rs.core.Response; +import lombok.Getter; +import lombok.Setter; +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.apache.commons.lang3.StringUtils; +import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; +import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; +import org.onap.policy.clamp.controlloop.common.startstop.CommonCommandLineArguments; +import org.onap.policy.common.utils.resources.ResourceUtils; + +/** + * This class reads and handles command line parameters for the control loop runtime service. + */ +public class ClRuntimeCommandLineArguments { + private static final String FILE_MESSAGE_PREAMBLE = " file \""; + private static final int HELP_LINE_LENGTH = 120; + + private final Options options; + private final CommonCommandLineArguments commonCommandLineArguments; + + @Getter() + @Setter() + private String configurationFilePath = null; + + /** + * Construct the options for the control loop runtime component. + */ + public ClRuntimeCommandLineArguments() { + options = new Options(); + commonCommandLineArguments = new CommonCommandLineArguments(options); + } + + /** + * Construct the options for the CLI editor and parse in the given arguments. + * + * @param args The command line arguments + */ + public ClRuntimeCommandLineArguments(final String[] args) { + // Set up the options with the default constructor + this(); + + // Parse the arguments + try { + parse(args); + } catch (final ControlLoopException e) { + throw new ControlLoopRuntimeException(Response.Status.NOT_ACCEPTABLE, + "parse error on control loop runtime 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 ControlLoopException on command argument errors + */ + public String parse(final String[] args) throws ControlLoopException { + // Clear all our arguments + setConfigurationFilePath(null); + CommandLine commandLine = null; + try { + commandLine = new DefaultParser().parse(options, args); + } catch (final ParseException e) { + throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, + "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) { + throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, + "too many command line arguments specified : " + Arrays.toString(args)); + } + + if (commandLine.hasOption('h')) { + return commonCommandLineArguments.help(Main.class.getName(), options); + } + + if (commandLine.hasOption('v')) { + return commonCommandLineArguments.version(); + } + + if (commandLine.hasOption('c')) { + setConfigurationFilePath(commandLine.getOptionValue('c')); + } + + return null; + } + + /** + * Validate the command line options. + * + * @throws ControlLoopException on command argument validation errors + */ + public void validate() throws ControlLoopException { + commonCommandLineArguments.validate(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; + + } +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/Main.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/Main.java new file mode 100644 index 000000000..8e60d68cf --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/Main.java @@ -0,0 +1,156 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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.clamp.controlloop.runtime.main.startstop; + +import java.util.Arrays; +import javax.ws.rs.core.Response; +import org.onap.policy.clamp.controlloop.common.ControlLoopConstants; +import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; +import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; +import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; +import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterHandler; +import org.onap.policy.common.utils.resources.MessageConstants; +import org.onap.policy.common.utils.services.Registry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class initiates ONAP Policy Framework Control Loop runtime component. + */ +public class Main { + + private static final Logger LOGGER = LoggerFactory.getLogger(Main.class); + + private ClRuntimeActivator activator; + private ClRuntimeParameterGroup parameterGroup; + + /** + * Instantiates the control loop runtime service. + * + * @param args the command line arguments + */ + public Main(final String[] args) { + final String argumentString = Arrays.toString(args); + LOGGER.info("Starting the control loop runtime service with arguments - {}", argumentString); + + // Check the arguments + final ClRuntimeCommandLineArguments arguments = new ClRuntimeCommandLineArguments(); + 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(); + + // Read the parameters + parameterGroup = new ClRuntimeParameterHandler().getParameters(arguments); + + // Now, create the activator for the service + activator = new ClRuntimeActivator(parameterGroup); + Registry.register(ControlLoopConstants.REG_CLRUNTIME_ACTIVATOR, activator); + + // Start the activator + activator.start(); + } catch (Exception exp) { + if (null != activator) { + Registry.unregister(ControlLoopConstants.REG_CLRUNTIME_ACTIVATOR); + } + throw new ControlLoopRuntimeException(Response.Status.BAD_REQUEST, + String.format(MessageConstants.START_FAILURE_MSG, MessageConstants.POLICY_CLAMP), exp); + } + + // Add a shutdown hook to shut everything down in an orderly manner + Runtime.getRuntime().addShutdownHook(new ClRuntimeShutdownHookClass()); + String successMsg = String.format(MessageConstants.START_SUCCESS_MSG, MessageConstants.POLICY_CLAMP); + LOGGER.info(successMsg); + } + + /** + * Check if main is running. + */ + public boolean isRunning() { + return activator != null && activator.isAlive(); + } + + /** + * Get the parameters specified in JSON. + * + * @return the parameters + */ + public ClRuntimeParameterGroup getParameters() { + return parameterGroup; + } + + /** + * Shut down Execution. + * + * @throws ControlLoopException on shutdown errors + */ + public void shutdown() throws ControlLoopException { + // clear the parameterGroup variable + parameterGroup = null; + + // clear the cl runtime activator + if (activator != null) { + activator.stop(); + } + } + + /** + * The Class ClRuntimeShutdownHookClass terminates the control loop runtime service when its run method is called. + */ + private class ClRuntimeShutdownHookClass extends Thread { + /* + * (non-Javadoc) + * + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + if (!activator.isAlive()) { + return; + } + + try { + // Shutdown the control loop runtime service and wait for everything to stop + activator.stop(); + } catch (final RuntimeException e) { + LOGGER.warn("error occured during shut down of the control loop runtime service", e); + } + } + } + + /** + * The main method. + * + * @param args the arguments + */ + public static void main(final String[] args) { // NOSONAR + /* + * NOTE: arguments are validated by the constructor, thus sonar is disabled. + */ + + new Main(args); + } +} |