Add DME Participant 48/11948/1
authoraravind.est <aravindhan.a@est.tech>
Fri, 20 Oct 2023 14:22:31 +0000 (15:22 +0100)
committeraravind.est <aravindhan.a@est.tech>
Fri, 20 Oct 2023 14:33:57 +0000 (15:33 +0100)
DME participant interacts with ICS to lifecycle manage ICS entities.
Dockerfile added for creating docker images.

Issue-ID: NONRTRIC-952
Signed-off-by: aravind.est <aravindhan.a@est.tech>
Change-Id: I4093678f80714cc7b481109e1861f67050fb9523

24 files changed:
participants/participant-impl-dme/Dockerfile [new file with mode: 0755]
participants/participant-impl-dme/pom.xml [new file with mode: 0755]
participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/Application.java [new file with mode: 0755]
participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/BeanConfiguration.java [new file with mode: 0755]
participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/config/MicrometerConfig.java [new file with mode: 0755]
participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/config/SecurityConfig.java [new file with mode: 0755]
participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/exception/DmeException.java [new file with mode: 0755]
participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/handler/AutomationCompositionElementHandler.java [new file with mode: 0755]
participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/models/ConfigurationEntity.java [new file with mode: 0755]
participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/models/DataConsumerEntity.java [new file with mode: 0755]
participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/models/DataProducerEntity.java [new file with mode: 0755]
participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/models/InfoTypeEntity.java [new file with mode: 0755]
participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/parameters/DmeParameters.java [new file with mode: 0755]
participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/parameters/DmeParticipantParameters.java [new file with mode: 0755]
participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/restclient/AcDmeClient.java [new file with mode: 0755]
participants/participant-impl-dme/src/main/resources/application.yaml [new file with mode: 0755]
participants/participant-impl-dme/src/test/java/org/oransc/participant/dme/handler/AcElementHandlerTest.java [new file with mode: 0755]
participants/participant-impl-dme/src/test/java/org/oransc/participant/dme/rest/ActuatorControllerTest.java [new file with mode: 0755]
participants/participant-impl-dme/src/test/java/org/oransc/participant/dme/restclient/AcA1PmsClientTest.java [new file with mode: 0755]
participants/participant-impl-dme/src/test/java/org/oransc/participant/dme/utils/CommonActuatorController.java [new file with mode: 0755]
participants/participant-impl-dme/src/test/java/org/oransc/participant/dme/utils/CommonTestData.java [new file with mode: 0755]
participants/participant-impl-dme/src/test/java/org/oransc/participant/dme/utils/ToscaUtils.java [new file with mode: 0755]
participants/participant-impl-dme/src/test/resources/participant-dme.yaml [new file with mode: 0755]
participants/pom.xml [new file with mode: 0755]

