From d5fb4e04527f47f78e9116e3573c21dd75ff8abb Mon Sep 17 00:00:00 2001 From: FrancescoFioraEst Date: Mon, 5 Jul 2021 10:36:42 +0100 Subject: Convert controlloop runtime to springboot framework Issue-ID: POLICY-3355 Change-Id: Ie1667b749eed28b7e526cd4695f45d8ed736c4e7 Signed-off-by: FrancescoFioraEst --- .../clamp/controlloop/runtime/Application.java | 32 ++ .../commissioning/CommissioningHandler.java | 78 ---- .../commissioning/CommissioningProvider.java | 14 +- .../rest/CommissioningController.java | 412 -------------------- .../runtime/config/AafConfiguration.java | 46 +++ .../runtime/config/ActivatorConfig.java | 46 +++ .../runtime/config/CoderHttpMesageConverter.java | 74 ++++ .../runtime/config/ConverterConfiguration.java | 36 ++ .../controlloop/runtime/config/FilterConfig.java | 45 +++ .../runtime/config/PropertiesConfig.java | 38 ++ .../controlloop/runtime/config/SecurityConfig.java | 47 +++ .../runtime/config/SpringFoxConfig.java | 45 +++ .../ControlLoopInstantiationProvider.java | 40 +- .../instantiation/InstantiationHandler.java | 79 ---- .../rest/InstantiationController.java | 420 -------------------- .../main/parameters/ClRuntimeParameterHandler.java | 21 +- .../runtime/main/rest/CommissioningController.java | 432 +++++++++++++++++++++ .../runtime/main/rest/ControlLoopAafFilter.java | 38 -- .../runtime/main/rest/InstantiationController.java | 424 ++++++++++++++++++++ .../main/rest/MonitoringQueryController.java | 385 ++++++++++++++++++ .../runtime/main/rest/RestController.java | 116 ------ .../runtime/main/startstop/ClRuntimeActivator.java | 108 +----- .../startstop/ClRuntimeCommandLineArguments.java | 132 ------- .../controlloop/runtime/main/startstop/Main.java | 159 -------- .../runtime/main/web/AbstractRestController.java | 91 +++++ .../runtime/main/web/ControlLoopAafFilter.java | 38 ++ .../main/web/RequestResponseLoggingFilter.java | 63 +++ .../runtime/main/web/RuntimeErrorController.java | 102 +++++ .../runtime/monitoring/MonitoringHandler.java | 81 ---- .../runtime/monitoring/MonitoringProvider.java | 50 +-- .../monitoring/rest/MonitoringQueryController.java | 380 ------------------ .../runtime/supervision/SupervisionHandler.java | 40 +- .../comm/ParticipantStatusListener.java | 6 +- .../src/main/resources/application.yaml | 22 ++ .../resources/parameters/ClRuntimeParameters.json | 63 +++ 35 files changed, 2138 insertions(+), 2065 deletions(-) create mode 100644 runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/Application.java delete mode 100644 runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningHandler.java delete mode 100644 runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/rest/CommissioningController.java create mode 100644 runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/AafConfiguration.java create mode 100644 runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/ActivatorConfig.java create mode 100644 runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/CoderHttpMesageConverter.java create mode 100644 runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/ConverterConfiguration.java create mode 100644 runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/FilterConfig.java create mode 100644 runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/PropertiesConfig.java create mode 100644 runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/SecurityConfig.java create mode 100644 runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/SpringFoxConfig.java delete mode 100644 runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationHandler.java delete mode 100644 runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationController.java create mode 100644 runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/CommissioningController.java delete mode 100644 runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/ControlLoopAafFilter.java create mode 100644 runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/InstantiationController.java create mode 100644 runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/MonitoringQueryController.java delete mode 100644 runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/RestController.java delete mode 100644 runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeCommandLineArguments.java delete mode 100644 runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/Main.java create mode 100644 runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/web/AbstractRestController.java create mode 100644 runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/web/ControlLoopAafFilter.java create mode 100644 runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/web/RequestResponseLoggingFilter.java create mode 100644 runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/web/RuntimeErrorController.java delete mode 100644 runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringHandler.java delete mode 100644 runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/rest/MonitoringQueryController.java create mode 100644 runtime-controlloop/src/main/resources/application.yaml create mode 100644 runtime-controlloop/src/main/resources/parameters/ClRuntimeParameters.json (limited to 'runtime-controlloop/src/main') diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/Application.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/Application.java new file mode 100644 index 000000000..a2b6f62d4 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/Application.java @@ -0,0 +1,32 @@ +/*- + * ============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; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningHandler.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningHandler.java deleted file mode 100644 index 74975e768..000000000 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningHandler.java +++ /dev/null @@ -1,78 +0,0 @@ -/*- - * ============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.commissioning; - -import java.io.IOException; -import java.util.Set; -import javax.ws.rs.core.Response; -import lombok.Getter; -import org.onap.policy.clamp.controlloop.common.handler.ControlLoopHandler; -import org.onap.policy.clamp.controlloop.runtime.commissioning.rest.CommissioningController; -import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; -import org.onap.policy.common.utils.services.Registry; -import org.onap.policy.models.base.PfModelRuntimeException; - -/** - * This class handles commissioning of control loop definitions. - */ -public final class CommissioningHandler extends ControlLoopHandler { - - @Getter - private CommissioningProvider provider; - - /** - * Gets the CommissioningHandler. - * - * @return CommissioningHandler - */ - public static CommissioningHandler getInstance() { - return Registry.get(CommissioningHandler.class.getName()); - } - - /** - * Create a handler. - * - * @param controlLoopParameters the parameters for access to the database - */ - public CommissioningHandler(ClRuntimeParameterGroup controlLoopParameters) { - super(controlLoopParameters.getDatabaseProviderParameters()); - } - - @Override - public Set> getProviderClasses() { - return Set.of(CommissioningController.class); - } - - @Override - public void startProviders() { - provider = new CommissioningProvider(getDatabaseProviderParameters()); - } - - @Override - public void stopProviders() { - try { - provider.close(); - } catch (IOException e) { - throw new PfModelRuntimeException(Response.Status.INTERNAL_SERVER_ERROR, - "an error has occured while stopping commissioning providers", e); - } - } -} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java index 5bbf6a079..22809e8c0 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java @@ -31,21 +31,23 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.MapUtils; import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider; import org.onap.policy.clamp.controlloop.models.messages.rest.commissioning.CommissioningResponse; +import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.base.PfModelRuntimeException; import org.onap.policy.models.provider.PolicyModelsProvider; import org.onap.policy.models.provider.PolicyModelsProviderFactory; -import org.onap.policy.models.provider.PolicyModelsProviderParameters; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplates; import org.onap.policy.models.tosca.authorative.concepts.ToscaTypedEntityFilter; +import org.springframework.stereotype.Component; /** * This class provides the create, read and delete actions on Commissioning of Control Loop concepts in the database to * the callers. */ +@Component public class CommissioningProvider implements Closeable { public static final String CONTROL_LOOP_NODE_TYPE = "org.onap.policy.clamp.controlloop.ControlLoop"; @@ -56,19 +58,20 @@ public class CommissioningProvider implements Closeable { /** * Create a commissioning provider. - * @param databaseProviderParameters parameters for database access + * + * @param controlLoopParameters the parameters for access to the database * @throws PfModelRuntimeException on errors creating the database provider */ - public CommissioningProvider(PolicyModelsProviderParameters databaseProviderParameters) { + public CommissioningProvider(ClRuntimeParameterGroup controlLoopParameters) { try { modelsProvider = new PolicyModelsProviderFactory() - .createPolicyModelsProvider(databaseProviderParameters); + .createPolicyModelsProvider(controlLoopParameters.getDatabaseProviderParameters()); } catch (PfModelException e) { throw new PfModelRuntimeException(e); } try { - clProvider = new ControlLoopProvider(databaseProviderParameters); + clProvider = new ControlLoopProvider(controlLoopParameters.getDatabaseProviderParameters()); } catch (PfModelException e) { throw new PfModelRuntimeException(e); } @@ -78,6 +81,7 @@ public class CommissioningProvider implements Closeable { public void close() throws IOException { try { modelsProvider.close(); + clProvider.close(); } catch (PfModelException e) { throw new IOException("error closing modelsProvider", e); } diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/rest/CommissioningController.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/rest/CommissioningController.java deleted file mode 100644 index ebfbbd5ee..000000000 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/rest/CommissioningController.java +++ /dev/null @@ -1,412 +0,0 @@ -/*- - * ============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.commissioning.rest; - -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import io.swagger.annotations.Authorization; -import io.swagger.annotations.Extension; -import io.swagger.annotations.ExtensionProperty; -import io.swagger.annotations.ResponseHeader; -import java.util.List; -import java.util.UUID; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; -import org.onap.policy.clamp.controlloop.models.messages.rest.commissioning.CommissioningResponse; -import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningHandler; -import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider; -import org.onap.policy.clamp.controlloop.runtime.main.rest.RestController; -import org.onap.policy.models.base.PfModelException; -import org.onap.policy.models.base.PfModelRuntimeException; -import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; -import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Class to provide REST end points for creating, deleting, querying commissioned control loops. - */ -public class CommissioningController extends RestController { - - private static final Logger LOGGER = LoggerFactory.getLogger(CommissioningController.class); - - private final CommissioningProvider provider; - - /** - * create Commissioning Controller. - */ - public CommissioningController() { - this.provider = CommissioningHandler.getInstance().getProvider(); - } - - /** - * Creates a control loop definition. - * - * @param requestId request ID used in ONAP logging - * @param body the body of control loop following TOSCA definition - * @return a response - */ - // @formatter:off - @POST - @Path("/commission") - @ApiOperation( - value = "Commissions control loop definitions", - notes = "Commissions control loop definitions, returning the commissioned control loop definition IDs", - response = CommissioningResponse.class, - tags = {"Control Loop Commissioning API"}, - authorizations = @Authorization(value = AUTHORIZATION_TYPE), - responseHeaders = { - @ResponseHeader( - name = VERSION_MINOR_NAME, - description = VERSION_MINOR_DESCRIPTION, - response = String.class), - @ResponseHeader( - name = VERSION_PATCH_NAME, - description = VERSION_PATCH_DESCRIPTION, - response = String.class), - @ResponseHeader( - name = VERSION_LATEST_NAME, - description = VERSION_LATEST_DESCRIPTION, - response = String.class), - @ResponseHeader( - name = REQUEST_ID_NAME, - description = REQUEST_ID_HDR_DESCRIPTION, - response = UUID.class) - }, - extensions = { - @Extension - ( - name = EXTENSION_NAME, - properties = { - @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), - @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) - } - ) - } - ) - @ApiResponses( - value = { - @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), - @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), - @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) - } - ) - // @formatter:on - public Response create(@HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Entity Body of Control Loop", required = true) ToscaServiceTemplate body) { - - try { - CommissioningResponse response = provider.createControlLoopDefinitions(body); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Status.OK)), requestId).entity(response) - .build(); - - } catch (PfModelRuntimeException | PfModelException e) { - LOGGER.warn("Commissioning of the control loops failed", e); - var resp = new CommissioningResponse(); - resp.setErrorDetails(e.getErrorResponse().getErrorMessage()); - return returnResponse(e.getErrorResponse().getResponseCode(), requestId, resp); - } - - } - - /** - * Deletes a control loop definition. - * - * @param requestId request ID used in ONAP logging - * @param name the name of the control loop definition to delete - * @param version the version of the control loop definition to delete - * @return a response - */ - // @formatter:off - @DELETE - @Path("/commission") - @ApiOperation(value = "Delete a commissioned control loop", - notes = "Deletes a Commissioned Control Loop, returning optional error details", - response = CommissioningResponse.class, - tags = {"Clamp Control Loop Commissioning API"}, - authorizations = @Authorization(value = AUTHORIZATION_TYPE), - responseHeaders = { - @ResponseHeader( - name = VERSION_MINOR_NAME, - description = VERSION_MINOR_DESCRIPTION, - response = String.class), - @ResponseHeader( - name = VERSION_PATCH_NAME, - description = VERSION_PATCH_DESCRIPTION, - response = String.class), - @ResponseHeader( - name = VERSION_LATEST_NAME, - description = VERSION_LATEST_DESCRIPTION, - response = String.class), - @ResponseHeader( - name = REQUEST_ID_NAME, - description = REQUEST_ID_HDR_DESCRIPTION, - response = UUID.class)}, - extensions = { - @Extension - ( - name = EXTENSION_NAME, - properties = { - @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), - @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) - } - ) - } - ) - @ApiResponses( - value = { - @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), - @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), - @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) - } - ) - // @formatter:on - public Response delete(@HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Control Loop definition name", required = true) @QueryParam("name") String name, - @ApiParam(value = "Control Loop definition version", required = true) @QueryParam("version") String version) { - - try { - CommissioningResponse response = provider.deleteControlLoopDefinition(name, version); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Status.OK)), requestId).entity(response) - .build(); - - } catch (PfModelRuntimeException | PfModelException e) { - LOGGER.warn("Decommisssioning of control loop failed", e); - var resp = new CommissioningResponse(); - resp.setErrorDetails(e.getErrorResponse().getErrorMessage()); - return returnResponse(e.getErrorResponse().getResponseCode(), requestId, resp); - } - - } - - /** - * Queries details of all or specific control loop definitions. - * - * @param requestId request ID used in ONAP logging - * @param name the name of the control loop definition to get, null for all definitions - * @param version the version of the control loop definition to get, null for all definitions - * @return the control loop definitions - */ - // @formatter:off - @GET - @Path("/commission") - @ApiOperation(value = "Query details of the requested commissioned control loop definitions", - notes = "Queries details of the requested commissioned control loop definitions, " - + "returning all control loop details", - response = ToscaNodeTemplate.class, - tags = {"Clamp Control Loop Commissioning API"}, - authorizations = @Authorization(value = AUTHORIZATION_TYPE), - responseHeaders = { - @ResponseHeader( - name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, - response = String.class), - @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, - response = String.class), - @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, - response = String.class), - @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, - response = UUID.class)}, - extensions = { - @Extension - ( - name = EXTENSION_NAME, - properties = { - @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), - @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) - } - ) - } - ) - @ApiResponses( - value = { - @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), - @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), - @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) - } - ) - // @formatter:on - public Response query(@HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Control Loop definition name", required = true) @QueryParam("name") String name, - @ApiParam(value = "Control Loop definition version", required = true) @QueryParam("version") String version) { - - try { - List response = provider.getControlLoopDefinitions(name, version); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Status.OK)), requestId).entity(response) - .build(); - - } catch (PfModelRuntimeException | PfModelException e) { - LOGGER.warn("Get of control loop definitions failed", e); - var resp = new CommissioningResponse(); - resp.setErrorDetails(e.getErrorResponse().getErrorMessage()); - return returnResponse(e.getErrorResponse().getResponseCode(), requestId, resp); - } - - } - - /** - * Retrieves the Tosca Service Template. - * - * @param requestId request ID used in ONAP logging - * @param name the name of the tosca service template to retrieve - * @param version the version of the tosca service template to get - * @return the specified tosca service template - */ - // @formatter:off - @GET - @Path("/commission/toscaservicetemplate") - @ApiOperation(value = "Query details of the requested tosca service templates", - notes = "Queries details of the requested commissioned tosca service template, " - + "returning all tosca service template details", - response = ToscaServiceTemplate.class, - tags = {"Clamp Control Loop Commissioning API"}, - authorizations = @Authorization(value = AUTHORIZATION_TYPE), - responseHeaders = { - @ResponseHeader( - name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, - response = String.class), - @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, - response = String.class), - @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, - response = String.class), - @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, - response = UUID.class)}, - extensions = { - @Extension - ( - name = EXTENSION_NAME, - properties = { - @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), - @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) - } - ) - } - ) - @ApiResponses( - value = { - @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), - @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), - @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) - } - ) - // @formatter:on - public Response queryToscaServiceTemplate( - @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Tosca service template name", required = true) @QueryParam("name") String name, - @ApiParam(value = "Tosca service template version", required = true) @QueryParam("version") String version) { - - try { - var response = provider.getToscaServiceTemplate(name, version); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Status.OK)), requestId).entity(response) - .build(); - - } catch (PfModelRuntimeException | PfModelException e) { - LOGGER.warn("Get of tosca service template failed", e); - var resp = new CommissioningResponse(); - resp.setErrorDetails(e.getErrorResponse().getErrorMessage()); - return returnResponse(e.getErrorResponse().getResponseCode(), requestId, resp); - } - - } - - /** - * Queries the elements of a specific control loop. - * - * @param requestId request ID used in ONAP logging - * @param name the name of the control loop definition to get - * @param version the version of the control loop definition to get - * @return the control loop element definitions - */ - // @formatter:off - @GET - @Path("/commission/elements") - @ApiOperation(value = "Query details of the requested commissioned control loop element definitions", - notes = "Queries details of the requested commissioned control loop element definitions, " - + "returning all control loop elements' details", - response = ToscaNodeTemplate.class, - tags = {"Clamp Control Loop Commissioning API"}, - authorizations = @Authorization(value = AUTHORIZATION_TYPE), - responseHeaders = { - @ResponseHeader( - name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, - response = String.class), - @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, - response = String.class), - @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, - response = String.class), - @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, - response = UUID.class)}, - extensions = { - @Extension - ( - name = EXTENSION_NAME, - properties = { - @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), - @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) - } - ) - } - ) - @ApiResponses( - value = { - @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), - @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), - @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) - } - ) - // @formatter:on - public Response queryElements(@HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Control Loop definition name", required = true) @QueryParam("name") String name, - @ApiParam(value = "Control Loop definition version", required = true) @QueryParam("version") String version) { - - try { - List nodeTemplate = provider.getControlLoopDefinitions(name, version); - // Prevent ambiguous queries with multiple returns - if (nodeTemplate.size() > 1) { - var resp = new CommissioningResponse(); - resp.setErrorDetails("Multiple ControlLoops are not supported"); - return returnResponse(Response.Status.NOT_ACCEPTABLE, requestId, resp); - } - - List response = provider.getControlLoopElementDefinitions(nodeTemplate.get(0)); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Status.OK)), requestId).entity(response) - .build(); - - } catch (PfModelRuntimeException | PfModelException e) { - LOGGER.warn("Get of control loop element definitions failed", e); - var resp = new CommissioningResponse(); - resp.setErrorDetails(e.getErrorResponse().getErrorMessage()); - return returnResponse(e.getErrorResponse().getResponseCode(), requestId, resp); - } - - } - - private Response returnResponse(Response.Status status, UUID requestId, CommissioningResponse resp) { - return addLoggingHeaders(addVersionControlHeaders(Response.status(status)), requestId).entity(resp).build(); - } -} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/AafConfiguration.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/AafConfiguration.java new file mode 100644 index 000000000..4483fbd1b --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/AafConfiguration.java @@ -0,0 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2017-2018 AT&T Intellectual Property. 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. + * ============LICENSE_END============================================ + * =================================================================== + * + */ + +package org.onap.policy.clamp.controlloop.runtime.config; + +import javax.servlet.Filter; +import org.onap.policy.clamp.controlloop.runtime.main.web.ControlLoopAafFilter; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; + +@Configuration +@Profile("clamp-aaf-authentication") +public class AafConfiguration { + + /** + * Method to return Aaf filter. + * + * @return Filter + */ + @Bean + public Filter aafFilter() { + return new ControlLoopAafFilter(); + } + +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/ActivatorConfig.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/ActivatorConfig.java new file mode 100644 index 000000000..1d6b92e77 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/ActivatorConfig.java @@ -0,0 +1,46 @@ +/*- + * ============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.config; + +import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; +import org.onap.policy.clamp.controlloop.runtime.main.startstop.ClRuntimeActivator; +import org.onap.policy.clamp.controlloop.runtime.supervision.SupervisionHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ActivatorConfig { + + /** + * Create and start ClRuntimeActivator. + * + * @param clRuntimeParameterGroup the parameters for the control loop runtime service + * @param supervisionHandler the SupervisionHandler + * @return ClRuntimeActivator + */ + @Bean + public ClRuntimeActivator clRuntimeActivator(ClRuntimeParameterGroup clRuntimeParameterGroup, + SupervisionHandler supervisionHandler) { + var clRuntimeActivator = new ClRuntimeActivator(clRuntimeParameterGroup, supervisionHandler); + clRuntimeActivator.start(); + return clRuntimeActivator; + } +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/CoderHttpMesageConverter.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/CoderHttpMesageConverter.java new file mode 100644 index 000000000..cdd6ea73b --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/CoderHttpMesageConverter.java @@ -0,0 +1,74 @@ +/*- + * ============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.config; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.nio.charset.StandardCharsets; +import javax.ws.rs.core.Response; +import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.coder.StandardYamlCoder; +import org.springframework.http.HttpInputMessage; +import org.springframework.http.HttpOutputMessage; +import org.springframework.http.MediaType; +import org.springframework.http.converter.AbstractHttpMessageConverter; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.http.converter.HttpMessageNotWritableException; + +public class CoderHttpMesageConverter extends AbstractHttpMessageConverter { + + private Coder coder; + + public CoderHttpMesageConverter(String type) { + super(new MediaType("application", type, StandardCharsets.UTF_8)); + this.coder = "json".equals(type) ? new StandardCoder() : new StandardYamlCoder(); + } + + @Override + protected boolean supports(Class clazz) { + return true; + } + + @Override + protected T readInternal(Class clazz, HttpInputMessage inputMessage) + throws IOException, HttpMessageNotReadableException { + try (var is = new InputStreamReader(inputMessage.getBody(), StandardCharsets.UTF_8)) { + return coder.decode(is, clazz); + } catch (CoderException e) { + throw new ControlLoopRuntimeException(Response.Status.BAD_REQUEST, e.getMessage(), e); + } + } + + @Override + protected void writeInternal(T t, HttpOutputMessage outputMessage) + throws IOException, HttpMessageNotWritableException { + try (var writer = new OutputStreamWriter(outputMessage.getBody(), StandardCharsets.UTF_8)) { + coder.encode(writer, t); + } catch (CoderException e) { + throw new ControlLoopRuntimeException(Response.Status.BAD_REQUEST, e.getMessage(), e); + } + } + +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/ConverterConfiguration.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/ConverterConfiguration.java new file mode 100644 index 000000000..ee0461994 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/ConverterConfiguration.java @@ -0,0 +1,36 @@ +/*- + * ============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.config; + +import java.util.List; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class ConverterConfiguration implements WebMvcConfigurer { + + @Override + public void extendMessageConverters(List> converters) { + converters.add(new CoderHttpMesageConverter<>("yaml")); + converters.add(new CoderHttpMesageConverter<>("json")); + } +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/FilterConfig.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/FilterConfig.java new file mode 100644 index 000000000..d58553ae4 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/FilterConfig.java @@ -0,0 +1,45 @@ +/*- + * ============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.config; + +import org.onap.policy.clamp.controlloop.runtime.main.web.RequestResponseLoggingFilter; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class FilterConfig { + + /** + * Logging Filter configuration. + * + * @return FilterRegistrationBean + */ + @Bean + public FilterRegistrationBean loggingFilter() { + FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); + + registrationBean.setFilter(new RequestResponseLoggingFilter()); + registrationBean.addUrlPatterns("/onap/controlloop/v2/*"); + + return registrationBean; + } +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/PropertiesConfig.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/PropertiesConfig.java new file mode 100644 index 000000000..04bd35da3 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/PropertiesConfig.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.config; + +import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; +import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; +import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterHandler; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class PropertiesConfig { + + @Bean + public ClRuntimeParameterGroup clRuntimeParameterGroup(@Value("${runtime.file}") String file) + throws ControlLoopException { + return new ClRuntimeParameterHandler().getParameters(file); + } +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/SecurityConfig.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/SecurityConfig.java new file mode 100644 index 000000000..846944ea2 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/SecurityConfig.java @@ -0,0 +1,47 @@ +/*- + * ============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.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@Configuration +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Value("${security.enable-csrf:true}") + private boolean csrfEnabled = true; + + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http.authorizeRequests() + .antMatchers().authenticated() + .anyRequest().authenticated() + .and().httpBasic(); + // @formatter:on + + if (!csrfEnabled) { + http.csrf().disable(); + } + } +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/SpringFoxConfig.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/SpringFoxConfig.java new file mode 100644 index 000000000..d8c703397 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/SpringFoxConfig.java @@ -0,0 +1,45 @@ +/*- + * ============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.config; + +import org.onap.policy.clamp.controlloop.runtime.main.rest.MonitoringQueryController; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; + +@Configuration +public class SpringFoxConfig { + + /** + * Docket Spring Fox Config. + * + * @return Docket + */ + @Bean + public Docket api() { + return new Docket(DocumentationType.SWAGGER_2).select() + .apis(RequestHandlerSelectors.basePackage(MonitoringQueryController.class.getPackageName())) + .paths(PathSelectors.any()).build(); + } +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java index f458d7c51..c01a0b989 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java @@ -39,6 +39,7 @@ import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationCommand; import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse; import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider; +import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; import org.onap.policy.clamp.controlloop.runtime.supervision.SupervisionHandler; import org.onap.policy.common.parameters.BeanValidationResult; import org.onap.policy.common.parameters.ObjectValidationResult; @@ -46,29 +47,35 @@ import org.onap.policy.common.parameters.ValidationResult; import org.onap.policy.common.parameters.ValidationStatus; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.base.PfModelRuntimeException; -import org.onap.policy.models.provider.PolicyModelsProviderParameters; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.springframework.stereotype.Component; /** * This class is dedicated to the Instantiation of Commissioned control loop. */ +@Component public class ControlLoopInstantiationProvider implements Closeable { private final ControlLoopProvider controlLoopProvider; private final CommissioningProvider commissioningProvider; + private final SupervisionHandler supervisionHandler; private static final Object lockit = new Object(); /** * Create a instantiation provider. * - * @param databaseProviderParameters the parameters for database access + * @param controlLoopParameters the parameters for access to the database + * @param commissioningProvider CommissioningProvider + * @param supervisionHandler SupervisionHandler * @throws PfModelRuntimeException on errors creating a provider */ - public ControlLoopInstantiationProvider(PolicyModelsProviderParameters databaseProviderParameters) { + public ControlLoopInstantiationProvider(ClRuntimeParameterGroup controlLoopParameters, + CommissioningProvider commissioningProvider, SupervisionHandler supervisionHandler) { + this.commissioningProvider = commissioningProvider; + this.supervisionHandler = supervisionHandler; try { - controlLoopProvider = new ControlLoopProvider(databaseProviderParameters); - commissioningProvider = new CommissioningProvider(databaseProviderParameters); + controlLoopProvider = new ControlLoopProvider(controlLoopParameters.getDatabaseProviderParameters()); } catch (PfModelException e) { throw new PfModelRuntimeException(e); } @@ -93,7 +100,7 @@ public class ControlLoopInstantiationProvider implements Closeable { var checkControlLoop = controlLoopProvider.getControlLoop(controlLoop.getKey().asIdentifier()); if (checkControlLoop != null) { throw new PfModelException(Response.Status.BAD_REQUEST, - controlLoop.getKey().asIdentifier() + " already defined"); + controlLoop.getKey().asIdentifier() + " already defined"); } } BeanValidationResult validationResult = validateControlLoops(controlLoops); @@ -105,7 +112,7 @@ public class ControlLoopInstantiationProvider implements Closeable { var response = new InstantiationResponse(); response.setAffectedControlLoops(controlLoops.getControlLoopList().stream() - .map(cl -> cl.getKey().asIdentifier()).collect(Collectors.toList())); + .map(cl -> cl.getKey().asIdentifier()).collect(Collectors.toList())); return response; } @@ -128,7 +135,7 @@ public class ControlLoopInstantiationProvider implements Closeable { var response = new InstantiationResponse(); response.setAffectedControlLoops(controlLoops.getControlLoopList().stream() - .map(cl -> cl.getKey().asIdentifier()).collect(Collectors.toList())); + .map(cl -> cl.getKey().asIdentifier()).collect(Collectors.toList())); return response; } @@ -148,18 +155,18 @@ public class ControlLoopInstantiationProvider implements Closeable { var subResult = new BeanValidationResult("entry " + controlLoop.getDefinition().getName(), controlLoop); List toscaNodeTemplates = commissioningProvider.getControlLoopDefinitions( - controlLoop.getDefinition().getName(), controlLoop.getDefinition().getVersion()); + controlLoop.getDefinition().getName(), controlLoop.getDefinition().getVersion()); if (toscaNodeTemplates.isEmpty()) { subResult.addResult(new ObjectValidationResult("ControlLoop", controlLoop.getDefinition().getName(), - ValidationStatus.INVALID, "Commissioned control loop definition not FOUND")); + ValidationStatus.INVALID, "Commissioned control loop definition not FOUND")); } else if (toscaNodeTemplates.size() > 1) { subResult.addResult(new ObjectValidationResult("ControlLoop", controlLoop.getDefinition().getName(), - ValidationStatus.INVALID, "Commissioned control loop definition not VALID")); + ValidationStatus.INVALID, "Commissioned control loop definition not VALID")); } else { List clElementDefinitions = - commissioningProvider.getControlLoopElementDefinitions(toscaNodeTemplates.get(0)); + commissioningProvider.getControlLoopElementDefinitions(toscaNodeTemplates.get(0)); // @formatter:off Map definitions = clElementDefinitions @@ -185,7 +192,7 @@ public class ControlLoopInstantiationProvider implements Closeable { * @return the validation result */ private ValidationResult validateDefinition(Map definitions, - ToscaConceptIdentifier definition) { + ToscaConceptIdentifier definition) { var result = new BeanValidationResult("entry " + definition.getName(), definition); ToscaConceptIdentifier identifier = definitions.get(definition.getName()); if (identifier == null) { @@ -214,12 +221,12 @@ public class ControlLoopInstantiationProvider implements Closeable { for (ControlLoop controlLoop : controlLoops) { if (!ControlLoopState.UNINITIALISED.equals(controlLoop.getState())) { throw new PfModelException(Response.Status.BAD_REQUEST, - "Control Loop State is still " + controlLoop.getState()); + "Control Loop State is still " + controlLoop.getState()); } } response.setAffectedControlLoops(Collections - .singletonList(controlLoopProvider.deleteControlLoop(name, version).getKey().asIdentifier())); + .singletonList(controlLoopProvider.deleteControlLoop(name, version).getKey().asIdentifier())); } return response; } @@ -248,7 +255,7 @@ public class ControlLoopInstantiationProvider implements Closeable { * @throws ControlLoopException on ordered state invalid */ public InstantiationResponse issueControlLoopCommand(InstantiationCommand command) - throws ControlLoopException, PfModelException { + throws ControlLoopException, PfModelException { if (command.getOrderedState() == null) { throw new ControlLoopException(Status.BAD_REQUEST, "ordered state invalid or not specified on command"); @@ -264,7 +271,6 @@ public class ControlLoopInstantiationProvider implements Closeable { controlLoopProvider.updateControlLoops(controlLoops); } - var supervisionHandler = SupervisionHandler.getInstance(); supervisionHandler.triggerControlLoopSupervision(command.getControlLoopIdentifierList()); var response = new InstantiationResponse(); response.setAffectedControlLoops(command.getControlLoopIdentifierList()); diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationHandler.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationHandler.java deleted file mode 100644 index 67fd9455e..000000000 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationHandler.java +++ /dev/null @@ -1,79 +0,0 @@ -/*- - * ============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.instantiation; - -import java.io.IOException; -import java.util.Set; -import javax.ws.rs.core.Response; -import lombok.Getter; -import org.onap.policy.clamp.controlloop.common.handler.ControlLoopHandler; -import org.onap.policy.clamp.controlloop.runtime.instantiation.rest.InstantiationController; -import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; -import org.onap.policy.common.utils.services.Registry; -import org.onap.policy.models.base.PfModelRuntimeException; - -/** - * This class handles instantiation of control loop instances. - * - *

It is effectively a singleton that is started at system start - */ -public final class InstantiationHandler extends ControlLoopHandler { - - @Getter - private ControlLoopInstantiationProvider controlLoopInstantiationProvider; - - /** - * Gets the InstantiationHandler. - * - * @return InstantiationHandler - */ - public static InstantiationHandler getInstance() { - return Registry.get(InstantiationHandler.class.getName()); - } - - /** - * Create a handler. - * - * @param controlLoopParameters the parameters for access to the database - */ - public InstantiationHandler(ClRuntimeParameterGroup controlLoopParameters) { - super(controlLoopParameters.getDatabaseProviderParameters()); - } - - @Override - public Set> getProviderClasses() { - return Set.of(InstantiationController.class); - } - - @Override - public void startProviders() { - controlLoopInstantiationProvider = new ControlLoopInstantiationProvider(getDatabaseProviderParameters()); - } - - @Override - public void stopProviders() { - try { - controlLoopInstantiationProvider.close(); - } catch (IOException e) { - throw new PfModelRuntimeException(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage()); - } - } -} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationController.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationController.java deleted file mode 100644 index ea36c71fb..000000000 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationController.java +++ /dev/null @@ -1,420 +0,0 @@ -/*- - * ============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.instantiation.rest; - -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import io.swagger.annotations.Authorization; -import io.swagger.annotations.Extension; -import io.swagger.annotations.ExtensionProperty; -import io.swagger.annotations.ResponseHeader; -import java.util.UUID; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; -import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops; -import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationCommand; -import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse; -import org.onap.policy.clamp.controlloop.runtime.instantiation.ControlLoopInstantiationProvider; -import org.onap.policy.clamp.controlloop.runtime.instantiation.InstantiationHandler; -import org.onap.policy.clamp.controlloop.runtime.main.rest.RestController; -import org.onap.policy.models.base.PfModelException; -import org.onap.policy.models.base.PfModelRuntimeException; -import org.onap.policy.models.errors.concepts.ErrorResponseInfo; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Class to provide REST end points for creating, deleting, query and commanding a control loop definition. - */ -public class InstantiationController extends RestController { - - private static final Logger LOGGER = LoggerFactory.getLogger(InstantiationController.class); - - // The CL provider for instantiation requests - private final ControlLoopInstantiationProvider provider; - - /** - * create Instantiation Controller. - */ - public InstantiationController() { - this.provider = InstantiationHandler.getInstance().getControlLoopInstantiationProvider(); - } - - /** - * Creates a control loop. - * - * @param requestId request ID used in ONAP logging - * @param controlLoops the control loops - * @return a response - */ - // @formatter:off - @POST - @Path("/instantiation") - @ApiOperation( - value = "Commissions control loop definitions", - notes = "Commissions control loop definitions, returning the control loop IDs", - response = InstantiationResponse.class, - tags = {"Control Loop Instantiation API"}, - authorizations = @Authorization(value = AUTHORIZATION_TYPE), - responseHeaders = { - @ResponseHeader( - name = VERSION_MINOR_NAME, - description = VERSION_MINOR_DESCRIPTION, - response = String.class), - @ResponseHeader( - name = VERSION_PATCH_NAME, - description = VERSION_PATCH_DESCRIPTION, - response = String.class), - @ResponseHeader( - name = VERSION_LATEST_NAME, - description = VERSION_LATEST_DESCRIPTION, - response = String.class), - @ResponseHeader( - name = REQUEST_ID_NAME, - description = REQUEST_ID_HDR_DESCRIPTION, - response = UUID.class) - }, - extensions = { - @Extension - ( - name = EXTENSION_NAME, - properties = { - @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), - @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) - } - ) - } - ) - @ApiResponses( - value = { - @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), - @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), - @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) - } - ) - // @formatter:on - public Response create( - @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Entity Body of Control Loop", required = true) ControlLoops controlLoops) { - - try { - InstantiationResponse response = provider.createControlLoops(controlLoops); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Status.OK)), requestId).entity(response) - .build(); - - } catch (PfModelRuntimeException | PfModelException e) { - LOGGER.warn("creation of control loop failed", e); - return createInstantiationErrorResponse(e, requestId); - } - } - - /** - * Queries details of all control loops. - * - * @param requestId request ID used in ONAP logging - * @param name the name of the control loop to get, null for all control loops - * @param version the version of the control loop to get, null for all control loops - * @return the control loops - */ - // @formatter:off - @GET - @Path("/instantiation") - @ApiOperation(value = "Query details of the requested control loops", - notes = "Queries details of the requested control loops, returning all control loop details", - response = ControlLoops.class, - tags = { - "Clamp control loop Instantiation API" - }, - authorizations = @Authorization(value = AUTHORIZATION_TYPE), - responseHeaders = { - @ResponseHeader( - name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, - response = String.class), - @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, - response = String.class), - @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, - response = String.class), - @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, - response = UUID.class)}, - extensions = { - @Extension - ( - name = EXTENSION_NAME, - properties = { - @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), - @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) - } - ) - } - ) - @ApiResponses( - value = { - @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), - @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), - @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) - } - ) - // @formatter:on - public Response query( - @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Control Loop definition name", required = true) @QueryParam("name") String name, - @ApiParam(value = "Control Loop definition version", - required = true) @QueryParam("version") String version) { - - try { - var response = provider.getControlLoops(name, version); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Status.OK)), requestId).entity(response) - .build(); - - } catch (PfModelRuntimeException | PfModelException e) { - LOGGER.warn("commisssioning of control loop failed", e); - return createInstantiationErrorResponse(e, requestId); - } - - } - - /** - * Updates a control loop. - * - * @param requestId request ID used in ONAP logging - * @param controlLoops the control loops - * @return a response - */ - // @formatter:off - @PUT - @Path("/instantiation") - @ApiOperation( - value = "Updates control loop definitions", - notes = "Updates control loop definitions, returning the updated control loop definition IDs", - response = InstantiationResponse.class, - tags = { - "Control Loop Instantiation API" - }, - authorizations = @Authorization(value = AUTHORIZATION_TYPE), - responseHeaders = { - @ResponseHeader( - name = VERSION_MINOR_NAME, - description = VERSION_MINOR_DESCRIPTION, - response = String.class), - @ResponseHeader( - name = VERSION_PATCH_NAME, - description = VERSION_PATCH_DESCRIPTION, - response = String.class), - @ResponseHeader( - name = VERSION_LATEST_NAME, - description = VERSION_LATEST_DESCRIPTION, - response = String.class), - @ResponseHeader( - name = REQUEST_ID_NAME, - description = REQUEST_ID_HDR_DESCRIPTION, - response = UUID.class) - }, - extensions = { - @Extension - ( - name = EXTENSION_NAME, - properties = { - @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), - @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) - } - ) - } - ) - @ApiResponses( - value = { - @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), - @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), - @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) - } - ) - // @formatter:on - public Response update( - @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Entity Body of Control Loop", required = true) ControlLoops controlLoops) { - - try { - InstantiationResponse response = provider.updateControlLoops(controlLoops); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Status.OK)), requestId).entity(response) - .build(); - - } catch (PfModelRuntimeException | PfModelException e) { - LOGGER.warn("update of control loops failed", e); - return createInstantiationErrorResponse(e, requestId); - } - } - - /** - * Deletes a control loop definition. - * - * @param requestId request ID used in ONAP logging - * @param name the name of the control loop to delete - * @param version the version of the control loop to delete - * @return a response - */ - // @formatter:off - @DELETE - @Path("/instantiation") - @ApiOperation(value = "Delete a control loop", - notes = "Deletes a control loop, returning optional error details", - response = InstantiationResponse.class, - tags = { - "Clamp Control Loop Instantiation API" - }, - authorizations = @Authorization(value = AUTHORIZATION_TYPE), - responseHeaders = { - @ResponseHeader( - name = VERSION_MINOR_NAME, - description = VERSION_MINOR_DESCRIPTION, - response = String.class), - @ResponseHeader( - name = VERSION_PATCH_NAME, - description = VERSION_PATCH_DESCRIPTION, - response = String.class), - @ResponseHeader( - name = VERSION_LATEST_NAME, - description = VERSION_LATEST_DESCRIPTION, - response = String.class), - @ResponseHeader( - name = REQUEST_ID_NAME, - description = REQUEST_ID_HDR_DESCRIPTION, - response = UUID.class)}, - extensions = { - @Extension - ( - name = EXTENSION_NAME, - properties = { - @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), - @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) - } - ) - } - ) - @ApiResponses( - value = { - @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), - @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), - @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) - } - ) - // @formatter:on - - public Response delete( - @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Control Loop definition name", required = true) @QueryParam("name") String name, - @ApiParam(value = "Control Loop definition version", required = true) - @QueryParam("version") String version) { - - try { - InstantiationResponse response = provider.deleteControlLoop(name, version); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Status.OK)), requestId).entity(response) - .build(); - - } catch (PfModelRuntimeException | PfModelException e) { - LOGGER.warn("delete of control loop failed", e); - return createInstantiationErrorResponse(e, requestId); - } - } - - /** - * Issues control loop commands to control loops. - * - * @param requestId request ID used in ONAP logging - * @param command the command to issue to control loops - * @return the control loop definitions - */ - // @formatter:off - @PUT - @Path("/instantiation/command") - @ApiOperation(value = "Issue a command to the requested control loops", - notes = "Issues a command to a control loop, ordering a state change on the control loop", - response = InstantiationResponse.class, - tags = { - "Clamp Control Loop Instantiation API" - }, - authorizations = @Authorization(value = AUTHORIZATION_TYPE), - responseHeaders = { - @ResponseHeader( - name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, - response = String.class), - @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, - response = String.class), - @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, - response = String.class), - @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, - response = UUID.class)}, - extensions = { - @Extension - ( - name = EXTENSION_NAME, - properties = { - @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), - @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) - } - ) - } - ) - @ApiResponses( - value = { - @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), - @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), - @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) - } - ) - // @formatter:on - public Response issueControlLoopCommand( - @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Entity Body of control loop command", required = true) InstantiationCommand command) { - - try { - InstantiationResponse response = provider.issueControlLoopCommand(command); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Status.ACCEPTED)), requestId) - .entity(response).build(); - - } catch (PfModelRuntimeException | PfModelException | ControlLoopException e) { - LOGGER.warn("creation of control loop failed", e); - return createInstantiationErrorResponse(e, requestId); - } - } - - /** - * create a Instantiation Response from an exception. - * @param e the error - * @param requestId request ID used in ONAP logging - * @return the Instantiation Response - */ - private Response createInstantiationErrorResponse(ErrorResponseInfo e, UUID requestId) { - var resp = new InstantiationResponse(); - resp.setErrorDetails(e.getErrorResponse().getErrorMessage()); - return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())), - requestId).entity(resp).build(); - } -} - 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 index a463ad171..bcf1124d2 100644 --- 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 @@ -23,7 +23,6 @@ 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; @@ -39,37 +38,33 @@ public class ClRuntimeParameterHandler { /** * Read the parameters from the parameter file. * - * @param arguments the arguments passed to control loop runtime + * @param path the path 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 { + public ClRuntimeParameterGroup getParameters(final String path) throws ControlLoopException { ClRuntimeParameterGroup clRuntimeParameterGroup = null; // Read the parameters try { // Read the parameters from JSON - File file = new File(arguments.getFullConfigurationFilePath()); + File file = new File(path); 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); + throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, + "error reading parameters from \"" + path + "\"\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() + "\""); + throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, "no parameters found in \"" + path + "\""); } // 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()); + throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, + "validation error(s) on parameters from \"" + path + "\"\n" + validationResult.getResult()); } return clRuntimeParameterGroup; diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/CommissioningController.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/CommissioningController.java new file mode 100644 index 000000000..a03254272 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/CommissioningController.java @@ -0,0 +1,432 @@ +/*- + * ============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.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.Authorization; +import io.swagger.annotations.Extension; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.ResponseHeader; +import java.util.List; +import java.util.UUID; +import org.onap.policy.clamp.controlloop.models.messages.rest.commissioning.CommissioningResponse; +import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider; +import org.onap.policy.clamp.controlloop.runtime.main.web.AbstractRestController; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.base.PfModelRuntimeException; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +/** + * Class to provide REST end points for creating, deleting, querying commissioned control loops. + */ +@RestController +public class CommissioningController extends AbstractRestController { + + private static final Logger LOGGER = LoggerFactory.getLogger(CommissioningController.class); + + private final CommissioningProvider provider; + + /** + * Create Commissioning Controller. + * + * @param provider the CommissioningProvider + */ + public CommissioningController(CommissioningProvider provider) { + this.provider = provider; + } + + /** + * Creates a control loop definition. + * + * @param requestId request ID used in ONAP logging + * @param body the body of control loop following TOSCA definition + * @return a response + */ + // @formatter:off + @PostMapping(value = "/commission", + consumes = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}, + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) + @ApiOperation( + value = "Commissions control loop definitions", + notes = "Commissions control loop definitions, returning the commissioned control loop definition IDs", + response = CommissioningResponse.class, + tags = {"Control Loop Commissioning API"}, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + responseHeaders = { + @ResponseHeader( + name = VERSION_MINOR_NAME, + description = VERSION_MINOR_DESCRIPTION, + response = String.class), + @ResponseHeader( + name = VERSION_PATCH_NAME, + description = VERSION_PATCH_DESCRIPTION, + response = String.class), + @ResponseHeader( + name = VERSION_LATEST_NAME, + description = VERSION_LATEST_DESCRIPTION, + response = String.class), + @ResponseHeader( + name = REQUEST_ID_NAME, + description = REQUEST_ID_HDR_DESCRIPTION, + response = UUID.class) + }, + extensions = { + @Extension + ( + name = EXTENSION_NAME, + properties = { + @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), + @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) + } + ) + } + ) + @ApiResponses( + value = { + @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) + } + ) + // @formatter:on + public ResponseEntity create( + @RequestHeader( + name = REQUEST_ID_NAME, + required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Entity Body of Control Loop", required = true) @RequestBody ToscaServiceTemplate body) { + try { + return ResponseEntity.ok().body(provider.createControlLoopDefinitions(body)); + + } catch (PfModelRuntimeException | PfModelException e) { + LOGGER.warn("Commissioning of the control loops failed", e); + var resp = new CommissioningResponse(); + resp.setErrorDetails(e.getErrorResponse().getErrorMessage()); + return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).body(resp); + } + + } + + /** + * Deletes a control loop definition. + * + * @param requestId request ID used in ONAP logging + * @param name the name of the control loop definition to delete + * @param version the version of the control loop definition to delete + * @return a response + */ + // @formatter:off + @DeleteMapping(value = "/commission", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) + @ApiOperation(value = "Delete a commissioned control loop", + notes = "Deletes a Commissioned Control Loop, returning optional error details", + response = CommissioningResponse.class, + tags = {"Clamp Control Loop Commissioning API"}, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + responseHeaders = { + @ResponseHeader( + name = VERSION_MINOR_NAME, + description = VERSION_MINOR_DESCRIPTION, + response = String.class), + @ResponseHeader( + name = VERSION_PATCH_NAME, + description = VERSION_PATCH_DESCRIPTION, + response = String.class), + @ResponseHeader( + name = VERSION_LATEST_NAME, + description = VERSION_LATEST_DESCRIPTION, + response = String.class), + @ResponseHeader( + name = REQUEST_ID_NAME, + description = REQUEST_ID_HDR_DESCRIPTION, + response = UUID.class)}, + extensions = { + @Extension + ( + name = EXTENSION_NAME, + properties = { + @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), + @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) + } + ) + } + ) + @ApiResponses( + value = { + @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) + } + ) + // @formatter:on + public ResponseEntity delete( + @RequestHeader( + name = REQUEST_ID_NAME, + required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Control Loop definition name", required = true) @RequestParam( + value = "name") String name, + @ApiParam( + value = "Control Loop definition version", + required = true) @RequestParam("version") String version) { + + try { + return ResponseEntity.ok().body(provider.deleteControlLoopDefinition(name, version)); + + } catch (PfModelRuntimeException | PfModelException e) { + LOGGER.warn("Decommisssioning of control loop failed", e); + var resp = new CommissioningResponse(); + resp.setErrorDetails(e.getErrorResponse().getErrorMessage()); + return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).body(resp); + } + + } + + /** + * Queries details of all or specific control loop definitions. + * + * @param requestId request ID used in ONAP logging + * @param name the name of the control loop definition to get, null for all definitions + * @param version the version of the control loop definition to get, null for all definitions + * @return the control loop definitions + */ + // @formatter:off + @GetMapping(value = "/commission", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) + @ApiOperation(value = "Query details of the requested commissioned control loop definitions", + notes = "Queries details of the requested commissioned control loop definitions, " + + "returning all control loop details", + response = ToscaNodeTemplate.class, + tags = {"Clamp Control Loop Commissioning API"}, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + responseHeaders = { + @ResponseHeader( + name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, + response = String.class), + @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, + response = UUID.class)}, + extensions = { + @Extension + ( + name = EXTENSION_NAME, + properties = { + @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), + @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) + } + ) + } + ) + @ApiResponses( + value = { + @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) + } + ) + // @formatter:on + public ResponseEntity query( + @RequestHeader( + name = REQUEST_ID_NAME, + required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Control Loop definition name", required = false) @RequestParam( + value = "name", + required = false) String name, + @ApiParam(value = "Control Loop definition version", required = false) @RequestParam( + value = "version", + required = false) String version) { + + try { + return ResponseEntity.ok().body(provider.getControlLoopDefinitions(name, version)); + + } catch (PfModelRuntimeException | PfModelException e) { + LOGGER.warn("Get of control loop definitions failed", e); + var resp = new CommissioningResponse(); + resp.setErrorDetails(e.getErrorResponse().getErrorMessage()); + return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).body(resp); + } + + } + + /** + * Retrieves the Tosca Service Template. + * + * @param requestId request ID used in ONAP logging + * @param name the name of the tosca service template to retrieve + * @param version the version of the tosca service template to get + * @return the specified tosca service template + */ + // @formatter:off + @GetMapping(value = "/commission/toscaservicetemplate", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) + @ApiOperation(value = "Query details of the requested tosca service templates", + notes = "Queries details of the requested commissioned tosca service template, " + + "returning all tosca service template details", + response = ToscaServiceTemplate.class, + tags = {"Clamp Control Loop Commissioning API"}, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + responseHeaders = { + @ResponseHeader( + name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, + response = String.class), + @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, + response = UUID.class)}, + extensions = { + @Extension + ( + name = EXTENSION_NAME, + properties = { + @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), + @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) + } + ) + } + ) + @ApiResponses( + value = { + @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) + } + ) + // @formatter:on + public ResponseEntity queryToscaServiceTemplate( + @RequestHeader( + name = REQUEST_ID_NAME, + required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Tosca service template name", required = false) @RequestParam( + value = "name", + required = false) String name, + @ApiParam(value = "Tosca service template version", required = true) @RequestParam( + value = "version", + required = false) String version) { + + try { + return ResponseEntity.ok().body(provider.getToscaServiceTemplate(name, version)); + + } catch (PfModelRuntimeException | PfModelException e) { + LOGGER.warn("Get of tosca service template failed", e); + var resp = new CommissioningResponse(); + resp.setErrorDetails(e.getErrorResponse().getErrorMessage()); + return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).body(resp); + } + + } + + /** + * Queries the elements of a specific control loop. + * + * @param requestId request ID used in ONAP logging + * @param name the name of the control loop definition to get + * @param version the version of the control loop definition to get + * @return the control loop element definitions + */ + // @formatter:off + @GetMapping(value = "/commission/elements", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) + @ApiOperation(value = "Query details of the requested commissioned control loop element definitions", + notes = "Queries details of the requested commissioned control loop element definitions, " + + "returning all control loop elements' details", + response = ToscaNodeTemplate.class, + tags = {"Clamp Control Loop Commissioning API"}, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + responseHeaders = { + @ResponseHeader( + name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, + response = String.class), + @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, + response = UUID.class)}, + extensions = { + @Extension + ( + name = EXTENSION_NAME, + properties = { + @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), + @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) + } + ) + } + ) + @ApiResponses( + value = { + @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) + } + ) + // @formatter:on + public ResponseEntity queryElements( + @RequestHeader( + name = REQUEST_ID_NAME, + required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Control Loop definition name", required = false) @RequestParam( + value = "name", + required = false) String name, + @ApiParam(value = "Control Loop definition version", required = true) @RequestParam( + value = "version", + required = false) String version) { + + try { + List nodeTemplate = provider.getControlLoopDefinitions(name, version); + // Prevent ambiguous queries with multiple returns + if (nodeTemplate.size() > 1) { + var resp = new CommissioningResponse(); + resp.setErrorDetails("Multiple ControlLoops are not supported"); + return ResponseEntity.status(HttpStatus.NOT_ACCEPTABLE).body(resp); + } + + List response = provider.getControlLoopElementDefinitions(nodeTemplate.get(0)); + return ResponseEntity.ok().body(response); + + } catch (PfModelRuntimeException | PfModelException e) { + LOGGER.warn("Get of control loop element definitions failed", e); + var resp = new CommissioningResponse(); + resp.setErrorDetails(e.getErrorResponse().getErrorMessage()); + return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).body(resp); + } + + } +} 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 deleted file mode 100644 index f166de5d6..000000000 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/ControlLoopAafFilter.java +++ /dev/null @@ -1,38 +0,0 @@ -/*- - * ============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/InstantiationController.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/InstantiationController.java new file mode 100644 index 000000000..aba585e29 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/InstantiationController.java @@ -0,0 +1,424 @@ +/*- + * ============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.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.Authorization; +import io.swagger.annotations.Extension; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.ResponseHeader; +import java.util.UUID; +import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops; +import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationCommand; +import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse; +import org.onap.policy.clamp.controlloop.runtime.instantiation.ControlLoopInstantiationProvider; +import org.onap.policy.clamp.controlloop.runtime.main.web.AbstractRestController; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.base.PfModelRuntimeException; +import org.onap.policy.models.errors.concepts.ErrorResponseInfo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +/** + * Class to provide REST end points for creating, deleting, query and commanding a control loop definition. + */ +@RestController +public class InstantiationController extends AbstractRestController { + + private static final Logger LOGGER = LoggerFactory.getLogger(InstantiationController.class); + + // The CL provider for instantiation requests + private final ControlLoopInstantiationProvider provider; + + /** + * Create Instantiation Controller. + * + * @param provider the ControlLoopInstantiationProvider + */ + public InstantiationController(ControlLoopInstantiationProvider provider) { + this.provider = provider; + } + + /** + * Creates a control loop. + * + * @param requestId request ID used in ONAP logging + * @param controlLoops the control loops + * @return a response + */ + // @formatter:off + @PostMapping(value = "/instantiation", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}, + consumes = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) + @ApiOperation( + value = "Commissions control loop definitions", + notes = "Commissions control loop definitions, returning the control loop IDs", + response = InstantiationResponse.class, + tags = {"Control Loop Instantiation API"}, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + responseHeaders = { + @ResponseHeader( + name = VERSION_MINOR_NAME, + description = VERSION_MINOR_DESCRIPTION, + response = String.class), + @ResponseHeader( + name = VERSION_PATCH_NAME, + description = VERSION_PATCH_DESCRIPTION, + response = String.class), + @ResponseHeader( + name = VERSION_LATEST_NAME, + description = VERSION_LATEST_DESCRIPTION, + response = String.class), + @ResponseHeader( + name = REQUEST_ID_NAME, + description = REQUEST_ID_HDR_DESCRIPTION, + response = UUID.class) + }, + extensions = { + @Extension + ( + name = EXTENSION_NAME, + properties = { + @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), + @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) + } + ) + } + ) + @ApiResponses( + value = { + @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) + } + ) + // @formatter:on + public ResponseEntity create( + @RequestHeader(name = REQUEST_ID_NAME, required = false) + @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Entity Body of Control Loop", required = true) + @RequestBody ControlLoops controlLoops) { + + try { + return ResponseEntity.ok().body(provider.createControlLoops(controlLoops)); + + } catch (PfModelRuntimeException | PfModelException e) { + LOGGER.warn("creation of control loop failed", e); + return createInstantiationErrorResponse(e); + } + } + + /** + * Queries details of all control loops. + * + * @param requestId request ID used in ONAP logging + * @param name the name of the control loop to get, null for all control loops + * @param version the version of the control loop to get, null for all control loops + * @return the control loops + */ + // @formatter:off + @GetMapping(value = "/instantiation", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) + @ApiOperation(value = "Query details of the requested control loops", + notes = "Queries details of the requested control loops, returning all control loop details", + response = ControlLoops.class, + tags = { + "Clamp control loop Instantiation API" + }, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + responseHeaders = { + @ResponseHeader( + name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, + response = String.class), + @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, + response = UUID.class)}, + extensions = { + @Extension + ( + name = EXTENSION_NAME, + properties = { + @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), + @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) + } + ) + } + ) + @ApiResponses( + value = { + @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) + } + ) + // @formatter:on + public ResponseEntity query( + @RequestHeader(name = REQUEST_ID_NAME, required = false) + @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Control Loop definition name", required = false) + @RequestParam(value = "name", required = false) String name, + @ApiParam(value = "Control Loop definition version", required = false) + @RequestParam(value = "version", required = false) String version) { + + try { + return ResponseEntity.ok().body(provider.getControlLoops(name, version)); + + } catch (PfModelRuntimeException | PfModelException e) { + LOGGER.warn("commisssioning of control loop failed", e); + return createInstantiationErrorResponse(e); + } + + } + + /** + * Updates a control loop. + * + * @param requestId request ID used in ONAP logging + * @param controlLoops the control loops + * @return a response + */ + // @formatter:off + @PutMapping(value = "/instantiation", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}, + consumes = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) + @ApiOperation( + value = "Updates control loop definitions", + notes = "Updates control loop definitions, returning the updated control loop definition IDs", + response = InstantiationResponse.class, + tags = { + "Control Loop Instantiation API" + }, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + responseHeaders = { + @ResponseHeader( + name = VERSION_MINOR_NAME, + description = VERSION_MINOR_DESCRIPTION, + response = String.class), + @ResponseHeader( + name = VERSION_PATCH_NAME, + description = VERSION_PATCH_DESCRIPTION, + response = String.class), + @ResponseHeader( + name = VERSION_LATEST_NAME, + description = VERSION_LATEST_DESCRIPTION, + response = String.class), + @ResponseHeader( + name = REQUEST_ID_NAME, + description = REQUEST_ID_HDR_DESCRIPTION, + response = UUID.class) + }, + extensions = { + @Extension + ( + name = EXTENSION_NAME, + properties = { + @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), + @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) + } + ) + } + ) + @ApiResponses( + value = { + @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) + } + ) + // @formatter:on + public ResponseEntity update( + @RequestHeader(name = REQUEST_ID_NAME, required = false) + @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Entity Body of Control Loop", required = true) + @RequestBody ControlLoops controlLoops) { + + try { + return ResponseEntity.ok().body(provider.updateControlLoops(controlLoops)); + + } catch (PfModelRuntimeException | PfModelException e) { + LOGGER.warn("update of control loops failed", e); + return createInstantiationErrorResponse(e); + } + } + + /** + * Deletes a control loop definition. + * + * @param requestId request ID used in ONAP logging + * @param name the name of the control loop to delete + * @param version the version of the control loop to delete + * @return a response + */ + // @formatter:off + @DeleteMapping(value = "/instantiation", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) + @ApiOperation(value = "Delete a control loop", + notes = "Deletes a control loop, returning optional error details", + response = InstantiationResponse.class, + tags = { + "Clamp Control Loop Instantiation API" + }, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + responseHeaders = { + @ResponseHeader( + name = VERSION_MINOR_NAME, + description = VERSION_MINOR_DESCRIPTION, + response = String.class), + @ResponseHeader( + name = VERSION_PATCH_NAME, + description = VERSION_PATCH_DESCRIPTION, + response = String.class), + @ResponseHeader( + name = VERSION_LATEST_NAME, + description = VERSION_LATEST_DESCRIPTION, + response = String.class), + @ResponseHeader( + name = REQUEST_ID_NAME, + description = REQUEST_ID_HDR_DESCRIPTION, + response = UUID.class)}, + extensions = { + @Extension + ( + name = EXTENSION_NAME, + properties = { + @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), + @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) + } + ) + } + ) + @ApiResponses( + value = { + @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) + } + ) + // @formatter:on + + public ResponseEntity delete( + @RequestHeader(name = REQUEST_ID_NAME, required = false) + @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Control Loop definition name", required = true) + @RequestParam("name") String name, + @ApiParam(value = "Control Loop definition version") + @RequestParam(value = "version", required = false) String version) { + + try { + return ResponseEntity.ok().body(provider.deleteControlLoop(name, version)); + + } catch (PfModelRuntimeException | PfModelException e) { + LOGGER.warn("delete of control loop failed", e); + return createInstantiationErrorResponse(e); + } + } + + /** + * Issues control loop commands to control loops. + * + * @param requestId request ID used in ONAP logging + * @param command the command to issue to control loops + * @return the control loop definitions + */ + // @formatter:off + @PutMapping(value = "/instantiation/command", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}, + consumes = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) + @ApiOperation(value = "Issue a command to the requested control loops", + notes = "Issues a command to a control loop, ordering a state change on the control loop", + response = InstantiationResponse.class, + tags = { + "Clamp Control Loop Instantiation API" + }, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + responseHeaders = { + @ResponseHeader( + name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, + response = String.class), + @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, + response = UUID.class)}, + extensions = { + @Extension + ( + name = EXTENSION_NAME, + properties = { + @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), + @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) + } + ) + } + ) + @ApiResponses( + value = { + @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) + } + ) + // @formatter:on + public ResponseEntity issueControlLoopCommand( + @RequestHeader(name = REQUEST_ID_NAME, required = false) + @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Entity Body of control loop command", required = true) + @RequestBody InstantiationCommand command) { + + try { + return ResponseEntity.accepted().body(provider.issueControlLoopCommand(command)); + + } catch (PfModelRuntimeException | PfModelException | ControlLoopException e) { + LOGGER.warn("creation of control loop failed", e); + return createInstantiationErrorResponse(e); + } + } + + /** + * create a Instantiation Response from an exception. + * + * @param e the error + * @return the Instantiation Response + */ + private ResponseEntity createInstantiationErrorResponse(ErrorResponseInfo e) { + var resp = new InstantiationResponse(); + resp.setErrorDetails(e.getErrorResponse().getErrorMessage()); + return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).body(resp); + } +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/MonitoringQueryController.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/MonitoringQueryController.java new file mode 100644 index 000000000..86531597a --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/MonitoringQueryController.java @@ -0,0 +1,385 @@ +/*- + * ============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.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.Authorization; +import io.swagger.annotations.Extension; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.ResponseHeader; +import java.time.Instant; +import java.util.UUID; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatisticsList; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatisticsList; +import org.onap.policy.clamp.controlloop.runtime.main.web.AbstractRestController; +import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringProvider; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.base.PfModelRuntimeException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +/** + * This class handles REST endpoints for CL Statistics monitoring. + */ +@RestController +public class MonitoringQueryController extends AbstractRestController { + + private static final Logger LOGGER = LoggerFactory.getLogger(MonitoringQueryController.class); + private final MonitoringProvider provider; + + /** + * Create Monitoring Controller. + * + * @param provider the MonitoringProvider + */ + public MonitoringQueryController(MonitoringProvider provider) { + this.provider = provider; + } + + /** + * Queries details of control loop participants statistics. + * + * @param requestId request ID used in ONAP logging + * @param name the name of the participant to get, null for all participants statistics + * @param version the version of the participant to get, null for all participants with the given name + * @param recordCount the record count to be fetched + * @param startTime the time from which to get statistics + * @param endTime the time to which to get statistics + * @return the participant statistics + */ + // @formatter:off + @GetMapping(value = "/monitoring/participant", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) + @ApiOperation(value = "Query details of the requested participant stats", + notes = "Queries details of the requested participant stats, returning all participant stats", + response = ParticipantStatisticsList.class, + tags = { + "Clamp control loop Monitoring API" + }, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + responseHeaders = { + @ResponseHeader( + name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, + response = String.class), + @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, + response = UUID.class)}, + extensions = { + @Extension + ( + name = EXTENSION_NAME, + properties = { + @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), + @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) + } + ) + } + ) + @ApiResponses( + value = { + @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) + } + ) + // @formatter:on + public ResponseEntity queryParticipantStatistics( + @RequestHeader( + name = REQUEST_ID_NAME, + required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Control Loop participant name") @RequestParam( + value = "name", + required = false) final String name, + @ApiParam(value = "Control Loop participant version", required = false) @RequestParam( + value = "version", + required = false) final String version, + @ApiParam(value = "Record count", required = false) @RequestParam( + value = "recordCount", + required = false, + defaultValue = "0") final int recordCount, + @ApiParam(value = "start time", required = false) @RequestParam( + value = "startTime", + required = false) final String startTime, + @ApiParam(value = "end time", required = false) @RequestParam( + value = "endTime", + required = false) final String endTime) { + + try { + Instant startTimestamp = null; + Instant endTimestamp = null; + + if (startTime != null) { + startTimestamp = Instant.parse(startTime); + } + if (endTime != null) { + endTimestamp = Instant.parse(endTime); + } + return ResponseEntity.ok().body(provider.fetchFilteredParticipantStatistics(name, version, recordCount, + startTimestamp, endTimestamp)); + + } catch (PfModelRuntimeException e) { + LOGGER.warn("Monitoring of participants statistics failed", e); + return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).build(); + } + + } + + /** + * Queries details of all participant statistics per control loop. + * + * @param requestId request ID used in ONAP logging + * @param name the name of the control loop + * @param version version of the control loop + * @return the control loop element statistics + */ + // @formatter:off + @GetMapping(value = "/monitoring/participants/controlloop", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) + @ApiOperation(value = "Query details of all the participant stats in a control loop", + notes = "Queries details of the participant stats, returning all participant stats", + response = ClElementStatisticsList.class, + tags = { + "Clamp control loop Monitoring API" + }, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + responseHeaders = { + @ResponseHeader( + name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, + response = String.class), + @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, + response = UUID.class)}, + extensions = { + @Extension + ( + name = EXTENSION_NAME, + properties = { + @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), + @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) + } + ) + }) + @ApiResponses( + value = { + @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) + } + ) + // @formatter:on + public ResponseEntity queryParticipantStatisticsPerControlLoop( + @RequestHeader( + name = REQUEST_ID_NAME, + required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Control Loop name", required = true) @RequestParam( + value = "name", + required = false) final String name, + @ApiParam(value = "Control Loop version", required = true) @RequestParam( + value = "version", + required = false) final String version) { + + try { + return ResponseEntity.ok().body(provider.fetchParticipantStatsPerControlLoop(name, version)); + + } catch (PfModelRuntimeException e) { + LOGGER.warn("Monitoring of Cl participant statistics failed", e); + return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).build(); + } + + } + + /** + * Queries details of all control loop element statistics per control loop. + * + * @param requestId request ID used in ONAP logging + * @param name the name of the control loop + * @param version version of the control loop + * @return the control loop element statistics + */ + // @formatter:off + @GetMapping(value = "/monitoring/clelements/controlloop", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) + @ApiOperation(value = "Query details of the requested cl element stats in a control loop", + notes = "Queries details of the requested cl element stats, returning all clElement stats", + response = ClElementStatisticsList.class, + tags = { + "Clamp control loop Monitoring API" + }, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + responseHeaders = { + @ResponseHeader( + name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, + response = String.class), + @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, + response = UUID.class)}, + extensions = { + @Extension + ( + name = EXTENSION_NAME, + properties = { + @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), + @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) + } + ) + }) + @ApiResponses( + value = { + @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) + } + ) + // @formatter:on + public ResponseEntity queryElementStatisticsPerControlLoop( + @RequestHeader( + name = REQUEST_ID_NAME, + required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Control Loop name", required = true) @RequestParam( + value = "name", + required = false) final String name, + @ApiParam(value = "Control Loop version", required = true) @RequestParam( + value = "version", + required = false) final String version) { + + try { + return ResponseEntity.ok().body(provider.fetchClElementStatsPerControlLoop(name, version)); + + } catch (PfModelRuntimeException e) { + LOGGER.warn("Monitoring of Cl Element statistics failed", e); + return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).build(); + } + + } + + /** + * Queries details of all control loop element statistics per control loop. + * + * @param requestId request ID used in ONAP logging + * @param name the name of the control loop + * @param version version of the control loop + * @param id Id of the control loop element + * @param recordCount the record count to be fetched + * @param startTime the time from which to get statistics + * @param endTime the time to which to get statistics + * @return the control loop element statistics + */ + // @formatter:off + @GetMapping(value = "/monitoring/clelement", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) + @ApiOperation(value = "Query details of the requested cl element stats", + notes = "Queries details of the requested cl element stats, returning all clElement stats", + response = ClElementStatisticsList.class, + tags = { + "Clamp control loop Monitoring API" + }, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + responseHeaders = { + @ResponseHeader( + name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, + response = String.class), + @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, + response = UUID.class)}, + extensions = { + @Extension + ( + name = EXTENSION_NAME, + properties = { + @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), + @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) + } + ) + }) + @ApiResponses( + value = { + @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) + } + ) + // @formatter:on + public ResponseEntity queryElementStatistics( + @RequestHeader( + name = REQUEST_ID_NAME, + required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Participant name", required = true) @RequestParam( + value = "name", + required = false) final String name, + @ApiParam(value = "Participant version", required = true) @RequestParam( + value = "version", + required = false) final String version, + @ApiParam(value = "Record count", required = false) @RequestParam( + value = "recordCount", + required = false, + defaultValue = "0") final int recordCount, + @ApiParam(value = "Control Loop element id", required = false) @RequestParam( + value = "id", + required = false) final String id, + @ApiParam(value = "start time", required = false) @RequestParam( + value = "startTime", + required = false) final String startTime, + @ApiParam(value = "end time", required = false) @RequestParam( + value = "endTime", + required = false) final String endTime) { + + try { + Instant startTimestamp = null; + Instant endTimestamp = null; + + if (startTime != null) { + startTimestamp = Instant.parse(startTime); + } + if (endTime != null) { + endTimestamp = Instant.parse(endTime); + } + return ResponseEntity.ok().body(provider.fetchFilteredClElementStatistics(name, version, id, startTimestamp, + endTimestamp, recordCount)); + + } catch (PfModelRuntimeException | PfModelException e) { + LOGGER.warn("Monitoring of Cl Element statistics failed", e); + return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).build(); + } + + } + +} 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 deleted file mode 100644 index 4955e4a2f..000000000 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/RestController.java +++ /dev/null @@ -1,116 +0,0 @@ -/*- - * ============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 - * @param requestId unique ID for this request - * @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 index 957f53600..323f76178 100644 --- 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 @@ -20,36 +20,30 @@ package org.onap.policy.clamp.controlloop.runtime.main.startstop; -import java.util.HashSet; +import java.io.Closeable; +import java.io.IOException; import java.util.List; -import java.util.Set; -import java.util.concurrent.atomic.AtomicReference; import javax.ws.rs.core.Response.Status; +import lombok.Getter; 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 { +public class ClRuntimeActivator extends ServiceManagerContainer implements Closeable { // Name of the message type for messages on topics private static final String[] MSG_TYPE_NAMES = {"messageType"}; - private final ClRuntimeParameterGroup clRuntimeParameterGroup; + @Getter + private final ClRuntimeParameterGroup parameterGroup; // Topics from which the application receives and to which the application sends messages private List topicSinks; @@ -64,15 +58,12 @@ public class ClRuntimeActivator extends ServiceManagerContainer { * Instantiate the activator for the control loop runtime as a complete service. * * @param clRuntimeParameterGroup the parameters for the control loop runtime service + * @param supervisionHandler SupervisionHandler * @throws ControlLoopRuntimeException if the activator does not start */ - public ClRuntimeActivator(final ClRuntimeParameterGroup clRuntimeParameterGroup) { - - if (clRuntimeParameterGroup == null || !clRuntimeParameterGroup.isValid()) { - throw new ControlLoopRuntimeException(Status.INTERNAL_SERVER_ERROR, "ParameterGroup not valid"); - } - - this.clRuntimeParameterGroup = clRuntimeParameterGroup; + public ClRuntimeActivator(final ClRuntimeParameterGroup clRuntimeParameterGroup, + SupervisionHandler supervisionHandler) { + this.parameterGroup = clRuntimeParameterGroup; topicSinks = TopicEndpointManager.getManager() .addTopicSinks(clRuntimeParameterGroup.getTopicParameterGroup().getTopicSinks()); @@ -87,77 +78,22 @@ public class ClRuntimeActivator extends ServiceManagerContainer { "topic message dispatcher failed to start", e); } - final AtomicReference commissioningHandler = new AtomicReference<>(); - final AtomicReference instantiationHandler = new AtomicReference<>(); - final AtomicReference supervisionHandler = new AtomicReference<>(); - final AtomicReference monitoringHandler = new AtomicReference<>(); - final AtomicReference 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("Supervision Providers", () -> supervisionHandler.startProviders(), + () -> supervisionHandler.stopProviders()); + addAction("Supervision Listeners", () -> supervisionHandler.startAndRegisterListeners(msgDispatcher), + () -> supervisionHandler.stopAndUnregisterListeners(msgDispatcher)); + addAction("Supervision Publishers", () -> supervisionHandler.startAndRegisterPublishers(topicSinks), + () -> supervisionHandler.stopAndUnregisterPublishers()); addAction("Topic Message Dispatcher", this::registerMsgDispatcher, this::unregisterMsgDispatcher); - - clRuntimeParameterGroup.getRestServerParameters().setName(clRuntimeParameterGroup.getName()); - - addAction("REST server", - () -> { - Set> providerClasses = new HashSet<>(); - providerClasses.addAll(commissioningHandler.get().getProviderClasses()); - providerClasses.addAll(instantiationHandler.get().getProviderClasses()); - providerClasses.addAll(supervisionHandler.get().getProviderClasses()); - providerClasses.addAll(monitoringHandler.get().getProviderClasses()); - - var 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 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). */ @@ -176,12 +112,10 @@ public class ClRuntimeActivator extends ServiceManagerContainer { } } - /** - * Get the parameters used by the activator. - * - * @return the parameters of the activator - */ - public ClRuntimeParameterGroup getParameterGroup() { - return clRuntimeParameterGroup; + @Override + public void close() throws IOException { + if (isAlive()) { + stop(); + } } } 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 deleted file mode 100644 index 54167e8a6..000000000 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeCommandLineArguments.java +++ /dev/null @@ -1,132 +0,0 @@ -/*- - * ============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 lombok.Getter; -import lombok.Setter; -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.DefaultParser; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; -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 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 - * @throws ControlLoopRuntimeException if the arguments are invalid - */ - 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()); - } -} 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 deleted file mode 100644 index de1ce6f5d..000000000 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/Main.java +++ /dev/null @@ -1,159 +0,0 @@ -/*- - * ============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 - * @throws ControlLoopRuntimeException if the CLAMP runtime fails to start - */ - public Main(final String[] args) { - final var argumentString = Arrays.toString(args); - LOGGER.info("Starting the control loop runtime service with arguments - {}", argumentString); - - // Check the arguments - final var 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()); - var successMsg = String.format(MessageConstants.START_SUCCESS_MSG, MessageConstants.POLICY_CLAMP); - LOGGER.info(successMsg); - } - - /** - * Check if main is running. - * - * @return true if the CLAMP runtime 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); - } -} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/web/AbstractRestController.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/web/AbstractRestController.java new file mode 100644 index 000000000..7d279ba67 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/web/AbstractRestController.java @@ -0,0 +1,91 @@ +/*- + * ============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.web; + +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 javax.ws.rs.core.MediaType; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * Common superclass to provide REST endpoints for the participant simulator. + */ +// @formatter:off +@RequestMapping(value = "/v2", produces = {MediaType.APPLICATION_JSON, AbstractRestController.APPLICATION_YAML}) +@Api(value = "Control Loop Commissioning API") +@SwaggerDefinition( + info = @Info(description = + "Control Loop Service", version = "v1.0", + title = "Control Loop"), + consumes = {MediaType.APPLICATION_JSON, AbstractRestController.APPLICATION_YAML}, + produces = {MediaType.APPLICATION_JSON, AbstractRestController.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 abstract class AbstractRestController { + 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"; + + /** + * Constructor. + */ + protected AbstractRestController() { + } +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/web/ControlLoopAafFilter.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/web/ControlLoopAafFilter.java new file mode 100644 index 000000000..739a691c9 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/web/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.web; + +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/web/RequestResponseLoggingFilter.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/web/RequestResponseLoggingFilter.java new file mode 100644 index 000000000..eb08391a9 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/web/RequestResponseLoggingFilter.java @@ -0,0 +1,63 @@ +/*- + * ============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.web; + +import java.io.IOException; +import java.util.UUID; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +@Component +@Order(2) +public class RequestResponseLoggingFilter implements Filter { + + private static final String VERSION_MINOR_NAME = "X-MinorVersion"; + private static final String VERSION_PATCH_NAME = "X-PatchVersion"; + private static final String VERSION_LATEST_NAME = "X-LatestVersion"; + public static final String API_VERSION = "1.0.0"; + public static final String REQUEST_ID_NAME = "X-ONAP-RequestID"; + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + + + HttpServletResponse res = (HttpServletResponse) response; + HttpServletRequest req = (HttpServletRequest) request; + + String requestId = req.getHeader(REQUEST_ID_NAME); + res.addHeader(REQUEST_ID_NAME, requestId != null ? requestId : UUID.randomUUID().toString()); + + res.addHeader(VERSION_MINOR_NAME, "0"); + res.addHeader(VERSION_PATCH_NAME, "0"); + res.addHeader(VERSION_LATEST_NAME, API_VERSION); + + chain.doFilter(request, response); + } + +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/web/RuntimeErrorController.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/web/RuntimeErrorController.java new file mode 100644 index 000000000..2dc7a6b8e --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/web/RuntimeErrorController.java @@ -0,0 +1,102 @@ +/*- + * ============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.web; + +import io.swagger.v3.oas.annotations.Hidden; +import java.util.Map; +import javax.servlet.RequestDispatcher; +import javax.servlet.http.HttpServletRequest; +import org.onap.policy.clamp.controlloop.models.messages.rest.SimpleResponse; +import org.onap.policy.clamp.controlloop.models.messages.rest.TypedSimpleResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.error.ErrorAttributeOptions; +import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.boot.web.servlet.error.ErrorController; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.context.request.ServletWebRequest; + +@Controller +@Hidden +public class RuntimeErrorController implements ErrorController { + + private static final Logger LOGGER = LoggerFactory.getLogger(RuntimeErrorController.class); + + private final ErrorAttributes errorAttributes; + + @Value("${server.error.path}") + private String path; + + /** + * Constructor. + * + * @param errorAttributes ErrorAttributes + */ + public RuntimeErrorController(ErrorAttributes errorAttributes) { + this.errorAttributes = errorAttributes; + } + + protected HttpStatus getStatus(HttpServletRequest request) { + Integer statusCode = (Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE); + if (statusCode == null) { + return HttpStatus.INTERNAL_SERVER_ERROR; + } + try { + return HttpStatus.valueOf(statusCode); + } catch (Exception ex) { + LOGGER.error("statusCode {} Not Valid", statusCode, ex); + return HttpStatus.INTERNAL_SERVER_ERROR; + } + } + + /** + * Handle Errors not handled to GlobalControllerExceptionHandler. + * + * @param request HttpServletRequest + * @return ResponseEntity + */ + @RequestMapping(value = "${server.error.path}", produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity> handleError(HttpServletRequest request) { + Map map = this.errorAttributes.getErrorAttributes(new ServletWebRequest(request), + ErrorAttributeOptions.defaults()); + + StringBuilder sb = new StringBuilder(); + final Object error = map.get("error"); + if (error != null) { + sb.append(error.toString()).append(" "); + } + final Object message = map.get("message"); + if (message != null) { + sb.append(message.toString()); + } + + TypedSimpleResponse resp = new TypedSimpleResponse<>(); + resp.setErrorDetails(sb.toString()); + + return ResponseEntity.status(getStatus(request)).body(resp); + + } +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringHandler.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringHandler.java deleted file mode 100644 index 1584766f1..000000000 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringHandler.java +++ /dev/null @@ -1,81 +0,0 @@ -/*- - * ============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.monitoring; - -import java.io.IOException; -import java.util.Set; -import javax.ws.rs.core.Response; -import lombok.Getter; -import org.onap.policy.clamp.controlloop.common.handler.ControlLoopHandler; -import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; -import org.onap.policy.clamp.controlloop.runtime.monitoring.rest.MonitoringQueryController; -import org.onap.policy.common.utils.services.Registry; -import org.onap.policy.models.base.PfModelRuntimeException; - -/** - * This class handles monitoring of control loop definitions, - * so only one object of this type should be built at a time. - * - *

- * It is effectively a singleton that is started at system start. - */ -public class MonitoringHandler extends ControlLoopHandler { - - @Getter - private MonitoringProvider monitoringProvider; - - /** - * Gets the Monitoring Handler. - * - * @return MonitoringHandler - */ - public static MonitoringHandler getInstance() { - return Registry.get(MonitoringHandler.class.getName()); - } - - /** - * Create a handler. - * - * @param controlLoopParameters the parameters for access to the database - */ - public MonitoringHandler(ClRuntimeParameterGroup controlLoopParameters) { - super(controlLoopParameters.getDatabaseProviderParameters()); - } - - @Override - public Set> getProviderClasses() { - return Set.of(MonitoringQueryController.class); - } - - @Override - public void startProviders() { - monitoringProvider = new MonitoringProvider(getDatabaseProviderParameters()); - } - - @Override - public void stopProviders() { - try { - monitoringProvider.close(); - } catch (IOException e) { - throw new PfModelRuntimeException(Response.Status.INTERNAL_SERVER_ERROR, "Cannot stop provider", e); - } - } -} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringProvider.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringProvider.java index 1bc1312e7..a68505877 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringProvider.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringProvider.java @@ -36,14 +36,16 @@ import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ClElementStatisticsProvider; import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider; import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantStatisticsProvider; +import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.base.PfModelRuntimeException; -import org.onap.policy.models.provider.PolicyModelsProviderParameters; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.springframework.stereotype.Component; /** * This class provides information about statistics data of CL elements and CL Participants in database to callers. */ +@Component public class MonitoringProvider implements Closeable { private static final String DESC_ORDER = "DESC"; @@ -54,15 +56,17 @@ public class MonitoringProvider implements Closeable { /** * Create a Monitoring provider. * - * @param parameters parameters for accessing the database for monitoring + * @param controlLoopParameters the parameters for access to the database * @throws PfModelRuntimeException on errors creating the provider */ - public MonitoringProvider(PolicyModelsProviderParameters parameters) { + public MonitoringProvider(ClRuntimeParameterGroup controlLoopParameters) { try { - participantStatisticsProvider = new ParticipantStatisticsProvider(parameters); - clElementStatisticsProvider = new ClElementStatisticsProvider(parameters); - controlLoopProvider = new ControlLoopProvider(parameters); + participantStatisticsProvider = + new ParticipantStatisticsProvider(controlLoopParameters.getDatabaseProviderParameters()); + clElementStatisticsProvider = + new ClElementStatisticsProvider(controlLoopParameters.getDatabaseProviderParameters()); + controlLoopProvider = new ControlLoopProvider(controlLoopParameters.getDatabaseProviderParameters()); } catch (PfModelException e) { throw new PfModelRuntimeException(e); } @@ -83,10 +87,10 @@ public class MonitoringProvider implements Closeable { * @throws PfModelException on creation errors */ public ParticipantStatisticsList createParticipantStatistics(List participantStatistics) - throws PfModelException { + throws PfModelException { var participantStatisticsList = new ParticipantStatisticsList(); participantStatisticsList - .setStatisticsList(participantStatisticsProvider.createParticipantStatistics(participantStatistics)); + .setStatisticsList(participantStatisticsProvider.createParticipantStatistics(participantStatistics)); return participantStatisticsList; } @@ -99,10 +103,10 @@ public class MonitoringProvider implements Closeable { * @throws PfModelException on creation errors */ public ClElementStatisticsList createClElementStatistics(List clElementStatisticsList) - throws PfModelException { + throws PfModelException { var elementStatisticsList = new ClElementStatisticsList(); elementStatisticsList - .setClElementStatistics(clElementStatisticsProvider.createClElementStatistics(clElementStatisticsList)); + .setClElementStatistics(clElementStatisticsProvider.createClElementStatistics(clElementStatisticsList)); return elementStatisticsList; } @@ -118,13 +122,13 @@ public class MonitoringProvider implements Closeable { * @return the participant found */ public ParticipantStatisticsList fetchFilteredParticipantStatistics(@NonNull final String name, - final String version, int recordCount, Instant startTime, Instant endTime) { + final String version, int recordCount, Instant startTime, Instant endTime) { var participantStatisticsList = new ParticipantStatisticsList(); // Additional parameters can be added in filterMap for filtering data. Map filterMap = null; participantStatisticsList.setStatisticsList(participantStatisticsProvider.getFilteredParticipantStatistics(name, - version, startTime, endTime, filterMap, DESC_ORDER, recordCount)); + version, startTime, endTime, filterMap, DESC_ORDER, recordCount)); return participantStatisticsList; } @@ -138,16 +142,16 @@ public class MonitoringProvider implements Closeable { * @throws PfModelRuntimeException on errors getting participant statistics */ public ParticipantStatisticsList fetchParticipantStatsPerControlLoop(@NonNull final String controlLoopName, - @NonNull final String controlLoopVersion) { + @NonNull final String controlLoopVersion) { var statisticsList = new ParticipantStatisticsList(); List participantStatistics = new ArrayList<>(); try { // Fetch all participantIds for a specific control loop List participantIds = - getAllParticipantIdsPerControlLoop(controlLoopName, controlLoopVersion); + getAllParticipantIdsPerControlLoop(controlLoopName, controlLoopVersion); for (ToscaConceptIdentifier id : participantIds) { - participantStatistics.addAll(participantStatisticsProvider - .getFilteredParticipantStatistics(id.getName(), id.getVersion(), null, null, null, DESC_ORDER, 0)); + participantStatistics.addAll(participantStatisticsProvider.getFilteredParticipantStatistics( + id.getName(), id.getVersion(), null, null, null, DESC_ORDER, 0)); } statisticsList.setStatisticsList(participantStatistics); } catch (PfModelException e) { @@ -169,7 +173,7 @@ public class MonitoringProvider implements Closeable { * @throws PfModelException on errors getting control loop statistics */ public ClElementStatisticsList fetchFilteredClElementStatistics(@NonNull final String name, final String version, - final String id, Instant startTime, Instant endTime, int recordCount) throws PfModelException { + final String id, Instant startTime, Instant endTime, int recordCount) throws PfModelException { var clElementStatisticsList = new ClElementStatisticsList(); Map filterMap = new HashMap<>(); // Adding UUID in filter if present @@ -177,7 +181,7 @@ public class MonitoringProvider implements Closeable { filterMap.put("localName", id); } clElementStatisticsList.setClElementStatistics(clElementStatisticsProvider.getFilteredClElementStatistics(name, - version, startTime, endTime, filterMap, DESC_ORDER, recordCount)); + version, startTime, endTime, filterMap, DESC_ORDER, recordCount)); return clElementStatisticsList; } @@ -191,7 +195,7 @@ public class MonitoringProvider implements Closeable { * @throws PfModelRuntimeException on errors getting control loop statistics */ public ClElementStatisticsList fetchClElementStatsPerControlLoop(@NonNull final String name, - @NonNull final String version) { + @NonNull final String version) { var clElementStatisticsList = new ClElementStatisticsList(); List clElementStats = new ArrayList<>(); try { @@ -203,8 +207,8 @@ public class MonitoringProvider implements Closeable { // Collect control loop element statistics for each cl element. for (ControlLoopElement clElement : clElements) { clElementStats.addAll(fetchFilteredClElementStatistics(clElement.getParticipantId().getName(), - clElement.getParticipantId().getVersion(), clElement.getId().toString(), null, null, 0) - .getClElementStatistics()); + clElement.getParticipantId().getVersion(), clElement.getId().toString(), null, null, 0) + .getClElementStatistics()); } } clElementStatisticsList.setClElementStatistics(clElementStats); @@ -224,7 +228,7 @@ public class MonitoringProvider implements Closeable { * @throws PfModelException on errors */ public List getAllParticipantIdsPerControlLoop(String name, String version) - throws PfModelException { + throws PfModelException { List participantIds = new ArrayList<>(); var controlLoop = controlLoopProvider.getControlLoop(new ToscaConceptIdentifier(name, version)); if (controlLoop != null) { @@ -245,7 +249,7 @@ public class MonitoringProvider implements Closeable { * @throws PfModelException on errors */ public Map getAllClElementsIdPerControlLoop(String name, String version) - throws PfModelException { + throws PfModelException { Map clElementId = new HashMap<>(); var controlLoop = controlLoopProvider.getControlLoop(new ToscaConceptIdentifier(name, version)); if (controlLoop != null) { diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/rest/MonitoringQueryController.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/rest/MonitoringQueryController.java deleted file mode 100644 index 7fde5fba3..000000000 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/rest/MonitoringQueryController.java +++ /dev/null @@ -1,380 +0,0 @@ -/*- - * ============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.monitoring.rest; - -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import io.swagger.annotations.Authorization; -import io.swagger.annotations.Extension; -import io.swagger.annotations.ExtensionProperty; -import io.swagger.annotations.ResponseHeader; -import java.time.Instant; -import java.util.UUID; -import javax.ws.rs.DefaultValue; -import javax.ws.rs.GET; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.Path; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.Response; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatisticsList; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatisticsList; -import org.onap.policy.clamp.controlloop.runtime.main.rest.RestController; -import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringHandler; -import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringProvider; -import org.onap.policy.models.base.PfModelException; -import org.onap.policy.models.base.PfModelRuntimeException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * This class handles REST endpoints for CL Statistics monitoring. - */ -public class MonitoringQueryController extends RestController { - - private static final Logger LOGGER = LoggerFactory.getLogger(MonitoringQueryController.class); - private final MonitoringProvider provider; - - /** - * Create Monitoring Controller. - */ - public MonitoringQueryController() { - this.provider = MonitoringHandler.getInstance().getMonitoringProvider(); - } - - - /** - * Queries details of control loop participants statistics. - * - * @param requestId request ID used in ONAP logging - * @param name the name of the participant to get, null for all participants statistics - * @param version the version of the participant to get, null for all participants with the given name - * @param recordCount the record count to be fetched - * @param startTime the time from which to get statistics - * @param endTime the time to which to get statistics - * @return the participant statistics - */ - // @formatter:off - @GET - @Path("/monitoring/participant") - @ApiOperation(value = "Query details of the requested participant stats", - notes = "Queries details of the requested participant stats, returning all participant stats", - response = ParticipantStatisticsList.class, - tags = { - "Clamp control loop Monitoring API" - }, - authorizations = @Authorization(value = AUTHORIZATION_TYPE), - responseHeaders = { - @ResponseHeader( - name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, - response = String.class), - @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, - response = String.class), - @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, - response = String.class), - @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, - response = UUID.class)}, - extensions = { - @Extension - ( - name = EXTENSION_NAME, - properties = { - @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), - @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) - } - ) - } - ) - @ApiResponses( - value = { - @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), - @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), - @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) - } - ) - // @formatter:on - public Response queryParticipantStatistics(@HeaderParam(REQUEST_ID_NAME) - @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Control Loop participant name", required = true) - @QueryParam("name") final String name, - @ApiParam(value = "Control Loop participant version", required = true) - @QueryParam("version") final String version, - @ApiParam(value = "Record count", required = false) @DefaultValue("0") - @QueryParam("recordCount") final int recordCount, - @ApiParam(value = "start time", required = false) - @QueryParam("startTime") final String startTime, - @ApiParam(value = "end time", required = false) - @QueryParam("endTime") final String endTime) { - - try { - Instant startTimestamp = null; - Instant endTimestamp = null; - - if (startTime != null) { - startTimestamp = Instant.parse(startTime); - } - if (endTime != null) { - endTimestamp = Instant.parse(endTime); - } - ParticipantStatisticsList response = provider.fetchFilteredParticipantStatistics(name, version, recordCount, - startTimestamp, endTimestamp); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId) - .entity(response) - .build(); - - } catch (PfModelRuntimeException e) { - LOGGER.warn("Monitoring of participants statistics failed", e); - return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())), - requestId).build(); - } - - } - - /** - * Queries details of all participant statistics per control loop. - * - * @param requestId request ID used in ONAP logging - * @param name the name of the control loop - * @param version version of the control loop - * @return the control loop element statistics - */ - // @formatter:off - @GET - @Path("/monitoring/participants/controlloop") - @ApiOperation(value = "Query details of all the participant stats in a control loop", - notes = "Queries details of the participant stats, returning all participant stats", - response = ClElementStatisticsList.class, - tags = { - "Clamp control loop Monitoring API" - }, - authorizations = @Authorization(value = AUTHORIZATION_TYPE), - responseHeaders = { - @ResponseHeader( - name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, - response = String.class), - @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, - response = String.class), - @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, - response = String.class), - @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, - response = UUID.class)}, - extensions = { - @Extension - ( - name = EXTENSION_NAME, - properties = { - @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), - @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) - } - ) - }) - @ApiResponses( - value = { - @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), - @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), - @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) - } - ) - // @formatter:on - public Response queryParticipantStatisticsPerControlLoop(@HeaderParam(REQUEST_ID_NAME) - @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Control Loop name", required = true) - @QueryParam("name") final String name, - @ApiParam(value = "Control Loop version", required = true) - @QueryParam("version") final String version) { - - try { - ParticipantStatisticsList response = provider.fetchParticipantStatsPerControlLoop(name, version); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId) - .entity(response) - .build(); - - } catch (PfModelRuntimeException e) { - LOGGER.warn("Monitoring of Cl participant statistics failed", e); - return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())), - requestId).build(); - } - - } - - - - /** - * Queries details of all control loop element statistics per control loop. - * - * @param requestId request ID used in ONAP logging - * @param name the name of the control loop - * @param version version of the control loop - * @return the control loop element statistics - */ - // @formatter:off - @GET - @Path("/monitoring/clelements/controlloop") - @ApiOperation(value = "Query details of the requested cl element stats in a control loop", - notes = "Queries details of the requested cl element stats, returning all clElement stats", - response = ClElementStatisticsList.class, - tags = { - "Clamp control loop Monitoring API" - }, - authorizations = @Authorization(value = AUTHORIZATION_TYPE), - responseHeaders = { - @ResponseHeader( - name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, - response = String.class), - @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, - response = String.class), - @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, - response = String.class), - @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, - response = UUID.class)}, - extensions = { - @Extension - ( - name = EXTENSION_NAME, - properties = { - @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), - @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) - } - ) - }) - @ApiResponses( - value = { - @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), - @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), - @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) - } - ) - // @formatter:on - public Response queryElementStatisticsPerControlLoop(@HeaderParam(REQUEST_ID_NAME) - @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Control Loop name", required = true) - @QueryParam("name") final String name, - @ApiParam(value = "Control Loop version", required = true) - @QueryParam("version") final String version) { - - try { - ClElementStatisticsList response = provider.fetchClElementStatsPerControlLoop(name, version); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId) - .entity(response) - .build(); - - } catch (PfModelRuntimeException e) { - LOGGER.warn("Monitoring of Cl Element statistics failed", e); - return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())), - requestId).build(); - } - - } - - - - - /** - * Queries details of all control loop element statistics per control loop. - * - * @param requestId request ID used in ONAP logging - * @param name the name of the control loop - * @param version version of the control loop - * @param id Id of the control loop element - * @param recordCount the record count to be fetched - * @param startTime the time from which to get statistics - * @param endTime the time to which to get statistics - * @return the control loop element statistics - */ - // @formatter:off - @GET - @Path("/monitoring/clelement") - @ApiOperation(value = "Query details of the requested cl element stats", - notes = "Queries details of the requested cl element stats, returning all clElement stats", - response = ClElementStatisticsList.class, - tags = { - "Clamp control loop Monitoring API" - }, - authorizations = @Authorization(value = AUTHORIZATION_TYPE), - responseHeaders = { - @ResponseHeader( - name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, - response = String.class), - @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, - response = String.class), - @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, - response = String.class), - @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, - response = UUID.class)}, - extensions = { - @Extension - ( - name = EXTENSION_NAME, - properties = { - @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), - @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) - } - ) - }) - @ApiResponses( - value = { - @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), - @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), - @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) - } - ) - // @formatter:on - public Response queryElementStatistics(@HeaderParam(REQUEST_ID_NAME) - @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Participant name", required = true) - @QueryParam("name") final String name, - @ApiParam(value = "Participant version", required = true) - @QueryParam("version") final String version, - @ApiParam(value = "Record count", required = false) - @DefaultValue("0") @QueryParam("recordCount") final int recordCount, - @ApiParam(value = "Control Loop element id", required = false) - @QueryParam("id") final String id, - @ApiParam(value = "start time", required = false) - @QueryParam("startTime") final String startTime, - @ApiParam(value = "end time", required = false) - @QueryParam("endTime") final String endTime) { - - try { - Instant startTimestamp = null; - Instant endTimestamp = null; - - if (startTime != null) { - startTimestamp = Instant.parse(startTime); - } - if (endTime != null) { - endTimestamp = Instant.parse(endTime); - } - ClElementStatisticsList response = provider.fetchFilteredClElementStatistics(name, version, id, - startTimestamp, endTimestamp, recordCount); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId) - .entity(response) - .build(); - - } catch (PfModelRuntimeException | PfModelException e) { - LOGGER.warn("Monitoring of Cl Element statistics failed", e); - return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())), - requestId).build(); - } - - } - -} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionHandler.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionHandler.java index 511185da1..e1b4be48b 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionHandler.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionHandler.java @@ -38,9 +38,8 @@ import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.Parti import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantControlLoopUpdate; import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType; import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantStatus; -import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningHandler; +import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider; import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; -import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringHandler; import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringProvider; import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantControlLoopStateChangePublisher; import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantControlLoopUpdatePublisher; @@ -48,19 +47,20 @@ import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantSta import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantStatusListener; import org.onap.policy.common.endpoints.event.comm.TopicSink; import org.onap.policy.common.endpoints.listeners.MessageTypeDispatcher; -import org.onap.policy.common.utils.services.Registry; import org.onap.policy.common.utils.services.ServiceManager; import org.onap.policy.common.utils.services.ServiceManagerException; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; /** * This class handles supervision of control loop instances, so only one object of this type should be built at a time. * *

It is effectively a singleton that is started at system start. */ +@Component public class SupervisionHandler extends ControlLoopHandler { private static final Logger LOGGER = LoggerFactory.getLogger(SupervisionHandler.class); @@ -71,7 +71,8 @@ public class SupervisionHandler extends ControlLoopHandler { private ControlLoopProvider controlLoopProvider; private ParticipantProvider participantProvider; - private MonitoringProvider monitoringProvider; + private final MonitoringProvider monitoringProvider; + private final CommissioningProvider commissioningProvider; // Publishers for participant communication private ParticipantStateChangePublisher stateChangePublisher; @@ -92,22 +93,19 @@ public class SupervisionHandler extends ControlLoopHandler { private ServiceManager manager; private ServiceManager publisherManager; - /** - * Gets the SupervisionHandler. - * - * @return SupervisionHandler - */ - public static SupervisionHandler getInstance() { - return Registry.get(SupervisionHandler.class.getName()); - } - /** * Create a handler. * * @param clRuntimeParameterGroup the parameters for the control loop runtime + * @param monitoringProvider the MonitoringProvider + * @param commissioningProvider the CommissioningProvider */ - public SupervisionHandler(ClRuntimeParameterGroup clRuntimeParameterGroup) { + public SupervisionHandler(ClRuntimeParameterGroup clRuntimeParameterGroup, MonitoringProvider monitoringProvider, + CommissioningProvider commissioningProvider) { super(clRuntimeParameterGroup.getDatabaseProviderParameters()); + this.monitoringProvider = monitoringProvider; + this.commissioningProvider = commissioningProvider; + // @formatter:off this.manager = new ServiceManager() .addAction("ControlLoop Provider", @@ -128,7 +126,8 @@ public class SupervisionHandler extends ControlLoopHandler { /** * Supervision trigger called when a command is issued on control loops. * - *

Causes supervision to start or continue supervision on the control loops in question. + *

+ * Causes supervision to start or continue supervision on the control loops in question. * * @param controlLoopIdentifierList the control loops for which the supervision command has been issued * @throws ControlLoopException on supervision triggering exceptions @@ -158,7 +157,7 @@ public class SupervisionHandler extends ControlLoopHandler { @Override public void startAndRegisterListeners(MessageTypeDispatcher msgDispatcher) { - msgDispatcher.register(ParticipantMessageType.PARTICIPANT_STATUS.name(), new ParticipantStatusListener()); + msgDispatcher.register(ParticipantMessageType.PARTICIPANT_STATUS.name(), new ParticipantStatusListener(this)); } @Override @@ -250,7 +249,7 @@ public class SupervisionHandler extends ControlLoopHandler { default: exceptionOccured(Response.Status.NOT_ACCEPTABLE, - "A control loop cannot be commanded to go into state " + controlLoop.getOrderedState().name()); + "A control loop cannot be commanded to go into state " + controlLoop.getOrderedState().name()); } } @@ -346,7 +345,6 @@ public class SupervisionHandler extends ControlLoopHandler { pclu.setControlLoop(controlLoop); // TODO: We should look up the correct TOSCA node template here for the control loop // Tiny hack implemented to return the tosca service template entry from the database and be passed onto dmaap - var commissioningProvider = CommissioningHandler.getInstance().getProvider(); pclu.setControlLoopDefinition(commissioningProvider.getToscaServiceTemplate(null, null)); controlLoopUpdatePublisher.send(pclu); } @@ -388,7 +386,6 @@ public class SupervisionHandler extends ControlLoopHandler { participantProvider.updateParticipants(participantList); } - monitoringProvider = MonitoringHandler.getInstance().getMonitoringProvider(); monitoringProvider.createParticipantStatistics(List.of(participantStatusMessage.getParticipantStatistics())); } @@ -401,14 +398,14 @@ public class SupervisionHandler extends ControlLoopHandler { for (ControlLoop controlLoop : participantStatusMessage.getControlLoops().getControlLoopList()) { if (controlLoop == null) { exceptionOccured(Response.Status.NOT_FOUND, - "PARTICIPANT_STATUS message references unknown control loop: " + controlLoop); + "PARTICIPANT_STATUS message references unknown control loop: " + controlLoop); } var dbControlLoop = controlLoopProvider .getControlLoop(new ToscaConceptIdentifier(controlLoop.getName(), controlLoop.getVersion())); if (dbControlLoop == null) { exceptionOccured(Response.Status.NOT_FOUND, - "PARTICIPANT_STATUS control loop not found in database: " + controlLoop); + "PARTICIPANT_STATUS control loop not found in database: " + controlLoop); } for (ControlLoopElement element : controlLoop.getElements().values()) { @@ -425,7 +422,6 @@ public class SupervisionHandler extends ControlLoopHandler { controlLoopProvider.updateControlLoop(dbControlLoop); } - monitoringProvider = MonitoringHandler.getInstance().getMonitoringProvider(); for (ControlLoop controlLoop : participantStatusMessage.getControlLoops().getControlLoopList()) { monitoringProvider.createClElementStatistics(controlLoop.getControlLoopElementStatisticsList(controlLoop)); } diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/ParticipantStatusListener.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/ParticipantStatusListener.java index a05f4aa20..88b838613 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/ParticipantStatusListener.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/ParticipantStatusListener.java @@ -25,7 +25,6 @@ import org.onap.policy.clamp.controlloop.runtime.supervision.SupervisionHandler; import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; import org.onap.policy.common.endpoints.listeners.ScoListener; import org.onap.policy.common.utils.coder.StandardCoderObject; -import org.onap.policy.common.utils.services.Registry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,13 +34,14 @@ import org.slf4j.LoggerFactory; public class ParticipantStatusListener extends ScoListener { private static final Logger LOGGER = LoggerFactory.getLogger(ParticipantStatusListener.class); - private final SupervisionHandler supervisionHandler = Registry.get(SupervisionHandler.class.getName()); + private final SupervisionHandler supervisionHandler; /** * Constructs the object. */ - public ParticipantStatusListener() { + public ParticipantStatusListener(SupervisionHandler supervisionHandler) { super(ParticipantStatus.class); + this.supervisionHandler = supervisionHandler; } @Override diff --git a/runtime-controlloop/src/main/resources/application.yaml b/runtime-controlloop/src/main/resources/application.yaml new file mode 100644 index 000000000..af9966d40 --- /dev/null +++ b/runtime-controlloop/src/main/resources/application.yaml @@ -0,0 +1,22 @@ +spring: + security: + user: + name: healthcheck + password: zb!XztG34 + http: + converters: + preferred-json-mapper: gson + +security: + enable-csrf: false + +server: + port: 6969 + servlet: + context-path: /onap/controlloop + error: + path: /error + + +runtime: + file: src/main/resources/parameters/ClRuntimeParameters.json diff --git a/runtime-controlloop/src/main/resources/parameters/ClRuntimeParameters.json b/runtime-controlloop/src/main/resources/parameters/ClRuntimeParameters.json new file mode 100644 index 000000000..a6c19837e --- /dev/null +++ b/runtime-controlloop/src/main/resources/parameters/ClRuntimeParameters.json @@ -0,0 +1,63 @@ +{ + "name": "ControlLoopRuntimeGroup", + "supervisionScannerIntervalSec": 1000, + "participantStateChangeIntervalSec": 1000, + "participantClUpdateIntervalSec": 1000, + "participantClStateChangeIntervalSec": 1000, + "restServerParameters": { + "host": "0.0.0.0", + "port": 6969, + "userName": "healthcheck", + "password": "zb!XztG34", + "https": false, + "aaf": false + }, + "participantParameters": { + "heartBeatMs": 120000, + "updateParameters": { + "maxRetryCount": 1, + "maxWaitMs": 30000 + }, + "stateChangeParameters": { + "maxRetryCount": 1, + "maxWaitMs": 30000 + } + }, + "databaseProviderParameters": { + "name": "PolicyProviderParameterGroup", + "implementation": "org.onap.policy.models.provider.impl.DatabasePolicyModelsProviderImpl", + "databaseDriver": "org.mariadb.jdbc.Driver", + "databaseUrl": "jdbc:mariadb://mariadb:3306/controlloop", + "databaseUser": "policy", + "databasePassword": "P01icY", + "persistenceUnit": "CommissioningMariaDb" + }, + "topicParameterGroup": { + "topicSources": [ + { + "topic": "POLICY-CLRUNTIME-PARTICIPANT", + "servers": [ + "message-router" + ], + "topicCommInfrastructure": "dmaap", + "fetchTimeout": 15000 + } + ], + "topicSinks": [ + { + "topic": "POLICY-CLRUNTIME-PARTICIPANT", + "servers": [ + "message-router" + ], + "topicCommInfrastructure": "dmaap" + }, + { + "topic": "POLICY-NOTIFICATION", + "servers": [ + "message-router" + ], + "topicCommInfrastructure": "dmaap" + } + ] + } +} -- cgit 1.2.3-korg