Add Commissioning Rest Controller 59/119259/6
authorERIMROB <robertas.rimkus@est.tech>
Thu, 11 Mar 2021 17:30:27 +0000 (17:30 +0000)
committerERIMROB <robertas.rimkus@est.tech>
Tue, 16 Mar 2021 12:56:16 +0000 (12:56 +0000)
This commit adds rest controller functions for commissioning service

Issue-ID: POLICY-2983
Change-Id: I5b316ba60a9aadfbc3c3b1dfb966bf82be27952c
Signed-off-by: ERIMROB <robertas.rimkus@est.tech>
tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningHandler.java [new file with mode: 0644]
tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/rest/CommissioningController.java [new file with mode: 0644]
tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationHandler.java
tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeActivator.java
tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/commissioning/rest/CommissioningControllerTest.java [new file with mode: 0644]
tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationControllerTest.java

diff --git a/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningHandler.java b/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningHandler.java
new file mode 100644 (file)
index 0000000..ab917b7
--- /dev/null
@@ -0,0 +1,101 @@
+/*-
+ * ============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.List;
+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.endpoints.event.comm.TopicSink;
+import org.onap.policy.common.endpoints.listeners.MessageTypeDispatcher;
+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<Class<?>> getProviderClasses() {
+        return Set.of(CommissioningController.class);
+    }
+
+    @Override
+    public void startAndRegisterListeners(MessageTypeDispatcher msgDispatcher) {
+        // No topic communication on this handler
+    }
+
+    @Override
+    public void startAndRegisterPublishers(List<TopicSink> topicSinks) {
+        // No topic communication on this handler
+    }
+
+    @Override
+    public void stopAndUnregisterPublishers() {
+        // No topic communication on this handler
+    }
+
+    @Override
+    public void stopAndUnregisterListeners(MessageTypeDispatcher msgDispatcher) {
+        // No topic communication on this handler
+    }
+
+    @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/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/rest/CommissioningController.java b/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/rest/CommissioningController.java
new file mode 100644 (file)
index 0000000..cd6c08e
--- /dev/null
@@ -0,0 +1,351 @@
+/*-
+ * ============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.errors.concepts.ErrorResponseInfo;
+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);
+            return createCommissioningErrorResponse(e, requestId);
+        }
+
+    }
+
+    /**
+     * 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);
+            return createCommissioningErrorResponse(e, requestId);
+        }
+
+    }
+
+    /**
+     * 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<ToscaNodeTemplate> 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);
+            return createCommissioningErrorResponse(e, requestId);
+        }
+
+    }
+
+    /**
+     * 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) throws Exception {
+
+        try {
+            List<ToscaNodeTemplate> nodeTemplate = provider.getControlLoopDefinitions(name, version);
+            //Prevent ambiguous queries with multiple returns
+            if (nodeTemplate.size() > 1) {
+                throw new Exception();
+            }
+            List<ToscaNodeTemplate> 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);
+            return createCommissioningErrorResponse(e, requestId);
+        }
+
+    }
+
+    private Response createCommissioningErrorResponse(ErrorResponseInfo e, UUID requestId) {
+        CommissioningResponse resp = new CommissioningResponse();
+        resp.setErrorDetails(e.getErrorResponse().getErrorMessage());
+        return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())),
+                requestId).entity(resp).build();
+    }
+
+}
index c4b0955..fd5288f 100644 (file)
@@ -27,6 +27,7 @@ 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.instantiation.rest.InstantiationController;
 import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup;
 import org.onap.policy.common.endpoints.event.comm.TopicSink;
@@ -66,11 +67,7 @@ public final class InstantiationHandler extends ControlLoopHandler {
 
     @Override
     public Set<Class<?>> getProviderClasses() {
-        Set<Class<?>> providerClasses = new HashSet<>();
-
-        providerClasses.add(InstantiationController.class);
-
-        return providerClasses;
+        return Set.of(InstantiationController.class);
     }
 
     @Override
index d3a5c58..0078f61 100644 (file)
 
 package org.onap.policy.clamp.controlloop.runtime.main.startstop;
 
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicReference;
 import javax.ws.rs.core.Response.Status;
 import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException;
+import org.onap.policy.clamp.controlloop.common.handler.ControlLoopHandler;
+import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningHandler;
 import org.onap.policy.clamp.controlloop.runtime.instantiation.InstantiationHandler;
 import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup;
 import org.onap.policy.clamp.controlloop.runtime.main.rest.ControlLoopAafFilter;
@@ -61,7 +64,6 @@ public class ClRuntimeActivator extends ServiceManagerContainer {
      * @param clRuntimeParameterGroup the parameters for the control loop runtime service
      */
     public ClRuntimeActivator(final ClRuntimeParameterGroup clRuntimeParameterGroup) {
-
         if (clRuntimeParameterGroup == null || !clRuntimeParameterGroup.isValid()) {
             throw new ControlLoopRuntimeException(Status.INTERNAL_SERVER_ERROR, "ParameterGroup not valid");
         }
@@ -81,53 +83,61 @@ public class ClRuntimeActivator extends ServiceManagerContainer {
                     "topic message dispatcher failed to start", e);
         }
 
