aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiam Fallon <liam.fallon@est.tech>2021-03-23 08:11:06 +0000
committerGerrit Code Review <gerrit@onap.org>2021-03-23 08:11:06 +0000
commita2f487328e5da5b2896f7918bd0706614af3d21c (patch)
treee4894a3a474ff3aeaa731bc4bbf5ede6ee0ce11d
parentb7585f9f12d053c2a11b27c7a48782e6b40f4546 (diff)
parent5988d899ddebf5d913b8785b860431d4da70a84f (diff)
Merge "Participant simulator Rest API" into tosca-poc
-rw-r--r--tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/rest/TypedSimpleResponse.java (renamed from tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/rest/SimulationQueryElementController.java)18
-rw-r--r--tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/ParticipantSimulatorParameters.java2
-rw-r--r--tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/RestController.java136
-rw-r--r--tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/SimulationHandler.java10
-rw-r--r--tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/SimulationProvider.java142
-rw-r--r--tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/rest/SimulationElementController.java194
-rw-r--r--tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/rest/SimulationParticipantController.java192
-rw-r--r--tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/CommonParticipantRestServer.java228
-rw-r--r--tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/RestControllerTest.java72
-rw-r--r--tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/TestListenerUtils.java128
-rw-r--r--tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/TestSimulationRestController.java153
-rw-r--r--tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/parameters/logback-test.xml42
-rw-r--r--tosca-controlloop/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryApi.java119
-rw-r--r--tosca-controlloop/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryFactory.java38
-rw-r--r--tosca-controlloop/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java88
15 files changed, 1506 insertions, 56 deletions
diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/rest/SimulationQueryElementController.java b/tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/rest/TypedSimpleResponse.java
index 2165da797..199ac8ee1 100644
--- a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/rest/SimulationQueryElementController.java
+++ b/tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/rest/TypedSimpleResponse.java
@@ -1,6 +1,6 @@
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation.
+ * Copyright (C) 2021 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,14 +18,18 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.policy.clamp.controlloop.participant.simulator.simulation.rest;
+package org.onap.policy.clamp.controlloop.models.messages.rest;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
/**
- * Class to provide REST end points for participant simulator to query details of controlLoopElements.
+ * Response returned when no extra output fields are needed.
*/
-public class SimulationQueryElementController {
- private static final Logger LOGGER = LoggerFactory.getLogger(SimulationQueryElementController.class);
+@Getter
+@Setter
+@ToString
+public class TypedSimpleResponse<T> extends SimpleResponse {
+ private T response;
}
diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/ParticipantSimulatorParameters.java b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/ParticipantSimulatorParameters.java
index dd28d4e5b..a4e62b446 100644
--- a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/ParticipantSimulatorParameters.java
+++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/ParticipantSimulatorParameters.java
@@ -22,6 +22,7 @@ package org.onap.policy.clamp.controlloop.participant.simulator.main.parameters;
import javax.validation.constraints.NotBlank;
import lombok.Getter;
+import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters;
import org.onap.policy.common.endpoints.parameters.RestServerParameters;
import org.onap.policy.common.parameters.ParameterGroupImpl;
import org.onap.policy.common.parameters.annotations.NotNull;
@@ -36,6 +37,7 @@ import org.onap.policy.models.provider.PolicyModelsProviderParameters;
@Getter
public class ParticipantSimulatorParameters extends ParameterGroupImpl {
private RestServerParameters restServerParameters;
+ private ParticipantIntermediaryParameters intermediaryParameters;
private PolicyModelsProviderParameters databaseProviderParameters;
/**
diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/RestController.java b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/RestController.java
new file mode 100644
index 000000000..120c52c26
--- /dev/null
+++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/RestController.java
@@ -0,0 +1,136 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.controlloop.participant.simulator.main.rest;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.BasicAuthDefinition;
+import io.swagger.annotations.Info;
+import io.swagger.annotations.SecurityDefinition;
+import io.swagger.annotations.SwaggerDefinition;
+import io.swagger.annotations.Tag;
+import java.net.HttpURLConnection;
+import java.util.UUID;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response.ResponseBuilder;
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException;
+import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters;
+import org.onap.policy.clamp.controlloop.participant.simulator.simulation.SimulationProvider;
+
+/**
+ * Common superclass to provide REST endpoints for the participant simulator.
+ */
+// @formatter:off
+@Path("/onap/participantsim/v2")
+@Api(value = "Participant Simulator API")
+@Produces({MediaType.APPLICATION_JSON, RestController.APPLICATION_YAML})
+@SwaggerDefinition(
+ info = @Info(description =
+ "Participant Simulator", version = "v1.0",
+ title = "Participant Simulator"),
+ consumes = {MediaType.APPLICATION_JSON, RestController.APPLICATION_YAML},
+ produces = {MediaType.APPLICATION_JSON, RestController.APPLICATION_YAML},
+ schemes = {SwaggerDefinition.Scheme.HTTP, SwaggerDefinition.Scheme.HTTPS},
+ tags = {@Tag(name = "participantsim", description = "Participant Simulator")},
+ securityDefinition = @SecurityDefinition(basicAuthDefinitions = {@BasicAuthDefinition(key = "basicAuth")}))
+// @formatter:on
+@NoArgsConstructor
+public class RestController {
+ public static final String APPLICATION_YAML = "application/yaml";
+
+ public static final String EXTENSION_NAME = "interface info";
+
+ public static final String API_VERSION_NAME = "api-version";
+ public static final String API_VERSION = "1.0.0";
+
+ public static final String LAST_MOD_NAME = "last-mod-release";
+ public static final String LAST_MOD_RELEASE = "Dublin";
+
+ public static final String VERSION_MINOR_NAME = "X-MinorVersion";
+ public static final String VERSION_MINOR_DESCRIPTION =
+ "Used to request or communicate a MINOR version back from the client"
+ + " to the server, and from the server back to the client";
+
+ public static final String VERSION_PATCH_NAME = "X-PatchVersion";
+ public static final String VERSION_PATCH_DESCRIPTION = "Used only to communicate a PATCH version in a response for"
+ + " troubleshooting purposes only, and will not be provided by" + " the client on request";
+
+ public static final String VERSION_LATEST_NAME = "X-LatestVersion";
+ public static final String VERSION_LATEST_DESCRIPTION = "Used only to communicate an API's latest version";
+
+ public static final String REQUEST_ID_NAME = "X-ONAP-RequestID";
+ public static final String REQUEST_ID_HDR_DESCRIPTION = "Used to track REST transactions for logging purpose";
+ public static final String REQUEST_ID_PARAM_DESCRIPTION = "RequestID for http transaction";
+
+ public static final String AUTHORIZATION_TYPE = "basicAuth";
+
+ public static final int AUTHENTICATION_ERROR_CODE = HttpURLConnection.HTTP_UNAUTHORIZED;
+ public static final int AUTHORIZATION_ERROR_CODE = HttpURLConnection.HTTP_FORBIDDEN;
+ public static final int SERVER_ERROR_CODE = HttpURLConnection.HTTP_INTERNAL_ERROR;
+
+ public static final String AUTHENTICATION_ERROR_MESSAGE = "Authentication Error";
+ public static final String AUTHORIZATION_ERROR_MESSAGE = "Authorization Error";
+ public static final String SERVER_ERROR_MESSAGE = "Internal Server Error";
+ @Getter(AccessLevel.PROTECTED)
+ // The provider for simulation requests
+ private static SimulationProvider simulationProvider;
+
+ /**
+ * Create a participant simulation provider.
+ * @return
+ *
+ * @throws ControlLoopRuntimeException on errors creating the provider
+ */
+ public static void init(ParticipantIntermediaryParameters participantParameters)
+ throws ControlLoopRuntimeException {
+ simulationProvider = new SimulationProvider(participantParameters);
+ }
+
+ /**
+ * Adds version headers to the response.
+ *
+ * @param respBuilder response builder
+ * @return the response builder, with version headers
+ */
+ public ResponseBuilder addVersionControlHeaders(ResponseBuilder respBuilder) {
+ return respBuilder.header(VERSION_MINOR_NAME, "0").header(VERSION_PATCH_NAME, "0").header(VERSION_LATEST_NAME,
+ API_VERSION);
+ }
+
+ /**
+ * Adds logging headers to the response.
+ *
+ * @param respBuilder response builder
+ * @return the response builder, with version logging
+ */
+ public ResponseBuilder addLoggingHeaders(ResponseBuilder respBuilder, UUID requestId) {
+ if (requestId == null) {
+ // Generate a random uuid if client does not embed requestId in rest request
+ return respBuilder.header(REQUEST_ID_NAME, UUID.randomUUID());
+ }
+
+ return respBuilder.header(REQUEST_ID_NAME, requestId);
+ }
+}
diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/SimulationHandler.java b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/SimulationHandler.java
index ab019990f..e409460c0 100644
--- a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/SimulationHandler.java
+++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/SimulationHandler.java
@@ -20,12 +20,12 @@
package org.onap.policy.clamp.controlloop.participant.simulator.simulation;
-import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.onap.policy.clamp.controlloop.common.handler.ControlLoopHandler;
import org.onap.policy.clamp.controlloop.participant.simulator.main.parameters.ParticipantSimulatorParameters;
-import org.onap.policy.clamp.controlloop.participant.simulator.simulation.rest.SimulationQueryElementController;
+import org.onap.policy.clamp.controlloop.participant.simulator.simulation.rest.SimulationElementController;
+import org.onap.policy.clamp.controlloop.participant.simulator.simulation.rest.SimulationParticipantController;
import org.onap.policy.common.endpoints.event.comm.TopicSink;
import org.onap.policy.common.endpoints.listeners.MessageTypeDispatcher;
@@ -46,11 +46,7 @@ public class SimulationHandler extends ControlLoopHandler {
@Override
public Set<Class<?>> getProviderClasses() {
- Set<Class<?>> providerClasses = new HashSet<>();
-
- providerClasses.add(SimulationQueryElementController.class);
-
- return providerClasses;
+ return Set.of(SimulationElementController.class, SimulationParticipantController.class);
}
@Override
diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/SimulationProvider.java b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/SimulationProvider.java
new file mode 100644
index 000000000..fc0a31fcb
--- /dev/null
+++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/SimulationProvider.java
@@ -0,0 +1,142 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.controlloop.participant.simulator.simulation;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.List;
+import lombok.Getter;
+import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException;
+import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant;
+import org.onap.policy.clamp.controlloop.models.messages.rest.TypedSimpleResponse;
+import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi;
+import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryFactory;
+import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters;
+
+/**
+ * This provider class simulation of participants and control loop elements.
+ */
+public class SimulationProvider implements Closeable {
+ @Getter
+ private final ParticipantIntermediaryApi intermediaryApi;
+
+ /**
+ * Create a participant simulation provider.
+ *
+ * @throws ControlLoopRuntimeException on errors creating the provider
+ */
+ public SimulationProvider(ParticipantIntermediaryParameters participantParameters)
+ throws ControlLoopRuntimeException {
+ intermediaryApi = new ParticipantIntermediaryFactory().createApiImplementation();
+ intermediaryApi.init(participantParameters);
+ }
+
+ @Override
+ public void close() throws IOException {
+ intermediaryApi.close();
+ }
+
+ /**
+ * Get the control loops.
+ *
+ * @param name the controlLoop, null to get all
+ * @param version the controlLoop, null to get all
+ * @return the control loops
+ * @throws ControlLoopException on errors getting the control loops
+ */
+ public ControlLoops getControlLoops(String name, String version) throws ControlLoopException {
+ return intermediaryApi.getControlLoops(name, version);
+ }
+
+ /**
+ * Update the given control loop in the simulator.
+ *
+ * @param controlLoop the control loop to update
+ * @return response simple response returned
+ * @throws ControlLoopException on errors updating the control loop
+ */
+ public TypedSimpleResponse<ControlLoop> updateControlLoop(ControlLoop controlLoop)
+ throws ControlLoopException {
+ TypedSimpleResponse<ControlLoop> response = new TypedSimpleResponse<>();
+ ControlLoop updatedControlLoop = intermediaryApi.updateControlLoopState(
+ controlLoop.getDefinition(), controlLoop.getOrderedState());
+ response.setResponse(updatedControlLoop);
+ return response;
+ }
+
+ /**
+ * Get the simulated control loop elements.
+ *
+ * @param name the controlLoopElement, null to get all
+ * @param version the controlLoopElement, null to get all
+ * @return the control loop elements
+ * @throws ControlLoopException on errors getting the control loop elements
+ */
+ public List<ControlLoopElement> getControlLoopElements(String name, String version) throws ControlLoopException {
+ return intermediaryApi.getControlLoopElements(name, version);
+ }
+
+ /**
+ * Update the given control loop element in the simulator.
+ *
+ * @param element the control loop element to update
+ * @return response simple response returned
+ * @throws ControlLoopException on errors updating the control loop element
+ */
+ public TypedSimpleResponse<ControlLoopElement> updateControlLoopElement(ControlLoopElement element)
+ throws ControlLoopException {
+ TypedSimpleResponse<ControlLoopElement> response = new TypedSimpleResponse<>();
+ response.setResponse(intermediaryApi.updateControlLoopElementState(
+ element.getId(), element.getOrderedState()));
+ return response;
+ }
+
+ /**
+ * Get the current simulated participants.
+ *
+ * @param name the participant, null to get all
+ * @param version the participant, null to get all
+ * @return the list of participants
+ * @throws ControlLoopException on errors getting the participants
+ */
+ public List<Participant> getParticipants(String name, String version) throws ControlLoopException {
+ return intermediaryApi.getParticipants(name, version);
+ }
+
+ /**
+ * Update a simulated participant.
+ *
+ * @param participant the participant to update
+ * @return TypedSimpleResponse simple response
+ * @throws ControlLoopException on errors updating the participant
+ */
+
+ public TypedSimpleResponse<Participant> updateParticipant(Participant participant) throws ControlLoopException {
+ TypedSimpleResponse<Participant> response = new TypedSimpleResponse<>();
+ response.setResponse(intermediaryApi.updateParticipantState(
+ participant.getDefinition(), participant.getParticipantState()));
+ return response;
+ }
+}
diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/rest/SimulationElementController.java b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/rest/SimulationElementController.java
new file mode 100644
index 000000000..f3c146352
--- /dev/null
+++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/rest/SimulationElementController.java
@@ -0,0 +1,194 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.controlloop.participant.simulator.simulation.rest;
+
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import io.swagger.annotations.Authorization;
+import io.swagger.annotations.Extension;
+import io.swagger.annotations.ExtensionProperty;
+import io.swagger.annotations.ResponseHeader;
+import java.util.List;
+import java.util.UUID;
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops;
+import org.onap.policy.clamp.controlloop.models.messages.rest.SimpleResponse;
+import org.onap.policy.clamp.controlloop.models.messages.rest.TypedSimpleResponse;
+import org.onap.policy.clamp.controlloop.participant.simulator.main.rest.RestController;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class to provide REST end points for participant simulator to query/update details of controlLoopElements.
+ */
+public class SimulationElementController extends RestController {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SimulationElementController.class);
+
+ /**
+ * Queries details of all control loop element within the simulator.
+ *
+ * @param requestId request ID used in ONAP logging
+ * @param name the name of the Control Loop element to get, null to get all
+ * @param version the version of the Control Loop element to get, null to get all
+ * @return the control loop elements
+ */
+ // @formatter:off
+ @GET
+ @Path("/elements/{name}/{version}")
+ @ApiOperation(value = "Query details of the requested simulated control loop elements",
+ notes = "Queries details of the requested simulated control loop elements, "
+ + "returning all control loop element details",
+ response = ControlLoops.class,
+ tags = {
+ "Clamp Control Loop Participant Simulator API"
+ },
+ authorizations = @Authorization(value = AUTHORIZATION_TYPE),
+ responseHeaders = {
+ @ResponseHeader(
+ name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION,
+ response = String.class),
+ @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION,
+ response = String.class),
+ @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
+ response = String.class),
+ @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION,
+ response = UUID.class)},
+ extensions = {
+ @Extension(
+ name = EXTENSION_NAME,
+ properties = {
+ @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
+ @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
+ }
+ )
+ }
+ )
+ @ApiResponses(
+ value = {
+ @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
+ @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
+ @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
+ }
+ )
+ // @formatter:on
+ public Response elements(@HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
+ @ApiParam(value = "Control loop element name", required = true) @PathParam("name") String name,
+ @ApiParam(value = "Control loop element version", required = true) @PathParam("version") String version) {
+
+ try {
+ List<ControlLoopElement> response = getSimulationProvider().getControlLoopElements(name, version);
+ return addLoggingHeaders(addVersionControlHeaders(Response.status(Status.OK)), requestId).entity(response)
+ .build();
+
+ } catch (ControlLoopException cle) {
+ LOGGER.warn("get of control loop elements failed", cle);
+ SimpleResponse resp = new SimpleResponse();
+ resp.setErrorDetails(cle.getErrorResponse().getErrorMessage());
+ return addLoggingHeaders(
+ addVersionControlHeaders(Response.status(cle.getErrorResponse().getResponseCode())), requestId)
+ .entity(resp).build();
+ }
+
+ }
+
+ /**
+ * Updates a control loop element in the simulator.
+ *
+ * @param requestId request ID used in ONAP logging
+ * @param body the body of a control loop element
+ * @return a response
+ */
+ // @formatter:off
+ @PUT
+ @Path("/elements")
+ @ApiOperation(
+ value = "Updates simulated control loop elements",
+ notes = "Updates simulated control loop elements, returning the updated control loop definition IDs",
+ response = TypedSimpleResponse.class,
+ tags = {
+ "Clamp Control Loop Participant Simulator API"
+ },
+ authorizations = @Authorization(value = AUTHORIZATION_TYPE),
+ responseHeaders = {
+ @ResponseHeader(
+ name = VERSION_MINOR_NAME,
+ description = VERSION_MINOR_DESCRIPTION,
+ response = String.class),
+ @ResponseHeader(
+ name = VERSION_PATCH_NAME,
+ description = VERSION_PATCH_DESCRIPTION,
+ response = String.class),
+ @ResponseHeader(
+ name = VERSION_LATEST_NAME,
+ description = VERSION_LATEST_DESCRIPTION,
+ response = String.class),
+ @ResponseHeader(
+ name = REQUEST_ID_NAME,
+ description = REQUEST_ID_HDR_DESCRIPTION,
+ response = UUID.class)
+ },
+ extensions = {
+ @Extension(
+ name = EXTENSION_NAME,
+ properties = {
+ @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
+ @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
+ }
+ )
+ }
+ )
+ @ApiResponses(
+ value = {
+ @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
+ @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
+ @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
+ }
+ )
+ // @formatter:on
+ public Response update(@HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
+ @ApiParam(value = "Body of a control loop element", required = true) ControlLoopElement body) {
+
+ try {
+ TypedSimpleResponse<ControlLoopElement> response =
+ getSimulationProvider().updateControlLoopElement(body);
+ return addLoggingHeaders(addVersionControlHeaders(Response.status(Status.OK)), requestId).entity(response)
+ .build();
+
+ } catch (ControlLoopException cle) {
+ LOGGER.warn("update of control loop element failed", cle);
+ TypedSimpleResponse<ControlLoopElement> resp = new TypedSimpleResponse<>();
+ resp.setErrorDetails(cle.getErrorResponse().getErrorMessage());
+ return addLoggingHeaders(
+ addVersionControlHeaders(Response.status(cle.getErrorResponse().getResponseCode())), requestId)
+ .entity(resp).build();
+ }
+ }
+}
diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/rest/SimulationParticipantController.java b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/rest/SimulationParticipantController.java
new file mode 100644
index 000000000..d6ca6d0d1
--- /dev/null
+++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/rest/SimulationParticipantController.java
@@ -0,0 +1,192 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.controlloop.participant.simulator.simulation.rest;
+
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import io.swagger.annotations.Authorization;
+import io.swagger.annotations.Extension;
+import io.swagger.annotations.ExtensionProperty;
+import io.swagger.annotations.ResponseHeader;
+import java.util.List;
+import java.util.UUID;
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant;
+import org.onap.policy.clamp.controlloop.models.messages.rest.SimpleResponse;
+import org.onap.policy.clamp.controlloop.models.messages.rest.TypedSimpleResponse;
+import org.onap.policy.clamp.controlloop.participant.simulator.main.rest.RestController;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class to provide REST end points for participant simulator to query/update details of all participants.
+ */
+public class SimulationParticipantController extends RestController {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SimulationParticipantController.class);
+
+ /**
+ * Queries details of all participants within the simulator.
+ *
+ * @param requestId request ID used in ONAP logging
+ * @param name the name of the participant to get, null to get all
+ * @param version the version of the participant to get, null to get all
+ * @return the participants
+ */
+ // @formatter:off
+ @GET
+ @Path("/participants/{name}/{version}")
+ @ApiOperation(value = "Query details of the requested simulated participants",
+ notes = "Queries details of the requested simulated participants, "
+ + "returning all participant details",
+ response = List.class,
+ tags = {
+ "Clamp Control Loop Participant Simulator API"
+ },
+ authorizations = @Authorization(value = AUTHORIZATION_TYPE),
+ responseHeaders = {
+ @ResponseHeader(
+ name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION,
+ response = String.class),
+ @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION,
+ response = String.class),
+ @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
+ response = String.class),
+ @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION,
+ response = UUID.class)},
+ extensions = {
+ @Extension(
+ name = EXTENSION_NAME,
+ properties = {
+ @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
+ @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
+ }
+ )
+ }
+ )
+ @ApiResponses(
+ value = {
+ @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
+ @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
+ @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
+ }
+ )
+ // @formatter:on
+ public Response participants(@HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
+ @ApiParam(value = "Participant name", required = true) @PathParam("name") String name,
+ @ApiParam(value = "Participant version", required = true) @PathParam("version") String version) {
+
+ try {
+ List<Participant> response = getSimulationProvider().getParticipants(name, version);
+ return addLoggingHeaders(addVersionControlHeaders(Response.status(Status.OK)), requestId).entity(response)
+ .build();
+
+ } catch (ControlLoopException cle) {
+ LOGGER.warn("get of participants failed", cle);
+ SimpleResponse resp = new SimpleResponse();
+ resp.setErrorDetails(cle.getErrorResponse().getErrorMessage());
+ return addLoggingHeaders(
+ addVersionControlHeaders(Response.status(cle.getErrorResponse().getResponseCode())), requestId)
+ .entity(resp).build();
+ }
+
+ }
+
+ /**
+ * Updates a participant in the simulator.
+ *
+ * @param requestId request ID used in ONAP logging
+ * @param body the body of a participant
+ * @return a response
+ */
+ // @formatter:off
+ @PUT
+ @Path("/participants")
+ @ApiOperation(
+ value = "Updates simulated participants",
+ notes = "Updates simulated participants, returning the updated control loop definition IDs",
+ response = TypedSimpleResponse.class,
+ tags = {
+ "Clamp Control Loop Participant Simulator API"
+ },
+ authorizations = @Authorization(value = AUTHORIZATION_TYPE),
+ responseHeaders = {
+ @ResponseHeader(
+ name = VERSION_MINOR_NAME,
+ description = VERSION_MINOR_DESCRIPTION,
+ response = String.class),
+ @ResponseHeader(
+ name = VERSION_PATCH_NAME,
+ description = VERSION_PATCH_DESCRIPTION,
+ response = String.class),
+ @ResponseHeader(
+ name = VERSION_LATEST_NAME,
+ description = VERSION_LATEST_DESCRIPTION,
+ response = String.class),
+ @ResponseHeader(
+ name = REQUEST_ID_NAME,
+ description = REQUEST_ID_HDR_DESCRIPTION,
+ response = UUID.class)
+ },
+ extensions = {
+ @Extension(
+ name = EXTENSION_NAME,
+ properties = {
+ @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
+ @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
+ }
+ )
+ }
+ )
+ @ApiResponses(
+ value = {
+ @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
+ @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
+ @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
+ }
+ )
+ // @formatter:on
+ public Response update(@HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
+ @ApiParam(value = "Body of a participant", required = true) Participant body) {
+
+ try {
+ TypedSimpleResponse<Participant> response = getSimulationProvider().updateParticipant(body);
+ return addLoggingHeaders(addVersionControlHeaders(Response.status(Status.OK)), requestId).entity(response)
+ .build();
+
+ } catch (ControlLoopException cle) {
+ LOGGER.warn("update of participant failed", cle);
+ TypedSimpleResponse<Participant> resp = new TypedSimpleResponse<>();
+ resp.setErrorDetails(cle.getErrorResponse().getErrorMessage());
+ return addLoggingHeaders(
+ addVersionControlHeaders(Response.status(cle.getErrorResponse().getResponseCode())), requestId)
+ .entity(resp).build();
+ }
+ }
+}
diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/CommonParticipantRestServer.java b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/CommonParticipantRestServer.java
new file mode 100644
index 000000000..7aae32629
--- /dev/null
+++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/CommonParticipantRestServer.java
@@ -0,0 +1,228 @@
+
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.controlloop.participant.simulator.main.rest;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException;
+import org.onap.policy.clamp.controlloop.participant.simulator.main.parameters.CommonTestData;
+import org.onap.policy.clamp.controlloop.participant.simulator.main.startstop.Main;
+import org.onap.policy.common.endpoints.event.comm.TopicEndpointManager;
+import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInstance;
+import org.onap.policy.common.gson.GsonMessageBodyHandler;
+import org.onap.policy.common.utils.network.NetworkUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class to perform Rest unit tests.
+ *
+ */
+
+public class CommonParticipantRestServer {
+
+ private static final String CONFIG_FILE = "src/test/resources/parameters/TestConfigParameters.json";
+ private static final Logger LOGGER = LoggerFactory.getLogger(CommonParticipantRestServer.class);
+ public static final String SELF = NetworkUtil.getHostname();
+ public static final String ENDPOINT_PREFIX = "onap/participantsim/v2/";
+ private static int port;
+ private static String httpPrefix;
+ private static Main main;
+
+ /**
+ * Allocates a port for the server, writes a config file, and then starts Main.
+ *
+ * @throws Exception if an error occurs
+ */
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ setUpBeforeClass(true);
+ }
+
+ /**
+ * Allocates a port for the server, writes a config file, and then starts Main, if
+ * specified.
+ *
+ * @param shouldStart {@code true} if Main should be started, {@code false} otherwise
+ * @throws Exception if an error occurs
+ */
+ public static void setUpBeforeClass(boolean shouldStart) throws Exception {
+ port = NetworkUtil.allocPort();
+ httpPrefix = "http://localhost:" + port + "/";
+
+ makeConfigFile();
+ HttpServletServerFactoryInstance.getServerFactory().destroy();
+ TopicEndpointManager.getManager().shutdown();
+
+ if (shouldStart) {
+ startMain();
+ }
+ }
+
+ /**
+ * Stops Main.
+ */
+ @AfterClass
+ public static void teardownAfterClass() {
+ try {
+ stopMain();
+
+ } catch (ControlLoopException exp) {
+ LOGGER.error("cannot stop main", exp);
+ }
+ }
+
+ /**
+ * Set up.
+ *
+ * @throws Exception if an error occurs
+ */
+ @Before
+ public void setUp() throws Exception {
+ // restart, if not currently running
+ if (main == null) {
+ startMain();
+ }
+ }
+
+ /**
+ * Verifies that an endpoint appears within the swagger response.
+ *
+ * @param endpoint the endpoint of interest
+ * @throws Exception if an error occurs
+ */
+ protected void testSwagger(final String endpoint) throws Exception {
+ final Invocation.Builder invocationBuilder = sendFqeRequest(httpPrefix + "swagger.yaml", true);
+ final String resp = invocationBuilder.get(String.class);
+ assertTrue(resp.contains(ENDPOINT_PREFIX + endpoint + ":"));
+ }
+
+ /**
+ * Makes a parameter configuration file.
+ *
+ * @throws IOException if an error occurs writing the configuration file
+ * @throws FileNotFoundException if an error occurs writing the configuration file
+ *
+ * @throws Exception if an error occurs
+ */
+ private static void makeConfigFile() throws FileNotFoundException, IOException {
+ String json = CommonTestData.getParticipantParameterGroupAsString(port);
+ File file = new File(String.format(CONFIG_FILE, port));
+ file.deleteOnExit();
+ try (FileOutputStream output = new FileOutputStream(file)) {
+ output.write(json.getBytes(StandardCharsets.UTF_8));
+ }
+ }
+
+ /**
+ * Starts the "Main".
+ *
+ * @throws InterruptedException
+ *
+ * @throws Exception if an error occurs
+ */
+ protected static void startMain() throws InterruptedException {
+ // make sure port is available
+ if (NetworkUtil.isTcpPortOpen("localhost", port, 1, 1L)) {
+ throw new IllegalStateException("port " + port + " is still in use");
+ }
+
+ final String[] configParameters = { "-c", CONFIG_FILE };
+
+ main = new Main(configParameters);
+
+ if (!NetworkUtil.isTcpPortOpen("localhost", port, 40, 250L)) {
+ throw new IllegalStateException("server is not listening on port " + port);
+ }
+ }
+
+ /**
+ * Stops the "Main".
+ *
+ * @throws ControlLoopException
+ *
+ * @throws Exception if an error occurs
+ */
+ private static void stopMain() throws ControlLoopException {
+ if (main != null) {
+ main.shutdown();
+ main = null;
+ }
+ }
+
+ /**
+ * Sends a request to an endpoint.
+ *
+ * @param endpoint the target endpoint
+ * @return a request builder
+ * @throws Exception if an error occurs
+ */
+ protected Invocation.Builder sendRequest(final String endpoint) throws Exception {
+ return sendFqeRequest(httpPrefix + ENDPOINT_PREFIX + endpoint, true);
+ }
+
+ /**
+ * Sends a request to an endpoint, without any authorization header.
+ *
+ * @param endpoint the target endpoint
+ * @return a request builder
+ * @throws Exception if an error occurs
+ */
+ protected Invocation.Builder sendNoAuthRequest(final String endpoint) throws Exception {
+ return sendFqeRequest(httpPrefix + ENDPOINT_PREFIX + endpoint, false);
+ }
+
+ /**
+ * Sends a request to a fully qualified endpoint.
+ *
+ * @param fullyQualifiedEndpoint the fully qualified target endpoint
+ * @param includeAuth if authorization header should be included
+ * @return a request builder
+ * @throws Exception if an error occurs
+ */
+ protected Invocation.Builder sendFqeRequest(final String fullyQualifiedEndpoint, boolean includeAuth)
+ throws Exception {
+ final Client client = ClientBuilder.newBuilder().build();
+ client.property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, "true");
+ client.register(GsonMessageBodyHandler.class);
+ if (includeAuth) {
+ client.register(HttpAuthenticationFeature.basic("healthcheck", "zb!XztG34"));
+ }
+ final WebTarget webTarget = client.target(fullyQualifiedEndpoint);
+ return webTarget.request(MediaType.APPLICATION_JSON);
+ }
+}
diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/RestControllerTest.java b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/RestControllerTest.java
new file mode 100644
index 000000000..c7a39c48b
--- /dev/null
+++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/RestControllerTest.java
@@ -0,0 +1,72 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.controlloop.participant.simulator.main.rest;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.UUID;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.ResponseBuilder;
+import org.junit.Before;
+import org.junit.Test;
+
+public class RestControllerTest {
+
+ private RestController ctlr;
+ private ResponseBuilder bldr;
+
+ @Before
+ public void setUp() {
+ ctlr = new RestController();
+ bldr = Response.status(Response.Status.OK);
+ }
+
+ @Test
+ public void testProduces() {
+ Produces annotation = RestController.class.getAnnotation(Produces.class);
+ assertNotNull(annotation);
+ assertThat(annotation.value()).contains(MediaType.APPLICATION_JSON)
+ .contains(RestController.APPLICATION_YAML);
+ }
+
+ @Test
+ public void testAddVersionControlHeaders() {
+ Response resp = ctlr.addVersionControlHeaders(bldr).build();
+ assertEquals("0", resp.getHeaderString(RestController.VERSION_MINOR_NAME));
+ assertEquals("0", resp.getHeaderString(RestController.VERSION_PATCH_NAME));
+ assertEquals("1.0.0", resp.getHeaderString(RestController.VERSION_LATEST_NAME));
+ }
+
+ @Test
+ public void testAddLoggingHeaders_Null() {
+ Response resp = ctlr.addLoggingHeaders(bldr, null).build();
+ assertNotNull(resp.getHeaderString(RestController.REQUEST_ID_NAME));
+ }
+
+ @Test
+ public void testAddLoggingHeaders_NonNull() {
+ UUID uuid = UUID.randomUUID();
+ Response resp = ctlr.addLoggingHeaders(bldr, uuid).build();
+ assertEquals(uuid.toString(), resp.getHeaderString(RestController.REQUEST_ID_NAME));
+ }
+}
diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/TestListenerUtils.java b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/TestListenerUtils.java
new file mode 100644
index 000000000..7b7dd2d84
--- /dev/null
+++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/TestListenerUtils.java
@@ -0,0 +1,128 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.controlloop.participant.simulator.main.rest;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState;
+import org.onap.policy.clamp.controlloop.participant.simulator.main.parameters.CommonTestData;
+import org.onap.policy.common.utils.coder.Coder;
+import org.onap.policy.common.utils.coder.StandardCoder;
+import org.onap.policy.common.utils.coder.YamlJsonTranslator;
+import org.onap.policy.common.utils.resources.ResourceUtils;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TestListenerUtils {
+
+ private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator();
+ private static final Coder CODER = new StandardCoder();
+ static CommonTestData commonTestData = new CommonTestData();
+ private static RestController restController;
+ private static final Logger LOGGER = LoggerFactory.getLogger(TestListenerUtils.class);
+
+ private TestListenerUtils() {}
+
+ /**
+ * Method to create a controlLoop from a yaml file.
+ *
+ * @return ControlLoop controlloop
+ */
+ public static ControlLoop createControlLoop() {
+ ControlLoop controlLoop = new ControlLoop();
+ List<ControlLoopElement> elements = new ArrayList<>();
+ ToscaServiceTemplate toscaServiceTemplate = testControlLoopRead();
+ Map<String, ToscaNodeTemplate> nodeTemplatesMap = toscaServiceTemplate
+ .getToscaTopologyTemplate().getNodeTemplates();
+ for (Map.Entry<String, ToscaNodeTemplate> toscaInputEntry : nodeTemplatesMap.entrySet()) {
+ ControlLoopElement clElement = new ControlLoopElement();
+ clElement.setId(UUID.randomUUID());
+
+ ToscaConceptIdentifier clElementParticipantId = new ToscaConceptIdentifier();
+ clElementParticipantId.setName(toscaInputEntry.getKey());
+ clElementParticipantId.setVersion(toscaInputEntry.getValue().getVersion());
+ clElement.setParticipantId(clElementParticipantId);
+
+ clElement.setDefinition(clElementParticipantId);
+ clElement.setState(ControlLoopState.UNINITIALISED);
+ clElement.setDescription(toscaInputEntry.getValue().getDescription());
+ clElement.setOrderedState(ControlLoopOrderedState.UNINITIALISED);
+ elements.add(clElement);
+ }
+ controlLoop.setElements(elements);
+ controlLoop.setName("PMSHInstance0");
+ controlLoop.setVersion("1.0.0");
+
+ ToscaConceptIdentifier definition = new ToscaConceptIdentifier();
+ definition.setName("PMSHInstance0");
+ definition.setVersion("1.0.0");
+ controlLoop.setDefinition(definition);
+
+ return controlLoop;
+ }
+
+ private static ToscaServiceTemplate testControlLoopRead() {
+ Set<String> controlLoopDirectoryContents = ResourceUtils
+ .getDirectoryContents("src/test/resources/rest/servicetemplates");
+
+ boolean atLeastOneControlLoopTested = false;
+ ToscaServiceTemplate toscaServiceTemplate = null;
+
+ for (String controlLoopFilePath : controlLoopDirectoryContents) {
+ if (!controlLoopFilePath.endsWith(".yaml")) {
+ continue;
+ }
+ atLeastOneControlLoopTested = true;
+ toscaServiceTemplate = testControlLoopYamlSerialization(controlLoopFilePath);
+ }
+
+ assertTrue(atLeastOneControlLoopTested);
+ return toscaServiceTemplate;
+ }
+
+ private static ToscaServiceTemplate testControlLoopYamlSerialization(String controlLoopFilePath) {
+ try {
+ String controlLoopString = ResourceUtils.getResourceAsString(controlLoopFilePath);
+ if (controlLoopString == null) {
+ throw new FileNotFoundException(controlLoopFilePath);
+ }
+
+ ToscaServiceTemplate serviceTemplate = yamlTranslator.fromYaml(
+ controlLoopString, ToscaServiceTemplate.class);
+ return serviceTemplate;
+ } catch (FileNotFoundException e) {
+ LOGGER.error("cannot find YAML file", controlLoopFilePath);
+ throw new IllegalArgumentException(e);
+ }
+ }
+}
diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/TestSimulationRestController.java b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/TestSimulationRestController.java
new file mode 100644
index 000000000..7adc88d09
--- /dev/null
+++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/TestSimulationRestController.java
@@ -0,0 +1,153 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.controlloop.participant.simulator.main.rest;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantState;
+import org.onap.policy.clamp.controlloop.models.messages.rest.TypedSimpleResponse;
+import org.onap.policy.clamp.controlloop.participant.simulator.main.parameters.CommonTestData;
+import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+
+/**
+ * Class to perform unit test of {@link TestSimulationRestController}.
+ */
+public class TestSimulationRestController extends CommonParticipantRestServer {
+ private static final String PARTICIPANTS_ENDPOINT = "participants";
+ private static final String ELEMENTS_ENDPOINT = "elements";
+ private static final CommInfrastructure INFRA = CommInfrastructure.NOOP;
+ private static final String TOPIC = "my-topic";
+ static CommonTestData commonTestData = new CommonTestData();
+ private static RestController restController;
+
+ /**
+ * Setup before class, instantiate SimulationProvider.
+ *
+ */
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ CommonParticipantRestServer.setUpBeforeClass();
+ }
+
+ @AfterClass
+ public static void teardownAfterClass() {
+ CommonParticipantRestServer.teardownAfterClass();
+ }
+
+ @Test
+ public void testSwagger() throws Exception {
+ super.testSwagger(ELEMENTS_ENDPOINT);
+ }
+
+ @Test
+ public void testQuery_Unauthorized() throws Exception {
+ Invocation.Builder invocationBuilder = super.sendNoAuthRequest(ELEMENTS_ENDPOINT);
+ Response rawresp = invocationBuilder.buildGet().invoke();
+ assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), rawresp.getStatus());
+ }
+
+ @Test
+ public void testQueryParticipants() throws Exception {
+ Participant participant = new Participant();
+ ToscaConceptIdentifier participantId = CommonTestData.getParticipantId();
+ participant.setDefinition(participantId);
+ participant.setName(participantId.getName());
+ participant.setVersion(participantId.getVersion());
+
+ // GET REST call for querying the participants
+ Invocation.Builder invocationBuilder =
+ super.sendRequest(PARTICIPANTS_ENDPOINT + "/" + participant.getKey().getName()
+ + "/" + participant.getVersion());
+
+ Response rawresp = invocationBuilder.buildGet().invoke();
+ // Response is not OK, as handling is not done
+ assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), rawresp.getStatus());
+ }
+
+ @Test
+ public void testQueryControlLoopElements() throws Exception {
+ // GET REST call for querying the controlLoop elements
+ Invocation.Builder invocationBuilder =
+ super.sendRequest(ELEMENTS_ENDPOINT + "/" + "PMSHInstance0" + "/" + "1.0.0");
+
+ Response rawresp = invocationBuilder.buildGet().invoke();
+ // Response is not OK, as handling is not done
+ assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), rawresp.getStatus());
+ }
+
+ @Test
+ public void testUpdateParticipant() throws Exception {
+ Participant participant = new Participant();
+ ToscaConceptIdentifier participantId = CommonTestData.getParticipantId();
+ participant.setDefinition(participantId);
+ participant.setName(participantId.getName());
+ participant.setVersion(participantId.getVersion());
+
+ List<Participant> participants = new ArrayList<>();
+ participants.add(participant);
+ assertEquals(ParticipantState.UNKNOWN, participants.get(0).getParticipantState());
+ // Change the state of the participant to PASSIVE from UNKNOWN
+ participants.get(0).setParticipantState(ParticipantState.PASSIVE);
+ Entity<Participant> entParticipant = Entity.entity(participants.get(0), MediaType.APPLICATION_JSON);
+
+ // PUT REST call for updating Participant
+ Invocation.Builder invocationBuilder = sendRequest(PARTICIPANTS_ENDPOINT);
+ Response rawresp = invocationBuilder.put(entParticipant);
+ TypedSimpleResponse<Participant> resp = rawresp.readEntity(TypedSimpleResponse.class);
+ // Response is not OK, as handling is not done
+ assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), rawresp.getStatus());
+ }
+
+ @Test
+ public void testUpdateControlLoopElement() throws Exception {
+ ControlLoop controlLoop = TestListenerUtils.createControlLoop();
+ List<ControlLoopElement> controlLoopElements = controlLoop.getElements();
+
+ // Check the initial state on the ControlLoopElement, which is UNINITIALISED
+ assertEquals(ControlLoopOrderedState.UNINITIALISED, controlLoopElements.get(0).getOrderedState());
+
+ // Change the state of the ControlLoopElement to PASSIVE from UNINITIALISED
+ controlLoopElements.get(0).setOrderedState(ControlLoopOrderedState.PASSIVE);
+ Entity<ControlLoopElement> entClElement = Entity.entity(controlLoopElements.get(0), MediaType.APPLICATION_JSON);
+
+ // PUT REST call for updating ControlLoopElement
+ Invocation.Builder invocationBuilder = sendRequest(ELEMENTS_ENDPOINT);
+ Response rawresp = invocationBuilder.put(entClElement);
+ TypedSimpleResponse<ControlLoopElement> resp = rawresp.readEntity(TypedSimpleResponse.class);
+ // Response is not OK, as handling is not done
+ assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), rawresp.getStatus());
+ }
+}
+
diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/parameters/logback-test.xml b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/parameters/logback-test.xml
deleted file mode 100644
index 54b578653..000000000
--- a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/parameters/logback-test.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ============LICENSE_START=======================================================
- Copyright (C) 2021 Nordix Foundation.
- ================================================================================
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- SPDX-License-Identifier: Apache-2.0
- ============LICENSE_END=========================================================
--->
-
-<configuration>
-
- <contextName>Participant</contextName>
- <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
- <property name="LOG_DIR" value="${java.io.tmpdir}/clamp_logging/" />
-
- <!-- USE FOR STD OUT ONLY -->
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <Pattern>%d %level %msg%n</Pattern>
- </encoder>
- </appender>
-
- <root level="info">
- <appender-ref ref="STDOUT" />
- </root>
-
- <logger name="org.onap.policy.clamp.controlloop.participant" level="trace" additivity="false">
- <appender-ref ref="STDOUT" />
- </logger>
-</configuration>
diff --git a/tosca-controlloop/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryApi.java b/tosca-controlloop/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryApi.java
new file mode 100644
index 000000000..6c3e029fe
--- /dev/null
+++ b/tosca-controlloop/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryApi.java
@@ -0,0 +1,119 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.controlloop.participant.intermediary.api;
+
+import java.util.List;
+import java.util.UUID;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatistics;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantState;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatistics;
+import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+
+/**
+ * This interface is used by participant implementations to use the participant intermediary.
+ */
+public interface ParticipantIntermediaryApi {
+ /**
+ * Initialise the participant intermediary.
+ *
+ * @param parameters the parameters for the intermediary
+ */
+ public void init(ParticipantIntermediaryParameters parameters);
+
+ /**
+ * Close the intermediary.
+ */
+ public void close();
+
+ /**
+ * Get participants loops from the intermediary API.
+ *
+ * @param name the participant name, null for all
+ * @param version the participant version, null for all
+ * @return the participants
+ */
+ public List<Participant> getParticipants(String name, String version);
+
+ /**
+ * Update the state of a participant.
+ *
+ * @param definition the definition of the participant to update the state on
+ * @param state the state of the participant
+ * @return updated participant
+ */
+ public Participant updateParticipantState(ToscaConceptIdentifier definition, ParticipantState state);
+
+ /**
+ * Update the statistics of a participant.
+ *
+ * @param participantStatistics the statistics of the participant
+ */
+ public void updateParticipantStatistics(ParticipantStatistics participantStatistics);
+
+ /**
+ * Get control loops from the intermediary API.
+ *
+ * @param name the control loop element name, null for all
+ * @param version the control loop element version, null for all
+ * @return the control loop elements
+ */
+ public ControlLoops getControlLoops(String name, String version);
+
+ /**
+ * Get control loop elements from the intermediary API.
+ *
+ * @param name the control loop element name, null for all
+ * @param version the control loop element version, null for all
+ * @return the control loop elements
+ */
+ public List<ControlLoopElement> getControlLoopElements(String name, String version);
+
+ /**
+ * Update the state of a control loop.
+ *
+ * @param definition the ID of the control loop to update the state on
+ * @param state the state of the control loop
+ * @return ControlLoop updated control loop
+ */
+ public ControlLoop updateControlLoopState(ToscaConceptIdentifier definition, ControlLoopOrderedState state);
+
+ /**
+ * Update the state of a control loop element.
+ *
+ * @param id the ID of the control loop element to update the state on
+ * @param state the state of the control loop element
+ * @return ControlLoopElement updated control loop element
+ */
+ public ControlLoopElement updateControlLoopElementState(UUID id, ControlLoopOrderedState state);
+
+ /**
+ * Update the control loop element statistics.
+ *
+ * @param elementStatistics the updated statistics
+ */
+ public void updateControlLoopElementStatistics(ClElementStatistics elementStatistics);
+}
diff --git a/tosca-controlloop/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryFactory.java b/tosca-controlloop/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryFactory.java
new file mode 100644
index 000000000..d7cc4b2ed
--- /dev/null
+++ b/tosca-controlloop/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryFactory.java
@@ -0,0 +1,38 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.controlloop.participant.intermediary.api;
+
+import org.onap.policy.clamp.controlloop.participant.intermediary.api.impl.ParticipantIntermediaryApiImpl;
+
+/**
+ * Factory class for creating {@link ParticipantIntermediaryApi} instances.
+ */
+public class ParticipantIntermediaryFactory {
+
+ /**
+ * Create an implementation of the {@link ParticipantIntermediaryApi} interface.
+ *
+ * @return the implementation of the API
+ */
+ public ParticipantIntermediaryApi createApiImplementation() {
+ return new ParticipantIntermediaryApiImpl();
+ }
+}
diff --git a/tosca-controlloop/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java b/tosca-controlloop/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java
new file mode 100644
index 000000000..939f927e6
--- /dev/null
+++ b/tosca-controlloop/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java
@@ -0,0 +1,88 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.controlloop.participant.intermediary.api.impl;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatistics;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantState;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatistics;
+import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi;
+import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+
+/**
+ * This class is api implementation used by participant intermediary.
+ */
+public class ParticipantIntermediaryApiImpl implements ParticipantIntermediaryApi {
+
+ @Override
+ public void init(ParticipantIntermediaryParameters parameters) {
+ }
+
+ @Override
+ public void close() {
+ }
+
+ @Override
+ public List<Participant> getParticipants(String name, String version) {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public Participant updateParticipantState(ToscaConceptIdentifier definition, ParticipantState state) {
+ return null;
+ }
+
+ @Override
+ public void updateParticipantStatistics(ParticipantStatistics participantStatistics) {
+ }
+
+ @Override
+ public ControlLoops getControlLoops(String name, String version) {
+ return null;
+ }
+
+ @Override
+ public List<ControlLoopElement> getControlLoopElements(String name, String version) {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public ControlLoop updateControlLoopState(ToscaConceptIdentifier definition, ControlLoopOrderedState state) {
+ return null;
+ }
+
+ @Override
+ public ControlLoopElement updateControlLoopElementState(UUID id, ControlLoopOrderedState state) {
+ return null;
+ }
+
+ @Override
+ public void updateControlLoopElementStatistics(ClElementStatistics elementStatistics) {
+ }
+}