summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorSirisha_Manchikanti <sirisha.manchikanti@est.tech>2021-12-14 18:12:07 +0000
committerSirisha_Manchikanti <sirisha.manchikanti@est.tech>2022-01-06 13:12:50 +0000
commit3d170c6e14976549cd2edc405c5c242110bff2ff (patch)
tree2201c54f4c9a227b4337c9a640ab2e2b8c1cc630 /plugins
parent5f46449a3a73a101fb6e7926dd48e1672ad3ed7b (diff)
Add ControlLoop distribution to runtime
This commit unpacks the csar received either from SDC or for local verification from file-system, prepares the toscaservicetemplate with needed node-types and data-types, forwards the template to controlloop runtime components for commisioning of controlloop. Issue-ID: POLICY-3808 Signed-off-by: Sirisha_Manchikanti <sirisha.manchikanti@est.tech> Change-Id: Ib3600542aca7b32ae19242c2f924bdaf2ab870a8
Diffstat (limited to 'plugins')
-rw-r--r--plugins/forwarding-plugins/src/main/java/org/onap/policy/distribution/forwarding/lifecycle/api/LifecycleApiControlLoopForwarder.java121
-rw-r--r--plugins/forwarding-plugins/src/main/java/org/onap/policy/distribution/forwarding/lifecycle/api/LifecycleApiControlLoopForwarderParameters.java47
-rw-r--r--plugins/forwarding-plugins/src/test/java/org/onap/policy/distribution/forwarding/lifecycle/api/LifecycleApiControlLoopForwarderParametersTest.java88
-rw-r--r--plugins/forwarding-plugins/src/test/java/org/onap/policy/distribution/forwarding/lifecycle/api/LifecycleApiControlLoopForwarderTest.java115
-rw-r--r--plugins/forwarding-plugins/src/test/java/org/onap/policy/distribution/forwarding/testclasses/LifecycleApiControlLoopSimulatorEndpoint.java54
-rw-r--r--plugins/forwarding-plugins/src/test/java/org/onap/policy/distribution/forwarding/testclasses/LifecycleApiControlLoopSimulatorMain.java67
-rw-r--r--plugins/forwarding-plugins/src/test/resources/parameters/LifecycleApiControlLoopForwarderParameters.json10
-rw-r--r--plugins/forwarding-plugins/src/test/resources/parameters/LifecycleApiControlLoopForwarderParametersInvalid.json10
-rw-r--r--plugins/forwarding-plugins/src/test/resources/parameters/sample_control_loop.json1022
-rw-r--r--plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/decoding/policy/file/ControlLoopDecoderFileInCsar.java117
-rw-r--r--plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/decoding/policy/file/ControlLoopDecoderFileInCsarParameterGroup.java44
-rw-r--r--plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/decoding/policy/file/PolicyDecoderFileInCsarToPolicy.java80
-rw-r--r--plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/util/ReceptionUtil.java92
-rw-r--r--plugins/reception-plugins/src/test/java/org/onap/policy/distribution/reception/decoding/policy/file/ControlLoopDecoderFileInCsarParameterGroupTest.java67
-rw-r--r--plugins/reception-plugins/src/test/java/org/onap/policy/distribution/reception/decoding/policy/file/ControlLoopDecoderFileInCsarTest.java96
-rw-r--r--plugins/reception-plugins/src/test/resources/parameters/FileInCsarControlLoopDecoderParameters.json3
-rw-r--r--plugins/reception-plugins/src/test/resources/parameters/FileInCsarControlLoopDecoderParametersInvalid.json3
-rw-r--r--plugins/reception-plugins/src/test/resources/service-Sampleservice-controlloop.csarbin0 -> 79322 bytes
18 files changed, 1967 insertions, 69 deletions
diff --git a/plugins/forwarding-plugins/src/main/java/org/onap/policy/distribution/forwarding/lifecycle/api/LifecycleApiControlLoopForwarder.java b/plugins/forwarding-plugins/src/main/java/org/onap/policy/distribution/forwarding/lifecycle/api/LifecycleApiControlLoopForwarder.java
new file mode 100644
index 00000000..605c68cd
--- /dev/null
+++ b/plugins/forwarding-plugins/src/main/java/org/onap/policy/distribution/forwarding/lifecycle/api/LifecycleApiControlLoopForwarder.java
@@ -0,0 +1,121 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * Modifications Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.distribution.forwarding.lifecycle.api;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.onap.policy.common.endpoints.http.client.HttpClient;
+import org.onap.policy.common.endpoints.http.client.HttpClientConfigException;
+import org.onap.policy.common.endpoints.http.client.HttpClientFactoryInstance;
+import org.onap.policy.common.parameters.ParameterService;
+import org.onap.policy.distribution.forwarding.PolicyForwarder;
+import org.onap.policy.distribution.forwarding.PolicyForwardingException;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaEntity;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class provides an implementation of {@link PolicyForwarder} interface for forwarding the
+ * controlloop design template to the life cycle api's of controlloop components.
+ *
+ * @author Sirisha Manchikanti (sirisha.manchikanti@est.tech)
+ */
+public class LifecycleApiControlLoopForwarder implements PolicyForwarder {
+
+ private static final String COMMISSION_CONTROLLOOP_URI = "/onap/controlloop/v2/commission";
+ private static final Logger LOGGER = LoggerFactory.getLogger(LifecycleApiControlLoopForwarder.class);
+
+ private LifecycleApiControlLoopForwarderParameters forwarderParameters;
+ private HttpClient controlLoopClient;
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void configure(final String parameterGroupName) throws HttpClientConfigException {
+ forwarderParameters = ParameterService.get(parameterGroupName);
+
+ controlLoopClient = HttpClientFactoryInstance.getClientFactory().build(
+ forwarderParameters.getControlLoopRuntimeParameters());
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void forward(final Collection<ToscaEntity> entities) throws PolicyForwardingException {
+ final List<ToscaEntity> failedEntities = new ArrayList<>();
+ for (final ToscaEntity entity : entities) {
+ forwardSingleEntity(failedEntities, entity);
+ }
+ if (!failedEntities.isEmpty()) {
+ throw new PolicyForwardingException(
+ "Failed forwarding the following entities: " + Arrays.toString(failedEntities.toArray()));
+ }
+ }
+
+ private void forwardSingleEntity(final List<ToscaEntity> failedEntities, final ToscaEntity entity) {
+ try {
+ if (entity instanceof ToscaServiceTemplate) {
+ final var toscaServiceTemplate = (ToscaServiceTemplate) entity;
+ if (null != toscaServiceTemplate.getToscaTopologyTemplate()
+ && null != toscaServiceTemplate.getNodeTypes()
+ && null != toscaServiceTemplate.getDataTypes()) {
+ commissionControlLoop(toscaServiceTemplate);
+ }
+ } else {
+ throw new PolicyForwardingException("The entity is not of type ToscaServiceTemplate - " + entity);
+ }
+ } catch (final Exception exp) {
+ LOGGER.error(exp.getMessage(), exp);
+ failedEntities.add(entity);
+ }
+ }
+
+ private Response commissionControlLoop(final ToscaServiceTemplate toscaServiceTemplate)
+ throws PolicyForwardingException {
+ return invokeHttpClient(Entity.entity(toscaServiceTemplate, MediaType.APPLICATION_JSON),
+ COMMISSION_CONTROLLOOP_URI);
+ }
+
+ private Response invokeHttpClient(final Entity<?> entity, final String path)
+ throws PolicyForwardingException {
+ var response = controlLoopClient.post(path, entity, Map.of(HttpHeaders.ACCEPT,
+ MediaType.APPLICATION_JSON, HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON));
+ if (response.getStatus() / 100 != 2) {
+ LOGGER.error(
+ "Invocation of path {} failed for entity {}. Response status: {}, Response status info: {}",
+ path, entity, response.getStatus(), response.getStatusInfo());
+ throw new PolicyForwardingException("Failed creating the entity - " + entity);
+ }
+ return response;
+ }
+}
+
diff --git a/plugins/forwarding-plugins/src/main/java/org/onap/policy/distribution/forwarding/lifecycle/api/LifecycleApiControlLoopForwarderParameters.java b/plugins/forwarding-plugins/src/main/java/org/onap/policy/distribution/forwarding/lifecycle/api/LifecycleApiControlLoopForwarderParameters.java
new file mode 100644
index 00000000..d1abce71
--- /dev/null
+++ b/plugins/forwarding-plugins/src/main/java/org/onap/policy/distribution/forwarding/lifecycle/api/LifecycleApiControlLoopForwarderParameters.java
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * Modifications Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.distribution.forwarding.lifecycle.api;
+
+import lombok.Getter;
+import org.onap.policy.common.endpoints.parameters.RestClientParameters;
+import org.onap.policy.common.parameters.annotations.NotBlank;
+import org.onap.policy.common.parameters.annotations.NotNull;
+import org.onap.policy.common.parameters.annotations.Valid;
+import org.onap.policy.distribution.main.parameters.PolicyForwarderConfigurationParameterGroup;
+
+/**
+ * Holds the parameters for the {@link LifecycleApiControlLoopForwarder}.
+ *
+ * @author Sirisha Manchikanti (sirisha.manchikanti@est.tech)
+ */
+@Getter
+@NotNull
+@NotBlank
+public class LifecycleApiControlLoopForwarderParameters extends PolicyForwarderConfigurationParameterGroup {
+ public static final String CONTROLLOOP_FORWARDER_PLUGIN_CLASS = LifecycleApiControlLoopForwarder.class.getName();
+
+ private @Valid RestClientParameters controlLoopRuntimeParameters;
+
+ public LifecycleApiControlLoopForwarderParameters() {
+ super(LifecycleApiControlLoopForwarderParameters.class.getSimpleName());
+ }
+}
diff --git a/plugins/forwarding-plugins/src/test/java/org/onap/policy/distribution/forwarding/lifecycle/api/LifecycleApiControlLoopForwarderParametersTest.java b/plugins/forwarding-plugins/src/test/java/org/onap/policy/distribution/forwarding/lifecycle/api/LifecycleApiControlLoopForwarderParametersTest.java
new file mode 100644
index 00000000..ba8d9bfb
--- /dev/null
+++ b/plugins/forwarding-plugins/src/test/java/org/onap/policy/distribution/forwarding/lifecycle/api/LifecycleApiControlLoopForwarderParametersTest.java
@@ -0,0 +1,88 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * Modifications Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.distribution.forwarding.lifecycle.api;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.onap.policy.common.parameters.ValidationStatus;
+import org.onap.policy.distribution.forwarding.testclasses.CommonTestData;
+
+/**
+ * Class to perform unit test of {@link LifecycleApiControlLoopForwarderParameters}.
+ *
+ * @author Sirisha Manchikanti (sirisha.manchikanti@est.tech)
+ */
+public class LifecycleApiControlLoopForwarderParametersTest {
+
+ private static final String CONTROLLOOP_RUNTIME_HOST_NAME = "0.0.0.0";
+ private static final int CONTROLLOOP_RUNTIME_PORT = 6969;
+ private static final String CONTROLLOOP_RUNTIME_USER = "policyadmin";
+ private static final String CONTROLLOOP_RUNTIME_PASSWORD = "zb!XztG34";
+
+
+ @Test
+ public void testValidParameters() {
+ final LifecycleApiControlLoopForwarderParameters configurationParameters =
+ CommonTestData.getPolicyForwarderParameters(
+ "src/test/resources/parameters/LifecycleApiControlLoopForwarderParameters.json",
+ LifecycleApiControlLoopForwarderParameters.class);
+
+ assertEquals(LifecycleApiControlLoopForwarderParameters.class.getSimpleName(),
+ configurationParameters.getName());
+
+ assertEquals(CONTROLLOOP_RUNTIME_HOST_NAME,
+ configurationParameters.getControlLoopRuntimeParameters().getHostname());
+ assertEquals(CONTROLLOOP_RUNTIME_PORT,
+ configurationParameters.getControlLoopRuntimeParameters().getPort());
+ assertFalse(configurationParameters.getControlLoopRuntimeParameters().isUseHttps());
+ assertEquals(CONTROLLOOP_RUNTIME_USER,
+ configurationParameters.getControlLoopRuntimeParameters().getUserName());
+ assertEquals(CONTROLLOOP_RUNTIME_PASSWORD,
+ configurationParameters.getControlLoopRuntimeParameters().getPassword());
+
+ assertThat(configurationParameters.validate().getResult()).isNull();
+ assertEquals(ValidationStatus.CLEAN, configurationParameters.validate().getStatus());
+ }
+
+ @Test
+ public void testInvalidParameters() {
+ final LifecycleApiForwarderParameters configurationParameters =
+ CommonTestData.getPolicyForwarderParameters(
+ "src/test/resources/parameters/LifecycleApiPolicyForwarderParametersInvalid.json",
+ LifecycleApiForwarderParameters.class);
+
+ assertEquals(ValidationStatus.INVALID, configurationParameters.validate().getStatus());
+ }
+
+ @Test
+ public void testEmptyParameters() {
+ final LifecycleApiForwarderParameters configurationParameters =
+ CommonTestData.getPolicyForwarderParameters("src/test/resources/parameters/EmptyParameters.json",
+ LifecycleApiForwarderParameters.class);
+
+ assertEquals(ValidationStatus.INVALID, configurationParameters.validate().getStatus());
+ }
+}
diff --git a/plugins/forwarding-plugins/src/test/java/org/onap/policy/distribution/forwarding/lifecycle/api/LifecycleApiControlLoopForwarderTest.java b/plugins/forwarding-plugins/src/test/java/org/onap/policy/distribution/forwarding/lifecycle/api/LifecycleApiControlLoopForwarderTest.java
new file mode 100644
index 00000000..047482ef
--- /dev/null
+++ b/plugins/forwarding-plugins/src/test/java/org/onap/policy/distribution/forwarding/lifecycle/api/LifecycleApiControlLoopForwarderTest.java
@@ -0,0 +1,115 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * Modifications Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.distribution.forwarding.lifecycle.api;
+
+import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.policy.common.parameters.ParameterGroup;
+import org.onap.policy.common.parameters.ParameterService;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.coder.StandardCoder;
+import org.onap.policy.common.utils.network.NetworkUtil;
+import org.onap.policy.common.utils.resources.ResourceUtils;
+import org.onap.policy.distribution.forwarding.PolicyForwardingException;
+import org.onap.policy.distribution.forwarding.testclasses.CommonTestData;
+import org.onap.policy.distribution.forwarding.testclasses.LifecycleApiControlLoopSimulatorMain;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaEntity;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+
+/**
+ * Class to perform unit test of {@link LifecycleApiControlLoopForwarder}.
+ *
+ * @author Sirisha Manchikanti (sirisha.manchikanti@est.tech)
+ */
+public class LifecycleApiControlLoopForwarderTest {
+
+ private static final String CONTROL_LOOP = "src/test/resources/parameters/sample_control_loop.json";
+ private final StandardCoder standardCoder = new StandardCoder();
+ private static final LifecycleApiControlLoopSimulatorMain simulator = new LifecycleApiControlLoopSimulatorMain();
+
+ /**
+ * Set up.
+ *
+ * @throws CoderException if any error occurs
+ * @throws PolicyForwardingException if any error occurs
+ * @throws InterruptedException if any error occurs
+ */
+ @BeforeClass
+ public static void setUp() throws PolicyForwardingException, CoderException, InterruptedException {
+ final ParameterGroup parameterGroup = CommonTestData.getPolicyForwarderParameters(
+ "src/test/resources/parameters/LifecycleApiControlLoopForwarderParameters.json",
+ LifecycleApiControlLoopForwarderParameters.class);
+ ParameterService.register(parameterGroup);
+ simulator.startLifecycycleApiSimulator();
+ if (!NetworkUtil.isTcpPortOpen("0.0.0.0", 6969, 50, 200L)) {
+ throw new IllegalStateException("cannot connect to port 6969");
+ }
+ }
+
+ /**
+ * Tear down.
+ */
+ @AfterClass
+ public static void tearDown() {
+ ParameterService.deregister(LifecycleApiControlLoopForwarderParameters.class.getSimpleName());
+ simulator.stopLifecycycleApiSimulator();
+ }
+
+ @Test
+ public void testForwardControlLoopUsingSimulator() throws Exception {
+ assertThatCode(() -> {
+ final ToscaServiceTemplate toscaServiceTemplate =
+ standardCoder.decode(ResourceUtils.getResourceAsString(CONTROL_LOOP), ToscaServiceTemplate.class);
+
+ final LifecycleApiControlLoopForwarder forwarder = new LifecycleApiControlLoopForwarder();
+ forwarder.configure(LifecycleApiControlLoopForwarderParameters.class.getSimpleName());
+
+ final Collection<ToscaEntity> controlLoopList = new ArrayList<>();
+ controlLoopList.add(toscaServiceTemplate);
+
+ forwarder.forward(controlLoopList);
+
+ }).doesNotThrowAnyException();
+ }
+
+ @Test
+ public void testForwardControlLoopFailureUsingSimulator() throws Exception {
+
+ final ToscaEntity toscaEntity = new ToscaEntity();
+ toscaEntity.setName("FailureCase");
+
+ final LifecycleApiControlLoopForwarder forwarder = new LifecycleApiControlLoopForwarder();
+ forwarder.configure(LifecycleApiControlLoopForwarderParameters.class.getSimpleName());
+
+ final Collection<ToscaEntity> controlLoopList = new ArrayList<>();
+ controlLoopList.add(toscaEntity);
+
+ assertThatThrownBy(() -> forwarder.forward(controlLoopList)).isInstanceOf(PolicyForwardingException.class)
+ .hasMessageContaining("Failed forwarding the following entities:");
+ }
+}
diff --git a/plugins/forwarding-plugins/src/test/java/org/onap/policy/distribution/forwarding/testclasses/LifecycleApiControlLoopSimulatorEndpoint.java b/plugins/forwarding-plugins/src/test/java/org/onap/policy/distribution/forwarding/testclasses/LifecycleApiControlLoopSimulatorEndpoint.java
new file mode 100644
index 00000000..d361d166
--- /dev/null
+++ b/plugins/forwarding-plugins/src/test/java/org/onap/policy/distribution/forwarding/testclasses/LifecycleApiControlLoopSimulatorEndpoint.java
@@ -0,0 +1,54 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * Modifications Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.distribution.forwarding.testclasses;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+
+/**
+ * Class to provide rest end points for LifecycleApiControlLoopSimulator.
+ *
+ * @author Sirisha Manchikanti (sirisha.manchikanti@est.tech)
+ */
+@Path("/onap")
+@Produces(MediaType.APPLICATION_JSON)
+public class LifecycleApiControlLoopSimulatorEndpoint {
+
+ /**
+ * ControlLoop commissioning end-point.
+ *
+ * @param body the post body
+ * @return the response object
+ */
+ @POST
+ @Path("/controlloop/v2/commission")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response commissionControlLoop(final ToscaServiceTemplate body) {
+ return Response.status(Response.Status.OK).entity(body).build();
+ }
+}
diff --git a/plugins/forwarding-plugins/src/test/java/org/onap/policy/distribution/forwarding/testclasses/LifecycleApiControlLoopSimulatorMain.java b/plugins/forwarding-plugins/src/test/java/org/onap/policy/distribution/forwarding/testclasses/LifecycleApiControlLoopSimulatorMain.java
new file mode 100644
index 00000000..a60fda1d
--- /dev/null
+++ b/plugins/forwarding-plugins/src/test/java/org/onap/policy/distribution/forwarding/testclasses/LifecycleApiControlLoopSimulatorMain.java
@@ -0,0 +1,67 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * Modifications Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.distribution.forwarding.testclasses;
+
+import org.onap.policy.common.endpoints.http.server.RestServer;
+import org.onap.policy.common.endpoints.parameters.RestServerParameters;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.coder.StandardCoder;
+import org.onap.policy.common.utils.resources.ResourceUtils;
+import org.onap.policy.distribution.forwarding.PolicyForwardingException;
+import org.onap.policy.distribution.forwarding.lifecycle.api.LifecycleApiControlLoopForwarder;
+import org.onap.policy.distribution.main.rest.aaf.AafDistributionFilter;
+
+/**
+ * The class for starting/stopping simulator for testing {@link LifecycleApiControlLoopForwarder} .
+ *
+ * @author Sirisha Manchikanti (sirisha.manchikanti@est.tech)
+ */
+public class LifecycleApiControlLoopSimulatorMain {
+ private RestServer restServer;
+
+ /**
+ * Starts the simulator.
+ *
+ * @throws PolicyForwardingException if error occurs
+ * @throws CoderException if error occurs
+ */
+ public void startLifecycycleApiSimulator() throws PolicyForwardingException, CoderException {
+ final StandardCoder standardCoder = new StandardCoder();
+ final RestServerParameters restServerParameters = standardCoder.decode(
+ ResourceUtils.getResourceAsString("src/test/resources/parameters/RestServerParameters.json"),
+ RestServerParameters.class);
+ restServer = new RestServer(restServerParameters, AafDistributionFilter.class,
+ LifecycleApiControlLoopSimulatorEndpoint.class);
+ if (!restServer.start()) {
+ throw new PolicyForwardingException("Failed to start rest simulator. Check log for more details...");
+ }
+ }
+
+ /**
+ * Shut down Execution.
+ */
+ public void stopLifecycycleApiSimulator() {
+ if (restServer != null) {
+ restServer.stop();
+ }
+ }
+}
diff --git a/plugins/forwarding-plugins/src/test/resources/parameters/LifecycleApiControlLoopForwarderParameters.json b/plugins/forwarding-plugins/src/test/resources/parameters/LifecycleApiControlLoopForwarderParameters.json
new file mode 100644
index 00000000..1eef9773
--- /dev/null
+++ b/plugins/forwarding-plugins/src/test/resources/parameters/LifecycleApiControlLoopForwarderParameters.json
@@ -0,0 +1,10 @@
+{
+ "controlLoopRuntimeParameters": {
+ "clientName": "policy-clamp-cl-runtime",
+ "hostname": "0.0.0.0",
+ "port": 6969,
+ "useHttps": false,
+ "userName": "policyadmin",
+ "password": "zb!XztG34"
+ }
+}
diff --git a/plugins/forwarding-plugins/src/test/resources/parameters/LifecycleApiControlLoopForwarderParametersInvalid.json b/plugins/forwarding-plugins/src/test/resources/parameters/LifecycleApiControlLoopForwarderParametersInvalid.json
new file mode 100644
index 00000000..5ac0c4ee
--- /dev/null
+++ b/plugins/forwarding-plugins/src/test/resources/parameters/LifecycleApiControlLoopForwarderParametersInvalid.json
@@ -0,0 +1,10 @@
+{
+ "controlLoopRuntimeParameters": {
+ "clientName": "policy-clamp-cl-runtime",
+ "hostname": "",
+ "port": 6969,
+ "useHttps": false,
+ "userName": "policyadmin",
+ "password": "zb!XztG34"
+ }
+}
diff --git a/plugins/forwarding-plugins/src/test/resources/parameters/sample_control_loop.json b/plugins/forwarding-plugins/src/test/resources/parameters/sample_control_loop.json
new file mode 100644
index 00000000..20dedc50
--- /dev/null
+++ b/plugins/forwarding-plugins/src/test/resources/parameters/sample_control_loop.json
@@ -0,0 +1,1022 @@
+{
+ "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
+ }
+ }
+ },
+ "onap.datatype.controlloop.Target": {
+ "derived_from": "tosca.datatypes.Root",
+ "description": "Definition for a entity in A&AI to perform a control loop operation on",
+ "properties": {
+ "targetType": {
+ "type": "string",
+ "description": "Category for the target type",
+ "required": true,
+ "constraints": [
+ {
+ "valid_values": [
+ "VNF",
+ "VM",
+ "VFMODULE",
+ "PNF"
+ ]
+ }
+ ]
+ },
+ "entityIds": {
+ "type": "map",
+ "description": "Map of values that identify the resource. If none are provided, it is assumed that the\nentity that generated the ONSET event will be the target.\n",
+ "required": false,
+ "metadata": {
+ "clamp_possible_values": "ClampExecution:CSAR_RESOURCES"
+ },
+ "entry_schema": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "onap.datatype.controlloop.Actor": {
+ "derived_from": "tosca.datatypes.Root",
+ "description": "An actor/operation/target definition",
+ "properties": {
+ "actor": {
+ "type": "string",
+ "description": "The actor performing the operation.",
+ "required": true,
+ "metadata": {
+ "clamp_possible_values": "Dictionary:DefaultActors,ClampExecution:CDS/actor"
+ }
+ },
+ "operation": {
+ "type": "string",
+ "description": "The operation the actor is performing.",
+ "metadata": {
+ "clamp_possible_values": "Dictionary:DefaultOperations,ClampExecution:CDS/operation"
+ },
+ "required": true
+ },
+ "target": {
+ "type": "onap.datatype.controlloop.Target",
+ "description": "The resource the operation should be performed on.",
+ "required": true
+ },
+ "payload": {
+ "type": "map",
+ "description": "Name/value pairs of payload information passed by Policy to the actor",
+ "required": false,
+ "metadata": {
+ "clamp_possible_values": "ClampExecution:CDS/payload"
+ },
+ "entry_schema": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "onap.datatype.controlloop.Operation": {
+ "derived_from": "tosca.datatypes.Root",
+ "description": "An operation supported by an actor",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique identifier for the operation",
+ "required": true
+ },
+ "description": {
+ "type": "string",
+ "description": "A user-friendly description of the intent for the operation",
+ "required": false
+ },
+ "operation": {
+ "type": "onap.datatype.controlloop.Actor",
+ "description": "The definition of the operation to be performed.",
+ "required": true
+ },
+ "timeout": {
+ "type": "integer",
+ "description": "The amount of time for the actor to perform the operation.",
+ "required": true
+ },
+ "retries": {
+ "type": "integer",
+ "description": "The number of retries the actor should attempt to perform the operation.",
+ "required": true,
+ "default": 0
+ },
+ "success": {
+ "type": "string",
+ "description": "Points to the operation to invoke on success. A value of \"final_success\" indicates and end to the operation.",
+ "required": false,
+ "default": "final_success"
+ },
+ "failure": {
+ "type": "string",
+ "description": "Points to the operation to invoke on Actor operation failure.",
+ "required": false,
+ "default": "final_failure"
+ },
+ "failure_timeout": {
+ "type": "string",
+ "description": "Points to the operation to invoke when the time out for the operation occurs.",
+ "required": false,
+ "default": "final_failure_timeout"
+ },
+ "failure_retries": {
+ "type": "string",
+ "description": "Points to the operation to invoke when the current operation has exceeded its max retries.",
+ "required": false,
+ "default": "final_failure_retries"
+ },
+ "failure_exception": {
+ "type": "string",
+ "description": "Points to the operation to invoke when the current operation causes an exception.",
+ "required": false,
+ "default": "final_failure_exception"
+ },
+ "failure_guard": {
+ "type": "string",
+ "description": "Points to the operation to invoke when the current operation is blocked due to guard policy enforcement.",
+ "required": false,
+ "default": "final_failure_guard"
+ }
+ }
+ },
+ "onap.datatypes.monitoring.managedObjectDNsBasic": {
+ "constraints": [],
+ "properties": {
+ "DN": {
+ "name": "DN",
+ "type": "string",
+ "typeVersion": "0.0.0",
+ "description": "Managed object distinguished name",
+ "required": true,
+ "constraints": [],
+ "metadata": {}
+ }
+ },
+ "name": "onap.datatypes.monitoring.managedObjectDNsBasic",
+ "version": "0.0.0",
+ "derived_from": "tosca.datatypes.Root",
+ "metadata": {}
+ },
+ "onap.datatypes.monitoring.managedObjectDNsBasics": {
+ "constraints": [],
+ "properties": {
+ "managedObjectDNsBasic": {
+ "name": "managedObjectDNsBasic",
+ "type": "map",
+ "typeVersion": "0.0.0",
+ "description": "Managed object distinguished name object",
+ "required": true,
+ "constraints": [],
+ "entry_schema": {
+ "type": "onap.datatypes.monitoring.managedObjectDNsBasic",
+ "typeVersion": "0.0.0",
+ "constraints": []
+ },
+ "metadata": {}
+ }
+ },
+ "name": "onap.datatypes.monitoring.managedObjectDNsBasics",
+ "version": "0.0.0",
+ "derived_from": "tosca.datatypes.Root",
+ "metadata": {}
+ },
+ "onap.datatypes.monitoring.measurementGroup": {
+ "constraints": [],
+ "properties": {
+ "measurementTypes": {
+ "name": "measurementTypes",
+ "type": "list",
+ "typeVersion": "0.0.0",
+ "description": "List of measurement types",
+ "required": true,
+ "constraints": [],
+ "entry_schema": {
+ "type": "onap.datatypes.monitoring.measurementTypes",
+ "typeVersion": "0.0.0",
+ "constraints": []
+ },
+ "metadata": {}
+ },
+ "managedObjectDNsBasic": {
+ "name": "managedObjectDNsBasic",
+ "type": "list",
+ "typeVersion": "0.0.0",
+ "description": "List of managed object distinguished names",
+ "required": true,
+ "constraints": [],
+ "entry_schema": {
+ "type": "onap.datatypes.monitoring.managedObjectDNsBasics",
+ "typeVersion": "0.0.0",
+ "constraints": []
+ },
+ "metadata": {}
+ }
+ },
+ "name": "onap.datatypes.monitoring.measurementGroup",
+ "version": "0.0.0",
+ "derived_from": "tosca.datatypes.Root",
+ "metadata": {}
+ },
+ "onap.datatypes.monitoring.measurementGroups": {
+ "constraints": [],
+ "properties": {
+ "measurementGroup": {
+ "name": "measurementGroup",
+ "type": "map",
+ "typeVersion": "0.0.0",
+ "description": "Measurement Group",
+ "required": true,
+ "constraints": [],
+ "entry_schema": {
+ "type": "onap.datatypes.monitoring.measurementGroup",
+ "typeVersion": "0.0.0",
+ "constraints": []
+ },
+ "metadata": {}
+ }
+ },
+ "name": "onap.datatypes.monitoring.measurementGroups",
+ "version": "0.0.0",
+ "derived_from": "tosca.datatypes.Root",
+ "metadata": {}
+ },
+ "onap.datatypes.monitoring.measurementType": {
+ "constraints": [],
+ "properties": {
+ "measurementType": {
+ "name": "measurementType",
+ "type": "string",
+ "typeVersion": "0.0.0",
+ "description": "Measurement type",
+ "required": true,
+ "constraints": [],
+ "metadata": {}
+ }
+ },
+ "name": "onap.datatypes.monitoring.measurementType",
+ "version": "0.0.0",
+ "derived_from": "tosca.datatypes.Root",
+ "metadata": {}
+ },
+ "onap.datatypes.monitoring.measurementTypes": {
+ "constraints": [],
+ "properties": {
+ "measurementType": {
+ "name": "measurementType",
+ "type": "map",
+ "typeVersion": "0.0.0",
+ "description": "Measurement type object",
+ "required": true,
+ "constraints": [],
+ "entry_schema": {
+ "type": "onap.datatypes.monitoring.measurementType",
+ "typeVersion": "0.0.0",
+ "constraints": []
+ },
+ "metadata": {}
+ }
+ },
+ "name": "onap.datatypes.monitoring.measurementTypes",
+ "version": "0.0.0",
+ "derived_from": "tosca.datatypes.Root",
+ "metadata": {}
+ },
+ "onap.datatypes.monitoring.nfFilter": {
+ "constraints": [],
+ "properties": {
+ "modelNames": {
+ "name": "modelNames",
+ "type": "list",
+ "typeVersion": "0.0.0",
+ "description": "List of model names",
+ "required": true,
+ "constraints": [],
+ "entry_schema": {
+ "type": "string",
+ "typeVersion": "0.0.0",
+ "constraints": []
+ },
+ "metadata": {}
+ },
+ "modelInvariantIDs": {
+ "name": "modelInvariantIDs",
+ "type": "list",
+ "typeVersion": "0.0.0",
+ "description": "List of model invariant IDs",
+ "required": true,
+ "constraints": [],
+ "entry_schema": {
+ "type": "string",
+ "typeVersion": "0.0.0",
+ "constraints": []
+ },
+ "metadata": {}
+ },
+ "modelVersionIDs": {
+ "name": "modelVersionIDs",
+ "type": "list",
+ "typeVersion": "0.0.0",
+ "description": "List of model version IDs",
+ "required": true,
+ "constraints": [],
+ "entry_schema": {
+ "type": "string",
+ "typeVersion": "0.0.0",
+ "constraints": []
+ },
+ "metadata": {}
+ },
+ "nfNames": {
+ "name": "nfNames",
+ "type": "list",
+ "typeVersion": "0.0.0",
+ "description": "List of network functions",
+ "required": true,
+ "constraints": [],
+ "entry_schema": {
+ "type": "string",
+ "typeVersion": "0.0.0",
+ "constraints": []
+ },
+ "metadata": {}
+ }
+ },
+ "name": "onap.datatypes.monitoring.nfFilter",
+ "version": "0.0.0",
+ "derived_from": "tosca.datatypes.Root",
+ "metadata": {}
+ },
+ "onap.datatypes.monitoring.subscription": {
+ "constraints": [],
+ "properties": {
+ "measurementGroups": {
+ "name": "measurementGroups",
+ "type": "list",
+ "typeVersion": "0.0.0",
+ "description": "Measurement Groups",
+ "required": true,
+ "constraints": [],
+ "entry_schema": {
+ "type": "onap.datatypes.monitoring.measurementGroups",
+ "typeVersion": "0.0.0",
+ "constraints": []
+ },
+ "metadata": {}
+ },
+ "fileBasedGP": {
+ "name": "fileBasedGP",
+ "type": "integer",
+ "typeVersion": "0.0.0",
+ "description": "File based granularity period",
+ "required": true,
+ "constraints": [],
+ "metadata": {}
+ },
+ "fileLocation": {
+ "name": "fileLocation",
+ "type": "string",
+ "typeVersion": "0.0.0",
+ "description": "ROP file location",
+ "required": true,
+ "constraints": [],
+ "metadata": {}
+ },
+ "subscriptionName": {
+ "name": "subscriptionName",
+ "type": "string",
+ "typeVersion": "0.0.0",
+ "description": "Name of the subscription",
+ "required": true,
+ "constraints": [],
+ "metadata": {}
+ },
+ "administrativeState": {
+ "name": "administrativeState",
+ "type": "string",
+ "typeVersion": "0.0.0",
+ "description": "State of the subscription",
+ "required": true,
+ "constraints": [
+ {
+ "valid_values": [
+ "LOCKED",
+ "UNLOCKED"
+ ]
+ }
+ ],
+ "metadata": {}
+ },
+ "nfFilter": {
+ "name": "nfFilter",
+ "type": "map",
+ "typeVersion": "0.0.0",
+ "description": "Network function filter",
+ "required": true,
+ "constraints": [],
+ "entry_schema": {
+ "type": "onap.datatypes.monitoring.nfFilter",
+ "typeVersion": "0.0.0",
+ "constraints": []
+ },
+ "metadata": {}
+ }
+ },
+ "name": "onap.datatypes.monitoring.subscription",
+ "version": "0.0.0",
+ "derived_from": "tosca.datatypes.Root",
+ "metadata": {}
+ },
+ "org.onap.datatypes.policy.clamp.controlloop.httpControlLoopElement.RestRequest": {
+ "version": "1.0.0",
+ "derived_from": "tosca.datatypes.Root",
+ "properties": {
+ "restRequestId": {
+ "type": "onap.datatypes.ToscaConceptIdentifier",
+ "typeVersion": "1.0.0",
+ "required": true,
+ "description": "The name and version of a REST request to be sent to a REST endpoint"
+ },
+ "httpMethod": {
+ "type": "string",
+ "required": true,
+ "constraints": [
+ {
+ "valid_values": [
+ "POST",
+ "PUT",
+ "GET",
+ "DELETE"
+ ]
+ }
+ ],
+ "description": "The REST method to use"
+ },
+ "path": {
+ "type": "string",
+ "required": true,
+ "description": "The path of the REST request relative to the base URL"
+ },
+ "body": {
+ "type": "string",
+ "required": false,
+ "description": "The body of the REST request for PUT and POST requests"
+ },
+ "expectedResponse": {
+ "type": "integer",
+ "required": true,
+ "constraints": [],
+ "description": "THe expected HTTP status code for the REST request"
+ }
+ },
+ "org.onap.datatypes.policy.clamp.controlloop.httpControlLoopElement.ConfigurationEntity": {
+ "version": "1.0.0",
+ "derived_from": "tosca.datatypes.Root",
+ "properties": {
+ "configurationEntityId": {
+ "type": "onap.datatypes.ToscaConceptIdentifier",
+ "typeVersion": "1.0.0",
+ "required": true,
+ "description": "The name and version of a Configuration Entity to be handled by the HTTP Control Loop Element"
+ },
+ "restSequence": {
+ "type": "list",
+ "entry_schema": {
+ "type": "org.onap.datatypes.policy.clamp.controlloop.httpControlLoopElement.RestRequest",
+ "typeVersion": "1.0.0"
+ },
+ "description": "A sequence of REST commands to send to the REST endpoint"
+ }
+ }
+ }
+ }
+ },
+ "node_types": {
+ "org.onap.policy.clamp.controlloop.Participant": {
+ "version": "1.0.1",
+ "derived_from": "tosca.nodetypes.Root",
+ "properties": {
+ "provider": {
+ "type": "string",
+ "requred": false
+ }
+ }
+ },
+ "org.onap.policy.clamp.controlloop.ControlLoopElement": {
+ "version": "1.0.1",
+ "derived_from": "tosca.nodetypes.Root",
+ "properties": {
+ "provider": {
+ "type": "string",
+ "required": false,
+ "metadata": {
+ "common": true
+ },
+ "description": "Specifies the organization that provides the control loop element"
+ },
+ "participant_id": {
+ "type": "onap.datatypes.ToscaConceptIdentifier",
+ "requred": true,
+ "metadata": {
+ "common": true
+ }
+ },
+ "participantType": {
+ "type": "onap.datatypes.ToscaConceptIdentifier",
+ "required": true,
+ "metadata": {
+ "common": true
+ },
+ "description": "The identity of the participant type that hosts this type of Control Loop Element"
+ },
+ "startPhase": {
+ "type": "integer",
+ "required": false,
+ "constraints": [
+ {
+ "greater_or_equal": 0
+ }
+ ],
+ "metadata": {
+ "common": true
+ },
+ "description": "A value indicating the start phase in which this control loop element will be started, the first start phase is zero. Control Loop Elements are started in their start_phase order and stopped in reverse start phase order. Control Loop Elements with the same start phase are started and stopped simultaneously"
+ },
+ "uninitializedToPassiveTimeout": {
+ "type": "integer",
+ "required": false,
+ "constraints": [
+ {
+ "greater_or_equal": 0
+ }
+ ],
+ "default": 60,
+ "metadata": {
+ "common": true
+ },
+ "description": "The maximum time in seconds to wait for a state chage from uninitialized to passive"
+ },
+ "passiveToRunningTimeout": {
+ "type": "integer",
+ "required": false,
+ "constraints": [
+ {
+ "greater_or_equal": 0
+ }
+ ],
+ "default": 60,
+ "metadata": {
+ "common": true
+ },
+ "description": "The maximum time in seconds to wait for a state chage from passive to running"
+ },
+ "runningToPassiveTimeout": {
+ "type": "integer",
+ "required": false,
+ "constraints": [
+ {
+ "greater_or_equal": 0
+ }
+ ],
+ "default": 60,
+ "metadata": {
+ "common": true
+ },
+ "description": "The maximum time in seconds to wait for a state chage from running to passive"
+ },
+ "passiveToUninitializedTimeout": {
+ "type": "integer",
+ "required": false,
+ "constraints": [
+ {
+ "greater_or_equal": 0
+ }
+ ],
+ "default": 60,
+ "metadata": {
+ "common": true
+ },
+ "description": "The maximum time in seconds to wait for a state chage from passive to uninitialized"
+ }
+ }
+ },
+ "org.onap.policy.clamp.controlloop.ControlLoop": {
+ "version": "1.0.1",
+ "derived_from": "tosca.nodetypes.Root",
+ "properties": {
+ "provider": {
+ "type": "string",
+ "required": false,
+ "metadata": {
+ "common": true
+ },
+ "description": "Specifies the organization that provides the control loop element"
+ },
+ "elements": {
+ "type": "list",
+ "required": true,
+ "metadata": {
+ "common": true
+ },
+ "entry_schema": {
+ "type": "onap.datatypes.ToscaConceptIdentifier"
+ },
+ "description": "Specifies a list of control loop element definitions that make up this control loop definition"
+ }
+ }
+ },
+ "org.onap.policy.clamp.controlloop.PolicyControlLoopElement": {
+ "version": "1.0.1",
+ "derived_from": "org.onap.policy.clamp.controlloop.ControlLoopElement",
+ "properties": {
+ "policy_type_id": {
+ "type": "onap.datatypes.ToscaConceptIdentifier",
+ "requred": true
+ },
+ "policy_id": {
+ "type": "onap.datatypes.ToscaConceptIdentifier",
+ "requred": false
+ }
+ }
+ },
+ "org.onap.policy.clamp.controlloop.DerivedPolicyControlLoopElement": {
+ "version": "1.0.1",
+ "derived_from": "org.onap.policy.clamp.controlloop.PolicyControlLoopElement",
+ "properties": {
+ "policy_type_id": {
+ "type": "onap.datatypes.ToscaConceptIdentifier",
+ "requred": true
+ },
+ "policy_id": {
+ "type": "onap.datatypes.ToscaConceptIdentifier",
+ "requred": false
+ }
+ }
+ },
+ "org.onap.policy.clamp.controlloop.DerivedDerivedPolicyControlLoopElement": {
+ "version": "1.0.1",
+ "derived_from": "org.onap.policy.clamp.controlloop.DerivedPolicyControlLoopElement",
+ "properties": {
+ "policy_type_id": {
+ "type": "onap.datatypes.ToscaConceptIdentifier",
+ "requred": true
+ },
+ "policy_id": {
+ "type": "onap.datatypes.ToscaConceptIdentifier",
+ "requred": false
+ }
+ }
+ },
+ "org.onap.policy.clamp.controlloop.CDSControlLoopElement": {
+ "version": "1.0.1",
+ "derived_from": "org.onap.policy.clamp.controlloop.ControlLoopElement",
+ "properties": {
+ "cds_blueprint_id": {
+ "type": "onap.datatypes.ToscaConceptIdentifier",
+ "requred": true
+ }
+ }
+ },
+ "org.onap.policy.clamp.controlloop.K8SMicroserviceControlLoopElement": {
+ "version": "1.0.1",
+ "derived_from": "org.onap.policy.clamp.controlloop.ControlLoopElement",
+ "properties": {
+ "chart": {
+ "type": "string",
+ "required": true
+ },
+ "configs": {
+ "type": "list",
+ "required": false
+ },
+ "requirements": {
+ "type": "string",
+ "requred": false
+ },
+ "templates": {
+ "type": "list",
+ "required": false,
+ "entry_schema": null
+ },
+ "values": {
+ "type": "string",
+ "requred": true
+ }
+ }
+ },
+ "org.onap.policy.clamp.controlloop.HttpControlLoopElement": {
+ "version": "1.0.1",
+ "derived_from": "org.onap.policy.clamp.controlloop.ControlLoopElement",
+ "properties": {
+ "baseUrl": {
+ "type": "string",
+ "required": true,
+ "description": "The base URL to be prepended to each path, identifies the host for the REST endpoints."
+ },
+ "httpHeaders": {
+ "type": "map",
+ "required": false,
+ "entry_schema": {
+ "type": "string"
+ },
+ "description": "HTTP headers to send on REST requests"
+ },
+ "configurationEntities": {
+ "type": "map",
+ "required": true,
+ "entry_schema": {
+ "type": "org.onap.datatypes.policy.clamp.controlloop.httpControlLoopElement.ConfigurationEntity",
+ "typeVersion": "1.0.0"
+ },
+ "description": "The connfiguration entities the Control Loop Element is managing and their associated REST requests"
+ }
+ }
+ }
+ },
+ "topology_template": {
+ "inputs": {
+ "pmsh_monitoring_policy": {
+ "type": "onap.datatypes.ToscaConceptIdentifier",
+ "description": "The ID of the PMSH monitoring policy to use",
+ "default": {
+ "name": "MICROSERVICE_vLoadBalancerMS_v1_0_dcae-pm-subscription-handler_1_0_0test",
+ "version": "1.0.0"
+ }
+ },
+ "pmsh_operational_policy": {
+ "type": "onap.datatypes.ToscaConceptIdentifier",
+ "description": "The ID of the PMSH operational policy to use",
+ "default": {
+ "name": "operational.apex.pmcontrol",
+ "version": "1.0.0"
+ }
+ }
+ },
+ "node_templates": {
+ "org.onap.policy.controlloop.PolicyControlLoopParticipant": {
+ "version": "2.3.1",
+ "type": "org.onap.policy.clamp.controlloop.Participant",
+ "type_version": "1.0.1",
+ "description": "Participant for DCAE microservices",
+ "properties": {
+ "provider": "ONAP"
+ }
+ },
+ "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement": {
+ "version": "1.2.3",
+ "type": "org.onap.policy.clamp.controlloop.PolicyControlLoopElement",
+ "type_version": "1.0.0",
+ "description": "Control loop element for the monitoring policy for Performance Management Subscription Handling",
+ "properties": {
+ "provider": "Ericsson",
+ "participant_id": {
+ "name": "org.onap.PM_Policy",
+ "version": "1.0.0"
+ },
+ "participantType": {
+ "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+ "version": "2.3.1"
+ },
+ "policy_type_id": {
+ "name": "onap.policies.monitoring.pm-subscription-handler",
+ "version": "1.0.0"
+ },
+ "policy_id": {
+ "get_input": "pmsh_monitoring_policy"
+ }
+ }
+ },
+ "org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement": {
+ "version": "1.2.3",
+ "type": "org.onap.policy.clamp.controlloop.PolicyControlLoopElement",
+ "type_version": "1.0.0",
+ "description": "Control loop element for the operational policy for Performance Management Subscription Handling",
+ "properties": {
+ "provider": "Ericsson",
+ "participant_id": {
+ "name": "org.onap.PM_Policy",
+ "version": "1.0.0"
+ },
+ "participantType": {
+ "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+ "version": "2.3.1"
+ },
+ "policy_type_id": {
+ "name": "onap.policies.operational.pm-subscription-handler",
+ "version": "1.0.0"
+ },
+ "policy_id": {
+ "get_input": "pmsh_operational_policy"
+ }
+ }
+ },
+ "org.onap.domain.pmsh.DerivedPolicyControlLoopElement": {
+ "version": "1.2.3",
+ "type": "org.onap.policy.clamp.controlloop.DerivedPolicyControlLoopElement",
+ "type_version": "1.0.0",
+ "description": "Control loop for Performance Management Subscription Handling",
+ "properties": {
+ "provider": "Ericsson",
+ "participantType": {
+ "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+ "version": "2.3.1"
+ },
+ "participant_id": {
+ "name": "org.onap.PM_Policy",
+ "version": "1.0.0"
+ }
+ }
+ },
+ "org.onap.domain.pmsh.DerivedDerivedPolicyControlLoopElement": {
+ "version": "1.2.3",
+ "type": "org.onap.policy.clamp.controlloop.DerivedDerivedPolicyControlLoopElement",
+ "type_version": "1.0.0",
+ "description": "Control loop for Performance Management Subscription Handling",
+ "properties": {
+ "provider": "Ericsson",
+ "participantType": {
+ "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+ "version": "2.3.1"
+ },
+ "participant_id": {
+ "name": "org.onap.PM_Policy",
+ "version": "1.0.0"
+ }
+ }
+ },
+ "org.onap.k8s.controlloop.K8SControlLoopParticipant": {
+ "version": "2.3.4",
+ "type": "org.onap.policy.clamp.controlloop.Participant",
+ "type_version": "1.0.1",
+ "description": "Participant for K8S",
+ "properties": {
+ "provider": "ONAP"
+ }
+ },
+ "org.onap.domain.database.PMSH_K8SMicroserviceControlLoopElement": {
+ "version": "1.2.3",
+ "type": "org.onap.policy.clamp.controlloop.K8SMicroserviceControlLoopElement",
+ "type_version": "1.0.0",
+ "description": "Control loop element for the K8S microservice for PMSH",
+ "properties": {
+ "provider": "ONAP",
+ "participant_id": {
+ "name": "K8sParticipant0",
+ "version": "1.0.0"
+ },
+ "participantType": {
+ "name": "org.onap.k8s.controlloop.K8SControlLoopParticipant",
+ "version": "2.3.4"
+ },
+ "chart": {
+ "chartId": {
+ "name": "dcae-pmsh",
+ "version": "8.0.0"
+ },
+ "namespace": "onap",
+ "releaseName": "pmshms",
+ "repository": {
+ "repoName": "chartmuseum",
+ "protocol": "http",
+ "address": "10.152.183.120",
+ "port": 80,
+ "userName": "onapinitializer",
+ "password": "demo123456!"
+ },
+ "overrideParams": {
+ "global.masterPassword": "test"
+ }
+ }
+ }
+ },
+ "org.onap.domain.database.Local_K8SMicroserviceControlLoopElement": {
+ "version": "1.2.3",
+ "type": "org.onap.policy.clamp.controlloop.K8SMicroserviceControlLoopElement",
+ "type_version": "1.0.0",
+ "description": "Control loop element for the K8S microservice for local chart",
+ "properties": {
+ "provider": "ONAP",
+ "participant_id": {
+ "name": "K8sParticipant0",
+ "version": "1.0.0"
+ },
+ "participantType": {
+ "name": "org.onap.k8s.controlloop.K8SControlLoopParticipant",
+ "version": "2.3.4"
+ },
+ "chart": {
+ "chartId": {
+ "name": "nginx-ingress",
+ "version": "0.9.1"
+ },
+ "releaseName": "nginxms",
+ "namespace": "test"
+ }
+ }
+ },
+ "org.onap.controlloop.HttpControlLoopParticipant": {
+ "version": "2.3.4",
+ "type": "org.onap.policy.clamp.controlloop.Participant",
+ "type_version": "1.0.1",
+ "description": "Participant for Http requests",
+ "properties": {
+ "provider": "ONAP"
+ }
+ },
+ "org.onap.domain.database.Http_PMSHMicroserviceControlLoopElement": {
+ "version": "1.2.3",
+ "type": "org.onap.policy.clamp.controlloop.HttpControlLoopElement",
+ "type_version": "1.0.1",
+ "description": "Control loop element for the http requests of PMSH microservice",
+ "properties": {
+ "provider": "ONAP",
+ "participant_id": {
+ "name": "HttpParticipant0",
+ "version": "1.0.0"
+ },
+ "participantType": {
+ "name": "org.onap.k8s.controlloop.HttpControlLoopParticipant",
+ "version": "2.3.4"
+ },
+ "uninitializedToPassiveTimeout": 180,
+ "startPhase": 1,
+ "baseUrl": "http://10.152.183.51:8500",
+ "httpHeaders": {
+ "Content-Type": "application/json"
+ },
+ "configurationEntities": [
+ {
+ "configurationEntityId": {
+ "name": "entity1",
+ "version": "1.0.1"
+ },
+ "restSequence": [
+ {
+ "restRequestId": {
+ "name": "request1",
+ "version": "1.0.1"
+ },
+ "httpMethod": "PUT",
+ "path": "v1/kv/dcae-pmsh2",
+ "body": "{ \"control_loop_name\":\"pmsh-control-loop\", \"operational_policy_name\":\"pmsh-operational-policy\", \"aaf_password\":\"demo123456!\", \"aaf_identity\":\"dcae@dcae.onap.org\", \"cert_path\":\"/opt/app/pmsh/etc/certs/cert.pem\", \"key_path\":\"/opt/app/pmsh/etc/certs/key.pem\", \"ca_cert_path\":\"/opt/app/pmsh/etc/certs/cacert.pem\", \"enable_tls\":\"true\", \"pmsh_policy\":{ \"subscription\":{ \"subscriptionName\":\"ExtraPM-All-gNB-R2B\", \"administrativeState\":\"UNLOCKED\", \"fileBasedGP\":15, \"fileLocation\":\"\\/pm\\/pm.xml\", \"nfFilter\":{ \"nfNames\":[ \"^pnf.*\", \"^vnf.*\" ], \"modelInvariantIDs\":[ ], \"modelVersionIDs\":[ ], \"modelNames\":[ ] }, \"measurementGroups\":[ { \"measurementGroup\":{ \"measurementTypes\":[ { \"measurementType\":\"countera\" }, { \"measurementType\":\"counterb\" } ], \"managedObjectDNsBasic\":[ { \"DN\":\"dna\" }, { \"DN\":\"dnb\" } ] } }, { \"measurementGroup\":{ \"measurementTypes\":[ { \"measurementType\":\"counterc\" }, { \"measurementType\":\"counterd\" } ], \"managedObjectDNsBasic\":[ { \"DN\":\"dnc\" }, { \"DN\":\"dnd\" } ] } } ] } }, \"streams_subscribes\":{ \"aai_subscriber\":{ \"type\":\"message_router\", \"dmaap_info\":{ \"topic_url\":\"https://10.152.183.151:3905/events/AAI_EVENT\", \"client_role\":\"org.onap.dcae.aaiSub\", \"location\":\"san-francisco\", \"client_id\":\"1575976809466\" } }, \"policy_pm_subscriber\":{ \"type\":\"message_router\", \"dmaap_info\":{ \"topic_url\":\"https://10.152.183.151:3905/events/org.onap.dmaap.mr.PM_SUBSCRIPTIONS\", \"client_role\":\"org.onap.dcae.pmSubscriber\", \"location\":\"san-francisco\", \"client_id\":\"1575876809456\" } } }, \"streams_publishes\":{ \"policy_pm_publisher\":{ \"type\":\"message_router\", \"dmaap_info\":{ \"topic_url\":\"https://10.152.183.151:3905/events/org.onap.dmaap.mr.PM_SUBSCRIPTIONS\", \"client_role\":\"org.onap.dcae.pmPublisher\", \"location\":\"san-francisco\", \"client_id\":\"1475976809466\" } }, \"other_publisher\":{ \"type\":\"message_router\", \"dmaap_info\":{ \"topic_url\":\"https://10.152.183.151:3905/events/org.onap.dmaap.mr.SOME_OTHER_TOPIC\", \"client_role\":\"org.onap.dcae.pmControlPub\", \"location\":\"san-francisco\", \"client_id\":\"1875976809466\" } } } }",
+ "expectedResponse": 200
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "org.onap.domain.sample.GenericK8s_ControlLoopDefinition": {
+ "version": "1.2.3",
+ "type": "org.onap.policy.clamp.controlloop.ControlLoop",
+ "type_version": "1.0.0",
+ "description": "Control loop for Hello World",
+ "properties": {
+ "provider": "ONAP",
+ "elements": [
+ {
+ "name": "org.onap.domain.database.PMSH_K8SMicroserviceControlLoopElement",
+ "version": "1.2.3"
+ },
+ {
+ "name": "org.onap.domain.database.Local_K8SMicroserviceControlLoopElement",
+ "version": "1.2.3"
+ },
+ {
+ "name": "org.onap.domain.database.Http_PMSHMicroserviceControlLoopElement",
+ "version": "1.2.3"
+ },
+ {
+ "name": "org.onap.domain.pmsh.DerivedPolicyControlLoopElement",
+ "version": "1.2.3"
+ },
+ {
+ "name": "org.onap.domain.pmsh.DerivedDerivedPolicyControlLoopElement",
+ "version": "1.2.3"
+ },
+ {
+ "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement",
+ "version": "1.2.3"
+ },
+ {
+ "name": "org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement",
+ "version": "1.2.3"
+ }
+ ]
+ }
+ }
+ }
+ }
+}
diff --git a/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/decoding/policy/file/ControlLoopDecoderFileInCsar.java b/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/decoding/policy/file/ControlLoopDecoderFileInCsar.java
new file mode 100644
index 00000000..96db632c
--- /dev/null
+++ b/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/decoding/policy/file/ControlLoopDecoderFileInCsar.java
@@ -0,0 +1,117 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * Modifications Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.distribution.reception.decoding.policy.file;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import org.onap.policy.common.parameters.ParameterService;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.distribution.model.Csar;
+import org.onap.policy.distribution.model.PolicyInput;
+import org.onap.policy.distribution.reception.decoding.PolicyDecoder;
+import org.onap.policy.distribution.reception.decoding.PolicyDecodingException;
+import org.onap.policy.distribution.reception.util.ReceptionUtil;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaEntity;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+
+/**
+ * This class extracts controlloop information from a CSAR file.
+ *
+ * @author Sirisha Manchikanti (sirisha.manchikanti@est.tech)
+ */
+public class ControlLoopDecoderFileInCsar implements PolicyDecoder<Csar, ToscaEntity> {
+
+ private ControlLoopDecoderFileInCsarParameterGroup decoderParameters;
+ private static final String NODE_TYPES = "nodes.yml";
+ private static final String DATA_TYPES = "data.yml";
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void configure(final String parameterGroupName) {
+ decoderParameters = ParameterService.get(parameterGroupName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean canHandle(final PolicyInput policyInput) {
+ return policyInput.getClass().isAssignableFrom(Csar.class);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public Collection<ToscaEntity> decode(final Csar csar) throws PolicyDecodingException {
+ final Collection<ToscaEntity> controlLoopList = new ArrayList<>();
+ ToscaServiceTemplate nodeTypes = null;
+ ToscaServiceTemplate dataTypes = null;
+
+ try (var zipFile = new ZipFile(csar.getCsarFilePath())) {
+ final Enumeration<? extends ZipEntry> entries = zipFile.entries();
+ while (entries.hasMoreElements()) {
+ //
+ // Sonar will flag this as a Security Hotspot
+ // "Expanding archive files is security-sensitive"
+ // isZipEntryValid ensures the file being read exists in the archive
+ //
+ final ZipEntry entry = entries.nextElement(); // NOSONAR
+ final String entryName = entry.getName();
+
+ // Store node_types
+ if (entryName.contains(NODE_TYPES)) {
+ nodeTypes = ReceptionUtil.decodeFile(zipFile, entry);
+ }
+
+ // Store data_types
+ if (entryName.contains(DATA_TYPES)) {
+ dataTypes = ReceptionUtil.decodeFile(zipFile, entry);
+ }
+
+ if (entryName.contains(decoderParameters.getControlLoopType())) {
+ ReceptionUtil.validateZipEntry(entryName, csar.getCsarFilePath(), entry.getSize());
+ final ToscaServiceTemplate controlLoop = ReceptionUtil.decodeFile(zipFile, entry);
+ if (null != controlLoop.getToscaTopologyTemplate()) {
+ if (null != nodeTypes) {
+ controlLoop.setNodeTypes(nodeTypes.getNodeTypes());
+ }
+ if (null != dataTypes) {
+ controlLoop.setDataTypes(dataTypes.getDataTypes());
+ }
+ controlLoopList.add(controlLoop);
+ }
+ }
+ }
+ } catch (final IOException | CoderException exp) {
+ throw new PolicyDecodingException("Failed decoding the controlloop", exp);
+ }
+
+ return controlLoopList;
+ }
+}
diff --git a/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/decoding/policy/file/ControlLoopDecoderFileInCsarParameterGroup.java b/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/decoding/policy/file/ControlLoopDecoderFileInCsarParameterGroup.java
new file mode 100644
index 00000000..358b1f87
--- /dev/null
+++ b/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/decoding/policy/file/ControlLoopDecoderFileInCsarParameterGroup.java
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * Modifications Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.distribution.reception.decoding.policy.file;
+
+import lombok.Getter;
+import org.onap.policy.common.parameters.annotations.NotBlank;
+import org.onap.policy.common.parameters.annotations.NotNull;
+import org.onap.policy.distribution.reception.parameters.PolicyDecoderConfigurationParameterGroup;
+
+/**
+ * Holds the parameters for the{@link ControlLoopDecoderFileInCsar}.
+ *
+ * @author Sirisha Manchikanti (sirisha.manchikanti@est.tech)
+ */
+@Getter
+@NotNull
+@NotBlank
+public class ControlLoopDecoderFileInCsarParameterGroup extends PolicyDecoderConfigurationParameterGroup {
+
+ private String controlLoopType;
+
+ public ControlLoopDecoderFileInCsarParameterGroup() {
+ super(ControlLoopDecoderFileInCsarParameterGroup.class.getSimpleName());
+ }
+}
diff --git a/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/decoding/policy/file/PolicyDecoderFileInCsarToPolicy.java b/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/decoding/policy/file/PolicyDecoderFileInCsarToPolicy.java
index 72316f28..c4ba21fe 100644
--- a/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/decoding/policy/file/PolicyDecoderFileInCsarToPolicy.java
+++ b/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/decoding/policy/file/PolicyDecoderFileInCsarToPolicy.java
@@ -1,7 +1,7 @@
/*-
* ============LICENSE_START=======================================================
* Copyright (C) 2018 Ericsson. All rights reserved.
- * Copyright (C) 2019 Nordix Foundation.
+ * Copyright (C) 2022 Nordix Foundation.
* Modifications Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved.
* Modifications Copyright (C) 2021 Bell Canada. All rights reserved.
* ================================================================================
@@ -24,7 +24,6 @@
package org.onap.policy.distribution.reception.decoding.policy.file;
import java.io.IOException;
-import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
@@ -32,12 +31,11 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.onap.policy.common.parameters.ParameterService;
import org.onap.policy.common.utils.coder.CoderException;
-import org.onap.policy.common.utils.coder.StandardCoder;
-import org.onap.policy.common.utils.coder.StandardYamlCoder;
import org.onap.policy.distribution.model.Csar;
import org.onap.policy.distribution.model.PolicyInput;
import org.onap.policy.distribution.reception.decoding.PolicyDecoder;
import org.onap.policy.distribution.reception.decoding.PolicyDecodingException;
+import org.onap.policy.distribution.reception.util.ReceptionUtil;
import org.onap.policy.models.tosca.authorative.concepts.ToscaEntity;
import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
@@ -49,9 +47,6 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
public class PolicyDecoderFileInCsarToPolicy implements PolicyDecoder<Csar, ToscaEntity> {
private PolicyDecoderFileInCsarToPolicyParameterGroup decoderParameters;
- private StandardCoder coder;
- private StandardYamlCoder yamlCoder;
- private static final long MAX_FILE_SIZE = 512L * 1024;
/**
* {@inheritDoc}.
@@ -59,8 +54,6 @@ public class PolicyDecoderFileInCsarToPolicy implements PolicyDecoder<Csar, Tosc
@Override
public void configure(final String parameterGroupName) {
decoderParameters = ParameterService.get(parameterGroupName);
- coder = new StandardCoder();
- yamlCoder = new StandardYamlCoder();
}
/**
@@ -87,9 +80,15 @@ public class PolicyDecoderFileInCsarToPolicy implements PolicyDecoder<Csar, Tosc
// isZipEntryValid ensures the file being read exists in the archive
//
final ZipEntry entry = entries.nextElement(); // NOSONAR
- if (isZipEntryValid(entry.getName(), csar.getCsarFilePath(), entry.getSize())) {
- final ToscaServiceTemplate policy =
- decodeFile(zipFile, entry);
+ final String entryName = entry.getName();
+
+ //
+ // We only care about policy types and policies
+ //
+ if (entryName.contains(decoderParameters.getPolicyTypeFileName())
+ || entryName.contains(decoderParameters.getPolicyFileName())) {
+ ReceptionUtil.validateZipEntry(entryName, csar.getCsarFilePath(), entry.getSize());
+ final ToscaServiceTemplate policy = ReceptionUtil.decodeFile(zipFile, entry);
policyList.add(policy);
}
}
@@ -99,61 +98,4 @@ public class PolicyDecoderFileInCsarToPolicy implements PolicyDecoder<Csar, Tosc
return policyList;
}
-
- /**
- * Method to filter out Policy type and Policy files. In addition,
- * ensures validation of entries in the Zipfile. Attempts to solve path
- * injection java security issues.
- *
- * @param entryName name of the ZipEntry to check
- * @param csarPath Absolute path to the csar the ZipEntry is in
- * @param entrySize size of the ZipEntry
- * @return true if no injection detected, and it is a policy type or policy file.
- * @throws PolicyDecodingException if the file size is too large
- */
- private boolean isZipEntryValid(String entryName, String csarPath, long entrySize) throws PolicyDecodingException {
- //
- // We only care about policy types and policies
- //
- if (entryName.contains(decoderParameters.getPolicyTypeFileName())
- || entryName.contains(decoderParameters.getPolicyFileName())) {
- //
- // Check file size
- //
- if (entrySize > MAX_FILE_SIZE) {
- throw new PolicyDecodingException("Zip entry for " + entryName + " is too large " + entrySize);
- }
- //
- // Now ensure that there is no path injection
- //
- var path = Path.of(csarPath, entryName).normalize();
- //
- // Throw an exception if path is outside the csar
- //
- if (! path.startsWith(csarPath)) {
- throw new PolicyDecodingException("Potential path injection for zip entry " + entryName);
- }
- return true;
- }
-
- return false;
- }
-
- /**
- * Method to decode either a json or yaml file into an object.
- *
- * @param zipFile the zip file
- * @param entry the entry to read in the zip file.
- * @return the decoded ToscaServiceTemplate object.
- * @throws CoderException IOException if the file decoding fails.
- */
- private ToscaServiceTemplate decodeFile(ZipFile zipFile, final ZipEntry entry) throws IOException, CoderException {
- ToscaServiceTemplate policy = null;
- if (entry.getName().endsWith(".json")) {
- policy = coder.decode(zipFile.getInputStream(entry), ToscaServiceTemplate.class);
- } else if (entry.getName().endsWith(".yaml")) {
- policy = yamlCoder.decode(zipFile.getInputStream(entry), ToscaServiceTemplate.class);
- }
- return policy;
- }
}
diff --git a/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/util/ReceptionUtil.java b/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/util/ReceptionUtil.java
new file mode 100644
index 00000000..9c0bab43
--- /dev/null
+++ b/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/util/ReceptionUtil.java
@@ -0,0 +1,92 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * Modifications Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.distribution.reception.util;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.coder.StandardCoder;
+import org.onap.policy.common.utils.coder.StandardYamlCoder;
+import org.onap.policy.distribution.reception.decoding.PolicyDecodingException;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+
+/**
+ * This class extracts and validates information from a CSAR file.
+ *
+ * @author Sirisha Manchikanti (sirisha.manchikanti@est.tech)
+ */
+public class ReceptionUtil {
+
+ private static StandardCoder coder = new StandardCoder();
+ private static StandardYamlCoder yamlCoder = new StandardYamlCoder();
+ private static final long MAX_FILE_SIZE = 512L * 1024;
+
+ /**
+ * Method to ensure validation of entries in the Zipfile. Attempts to solve path
+ * injection java security issues.
+ *
+ * @param entryName name of the ZipEntry to check
+ * @param csarPath Absolute path to the csar the ZipEntry is in
+ * @param entrySize size of the ZipEntry
+ * @throws PolicyDecodingException if the file size is too large
+ */
+ public static void validateZipEntry(String entryName, String csarPath, long entrySize)
+ throws PolicyDecodingException {
+ //
+ // Check file size
+ //
+ if (entrySize > MAX_FILE_SIZE) {
+ throw new PolicyDecodingException("Zip entry for " + entryName + " is too large " + entrySize);
+ }
+ //
+ // Now ensure that there is no path injection
+ //
+ var path = Path.of(csarPath, entryName).normalize();
+ //
+ // Throw an exception if path is outside the csar
+ //
+ if (! path.startsWith(csarPath)) {
+ throw new PolicyDecodingException("Potential path injection for zip entry " + entryName);
+ }
+ }
+
+ /**
+ * Method to decode either a json or yaml file into an object.
+ *
+ * @param zipFile the zip file
+ * @param entry the entry to read in the zip file.
+ * @return the decoded ToscaServiceTemplate object.
+ * @throws CoderException IOException if the file decoding fails.
+ */
+ public static ToscaServiceTemplate decodeFile(ZipFile zipFile, final ZipEntry entry)
+ throws IOException, CoderException {
+ ToscaServiceTemplate toscaServiceTemplate = null;
+ if (entry.getName().endsWith(".json")) {
+ toscaServiceTemplate = coder.decode(zipFile.getInputStream(entry), ToscaServiceTemplate.class);
+ } else if (entry.getName().endsWith(".yml")) {
+ toscaServiceTemplate = yamlCoder.decode(zipFile.getInputStream(entry), ToscaServiceTemplate.class);
+ }
+ return toscaServiceTemplate;
+ }
+}
diff --git a/plugins/reception-plugins/src/test/java/org/onap/policy/distribution/reception/decoding/policy/file/ControlLoopDecoderFileInCsarParameterGroupTest.java b/plugins/reception-plugins/src/test/java/org/onap/policy/distribution/reception/decoding/policy/file/ControlLoopDecoderFileInCsarParameterGroupTest.java
new file mode 100644
index 00000000..16f80096
--- /dev/null
+++ b/plugins/reception-plugins/src/test/java/org/onap/policy/distribution/reception/decoding/policy/file/ControlLoopDecoderFileInCsarParameterGroupTest.java
@@ -0,0 +1,67 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * Modifications Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.distribution.reception.decoding.policy.file;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.onap.policy.common.parameters.ValidationStatus;
+import org.onap.policy.distribution.reception.handling.sdc.CommonTestData;
+
+/**
+ * Class to perform unit test of {@link ControlLoopDecoderFileInCsarParameterGroup}.
+ *
+ * @author Sirisha Manchikanti (sirisha.manchikanti@est.tech)
+ */
+public class ControlLoopDecoderFileInCsarParameterGroupTest {
+
+ @Test
+ public void testValidParameters() {
+ final ControlLoopDecoderFileInCsarParameterGroup configurationParameters = CommonTestData
+ .getPolicyDecoderParameters("src/test/resources/parameters/FileInCsarControlLoopDecoderParameters.json",
+ ControlLoopDecoderFileInCsarParameterGroup.class);
+
+ assertEquals(ControlLoopDecoderFileInCsarParameterGroup.class.getSimpleName(),
+ configurationParameters.getName());
+ assertEquals("controlloop", configurationParameters.getControlLoopType());
+ assertEquals(ValidationStatus.CLEAN, configurationParameters.validate().getStatus());
+ }
+
+ @Test
+ public void testInvalidParameters() {
+ final ControlLoopDecoderFileInCsarParameterGroup configurationParameters =
+ CommonTestData.getPolicyDecoderParameters(
+ "src/test/resources/parameters/FileInCsarControlLoopDecoderParametersInvalid.json",
+ ControlLoopDecoderFileInCsarParameterGroup.class);
+
+ assertEquals(ValidationStatus.INVALID, configurationParameters.validate().getStatus());
+ }
+
+ @Test
+ public void testEmptyParameters() {
+ final ControlLoopDecoderFileInCsarParameterGroup configurationParameters =
+ CommonTestData.getPolicyDecoderParameters("src/test/resources/parameters/EmptyParameters.json",
+ ControlLoopDecoderFileInCsarParameterGroup.class);
+
+ assertEquals(ValidationStatus.INVALID, configurationParameters.validate().getStatus());
+ }
+}
diff --git a/plugins/reception-plugins/src/test/java/org/onap/policy/distribution/reception/decoding/policy/file/ControlLoopDecoderFileInCsarTest.java b/plugins/reception-plugins/src/test/java/org/onap/policy/distribution/reception/decoding/policy/file/ControlLoopDecoderFileInCsarTest.java
new file mode 100644
index 00000000..e452a7ce
--- /dev/null
+++ b/plugins/reception-plugins/src/test/java/org/onap/policy/distribution/reception/decoding/policy/file/ControlLoopDecoderFileInCsarTest.java
@@ -0,0 +1,96 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * Modifications Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.distribution.reception.decoding.policy.file;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.util.Collection;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.policy.common.parameters.ParameterService;
+import org.onap.policy.distribution.model.Csar;
+import org.onap.policy.distribution.reception.decoding.PolicyDecodingException;
+import org.onap.policy.distribution.reception.handling.sdc.CommonTestData;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaEntity;
+
+/**
+ * Class to perform unit test of {@link ControlLoopDecoderFileInCsar}.
+ *
+ * @author Sirisha Manchikanti (sirisha.manchikanti@est.tech)
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class ControlLoopDecoderFileInCsarTest {
+
+ /**
+ * Set up.
+ */
+ @BeforeClass
+ public static void setUp() {
+ final ControlLoopDecoderFileInCsarParameterGroup configurationParameters = CommonTestData
+ .getPolicyDecoderParameters("src/test/resources/parameters/FileInCsarControlLoopDecoderParameters.json",
+ ControlLoopDecoderFileInCsarParameterGroup.class);
+ configurationParameters.setName(ControlLoopDecoderFileInCsarParameterGroup.class.getSimpleName());
+ ParameterService.register(configurationParameters);
+ }
+
+ /**
+ * Tear down.
+ */
+ @AfterClass
+ public static void tearDown() {
+ ParameterService.deregister(ControlLoopDecoderFileInCsarParameterGroup.class.getSimpleName());
+ }
+
+ @Test
+ public void testDecodeControlLoop() throws PolicyDecodingException {
+
+ final ControlLoopDecoderFileInCsar decoder = new ControlLoopDecoderFileInCsar();
+ decoder.configure(ControlLoopDecoderFileInCsarParameterGroup.class.getSimpleName());
+
+ final File file = new File("src/test/resources/service-Sampleservice-controlloop.csar");
+ final Csar csar = new Csar(file.getAbsolutePath());
+
+ assertTrue(decoder.canHandle(csar));
+ final Collection<ToscaEntity> controlLoopHolders = decoder.decode(csar);
+ assertEquals(1, controlLoopHolders.size());
+ }
+
+ @Test
+ public void testDecodeControlLoopZipError() {
+
+ final ControlLoopDecoderFileInCsar decoder = new ControlLoopDecoderFileInCsar();
+ decoder.configure(ControlLoopDecoderFileInCsarParameterGroup.class.getSimpleName());
+
+ final File file = new File("unknown.csar");
+ final Csar csar = new Csar(file.getAbsolutePath());
+
+ assertTrue(decoder.canHandle(csar));
+ assertThatThrownBy(() -> decoder.decode(csar)).isInstanceOf(PolicyDecodingException.class)
+ .hasMessageContaining("Failed decoding the controlloop");
+ }
+}
diff --git a/plugins/reception-plugins/src/test/resources/parameters/FileInCsarControlLoopDecoderParameters.json b/plugins/reception-plugins/src/test/resources/parameters/FileInCsarControlLoopDecoderParameters.json
new file mode 100644
index 00000000..ca112388
--- /dev/null
+++ b/plugins/reception-plugins/src/test/resources/parameters/FileInCsarControlLoopDecoderParameters.json
@@ -0,0 +1,3 @@
+{
+ "controlLoopType": "controlloop"
+}
diff --git a/plugins/reception-plugins/src/test/resources/parameters/FileInCsarControlLoopDecoderParametersInvalid.json b/plugins/reception-plugins/src/test/resources/parameters/FileInCsarControlLoopDecoderParametersInvalid.json
new file mode 100644
index 00000000..9d33896e
--- /dev/null
+++ b/plugins/reception-plugins/src/test/resources/parameters/FileInCsarControlLoopDecoderParametersInvalid.json
@@ -0,0 +1,3 @@
+{
+ "controlLoop": ""
+}
diff --git a/plugins/reception-plugins/src/test/resources/service-Sampleservice-controlloop.csar b/plugins/reception-plugins/src/test/resources/service-Sampleservice-controlloop.csar
new file mode 100644
index 00000000..03e29366
--- /dev/null
+++ b/plugins/reception-plugins/src/test/resources/service-Sampleservice-controlloop.csar
Binary files differ