-        final AtomicReference<InstantiationHandler> instantiationHandler = new AtomicReference<>();
-        final AtomicReference<RestServer> restServer = new AtomicReference<>();
+        final AtomicReference<ControlLoopHandler> commissioningHandler = new AtomicReference<>();
+        final AtomicReference<ControlLoopHandler> instantiationHandler = new AtomicReference<>();
 
+        final AtomicReference<RestServer> restServer = new AtomicReference<>();
         // @formatter:off
         addAction("Control loop runtime parameters",
-            () -> ParameterService.register(clRuntimeParameterGroup),
-            () -> ParameterService.deregister(clRuntimeParameterGroup.getName()));
-
+                () -> ParameterService.register(clRuntimeParameterGroup),
+                () -> ParameterService.deregister(clRuntimeParameterGroup.getName()));
         addAction("Topic endpoint management",
-            () -> TopicEndpointManager.getManager().start(),
-            () -> TopicEndpointManager.getManager().shutdown());
-
+                () -> 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("Providers",
-            () -> instantiationHandler.get().startProviders(),
-            () -> instantiationHandler.get().stopProviders());
+                () -> instantiationHandler.set(new InstantiationHandler(clRuntimeParameterGroup)),
+                () -> instantiationHandler.get().close());
 
-        addAction("Listeners",
-            () -> instantiationHandler.get().startAndRegisterListeners(msgDispatcher),
-            () -> instantiationHandler.get().stopAndUnregisterListeners(msgDispatcher));
-
-        addAction("Publishers",
-            () -> instantiationHandler.get().startAndRegisterPublishers(topicSinks),
-            () -> instantiationHandler.get().stopAndUnregisterPublishers());
+        addHandlerActions("Commissioning", commissioningHandler);
+        addHandlerActions("Instantiation", instantiationHandler);
 
         addAction("Topic Message Dispatcher", this::registerMsgDispatcher, this::unregisterMsgDispatcher);
 
         clRuntimeParameterGroup.getRestServerParameters().setName(clRuntimeParameterGroup.getName());
 
         addAction("REST server",
-            () -> {
-                Set<Class<?>> providerClasses = instantiationHandler.get().getProviderClasses();
+                () -> {
+                    Set<Class<?>> providerClasses = new HashSet<>();
+                    providerClasses.addAll(commissioningHandler.get().getProviderClasses());
+                    providerClasses.addAll(instantiationHandler.get().getProviderClasses());
 
-                RestServer server = new RestServer(clRuntimeParameterGroup.getRestServerParameters(),
+                    RestServer server = new RestServer(clRuntimeParameterGroup.getRestServerParameters(),
                             ControlLoopAafFilter.class,
                             providerClasses.toArray(new Class<?>[providerClasses.size()]));
-
-                restServer.set(server);
-                restServer.get().start();
-            },
-            () -> restServer.get().stop());
+                    restServer.set(server);
+                    restServer.get().start();
+                },
+                () -> restServer.get().stop());
         // @formatter:on
     }
 