diff --git a/participants/participant-impl-dme/Dockerfile b/participants/participant-impl-dme/Dockerfile
new file mode 100755 (executable)
index 0000000..7f95151
--- /dev/null
@@ -0,0 +1,58 @@
+#
+# ============LICENSE_START=======================================================
+#  Copyright (C) 2023 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=========================================================
+#
+FROM openjdk:17-jdk as jre-build
+
+RUN $JAVA_HOME/bin/jlink \
+--verbose \
+--add-modules ALL-MODULE-PATH \
+--strip-debug \
+--no-man-pages \
+--no-header-files \
+--compress=2 \
+--output /customjre
+
+# Use debian base image (same as openjdk uses)
+FROM debian:11-slim
+
+ENV JAVA_HOME=/jre
+ENV PATH="${JAVA_HOME}/bin:${PATH}"
+
+#copy JRE from the base image
+COPY --from=jre-build /customjre $JAVA_HOME
+
+ARG JAR
+
+WORKDIR /opt/app/participant/dme
+
+EXPOSE 8080
+
+ADD src/main/resources/application.yaml /opt/app/participant/dme/application.yaml
+ADD target/${JAR} /opt/app/participant/dme/participant-impl-dme.jar
+
+ARG user=nonrtric
+ARG group=nonrtric
+
+RUN groupadd $user && \
+    useradd -r -g $group $user
+RUN chown -R $user:$group /opt/app/participant/dme
+
+USER ${user}
+
+CMD ["/jre/bin/java", "-jar", "/opt/app/participant/dme/participant-impl-dme.jar"]
diff --git a/participants/participant-impl-dme/pom.xml b/participants/participant-impl-dme/pom.xml
new file mode 100755 (executable)
index 0000000..a856bd2
--- /dev/null
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+* ========================LICENSE_START=================================
+* O-RAN-SC
+* %%
+* Copyright (C) 2023 Nordix Foundation
+* %%
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+* ========================LICENSE_END===================================
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.o-ran-sc.nonrtric.plt</groupId>
+        <artifactId>participants</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+    </parent>
+
+    <groupId>org.o-ran-sc.nonrtric.plt.participants</groupId>
+    <artifactId>participant-impl-dme</artifactId>
+
+    <properties>
+        <maven.compiler.source>17</maven.compiler.source>
+        <maven.compiler.target>17</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onap.policy.clamp.participant</groupId>
+            <artifactId>policy-clamp-participant-intermediary</artifactId>
+            <version>${onap.acm.models.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.policy.clamp</groupId>
+            <artifactId>policy-clamp-models</artifactId>
+            <version>${onap.acm.models.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-registry-prometheus</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.openapitools</groupId>
+            <artifactId>jackson-databind-nullable</artifactId>
+            <version>${openapi.jackson.databind.nullable.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                        <phase>package</phase>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.openapitools</groupId>
+                <artifactId>openapi-generator-maven-plugin</artifactId>
+                <version>${openapi.maven.version}</version>
+                <executions>
+                    <execution>
+                        <id>dme-participant-spec-generator</id>
+                        <goals>
+                            <goal>generate</goal>
+                        </goals>
+                        <configuration>
+                            <inputSpec>${project.parent.basedir}/../openapi/dme/ics-api.yaml</inputSpec>
+                            <generatorName>java</generatorName>
+                            <library>resttemplate</library>
+                            <generateApiTests>false</generateApiTests>
+                            <generateModelTests>false</generateModelTests>
+                            <generateApiDocumentation>false</generateApiDocumentation>
+                            <generateModelDocumentation>false</generateModelDocumentation>
+                            <generateModels>true</generateModels>
+                            <additionalProperties>
+                                <additionalProperty>apiNameSuffix=ApiClient</additionalProperty>
+                            </additionalProperties>
+                            <configOptions>
+                                <sourceFolder>src/main/java</sourceFolder>
+                                <useJakartaEe>true</useJakartaEe>
+                                <invokerPackage>com.oransc.participant.dme</invokerPackage>
+                                <apiPackage>com.oransc.participant.dme.rest</apiPackage>
+                                <modelPackage>com.oransc.participant.dme.data</modelPackage>
+                                <generateClientAsBean>false</generateClientAsBean>
+                            </configOptions>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>io.fabric8</groupId>
+                <artifactId>docker-maven-plugin</artifactId>
+                <version>${docker-maven-plugin}</version>
+                <inherited>false</inherited>
+                <executions>
+                    <execution>
+                        <id>generate-nonrtric-plt-participant-impl-dme-image</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>build</goal>
+                        </goals>
+                        <configuration>
+                            <pullRegistry>${env.CONTAINER_PULL_REGISTRY}</pullRegistry>
+                            <images>
+                                <image>
+                                    <name>
+                                        o-ran-sc/nonrtric-plt-participant-impl-dme:${project.version}
+                                    </name>
+                                    <build>
+                                        <cleanup>try</cleanup>
+                                        <contextDir>${project.basedir}</contextDir>
+                                        <dockerFile>Dockerfile</dockerFile>
+                                        <args>
+                                            <JAR>${project.build.finalName}.jar</JAR>
+                                        </args>
+                                        <tags>
+                                            <tag>${project.version}</tag>
+                                        </tags>
+                                    </build>
+                                </image>
+                            </images>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>push-nonrtric-plt-participant-impl-dme-image</id>
+                        <goals>
+                            <goal>push</goal>
+                        </goals>
+                        <configuration>
+                            <pushRegistry>${env.CONTAINER_PUSH_REGISTRY}</pushRegistry>
+                            <images>
+                                <image>
+                                    <name>
+                                        o-ran-sc/nonrtric-plt-participant-impl-dme:${project.version}
+                                    </name>
+                                    <build>
+                                        <contextDir>${project.basedir}</contextDir>
+                                        <dockerFile>Dockerfile</dockerFile>
+                                        <args>
+                                            <JAR>${project.build.finalName}.jar</JAR>
+                                        </args>
+                                        <tags>
+                                            <tag>${project.version}</tag>
+                                            <tag>latest</tag>
+                                        </tags>
+                                    </build>
+                                </image>
+                            </images>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/Application.java b/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/Application.java
new file mode 100755 (executable)
index 0000000..73fd5a6
--- /dev/null
@@ -0,0 +1,36 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.oransc.participant.dme;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
+import org.springframework.context.annotation.ComponentScan;
+
+@SpringBootApplication
+@ComponentScan({"org.oransc.participant.dme", "org.onap.policy.clamp.acm.participant.intermediary"})
+@ConfigurationPropertiesScan("org.oransc.participant.dme.parameters")
+public class Application {
+
+    public static void main(String[] args) {
+        SpringApplication.run(Application.class, args);
+    }
+}
diff --git a/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/BeanConfiguration.java b/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/BeanConfiguration.java
new file mode 100755 (executable)
index 0000000..ac8296c
--- /dev/null
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.oransc.participant.dme;
+
+import com.oransc.participant.dme.rest.DataConsumerApiClient;
+import com.oransc.participant.dme.rest.DataProducerRegistrationApiClient;
+import lombok.RequiredArgsConstructor;
+import org.oransc.participant.dme.parameters.DmeParameters;
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.client.RestTemplate;
+
+@Configuration
+@RequiredArgsConstructor
+public class BeanConfiguration {
+
+    private final DmeParameters dmeParameters;
+
+    @Bean
+    public RestTemplate restTemplate(RestTemplateBuilder builder) {
+        return builder.build();
+    }
+
+    @Bean
+    public com.oransc.participant.dme.ApiClient dmeApiClient(RestTemplate restTemplate) {
+        com.oransc.participant.dme.ApiClient apiClient = new com.oransc.participant.dme.ApiClient(restTemplate);
+        return apiClient.setBasePath(dmeParameters.getBaseUrl());
+    }
+
+    @Bean
+    public DataProducerRegistrationApiClient dataProducerRegistrationApiClient(
+            com.oransc.participant.dme.ApiClient apiClient) {
+        return new DataProducerRegistrationApiClient(apiClient);
+    }
+
+    @Bean
+    public DataConsumerApiClient dataConsumerApiClient(com.oransc.participant.dme.ApiClient apiClient) {
+        return new DataConsumerApiClient(apiClient);
+    }
+}
diff --git a/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/config/MicrometerConfig.java b/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/config/MicrometerConfig.java
new file mode 100755 (executable)
index 0000000..77f7da0
--- /dev/null
@@ -0,0 +1,43 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2023 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.oransc.participant.dme.config;
+
+import io.micrometer.core.aop.TimedAspect;
+import io.micrometer.core.instrument.MeterRegistry;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class MicrometerConfig {
+
+    @Bean
+    public InitializingBean forcePrometheusPostProcessor(BeanPostProcessor meterRegistryPostProcessor,
+            MeterRegistry registry) {
+        return () -> meterRegistryPostProcessor.postProcessAfterInitialization(registry, "");
+    }
+
+    @Bean
+    public TimedAspect timedAspect(MeterRegistry registry) {
+        return new TimedAspect(registry);
+    }
+}
diff --git a/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/config/SecurityConfig.java b/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/config/SecurityConfig.java
new file mode 100755 (executable)
index 0000000..53df1d0
--- /dev/null
@@ -0,0 +1,38 @@
+/*-
+ * ========================LICENSE_START=================================
+ * Copyright (C) 2023 Nordix Foundation.
+ * ======================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================LICENSE_END===================================
+ */
+
+package org.oransc.participant.dme.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.Customizer;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
+import org.springframework.security.web.SecurityFilterChain;
+
+@Configuration
+public class SecurityConfig {
+    @Bean
+    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
+        http
+                .httpBasic(Customizer.withDefaults())
+                .authorizeHttpRequests(authorize -> authorize.anyRequest().authenticated())
+                .csrf(AbstractHttpConfigurer::disable);
+        return http.build();
+    }
+}
diff --git a/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/exception/DmeException.java b/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/exception/DmeException.java
new file mode 100755 (executable)
index 0000000..5a7861e
--- /dev/null
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.oransc.participant.dme.exception;
+
+import jakarta.ws.rs.core.Response;
+import java.io.Serial;
+import org.onap.policy.models.base.PfModelException;
+
+public class DmeException extends PfModelException {
+
+    @Serial
+    private static final long serialVersionUID = 6438746904567105054L;
+
+    public DmeException(int statusCode, String message) {
+        super(Response.Status.fromStatusCode(statusCode), message);
+    }
+
+    public DmeException(int statusCode, String message, Exception e) {
+        super(Response.Status.fromStatusCode(statusCode), message, e);
+    }
+}
diff --git a/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/handler/AutomationCompositionElementHandler.java b/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/handler/AutomationCompositionElementHandler.java
new file mode 100755 (executable)
index 0000000..612295e
--- /dev/null
@@ -0,0 +1,218 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.oransc.participant.dme.handler;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import jakarta.validation.Validation;
+import jakarta.validation.ValidationException;
+import java.lang.invoke.MethodHandles;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.http.HttpStatus;
+import org.onap.policy.clamp.acm.participant.intermediary.api.AutomationCompositionElementListener;
+import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi;
+import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy;
+import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition;
+import org.onap.policy.clamp.models.acm.concepts.DeployState;
+import org.onap.policy.clamp.models.acm.concepts.LockState;
+import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
+import org.onap.policy.clamp.models.acm.utils.AcmUtils;
+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.models.base.PfModelException;
+import org.oransc.participant.dme.exception.DmeException;
+import org.oransc.participant.dme.models.ConfigurationEntity;
+import org.oransc.participant.dme.models.DataConsumerEntity;
+import org.oransc.participant.dme.models.DataProducerEntity;
+import org.oransc.participant.dme.models.InfoTypeEntity;
+import org.oransc.participant.dme.restclient.AcDmeClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+@RequiredArgsConstructor
+public class AutomationCompositionElementHandler implements AutomationCompositionElementListener {
+
+    private static final Coder CODER = new StandardCoder();
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+    private final ParticipantIntermediaryApi intermediaryApi;
+
+    private final AcDmeClient acDmeClient;
+
+    // Map of acElement Id and DME services
+    @Getter(AccessLevel.PACKAGE)
+    private final Map<UUID, ConfigurationEntity> configRequestMap = new ConcurrentHashMap<>();
+
+    @Override
+    public void undeploy(UUID automationCompositionId, UUID automationCompositionElementId) throws DmeException {
+        var configurationEntity = configRequestMap.get(automationCompositionElementId);
+        if (configurationEntity != null && acDmeClient.isDmeHealthy()) {
+            if (configurationEntity.getDataConsumerEntities() != null) {
+                acDmeClient.deleteDataConsumer(configurationEntity.getDataConsumerEntities().stream()
+                                                       .map(DataConsumerEntity::getDataConsumerId)
+                                                       .collect(Collectors.toSet()));
+            }
+            if (configurationEntity.getDataProducerEntities() != null) {
+                acDmeClient.deleteDataProducer(configurationEntity.getDataProducerEntities().stream()
+                                                       .map(DataProducerEntity::getDataProducerId)
+                                                       .collect(Collectors.toSet()));
+            }
+            configRequestMap.remove(automationCompositionElementId);
+            intermediaryApi.updateAutomationCompositionElementState(automationCompositionId,
+                    automationCompositionElementId, DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR,
+                    "Undeployed");
+        } else {
+            LOGGER.warn("Failed to connect with DME. Service configuration is: {}", configurationEntity);
+            throw new DmeException(HttpStatus.SC_SERVICE_UNAVAILABLE, "Unable to connect with DME");
+        }
+    }
+
+    @Override
+    public void deploy(UUID automationCompositionId, AcElementDeploy element, Map<String, Object> properties)
+            throws DmeException {
+        try {
+            var configurationEntity = CODER.convert(properties, ConfigurationEntity.class);
+            var violations = Validation.buildDefaultValidatorFactory().getValidator().validate(configurationEntity);
+            if (violations.isEmpty()) {
+                if ((configurationEntity.getInfoTypeEntities() != null
+                             || configurationEntity.getDataProducerEntities() != null
+                             || configurationEntity.getDataConsumerEntities() != null) && acDmeClient.isDmeHealthy()) {
+                    if (configurationEntity.getInfoTypeEntities() != null) {
+                        acDmeClient.createInfoType(configurationEntity.getInfoTypeEntities().stream().collect(
+                                Collectors.toMap(InfoTypeEntity::getInfoTypeId, InfoTypeEntity::getPayload)));
+                    }
+                    if (configurationEntity.getDataProducerEntities() != null) {
+                        acDmeClient.createDataProducer(configurationEntity.getDataProducerEntities().stream().collect(
+                                Collectors.toMap(DataProducerEntity::getDataProducerId,
+                                        DataProducerEntity::getPayload)));
+                    }
+                    if (configurationEntity.getDataConsumerEntities() != null) {
+                        acDmeClient.createDataConsumer(configurationEntity.getDataConsumerEntities().stream().collect(
+                                Collectors.toMap(DataConsumerEntity::getDataConsumerId,
+                                        DataConsumerEntity::getPayload)));
+                    }
+
+                    configRequestMap.put(element.getId(), configurationEntity);
+                    intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(),
+                            DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Deployed");
+                } else {
+                    intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(),
+                            DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "Unable to connect with DME ");
+                    throw new DmeException(HttpStatus.SC_SERVICE_UNAVAILABLE, "Unable to connect with DME");
+                }
+            } else {
+                LOGGER.error("Violations found in the config request parameters: {}", violations);
+                throw new ValidationException("Constraint violations in the config request");
+            }
+        } catch (JsonProcessingException | ValidationException | CoderException | DmeException e) {
+            intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(),
+                    DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, e.getMessage());
+            throw new DmeException(HttpStatus.SC_BAD_REQUEST, "Invalid Configuration", e);
+        }
+    }
+
+    @Override
+    public void lock(UUID instanceId, UUID elementId) {
+        intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId, null, LockState.LOCKED,
+                StateChangeResult.NO_ERROR, "Locked");
+    }
+
+    @Override
+    public void unlock(UUID instanceId, UUID elementId) {
+        intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId, null, LockState.UNLOCKED,
+                StateChangeResult.NO_ERROR, "Unlocked");
+    }
+
+    @Override
+    public void delete(UUID instanceId, UUID elementId) {
+        intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId, DeployState.DELETED, null,
+                StateChangeResult.NO_ERROR, "Deleted");
+    }
+
+    @Override
+    public void update(UUID instanceId, AcElementDeploy element, Map<String, Object> properties) {
+        intermediaryApi.updateAutomationCompositionElementState(instanceId, element.getId(), DeployState.DEPLOYED, null,
+                StateChangeResult.NO_ERROR, "Update not supported");
+    }
+
+    @Override
+    public void prime(UUID compositionId, List<AutomationCompositionElementDefinition> elementDefinitionList) {
+        intermediaryApi.updateCompositionState(compositionId, AcTypeState.PRIMED, StateChangeResult.NO_ERROR, "Primed");
+    }
+
+    @Override
+    public void deprime(UUID compositionId) {
+        intermediaryApi.updateCompositionState(compositionId, AcTypeState.COMMISSIONED, StateChangeResult.NO_ERROR,
+                "Deprimed");
+    }
+
+    @Override
+    public void handleRestartComposition(UUID compositionId,
+            List<AutomationCompositionElementDefinition> elementDefinitionList, AcTypeState state) {
+        var finalState = AcTypeState.PRIMED.equals(state) || AcTypeState.PRIMING.equals(state) ? AcTypeState.PRIMED
+                                 : AcTypeState.COMMISSIONED;
+        intermediaryApi.updateCompositionState(compositionId, finalState, StateChangeResult.NO_ERROR, "Restarted");
+    }
+
+    @Override
+    public void handleRestartInstance(UUID automationCompositionId, AcElementDeploy element,
+            Map<String, Object> properties, DeployState deployState, LockState lockState) throws PfModelException {
+        if (DeployState.DEPLOYING.equals(deployState)) {
+            deploy(automationCompositionId, element, properties);
+            return;
+        }
+        if (DeployState.UNDEPLOYING.equals(deployState) || DeployState.DEPLOYED.equals(deployState)
+                    || DeployState.UPDATING.equals(deployState)) {
+            try {
+                var configurationEntity = CODER.convert(properties, ConfigurationEntity.class);
+                configRequestMap.put(element.getId(), configurationEntity);
+            } catch (ValidationException | CoderException e) {
+                throw new DmeException(HttpStatus.SC_BAD_REQUEST, "Invalid Configuration", e);
+            }
+        }
+        if (DeployState.UNDEPLOYING.equals(deployState)) {
+            undeploy(automationCompositionId, element.getId());
+            return;
+        }
+        deployState = AcmUtils.deployCompleted(deployState);
+        lockState = AcmUtils.lockCompleted(deployState, lockState);
+        intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(), deployState,
+                lockState, StateChangeResult.NO_ERROR, "Restarted");
+    }
+
+    @Override
+    public void migrate(UUID automationCompositionId, AcElementDeploy element, UUID compositionTargetId,
+            Map<String, Object> properties) {
+        intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(),
+                DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migrated");
+    }
+}
diff --git a/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/models/ConfigurationEntity.java b/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/models/ConfigurationEntity.java
new file mode 100755 (executable)
index 0000000..a312226
--- /dev/null
@@ -0,0 +1,40 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.oransc.participant.dme.models;
+
+import jakarta.validation.Valid;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+@Data
+@AllArgsConstructor
+public class ConfigurationEntity {
+
+    @Valid
+    private List<InfoTypeEntity> infoTypeEntities;
+
+    @Valid
+    private List<DataProducerEntity> dataProducerEntities;
+
+    @Valid
+    private List<DataConsumerEntity> dataConsumerEntities;
+}
diff --git a/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/models/DataConsumerEntity.java b/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/models/DataConsumerEntity.java
new file mode 100755 (executable)
index 0000000..381e0ff
--- /dev/null
@@ -0,0 +1,46 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.oransc.participant.dme.models;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+import jakarta.validation.constraints.NotNull;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+
+@Data
+@AllArgsConstructor
+@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
+public class DataConsumerEntity {
+
+    @NotNull
+    @JsonIgnore
+    private ToscaConceptIdentifier dataConsumerEntityId;
+
+    @NotNull
+    private String dataConsumerId;
+
+    @NotNull
+    private String payload;
+
+}
diff --git a/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/models/DataProducerEntity.java b/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/models/DataProducerEntity.java
new file mode 100755 (executable)
index 0000000..ab9b734
--- /dev/null
@@ -0,0 +1,46 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.oransc.participant.dme.models;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+import jakarta.validation.constraints.NotNull;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+
+@Data
+@AllArgsConstructor
+@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
+public class DataProducerEntity {
+
+    @NotNull
+    @JsonIgnore
+    private ToscaConceptIdentifier dataProducerEntityId;
+
+    @NotNull
+    private String dataProducerId;
+
+    @NotNull
+    private String payload;
+
+}
diff --git a/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/models/InfoTypeEntity.java b/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/models/InfoTypeEntity.java
new file mode 100755 (executable)
index 0000000..07d9735
--- /dev/null
@@ -0,0 +1,46 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.oransc.participant.dme.models;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+import jakarta.validation.constraints.NotNull;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+
+@Data
+@AllArgsConstructor
+@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
+public class InfoTypeEntity {
+
+    @NotNull
+    @JsonIgnore
+    private ToscaConceptIdentifier infoTypeEntityId;
+
+    @NotNull
+    private String infoTypeId;
+
+    @NotNull
+    private String payload;
+
+}
diff --git a/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/parameters/DmeParameters.java b/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/parameters/DmeParameters.java
new file mode 100755 (executable)
index 0000000..76581dc
--- /dev/null
@@ -0,0 +1,35 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.oransc.participant.dme.parameters;
+
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.validation.annotation.Validated;
+
+@Validated
+@Data
+@ConfigurationProperties(prefix = "dme")
+public class DmeParameters {
+
+    @NotNull
+    private String baseUrl;
+}
diff --git a/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/parameters/DmeParticipantParameters.java b/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/parameters/DmeParticipantParameters.java
new file mode 100755 (executable)
index 0000000..bfc6b0a
--- /dev/null
@@ -0,0 +1,41 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.oransc.participant.dme.parameters;
+
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotNull;
+import lombok.Getter;
+import lombok.Setter;
+import org.onap.policy.clamp.acm.participant.intermediary.parameters.ParticipantIntermediaryParameters;
+import org.onap.policy.clamp.acm.participant.intermediary.parameters.ParticipantParameters;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.validation.annotation.Validated;
+
+@Validated
+@Getter
+@Setter
+@ConfigurationProperties(prefix = "participant")
+public class DmeParticipantParameters implements ParticipantParameters {
+
+    @NotNull
+    @Valid
+    private ParticipantIntermediaryParameters intermediaryParameters;
+}
diff --git a/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/restclient/AcDmeClient.java b/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/restclient/AcDmeClient.java
new file mode 100755 (executable)
index 0000000..ab963e5
--- /dev/null
@@ -0,0 +1,107 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.oransc.participant.dme.restclient;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.oransc.participant.dme.data.ConsumerJob;
+import com.oransc.participant.dme.data.ProducerInfoTypeInfo;
+import com.oransc.participant.dme.data.ProducerRegistrationInfo;
+import com.oransc.participant.dme.rest.DataConsumerApiClient;
+import com.oransc.participant.dme.rest.DataProducerRegistrationApiClient;
+import java.util.Map;
+import java.util.Set;
+import lombok.RequiredArgsConstructor;
+import org.oransc.participant.dme.exception.DmeException;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+
+@Component
+@RequiredArgsConstructor
+public class AcDmeClient {
+
+    private final DataProducerRegistrationApiClient dataProducerRegistrationApiClient;
+    private final DataConsumerApiClient dataConsumerApiClient;
+    private final ObjectMapper objectMapper;
+
+    public boolean isDmeHealthy() {
+        return dataProducerRegistrationApiClient.getInfoTypdentifiersWithHttpInfo().getStatusCode().is2xxSuccessful();
+    }
+
+    public void createInfoType(Map<String, String> infoTypeMap) throws DmeException, JsonProcessingException {
+        for (Map.Entry<String, String> entry : infoTypeMap.entrySet()) {
+            String infoTypeName = entry.getKey();
+            ProducerInfoTypeInfo infoTypeInfo = objectMapper.readValue(entry.getValue(), ProducerInfoTypeInfo.class);
+            ResponseEntity<Object> objectResponseEntity =
+                    dataProducerRegistrationApiClient.putInfoTypeWithHttpInfo(infoTypeName, infoTypeInfo);
+            if (!objectResponseEntity.getStatusCode().is2xxSuccessful()) {
+                throw new DmeException(objectResponseEntity.getStatusCode().value(), "Error in creating info types");
+            }
+        }
+    }
+
+    public void createDataProducer(Map<String, String> dataProducerMap) throws DmeException, JsonProcessingException {
+        for (Map.Entry<String, String> entry : dataProducerMap.entrySet()) {
+            String infoProducerName = entry.getKey();
+            ProducerRegistrationInfo producerRegistrationInfo =
+                    objectMapper.readValue(entry.getValue(), ProducerRegistrationInfo.class);
+            ResponseEntity<Object> objectResponseEntity =
+                    dataProducerRegistrationApiClient.putInfoProducerWithHttpInfo(infoProducerName,
+                            producerRegistrationInfo);
+            if (!objectResponseEntity.getStatusCode().is2xxSuccessful()) {
+                throw new DmeException(objectResponseEntity.getStatusCode().value(), "Error in creating data producer");
+            }
+        }
+    }
+
+    public void createDataConsumer(Map<String, String> dataConsumerMap) throws DmeException, JsonProcessingException {
+        for (Map.Entry<String, String> entry : dataConsumerMap.entrySet()) {
+            String infoProducerName = entry.getKey();
+            ConsumerJob consumerJob = objectMapper.readValue(entry.getValue(), ConsumerJob.class);
+            ResponseEntity<Object> objectResponseEntity =
+                    dataConsumerApiClient.putIndividualInfoJobWithHttpInfo(infoProducerName, consumerJob);
+            if (!objectResponseEntity.getStatusCode().is2xxSuccessful()) {
+                throw new DmeException(objectResponseEntity.getStatusCode().value(), "Error in creating data consumer");
+            }
+        }
+    }
+
+    public void deleteDataProducer(Set<String> dataProducerList) throws DmeException {
+        for (String dataProducer : dataProducerList) {
+            ResponseEntity<Object> objectResponseEntity =
+                    dataProducerRegistrationApiClient.deleteInfoProducerWithHttpInfo(dataProducer);
+            if (!objectResponseEntity.getStatusCode().is2xxSuccessful()) {
+                throw new DmeException(objectResponseEntity.getStatusCode().value(), "Error in deleting data producer");
+            }
+        }
+    }
+
+    public void deleteDataConsumer(Set<String> dataConsumerList) throws DmeException {
+        for (String dataConsumer : dataConsumerList) {
+            ResponseEntity<Object> objectResponseEntity =
+                    dataConsumerApiClient.deleteIndividualInfoJobWithHttpInfo(dataConsumer);
+            if (!objectResponseEntity.getStatusCode().is2xxSuccessful()) {
+                throw new DmeException(objectResponseEntity.getStatusCode().value(), "Error in deleting data consumer");
+            }
+        }
+    }
+
+}
diff --git a/participants/participant-impl-dme/src/main/resources/application.yaml b/participants/participant-impl-dme/src/main/resources/application.yaml
new file mode 100755 (executable)
index 0000000..e1f60e1
--- /dev/null
@@ -0,0 +1,49 @@
+spring:
+  security:
+    user:
+      name: participantUser
+      password: zb!XztG34
+  autoconfigure:
+    exclude:
+      - org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
+      - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
+      - org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration
+      - org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration
+security:
+  enable-csrf: false
+
+dme:
+  baseUrl: http://localhost:63475
+
+participant:
+  intermediaryParameters:
+    reportingTimeIntervalMs: 120000
+    description: Participant Description
+    participantId: 101c62b3-8918-41b9-a747-d21eb79c6c08
+    clampAutomationCompositionTopics:
+      topicSources:
+        - topic: POLICY-ACRUNTIME-PARTICIPANT
+          servers:
+            - ${topicServer:localhost}
+          topicCommInfrastructure: dmaap
+          fetchTimeout: 15000
+      topicSinks:
+        - topic: POLICY-ACRUNTIME-PARTICIPANT
+          servers:
+            - ${topicServer:localhost}
+          topicCommInfrastructure: dmaap
+    participantSupportedElementTypes:
+      -
+        typeName: org.onap.policy.clamp.acm.DMEAutomationCompositionElement
+        typeVersion: 1.0.1
+
+management:
+  endpoints:
+    web:
+      base-path: /
+      exposure:
+        include: health, metrics, prometheus
+server:
+  port: 8080
+  servlet:
+    context-path: /nonrtric/dmeparticipant
diff --git a/participants/participant-impl-dme/src/test/java/org/oransc/participant/dme/handler/AcElementHandlerTest.java b/participants/participant-impl-dme/src/test/java/org/oransc/participant/dme/handler/AcElementHandlerTest.java
new file mode 100755 (executable)
index 0000000..fd4cc94
--- /dev/null
@@ -0,0 +1,294 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.oransc.participant.dme.handler;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi;
+import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
+import org.onap.policy.clamp.models.acm.concepts.DeployState;
+import org.onap.policy.clamp.models.acm.concepts.LockState;
+import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+import org.oransc.participant.dme.exception.DmeException;
+import org.oransc.participant.dme.restclient.AcDmeClient;
+import org.oransc.participant.dme.utils.CommonTestData;
+import org.oransc.participant.dme.utils.ToscaUtils;
+
+class AcElementHandlerTest {
+
+    private final AcDmeClient acDmeClient = mock(AcDmeClient.class);
+
+    private final CommonTestData commonTestData = new CommonTestData();
+
+    private static ToscaServiceTemplate serviceTemplate;
+    private static final String DME_AUTOMATION_COMPOSITION_ELEMENT =
+            "onap.policy.clamp.ac.element.DMEAutomationCompositionElement";
+
+    @BeforeAll
+    static void init() {
+        serviceTemplate = ToscaUtils.readAutomationCompositionFromTosca();
+    }
+
+    @BeforeEach
+    void startMocks() throws DmeException, JsonProcessingException {
+        when(acDmeClient.isDmeHealthy()).thenReturn(Boolean.TRUE);
+        doNothing().when(acDmeClient).createInfoType(any());
+    }
+
+    @Test
+    void test_automationCompositionElementStateChange() throws DmeException {
+        var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var automationCompositionElementHandler =
+                new AutomationCompositionElementHandler(participantIntermediaryApi, acDmeClient);
+
+        var automationCompositionId = commonTestData.getAutomationCompositionId();
+        var element = commonTestData.getAutomationCompositionElement();
+        var automationCompositionElementId = element.getId();
+
+        var nodeTemplatesMap = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates();
+        automationCompositionElementHandler.deploy(commonTestData.getAutomationCompositionId(), element,
+                nodeTemplatesMap.get(DME_AUTOMATION_COMPOSITION_ELEMENT).getProperties());
+        verify(participantIntermediaryApi).updateAutomationCompositionElementState(automationCompositionId,
+                automationCompositionElementId, DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Deployed");
+
+        automationCompositionElementHandler.undeploy(automationCompositionId, automationCompositionElementId);
+        verify(participantIntermediaryApi).updateAutomationCompositionElementState(automationCompositionId,
+                automationCompositionElementId, DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Undeployed");
+
+        when(acDmeClient.isDmeHealthy()).thenReturn(Boolean.FALSE);
+        assertThrows(DmeException.class, () -> automationCompositionElementHandler
+                .undeploy(automationCompositionId, automationCompositionElementId));
+    }
+
+    @Test
+    void test_AutomationCompositionElementUpdate() throws DmeException {
+        var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var automationCompositionElementHandler =
+                new AutomationCompositionElementHandler(participantIntermediaryApi, acDmeClient);
+
+        var element = commonTestData.getAutomationCompositionElement();
+        var nodeTemplatesMap = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates();
+        automationCompositionElementHandler.deploy(commonTestData.getAutomationCompositionId(), element,
+                nodeTemplatesMap.get(DME_AUTOMATION_COMPOSITION_ELEMENT).getProperties());
+        verify(participantIntermediaryApi).updateAutomationCompositionElementState(
+                commonTestData.getAutomationCompositionId(), element.getId(), DeployState.DEPLOYED, null,
+                StateChangeResult.NO_ERROR, "Deployed");
+    }
+
+    @Test
+    void test_AutomationCompositionElementUpdateWithUnhealthyA1pms() {
+        var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var automationCompositionElementHandler =
+                new AutomationCompositionElementHandler(participantIntermediaryApi, acDmeClient);
+
+        var element = commonTestData.getAutomationCompositionElement();
+        when(acDmeClient.isDmeHealthy()).thenReturn(Boolean.FALSE);
+
+        var nodeTemplatesMap = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates();
+        assertThrows(DmeException.class,
+                () -> automationCompositionElementHandler.deploy(commonTestData.getAutomationCompositionId(), element,
+                        nodeTemplatesMap.get(DME_AUTOMATION_COMPOSITION_ELEMENT).getProperties()));
+    }
+
+    @Test
+    void test_AutomationCompositionElementUpdateWithInvalidConfiguration() {
+        var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var automationCompositionElementHandler =
+                new AutomationCompositionElementHandler(participantIntermediaryApi, acDmeClient);
+
+        var element = commonTestData.getAutomationCompositionElement();
+        assertThrows(DmeException.class, () -> automationCompositionElementHandler
+                .deploy(commonTestData.getAutomationCompositionId(), element, Map.of()));
+    }
+
+    @Test
+    void testLock() {
+        var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var automationCompositionElementHandler =
+                new AutomationCompositionElementHandler(participantIntermediaryApi, acDmeClient);
+
+        var automationCompositionId = UUID.randomUUID();
+        var elementId = UUID.randomUUID();
+        automationCompositionElementHandler.lock(automationCompositionId, elementId);
+
+        verify(participantIntermediaryApi).updateAutomationCompositionElementState(automationCompositionId, elementId,
+                null, LockState.LOCKED, StateChangeResult.NO_ERROR, "Locked");
+    }
+
+    @Test
+    void testUnlock() {
+        var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var automationCompositionElementHandler =
+                new AutomationCompositionElementHandler(participantIntermediaryApi, acDmeClient);
+
+        var automationCompositionId = UUID.randomUUID();
+        var elementId = UUID.randomUUID();
+        automationCompositionElementHandler.unlock(automationCompositionId, elementId);
+
+        verify(participantIntermediaryApi).updateAutomationCompositionElementState(automationCompositionId, elementId,
+                null, LockState.UNLOCKED, StateChangeResult.NO_ERROR, "Unlocked");
+    }
+
+    @Test
+    void testUpdate() {
+        var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var automationCompositionElementHandler =
+                new AutomationCompositionElementHandler(participantIntermediaryApi, acDmeClient);
+
+        var automationCompositionId = UUID.randomUUID();
+        var element = commonTestData.getAutomationCompositionElement();
+        automationCompositionElementHandler.update(automationCompositionId, element, Map.of());
+
+        verify(participantIntermediaryApi).updateAutomationCompositionElementState(automationCompositionId,
+                element.getId(), DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Update not supported");
+    }
+
+    @Test
+    void testDelete() {
+        var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var automationCompositionElementHandler =
+                new AutomationCompositionElementHandler(participantIntermediaryApi, acDmeClient);
+
+        var automationCompositionId = UUID.randomUUID();
+        var elementId = UUID.randomUUID();
+        automationCompositionElementHandler.delete(automationCompositionId, elementId);
+
+        verify(participantIntermediaryApi).updateAutomationCompositionElementState(automationCompositionId, elementId,
+                DeployState.DELETED, null, StateChangeResult.NO_ERROR, "Deleted");
+    }
+
+    @Test
+    void testPrime() {
+        var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var automationCompositionElementHandler =
+                new AutomationCompositionElementHandler(participantIntermediaryApi, acDmeClient);
+
+        var compositionId = UUID.randomUUID();
+        automationCompositionElementHandler.prime(compositionId, List.of());
+
+        verify(participantIntermediaryApi).updateCompositionState(compositionId, AcTypeState.PRIMED,
+                StateChangeResult.NO_ERROR, "Primed");
+    }
+
+    @Test
+    void testDeprime() {
+        var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var automationCompositionElementHandler =
+                new AutomationCompositionElementHandler(participantIntermediaryApi, acDmeClient);
+
+        var compositionId = UUID.randomUUID();
+        automationCompositionElementHandler.deprime(compositionId);
+
+        verify(participantIntermediaryApi).updateCompositionState(compositionId, AcTypeState.COMMISSIONED,
+                StateChangeResult.NO_ERROR, "Deprimed");
+    }
+
+    @Test
+    void testHandleRestartComposition() {
+        var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var automationCompositionElementHandler =
+                new AutomationCompositionElementHandler(participantIntermediaryApi, acDmeClient);
+
+        var compositionId = UUID.randomUUID();
+        automationCompositionElementHandler.handleRestartComposition(compositionId, List.of(), AcTypeState.PRIMED);
+
+        verify(participantIntermediaryApi).updateCompositionState(compositionId, AcTypeState.PRIMED,
+                StateChangeResult.NO_ERROR, "Restarted");
+    }
+
+    @Test
+    void testHandleRestartInstanceDeploying() throws PfModelException {
+        var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var automationCompositionElementHandler =
+                new AutomationCompositionElementHandler(participantIntermediaryApi, acDmeClient);
+
+        var automationCompositionId = UUID.randomUUID();
+        var element = commonTestData.getAutomationCompositionElement();
+        var automationCompositionElementId = element.getId();
+        var nodeTemplatesMap = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates();
+        automationCompositionElementHandler.handleRestartInstance(automationCompositionId, element,
+                nodeTemplatesMap.get(DME_AUTOMATION_COMPOSITION_ELEMENT).getProperties(), DeployState.DEPLOYING,
+                LockState.NONE);
+        verify(participantIntermediaryApi).updateAutomationCompositionElementState(automationCompositionId,
+                automationCompositionElementId, DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Deployed");
+    }
+
+    @Test
+    void testHandleRestartInstanceDeployed() throws PfModelException {
+        var intermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var automationCompositionElementHandler =
+                new AutomationCompositionElementHandler(intermediaryApi, acDmeClient);
+
+        var automationCompositionId = UUID.randomUUID();
+        var element = commonTestData.getAutomationCompositionElement();
+        var nodeTemplatesMap = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates();
+        automationCompositionElementHandler.handleRestartInstance(automationCompositionId, element,
+                nodeTemplatesMap.get(DME_AUTOMATION_COMPOSITION_ELEMENT).getProperties(), DeployState.DEPLOYED,
+                LockState.LOCKED);
+        verify(intermediaryApi).updateAutomationCompositionElementState(automationCompositionId, element.getId(),
+                DeployState.DEPLOYED, LockState.LOCKED, StateChangeResult.NO_ERROR, "Restarted");
+    }
+
+    @Test
+    void testHandleRestartInstanceUndeployed() throws PfModelException {
+        var intermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var automationCompositionElementHandler =
+                new AutomationCompositionElementHandler(intermediaryApi, acDmeClient);
+
+        var automationCompositionId = UUID.randomUUID();
+        var element = commonTestData.getAutomationCompositionElement();
+        var automationCompositionElementId = element.getId();
+        var nodeTemplatesMap = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates();
+        automationCompositionElementHandler.handleRestartInstance(automationCompositionId, element,
+                nodeTemplatesMap.get(DME_AUTOMATION_COMPOSITION_ELEMENT).getProperties(), DeployState.UNDEPLOYING,
+                LockState.LOCKED);
+        verify(intermediaryApi).updateAutomationCompositionElementState(automationCompositionId,
+                automationCompositionElementId, DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Undeployed");
+    }
+
+    @Test
+    void testMigrate() {
+        var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var automationCompositionElementHandler =
+                new AutomationCompositionElementHandler(participantIntermediaryApi, acDmeClient);
+
+        var automationCompositionId = UUID.randomUUID();
+        var element = commonTestData.getAutomationCompositionElement();
+        automationCompositionElementHandler.migrate(automationCompositionId, element, UUID.randomUUID(), Map.of());
+
+        verify(participantIntermediaryApi).updateAutomationCompositionElementState(automationCompositionId,
+                element.getId(), DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migrated");
+    }
+}
diff --git a/participants/participant-impl-dme/src/test/java/org/oransc/participant/dme/rest/ActuatorControllerTest.java b/participants/participant-impl-dme/src/test/java/org/oransc/participant/dme/rest/ActuatorControllerTest.java
new file mode 100755 (executable)
index 0000000..bdcd3ed
--- /dev/null
@@ -0,0 +1,91 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.oransc.participant.dme.rest;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import jakarta.ws.rs.core.Response;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.oransc.participant.dme.utils.CommonActuatorController;
+import org.springframework.boot.test.autoconfigure.actuate.observability.AutoConfigureObservability;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.test.web.server.LocalServerPort;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+@AutoConfigureObservability(tracing = false)
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
+@ActiveProfiles("test")
+class ActuatorControllerTest extends CommonActuatorController {
+
+    private static final String HEALTH_ENDPOINT = "health";
+    private static final String METRICS_ENDPOINT = "metrics";
+    private static final String PROMETHEUS_ENDPOINT = "prometheus";
+
+    @LocalServerPort
+    private int randomServerPort;
+
+    @BeforeEach
+    public void setUpPort() {
+        super.setHttpPrefix(randomServerPort);
+    }
+
+    @Test
+    void testGetHealth_Unauthorized() {
+        assertUnauthorizedActGet(HEALTH_ENDPOINT);
+    }
+
+    @Test
+    void testGetMetrics_Unauthorized() {
+        assertUnauthorizedActGet(METRICS_ENDPOINT);
+    }
+
+    @Test
+    void testGetPrometheus_Unauthorized() {
+        assertUnauthorizedActGet(PROMETHEUS_ENDPOINT);
+    }
+
+    @Test
+    void testGetHealth() {
+        var invocationBuilder = super.sendActRequest(HEALTH_ENDPOINT);
+        var rawresp = invocationBuilder.buildGet().invoke();
+        assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+    }
+
+    @Test
+    void testGetMetrics() {
+        var invocationBuilder = super.sendActRequest(METRICS_ENDPOINT);
+        var rawresp = invocationBuilder.buildGet().invoke();
+        assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+    }
+
+    @Test
+    void testGePrometheus() {
+        var invocationBuilder = super.sendActRequest(PROMETHEUS_ENDPOINT);
+        var rawresp = invocationBuilder.buildGet().invoke();
+        assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+    }
+
+}
diff --git a/participants/participant-impl-dme/src/test/java/org/oransc/participant/dme/restclient/AcA1PmsClientTest.java b/participants/participant-impl-dme/src/test/java/org/oransc/participant/dme/restclient/AcA1PmsClientTest.java
new file mode 100755 (executable)
index 0000000..f7489d9
--- /dev/null
@@ -0,0 +1,173 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.oransc.participant.dme.restclient;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.oransc.participant.dme.rest.DataConsumerApiClient;
+import com.oransc.participant.dme.rest.DataProducerRegistrationApiClient;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.oransc.participant.dme.exception.DmeException;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+@ExtendWith(SpringExtension.class)
+class AcA1PmsClientTest {
+
+    @MockBean
+    DataProducerRegistrationApiClient dataProducerRegistrationApiClient;
+
+    @MockBean
+    DataConsumerApiClient dataConsumerApiClient;
+
+    @MockBean
+    AcDmeClient acDmeClient;
+
+    ObjectMapper objectMapper = new ObjectMapper();
+
+    @BeforeEach
+    void initialize() {
+        acDmeClient = new AcDmeClient(dataProducerRegistrationApiClient, dataConsumerApiClient, objectMapper);
+    }
+
+    @Test
+    void testHealthyDme() {
+        when(dataProducerRegistrationApiClient.getInfoTypdentifiersWithHttpInfo()).thenReturn(
+                ResponseEntity.ok().build());
+        assertTrue(acDmeClient.isDmeHealthy());
+    }
+
+    @Test
+    void testUnhealthyDme() {
+        when(dataProducerRegistrationApiClient.getInfoTypdentifiersWithHttpInfo()).thenReturn(
+                ResponseEntity.internalServerError().build());
+        assertFalse(acDmeClient.isDmeHealthy());
+    }
+
+    @ParameterizedTest
+    @MethodSource("getInfoTypes")
+    void testcreateInfoTypeSuccess(Map<String, String> infoTypeMap) {
+        when(dataProducerRegistrationApiClient.putInfoTypeWithHttpInfo(any(), any())).thenReturn(
+                ResponseEntity.ok().build());
+        assertDoesNotThrow(() -> acDmeClient.createInfoType(infoTypeMap));
+    }
+
+    @Test
+    void testcreateInfoTypeFailure() {
+        when(dataProducerRegistrationApiClient.putInfoTypeWithHttpInfo(any(), any())).thenReturn(
+                ResponseEntity.internalServerError().build());
+        assertThrows(DmeException.class, () -> acDmeClient.createInfoType(Map.of("infotype1", "{}")));
+    }
+
+    @ParameterizedTest
+    @MethodSource("getDataProducers")
+    void testcreateDataProducerSuccess(Map<String, String> dataProducerMap) {
+        when(dataProducerRegistrationApiClient.putInfoProducerWithHttpInfo(any(), any())).thenReturn(
+                ResponseEntity.ok().build());
+        assertDoesNotThrow(() -> acDmeClient.createDataProducer(dataProducerMap));
+    }
+
+
+    @Test
+    void testcreateDataProducerFailure() {
+        when(dataProducerRegistrationApiClient.putInfoProducerWithHttpInfo(any(), any())).thenReturn(
+                ResponseEntity.internalServerError().build());
+        assertThrows(DmeException.class, () -> acDmeClient.createDataProducer(Map.of("producer1", "{}")));
+    }
+
+    @ParameterizedTest
+    @MethodSource("getDataConsumers")
+    void testcreateDataConsumerSuccess(Map<String, String> dataConsumerMap) {
+        when(dataConsumerApiClient.putIndividualInfoJobWithHttpInfo(any(), any())).thenReturn(
+                ResponseEntity.ok().build());
+        assertDoesNotThrow(() -> acDmeClient.createDataConsumer(dataConsumerMap));
+    }
+
+    @Test
+    void testcreateDataConsumerFailure() {
+        when(dataConsumerApiClient.putIndividualInfoJobWithHttpInfo(any(), any())).thenReturn(
+                ResponseEntity.internalServerError().build());
+        assertThrows(DmeException.class, () -> acDmeClient.createDataConsumer(Map.of("consumer1", "{}")));
+    }
+
+    @ParameterizedTest
+    @MethodSource("getDeleteDataProducers")
+    void testDeleteDataProducerSuccess() {
+        when(dataProducerRegistrationApiClient.deleteInfoProducerWithHttpInfo(any())).thenReturn(
+                ResponseEntity.ok().build());
+        assertDoesNotThrow(() -> acDmeClient.deleteDataProducer(Set.of("producer1")));
+    }
+
+    @Test
+    void testDeleteDataProducerFailure() {
+        when(dataProducerRegistrationApiClient.deleteInfoProducerWithHttpInfo(any())).thenReturn(
+                ResponseEntity.internalServerError().build());
+        assertThrows(DmeException.class, () -> acDmeClient.deleteDataProducer(Set.of("producer1")));
+    }
+
+    @ParameterizedTest
+    @MethodSource("getDeleteDataConsumers")
+    void testDeleteDataConsumerSuccess() {
+        when(dataConsumerApiClient.deleteIndividualInfoJobWithHttpInfo(any())).thenReturn(ResponseEntity.ok().build());
+        assertDoesNotThrow(() -> acDmeClient.deleteDataConsumer(Set.of("consumer1")));
+    }
+
+    @Test
+    void testDeleteDataConsumerFailure() {
+        when(dataConsumerApiClient.deleteIndividualInfoJobWithHttpInfo(any())).thenReturn(
+                ResponseEntity.internalServerError().build());
+        assertThrows(DmeException.class, () -> acDmeClient.deleteDataConsumer(Set.of("consumer1")));
+    }
+
+    private static Stream<Arguments> getDeleteDataProducers() {
+        return Stream.of(Arguments.of(Set.of("producer1")), Arguments.of(Set.of()));
+    }
+
+    private static Stream<Arguments> getDeleteDataConsumers() {
+        return Stream.of(Arguments.of(Set.of("consumer1")), Arguments.of(Set.of()));
+    }
+    private static Stream<Arguments> getInfoTypes() {
+        return Stream.of(Arguments.of(Map.of("infotype1", "{}")), Arguments.of(Map.of()));
+    }
+
+    private static Stream<Arguments> getDataProducers() {
+        return Stream.of(Arguments.of(Map.of("dataproducers", "{}")), Arguments.of(Map.of()));
+    }
+
+    private static Stream<Arguments> getDataConsumers() {
+        return Stream.of(Arguments.of(Map.of("dataconsumer", "{}")), Arguments.of(Map.of()));
+    }
+}
diff --git a/participants/participant-impl-dme/src/test/java/org/oransc/participant/dme/utils/CommonActuatorController.java b/participants/participant-impl-dme/src/test/java/org/oransc/participant/dme/utils/CommonActuatorController.java
new file mode 100755 (executable)
index 0000000..894087a
--- /dev/null
@@ -0,0 +1,75 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.oransc.participant.dme.utils;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.Invocation;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
+import org.onap.policy.common.gson.GsonMessageBodyHandler;
+import org.onap.policy.common.utils.network.NetworkUtil;
+
+public class CommonActuatorController {
+
+    public static final String SELF = NetworkUtil.getHostname();
+    public static final String CONTEXT_PATH = "nonrtric/dmeparticipant/";
+
+    private static String httpPrefix;
+
+    protected Invocation.Builder sendActRequest(final String endpoint) {
+        return sendFqeRequest(httpPrefix + CONTEXT_PATH + endpoint, true);
+    }
+
+    protected Invocation.Builder sendNoAuthActRequest(final String endpoint) {
+        return sendFqeRequest(httpPrefix + CONTEXT_PATH + endpoint, false);
+    }
+
+    protected Invocation.Builder sendFqeRequest(final String fullyQualifiedEndpoint, boolean includeAuth) {
+        final Client client = ClientBuilder.newBuilder().build();
+
+        client.property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, "true");
+        client.register(GsonMessageBodyHandler.class);
+
+        if (includeAuth) {
+            client.register(HttpAuthenticationFeature.basic("participantUser", "zb!XztG34"));
+        }
+
+        final WebTarget webTarget = client.target(fullyQualifiedEndpoint);
+
+        return webTarget.request(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN);
+    }
+
+    protected void assertUnauthorizedActGet(final String endPoint) {
+        Response rawresp = sendNoAuthActRequest(endPoint).buildGet().invoke();
+        assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), rawresp.getStatus());
+    }
+
+    protected void setHttpPrefix(int port) {
+        httpPrefix = "http://" + SELF + ":" + port + "/";
+    }
+
+}
diff --git a/participants/participant-impl-dme/src/test/java/org/oransc/participant/dme/utils/CommonTestData.java b/participants/participant-impl-dme/src/test/java/org/oransc/participant/dme/utils/CommonTestData.java
new file mode 100755 (executable)
index 0000000..3cb897f
--- /dev/null
@@ -0,0 +1,55 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2022-2023 Nordix Foundation.
+ *  Modifications Copyright (C) 2022 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.oransc.participant.dme.utils;
+
+import java.util.List;
+import java.util.UUID;
+import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy;
+import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+
+public class CommonTestData {
+
+    private static final String TEST_KEY_NAME = "onap.policy.clamp.ac.element.DmeAutomationCompositionElement";
+    private static final List<UUID> AC_ID_LIST = List.of(UUID.randomUUID(), UUID.randomUUID());
+
+    public AcElementDeploy getAutomationCompositionElement() {
+        var element = new AcElementDeploy();
+        element.setId(UUID.randomUUID());
+        element.setDefinition(new ToscaConceptIdentifier(TEST_KEY_NAME, "1.0.1"));
+        element.setOrderedState(DeployOrder.DEPLOY);
+        return element;
+    }
+
+    public ToscaConceptIdentifier getDmeIdentifier(int instanceNo) {
+        return new ToscaConceptIdentifier("DmeInstance" + instanceNo, "1.0.0");
+    }
+
+    public UUID getAutomationCompositionId() {
+        return getAutomationCompositionId(0);
+    }
+
+    public UUID getAutomationCompositionId(int instanceNo) {
+        return AC_ID_LIST.get(instanceNo);
+    }
+
+}
diff --git a/participants/participant-impl-dme/src/test/java/org/oransc/participant/dme/utils/ToscaUtils.java b/participants/participant-impl-dme/src/test/java/org/oransc/participant/dme/utils/ToscaUtils.java
new file mode 100755 (executable)
index 0000000..99cedc1
--- /dev/null
@@ -0,0 +1,50 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 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.oransc.participant.dme.utils;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.onap.policy.common.utils.coder.YamlJsonTranslator;
+import org.onap.policy.common.utils.resources.ResourceUtils;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+
+/**
+ * Util class for Test scope.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class ToscaUtils {
+
+    private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator();
+    private static final String TOSCA_TEMPLATE_YAML = "participant-dme.yaml";
+
+    public static ToscaServiceTemplate readAutomationCompositionFromTosca() {
+        return serializeAutomationCompositionYaml();
+    }
+
+    private static ToscaServiceTemplate serializeAutomationCompositionYaml() {
+        String automationCompositionString = ResourceUtils.getResourceAsString(ToscaUtils.TOSCA_TEMPLATE_YAML);
+        return yamlTranslator.fromYaml(automationCompositionString, ToscaServiceTemplate.class);
+    }
+
+    public static void main(String[] args) {
+        System.out.println(serializeAutomationCompositionYaml());
+    }
+}
diff --git a/participants/participant-impl-dme/src/test/resources/participant-dme.yaml b/participants/participant-impl-dme/src/test/resources/participant-dme.yaml
new file mode 100755 (executable)
index 0000000..c72c8c7
--- /dev/null
@@ -0,0 +1,199 @@
+# ============LICENSE_START=======================================================
+# Copyright (C) 2023 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=========================================================
+tosca_definitions_version: tosca_simple_yaml_1_3
+data_types:
+  onap.datatypes.ToscaConceptIdentifier:
+    derived_from: tosca.datatypes.Root
+    properties:
+      name:
+        type: string
+        required: true
+      version:
+        type: string
+        required: true
+  org.onap.datatypes.policy.clamp.acm.DMEAutomationCompositionElement.InfoTypeEntity:
+    version: 1.0.0
+    derived_from: tosca.datatypes.Root
+    properties:
+      infoTypeEntityId:
+        type: onap.datatypes.ToscaConceptIdentifier
+        required: true
+        description: The name and version of a Configuration Entity to be handled by
+          the DME Automation Composition Element
+      infoTypeId:
+        type: string
+        required: true
+        description: Id of the info type
+      payload:
+        type: string
+        required: true
+        description: Json payload of info type
+  org.onap.datatypes.policy.clamp.acm.DMEAutomationCompositionElement.DataProducerEntity:
+    version: 1.0.0
+    derived_from: tosca.datatypes.Root
+    properties:
+      dataProducerEntityId:
+        type: onap.datatypes.ToscaConceptIdentifier
+        required: true
+        description: The name and version of a Configuration Entity to be handled by
+          the DME Automation Composition Element
+      dataProducerId:
+        type: string
+        required: true
+        description: Id of the info type
+      payload:
+        type: string
+        required: true
+        description: Json payload of info type
+  org.onap.datatypes.policy.clamp.acm.DMEAutomationCompositionElement.DataConsumerEntity:
+    version: 1.0.0
+    derived_from: tosca.datatypes.Root
+    properties:
+      dataConsumerEntityId:
+        type: onap.datatypes.ToscaConceptIdentifier
+        required: true
+        description: The name and version of a Configuration Entity to be handled by
+          the DME Automation Composition Element
+      dataConsumerId:
+        type: string
+        required: true
+        description: Id of the info type
+      payload:
+        type: string
+        required: true
+        description: Json payload of info type
+
+node_types:
+  org.onap.policy.clamp.acm.Participant:
+    version: 1.0.1
+    derived_from: tosca.nodetypes.Root
+    properties:
+      provider:
+        type: string
+        required: false
+  org.onap.policy.clamp.acm.AutomationCompositionElement:
+    version: 1.0.1
+    derived_from: tosca.nodetypes.Root
+    properties:
+      provider:
+        type: string
+        required: false
+      startPhase:
+        type: integer
+        required: false
+        constraints:
+          - greater-or-equal: 0
+        metadata:
+          common: true
+        description: A value indicating the start phase in which this automation composition element will be started, the
+          first start phase is zero. Automation Composition Elements are started in their start_phase order and stopped
+          in reverse start phase order. Automation Composition Elements with the same start phase are started and
+          stopped simultaneously
+  org.onap.policy.clamp.acm.AutomationComposition:
+    version: 1.0.1
+    derived_from: tosca.nodetypes.Root
+    properties:
+      provider:
+        type: string
+        required: false
+      elements:
+        type: list
+        required: true
+        entry_schema:
+          type: onap.datatypes.ToscaConceptIdentifier
+  org.onap.policy.clamp.acm.DMEAutomationCompositionElement:
+    version: 1.0.1
+    derived_from: org.onap.policy.clamp.acm.AutomationCompositionElement
+    properties:
+      infoTypeEntities:
+        type: list
+        required: true
+        entry_schema:
+          type: org.onap.datatypes.policy.clamp.acm.DMEAutomationCompositionElement.InfoTypeEntity
+          type_version: 1.0.0
+        description: The configuration entities of DME
+      dataProducerEntities:
+        type: list
+        required: true
+        entry_schema:
+          type: org.onap.datatypes.policy.clamp.acm.DMEAutomationCompositionElement.DataProducerEntity
+          type_version: 1.0.0
+        description: The configuration entities of DME
+      dataConsumerEntities:
+        type: list
+        required: true
+        entry_schema:
+          type: org.onap.datatypes.policy.clamp.acm.DMEAutomationCompositionElement.DataConsumerEntity
+          type_version: 1.0.0
+        description: The configuration entities of DME
+topology_template:
+  node_templates:
+    org.onap.policy.clamp.acm.DMEAutomationCompositionParticipant:
+      version: 2.3.4
+      type: org.onap.policy.clamp.acm.Participant
+      type_version: 1.0.1
+      description: Participant for DME
+      properties:
+        provider: ONAP
+
+    onap.policy.clamp.ac.element.DMEAutomationCompositionElement:
+      version: 1.2.3
+      type: org.onap.policy.clamp.acm.DMEAutomationCompositionElement
+      type_version: 1.0.1
+      description: Automation composition element for the DME Requests
+      properties:
+        provider: ONAP
+        participantType:
+          name: org.onap.policy.clamp.acm.DMEParticipant
+          version: 2.3.4
+        infoTypeEntities:
+          - infoTypeEntityId:
+              name: infoType1
+              version: 1.0.1
+            infoTypeId: json-file-data-from-filestore
+            payload: '{"info_job_data_schema": {"schema": "http://json-schema.org/draft-07/schema#","title":
+            "json-file-data-from-filestore","description": "json-file-data-from-filestore","type":
+            "object"}}'
+        dataProducerEntities:
+          - dataProducerEntityId:
+              name: producerType1
+              version: 1.0.1
+            dataProducerId: json-file-data-producer
+            payload: '{"info_job_callback_url": "http://localhost/jsonproducerjobcallback","info_producer_supervision_callback_url":
+            "http://localhost/jsonproducersupervisioncallback","supported_info_types": ["json-file-data-from-filestore"]}'
+        dataConsumerEntities:
+          - dataConsumerEntityId:
+              name: consumerType1
+              version: 1.0.1
+            dataConsumerId: json-file-consumer
+            payload: '{"info_type_id": "json-file-data-from-filestore","job_owner": "console","status_notification_uri":
+            "http://callback.nonrtric:80/post","job_definition": {"db-url": "http://influxdb2.nonrtric:8086","db-org":
+            "est","db-bucket": "pm-bucket","db-token": "token","filterType": "pmdata","filter":
+            {}}}'
+
+
+    onap.policy.clamp.ac.element.AutomationCompositionDefinition:
+      version: 1.2.3
+      type: org.onap.policy.clamp.acm.AutomationComposition
+      type_version: 1.0.1
+      description: Automation composition for DME request
+      properties:
+        provider: ONAP
+        elements:
+          - name: onap.policy.clamp.ac.element.DMEAutomationCompositionElement
+            version: 1.2.3
diff --git a/participants/pom.xml b/participants/pom.xml
new file mode 100755 (executable)
index 0000000..8eee1f5
--- /dev/null
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+* ========================LICENSE_START=================================
+* O-RAN-SC
+* %%
+* Copyright (C) 2023 Nordix Foundation
+* %%
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+* ========================LICENSE_END===================================
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>3.1.5</version>
+        <relativePath/>
+    </parent>
+    <groupId>org.o-ran-sc.nonrtric.plt</groupId>
+    <artifactId>participants</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <packaging>pom</packaging>
+    <name>NONRTRIC ACM Participants</name>
+    <description>O-RAN SC ACM Participants.</description>
+    <modules>
+        <module>participant-impl-dme</module>
+    </modules>
+    <repositories>
+        <repository>
+            <id>onap-releases</id>
+            <name>onap-releases</name>
+            <url>https://nexus.onap.org/content/repositories/releases/</url>
+        </repository>
+    </repositories>
+    <properties>
+        <java.version>17</java.version>
+        <openapi.maven.version>7.0.1</openapi.maven.version>
+        <docker-maven-plugin>0.30.0</docker-maven-plugin>
+        <jacoco-maven-plugin.version>0.8.10</jacoco-maven-plugin.version>
+        <onap.acm.models.version>7.0.1-SNAPSHOT</onap.acm.models.version>
+        <openapi.jackson.databind.nullable.version>0.2.6</openapi.jackson.databind.nullable.version>
+    </properties>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <skipTests>false</skipTests>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.jacoco</groupId>
+                <artifactId>jacoco-maven-plugin</artifactId>
+                <version>${jacoco-maven-plugin.version}</version>
+                <executions>
+                    <execution>
+                        <id>default-prepare-agent</id>
+                        <goals>
+                            <goal>prepare-agent</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>default-report</id>
+                        <phase>prepare-package</phase>
+                        <goals>
+                            <goal>report</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+    <issueManagement>
+        <system>JIRA</system>
+        <url>https://jira.o-ran-sc.org/</url>
+    </issueManagement>
+</project>