aboutsummaryrefslogtreecommitdiffstats
path: root/participant/participant-impl/participant-impl-acelement
diff options
context:
space:
mode:
Diffstat (limited to 'participant/participant-impl/participant-impl-acelement')
-rw-r--r--participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/config/FilterConfig.java44
-rw-r--r--participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/MessageHandler.java10
-rw-r--r--participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/MessagePublisher.java4
-rw-r--r--participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/rest/AbstractRestController.java96
-rw-r--r--participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/rest/AcElementController.java177
-rw-r--r--participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/rest/GlobalControllerExceptionHandler.java6
-rw-r--r--participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/ConfigService.java6
-rw-r--r--participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/rest/AcElementControllerTest.java169
-rw-r--r--participant/participant-impl/participant-impl-acelement/src/test/resources/config.json14
9 files changed, 510 insertions, 16 deletions
diff --git a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/config/FilterConfig.java b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/config/FilterConfig.java
new file mode 100644
index 000000000..1b447a0d5
--- /dev/null
+++ b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/config/FilterConfig.java
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 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.acm.element.config;
+
+import org.onap.policy.clamp.common.acm.rest.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<RequestResponseLoggingFilter> loggingFilter() {
+ FilterRegistrationBean<RequestResponseLoggingFilter> registrationBean = new FilterRegistrationBean<>();
+
+ registrationBean.setFilter(new RequestResponseLoggingFilter());
+ registrationBean.addUrlPatterns("/onap/policy/clamp/acelement/v2/*");
+ return registrationBean;
+ }
+}
diff --git a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/MessageHandler.java b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/MessageHandler.java
index 540c133f0..63b0ebcfd 100644
--- a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/MessageHandler.java
+++ b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/MessageHandler.java
@@ -29,10 +29,10 @@ import lombok.Getter;
import lombok.NonNull;
import org.onap.policy.clamp.acm.element.main.parameters.AcElement;
import org.onap.policy.clamp.acm.element.service.ElementService;
+import org.onap.policy.clamp.common.acm.exception.AutomationCompositionRuntimeException;
import org.onap.policy.clamp.models.acm.messages.dmaap.element.ElementMessage;
import org.onap.policy.clamp.models.acm.messages.rest.element.ElementConfig;
import org.onap.policy.clamp.models.acm.messages.rest.element.ElementType;
-import org.onap.policy.models.base.PfModelRuntimeException;
import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
import org.springframework.stereotype.Component;
@@ -75,10 +75,10 @@ public class MessageHandler {
*/
public void update(@NonNull ElementConfig elementConfig) {
if (elementType == null) {
- throw new PfModelRuntimeException(Response.Status.CONFLICT, "ElementType not defined!");
+ throw new AutomationCompositionRuntimeException(Response.Status.CONFLICT, "ElementType not defined!");
}
if (!elementType.equals(elementConfig.getElementType())) {
- throw new PfModelRuntimeException(Response.Status.CONFLICT, "wrong ElementType!");
+ throw new AutomationCompositionRuntimeException(Response.Status.CONFLICT, "wrong ElementType!");
}
getActiveService().update(elementConfig);
}
@@ -90,11 +90,11 @@ public class MessageHandler {
*/
public ElementService getActiveService() {
if (elementType == null) {
- throw new PfModelRuntimeException(Response.Status.CONFLICT, "ElementType not defined!");
+ throw new AutomationCompositionRuntimeException(Response.Status.CONFLICT, "ElementType not defined!");
}
var service = map.get(elementType);
if (service == null) {
- throw new PfModelRuntimeException(Response.Status.CONFLICT, "ElementService not found!");
+ throw new AutomationCompositionRuntimeException(Response.Status.CONFLICT, "ElementService not found!");
}
return service;
}
diff --git a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/MessagePublisher.java b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/MessagePublisher.java
index ef0a72f1f..928a4fe04 100644
--- a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/MessagePublisher.java
+++ b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/handler/MessagePublisher.java
@@ -22,10 +22,10 @@ package org.onap.policy.clamp.acm.element.handler;
import java.util.List;
import javax.ws.rs.core.Response;
+import org.onap.policy.clamp.common.acm.exception.AutomationCompositionRuntimeException;
import org.onap.policy.clamp.models.acm.messages.dmaap.element.ElementMessage;
import org.onap.policy.common.endpoints.event.comm.TopicSink;
import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClient;
-import org.onap.policy.models.base.PfModelRuntimeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@@ -58,7 +58,7 @@ public class MessagePublisher {
*/
public void publishMsg(final ElementMessage msg) {
if (!active) {
- throw new PfModelRuntimeException(Response.Status.CONFLICT, NOT_ACTIVE_TEXT);
+ throw new AutomationCompositionRuntimeException(Response.Status.CONFLICT, NOT_ACTIVE_TEXT);
}
topicSinkClient.send(msg);
diff --git a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/rest/AbstractRestController.java b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/rest/AbstractRestController.java
new file mode 100644
index 000000000..408458f99
--- /dev/null
+++ b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/rest/AbstractRestController.java
@@ -0,0 +1,96 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 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.acm.element.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 javax.ws.rs.core.MediaType;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+/**
+ * Common superclass to provide REST endpoints for the AC element.
+ */
+// @formatter:off
+@RequestMapping(
+ value = "/v2",
+ produces = {
+ MediaType.APPLICATION_JSON,
+ AbstractRestController.APPLICATION_YAML
+ }
+)
+@Api(value = "AC Element API")
+@SwaggerDefinition(
+ info = @Info(
+ description = "AC Element",
+ version = "v1.0",
+ title = "AC Element"
+ ),
+ consumes = {MediaType.APPLICATION_JSON, AbstractRestController.APPLICATION_YAML},
+ produces = {MediaType.APPLICATION_JSON, AbstractRestController.APPLICATION_YAML},
+ schemes = {SwaggerDefinition.Scheme.HTTP, SwaggerDefinition.Scheme.HTTPS},
+ tags = {
+ @Tag(name = "acelement", description = "Ac element implementation")
+ },
+ 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 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";
+
+} \ No newline at end of file
diff --git a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/rest/AcElementController.java b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/rest/AcElementController.java
index 833819a13..7a8662c34 100644
--- a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/rest/AcElementController.java
+++ b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/rest/AcElementController.java
@@ -20,10 +20,181 @@
package org.onap.policy.clamp.acm.element.main.rest;
+import io.swagger.annotations.ApiOperation;
+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 lombok.RequiredArgsConstructor;
+import org.onap.policy.clamp.acm.element.service.ConfigService;
+import org.onap.policy.clamp.models.acm.messages.rest.element.ElementConfig;
+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.RestController;
@RestController
-public class AcElementController {
+@RequiredArgsConstructor
+public class AcElementController extends AbstractRestController {
- //TODO : Implement REST methods for configuring Dmaap topic
-}
+ private final ConfigService configService;
+
+
+ /**
+ * REST endpoint to get the existing element config.
+ *
+ * @return the element config params
+ */
+ // @formatter:off
+ @GetMapping(path = "/config", produces = MediaType.APPLICATION_JSON_VALUE)
+ @ApiOperation(
+ value = "Return the element config",
+ response = ElementConfig.class,
+ tags = {
+ "Clamp Automation Composition AC Element Impl 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<ElementConfig> getElementConfig() {
+ return new ResponseEntity<>(configService.getElementConfig(), HttpStatus.OK);
+ }
+
+ /**
+ * REST endpoint to activate the element.
+ *
+ * @param params element parameters for this ac element
+ */
+ // @formatter:off
+ @PostMapping(path = "/activate", consumes = MediaType.APPLICATION_JSON_VALUE,
+ produces = MediaType.APPLICATION_JSON_VALUE)
+ @ApiOperation(
+ value = "Activates the element config",
+ response = ElementConfig.class,
+ tags = {
+ "Clamp Automation Composition AC Element Impl 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<Object> activateElement(@RequestBody ElementConfig params) {
+ configService.activateElement(params);
+ return new ResponseEntity<>(HttpStatus.CREATED);
+ }
+
+ /**
+ * REST endpoint to delete the element config.
+ *
+ * @return Status of operation
+ */
+ // @formatter:off
+ @DeleteMapping(path = "/deactivate")
+ @ApiOperation(
+ value = "Delete the element config",
+ response = ElementConfig.class,
+ tags = {
+ "Clamp Automation Composition AC Element Impl 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<Object> deleteConfig() {
+ configService.deleteConfig();
+ return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+
+ }
+} \ No newline at end of file
diff --git a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/rest/GlobalControllerExceptionHandler.java b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/rest/GlobalControllerExceptionHandler.java
index bb56bf993..41dcbef81 100644
--- a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/rest/GlobalControllerExceptionHandler.java
+++ b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/main/rest/GlobalControllerExceptionHandler.java
@@ -22,7 +22,7 @@
package org.onap.policy.clamp.acm.element.main.rest;
-import org.onap.policy.clamp.common.acm.exception.AutomationCompositionException;
+import org.onap.policy.clamp.common.acm.exception.AutomationCompositionRuntimeException;
import org.onap.policy.clamp.models.acm.messages.rest.SimpleResponse;
import org.onap.policy.clamp.models.acm.rest.RestUtils;
import org.springframework.http.ResponseEntity;
@@ -38,8 +38,8 @@ public class GlobalControllerExceptionHandler {
* @param ex AutomationCompositionException
* @return ResponseEntity
*/
- @ExceptionHandler(AutomationCompositionException.class)
- public ResponseEntity<SimpleResponse> handleBadRequest(AutomationCompositionException ex) {
+ @ExceptionHandler(AutomationCompositionRuntimeException.class)
+ public ResponseEntity<SimpleResponse> handleBadRequest(AutomationCompositionRuntimeException ex) {
return RestUtils.toSimpleResponse(ex);
}
}
diff --git a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/ConfigService.java b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/ConfigService.java
index f542be201..f8f9024f8 100644
--- a/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/ConfigService.java
+++ b/participant/participant-impl/participant-impl-acelement/src/main/java/org/onap/policy/clamp/acm/element/service/ConfigService.java
@@ -26,11 +26,11 @@ import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.onap.policy.clamp.acm.element.handler.MessageActivator;
import org.onap.policy.clamp.acm.element.handler.MessageHandler;
+import org.onap.policy.clamp.common.acm.exception.AutomationCompositionRuntimeException;
import org.onap.policy.clamp.models.acm.messages.dmaap.element.ElementMessage;
import org.onap.policy.clamp.models.acm.messages.rest.element.ElementConfig;
import org.onap.policy.common.endpoints.parameters.TopicParameterGroup;
import org.onap.policy.common.endpoints.parameters.TopicParameters;
-import org.onap.policy.models.base.PfModelRuntimeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
@@ -64,12 +64,12 @@ public class ConfigService {
parameters.setTopicSources(List.of(topicParameters));
if (!parameters.isValid()) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
+ throw new AutomationCompositionRuntimeException(Response.Status.BAD_REQUEST,
"Validation failed for topic parameter group. Kafka config not activated");
}
if (messageActivator.isAlive()) {
- throw new PfModelRuntimeException(Response.Status.CONFLICT,
+ throw new AutomationCompositionRuntimeException(Response.Status.CONFLICT,
"Service Manager already running, cannot add Topic endpoint management");
}
diff --git a/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/rest/AcElementControllerTest.java b/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/rest/AcElementControllerTest.java
new file mode 100644
index 000000000..c40cdeabc
--- /dev/null
+++ b/participant/participant-impl/participant-impl-acelement/src/test/java/org/onap/policy/clamp/acm/element/rest/AcElementControllerTest.java
@@ -0,0 +1,169 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 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.acm.element.rest;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.when;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import javax.ws.rs.core.Response;
+import org.apache.commons.io.FileUtils;
+import org.json.JSONObject;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.onap.policy.clamp.acm.element.main.parameters.AcElement;
+import org.onap.policy.clamp.acm.element.main.rest.AcElementController;
+import org.onap.policy.clamp.acm.element.service.ConfigService;
+import org.onap.policy.clamp.common.acm.exception.AutomationCompositionRuntimeException;
+import org.onap.policy.clamp.models.acm.messages.rest.element.ElementConfig;
+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.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+
+@ExtendWith(SpringExtension.class)
+@WebMvcTest(value = AcElementController.class)
+@EnableConfigurationProperties(value = AcElement.class)
+class AcElementControllerTest {
+
+ private static final Coder CODER = new StandardCoder();
+ private static final String ELEMENT_CONFIG_YAML = "src/test/resources/config.json";
+ private static final String RETRIEVE_CONFIG = "/v2/config";
+ private static final String ACTIVATE_CONFIG = "/v2/activate";
+ private static final String DEACTIVATE_CONFIG = "/v2/deactivate";
+ private static ElementConfig config;
+
+
+ @Autowired
+ private MockMvc mockMvc;
+
+ @MockBean
+ private ConfigService configService;
+
+ @Autowired
+ private WebApplicationContext context;
+
+ /**
+ * Read input element config json.
+ * @throws CoderException in case of error.
+ */
+ @BeforeAll
+ static void setupParams() throws CoderException {
+ config = CODER.decode(new File(ELEMENT_CONFIG_YAML), ElementConfig.class);
+ }
+
+ /**
+ * Mock service layer in Controller.
+ */
+ @BeforeEach
+ void mockServiceClass() {
+ this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build();
+ when(configService.getElementConfig()).thenReturn(config);
+ }
+
+ /**
+ * Test endpoint for retrieving element config.
+ * @throws Exception in case of error.
+ */
+ @Test
+ void retrieveElementConfig() throws Exception {
+ var requestBuilder = MockMvcRequestBuilders.get(RETRIEVE_CONFIG)
+ .accept(MediaType.APPLICATION_JSON_VALUE);
+
+ mockMvc.perform(requestBuilder).andExpect(status().isOk())
+ .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
+ .andExpect(jsonPath("$.elementType", is("STARTER")));
+ }
+
+ /**
+ * Test endpoint for activating element config.
+ * @throws Exception in case of error.
+ */
+ @Test
+ void activateConfig() throws Exception {
+ //Mocking successful activation of element config
+ doNothing().when(configService).activateElement(config);
+
+ var requestBuilder = MockMvcRequestBuilders.post(ACTIVATE_CONFIG)
+ .accept(MediaType.APPLICATION_JSON_VALUE)
+ .content(getElementConfigJson())
+ .contentType(MediaType.APPLICATION_JSON_VALUE);
+
+ mockMvc.perform(requestBuilder).andExpect(status().isCreated());
+
+ doThrow(new AutomationCompositionRuntimeException(Response.Status.CONFLICT, "service manager already running"))
+ .when(configService).activateElement(any());
+
+ //Activate Invalid config, expects HTTP status CONFLICT
+ requestBuilder = MockMvcRequestBuilders.post(ACTIVATE_CONFIG).accept(MediaType.APPLICATION_JSON_VALUE)
+ .content(getInvalidJson())
+ .contentType(MediaType.APPLICATION_JSON_VALUE);
+
+ mockMvc.perform(requestBuilder).andExpect(status().isConflict())
+ .andExpect(result -> assertEquals("service manager already running",
+ result.getResolvedException().getMessage()));
+ }
+
+ /**
+ * Test endpoint for deactivating element config.
+ * @throws Exception in case of error.
+ */
+ @Test
+ void deActivateConfig() throws Exception {
+
+ //Mocking successful deactivation of element config
+ doNothing().when(configService).deleteConfig();
+
+ var requestBuilder = MockMvcRequestBuilders.delete(DEACTIVATE_CONFIG);
+
+ mockMvc.perform(requestBuilder).andExpect(status().isNoContent());
+ }
+
+ private String getInvalidJson() {
+ return new JSONObject().toString();
+ }
+
+ private String getElementConfigJson() throws IOException {
+ return FileUtils.readFileToString(new File(ELEMENT_CONFIG_YAML), StandardCharsets.UTF_8);
+ }
+
+}
diff --git a/participant/participant-impl/participant-impl-acelement/src/test/resources/config.json b/participant/participant-impl/participant-impl-acelement/src/test/resources/config.json
new file mode 100644
index 000000000..bf4518255
--- /dev/null
+++ b/participant/participant-impl/participant-impl-acelement/src/test/resources/config.json
@@ -0,0 +1,14 @@
+{
+ "elementId":{
+ "name":"onap.policy.clamp.ac.element2",
+ "version":"1.0.0"
+ },
+ "timerSec":2000,
+ "elementType":"STARTER",
+ "topicParameterGroup":{
+ "server":"localhost",
+ "topic":"POLICY_UPDATE_MSG",
+ "fetchTimeout":15000,
+ "topicCommInfrastructure":"dmaap"
+ }
+} \ No newline at end of file