+    private void addHandlerActions(final String name, final AtomicReference<ControlLoopHandler> handler) {
+        addAction(name + " Providers",
+                () -> handler.get().startProviders(),
+                () -> handler.get().stopProviders());
+
+        addAction(name + " Listeners",
+                () -> handler.get().startAndRegisterListeners(msgDispatcher),
+                () -> handler.get().stopAndUnregisterListeners(msgDispatcher));
+
+        addAction(name + " Publishers",
+                () -> handler.get().startAndRegisterPublishers(topicSinks),
+                () -> handler.get().stopAndUnregisterPublishers());
+    }
+
     /**
      * Registers the dispatcher with the topic source(s).
      */
diff --git a/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/commissioning/rest/CommissioningControllerTest.java b/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/commissioning/rest/CommissioningControllerTest.java
new file mode 100644 (file)
index 0000000..fa14663
--- /dev/null
@@ -0,0 +1,202 @@
+/*-
+ * ============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 static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.core.Response;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.policy.clamp.controlloop.models.messages.rest.commissioning.CommissioningResponse;
+import org.onap.policy.clamp.controlloop.runtime.util.rest.CommonRestController;
+import org.onap.policy.common.utils.coder.YamlJsonTranslator;
+import org.onap.policy.common.utils.resources.ResourceUtils;
+import org.onap.policy.models.provider.PolicyModelsProvider;
+import org.onap.policy.models.provider.PolicyModelsProviderFactory;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+
+public class CommissioningControllerTest extends CommonRestController {
+
+    private static final String TOSCA_SERVICE_TEMPLATE_YAML =
+            "src/test/resources/servicetemplates/pmsh_multiple_cl_tosca.yaml";
+    private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator();
+    private static final String COMMISSIONING_ENDPOINT = "commission";
+    private static ToscaServiceTemplate serviceTemplate = new ToscaServiceTemplate();
+
+    /**
+     * starts Main and inserts a commissioning template.
+     *
+     * @throws Exception if an error occurs
+     */
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        CommonRestController.setUpBeforeClass("CommissioningApi");
+
+        serviceTemplate = yamlTranslator.fromYaml(ResourceUtils.getResourceAsString(TOSCA_SERVICE_TEMPLATE_YAML),
+                        ToscaServiceTemplate.class);
+    }
+
+    @AfterClass
+    public static void teardownAfterClass() {
+        CommonRestController.teardownAfterClass();
+    }
+
+    @Test
+    public void testSwagger() throws Exception {
+        super.testSwagger(COMMISSIONING_ENDPOINT);
+    }
+
+    @Test
+    public void testUnauthorizedCreate() throws Exception {
+        assertUnauthorizedPost(COMMISSIONING_ENDPOINT, Entity.json(serviceTemplate));
+    }
+
+    @Test
+    public void testUnauthorizedQuery() throws Exception {
+        assertUnauthorizedGet(COMMISSIONING_ENDPOINT);
+    }
+
+    @Test
+    public void testUnauthorizedQueryElements() throws Exception {
+        assertUnauthorizedGet(COMMISSIONING_ENDPOINT + "/elements");
+    }
+
+    @Test
+    public void testUnauthorizedDelete() throws Exception {
+        assertUnauthorizedDelete(COMMISSIONING_ENDPOINT);
+    }
+
+    @Test
+    public void testCreateBadRequest() throws Exception {
+        Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT);
+        Response resp = invocationBuilder.post(Entity.json("NotToscaServiceTempalte"));
+
+        assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus());
+        CommissioningResponse commissioningResponse = resp.readEntity(CommissioningResponse.class);
+        assertNotNull(commissioningResponse.getErrorDetails());
+        assertNull(commissioningResponse.getAffectedControlLoopDefinitions());
+    }
+
+    @Test
+    public void testCreate() throws Exception {
+        Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT);
+        Response resp = invocationBuilder.post(Entity.json(serviceTemplate));
+        assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
+        CommissioningResponse commissioningResponse = resp.readEntity(CommissioningResponse.class);
+
+        assertNotNull(commissioningResponse);
+        assertNull(commissioningResponse.getErrorDetails());
+        // Response should return the number of node templates present in the service template
+        assertThat(commissioningResponse.getAffectedControlLoopDefinitions()).hasSize(13);
+        for (String nodeTemplateName : serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().keySet()) {
+            assertTrue(commissioningResponse.getAffectedControlLoopDefinitions().stream()
+                    .anyMatch(ac -> ac.getName().equals(nodeTemplateName)));
+        }
+    }
+
+    @Test
+    public void testQuery_NoResultWithThisName() throws Exception {
+        createEntryInDB();
+
+        Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT + "?name=noResultWithThisName");
+        Response rawresp = invocationBuilder.buildGet().invoke();
+        assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+        List entityList = rawresp.readEntity(List.class);
+        assertThat(entityList).isEmpty();
+    }
+
+    @Test
+    public void testQuery() throws Exception {
+        createEntryInDB();
+
+        Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT);
+        Response rawresp = invocationBuilder.buildGet().invoke();
+        assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+        List entityList = rawresp.readEntity(List.class);
+        assertNotNull(entityList);
+        assertThat(entityList).hasSize(2);
+    }
+
+    @Test
+    public void testQueryElementsBadRequest() throws Exception {
+        createEntryInDB();
+
+        //Call get elements with no info
+        Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT + "/elements");
+        Response resp = invocationBuilder.buildGet().invoke();
+        assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), resp.getStatus());
+    }
+
+    @Test
+    public void testQueryElements() throws Exception {
+        createEntryInDB();
+
+        Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT + "/elements"
+                + "?name=org.onap.domain.pmsh.PMSHControlLoopDefinition");
+        Response rawresp = invocationBuilder.buildGet().invoke();
+        assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+        List entityList = rawresp.readEntity(List.class);
+        assertNotNull(entityList);
+        assertThat(entityList).hasSize(4);
+    }
+
+    @Test
+    public void testDeleteBadRequest() throws Exception {
+        createEntryInDB();
+
+        Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT);
+        //Call delete with no info
+        Response resp = invocationBuilder.delete();
+        assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), resp.getStatus());
+    }
+
+    @Test
+    public void testDelete() throws Exception {
+        createEntryInDB();
+
+        Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT + "?name="
+                + serviceTemplate.getName() + "&version=" + serviceTemplate.getVersion());
+        //Call delete with no info
+        Response resp = invocationBuilder.delete();
+        assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
+
+        try (PolicyModelsProvider modelsProvider = new PolicyModelsProviderFactory()
+                .createPolicyModelsProvider(CommonRestController.getParameters())) {
+            List<ToscaServiceTemplate> templatesInDB = modelsProvider.getServiceTemplateList(null, null);
+            assertThat(templatesInDB).isEmpty();
+        }
+    }
+
+    private synchronized void createEntryInDB() throws Exception {
+        try (PolicyModelsProvider modelsProvider = new PolicyModelsProviderFactory()
+                .createPolicyModelsProvider(CommonRestController.getParameters())) {
+            modelsProvider.createServiceTemplate(serviceTemplate);
+        }
+    }
+}
index 9244c7a..eaeefb3 100644 (file)
@@ -112,7 +112,7 @@ public class InstantiationControllerTest extends CommonRestController {
     }
 
     @Test
-    public void testComand_Unauthorized() throws Exception {
+    public void testCommand_Unauthorized() throws Exception {
         InstantiationCommand instantiationCommand = InstantiationUtils
                 .getInstantiationCommandFromResource(CL_INSTANTIATION_CHANGE_STATE_JSON, "Unauthorized");
 
@@ -274,14 +274,14 @@ public class InstantiationControllerTest extends CommonRestController {
     }
 
     @Test
-    public void testComand_NotFound1() throws Exception {
+    public void testCommand_NotFound1() throws Exception {
         Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_COMMAND_ENDPOINT);
         Response resp = invocationBuilder.put(Entity.json(new InstantiationCommand()));
         assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus());
     }
 
     @Test
-    public void testComand_NotFound2() throws Exception {
+    public void testCommand_NotFound2() throws Exception {
         InstantiationCommand command =
                 InstantiationUtils.getInstantiationCommandFromResource(CL_INSTANTIATION_CHANGE_STATE_JSON, "Command");
         command.setOrderedState(null);