summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrunomilitzer <bruno.militzer@est.tech>2021-08-30 18:40:01 +0100
committerbrunomilitzer <bruno.militzer@est.tech>2021-09-09 17:19:54 +0100
commit09d8a86e2126ccc9a12456ddead12a5fe8f58697 (patch)
tree3bdd01daa29a0852453c789d1ee1c2d5593ac36a
parentf16d42aec838b7e8faf39af2a3f46dfb5fed0605 (diff)
Fixed Delete Instance Properties Endpoint
Fixed issue regarding that control loops was not getting instantiated Fixed issue regarding state change that was not receiving paramaters Added appropriate Camel Endpoints Unit tests will be applied on POLICY-3568 and POLICY-3567 Issue-ID: POLICY-3558 Change-Id: I11a1093bdb16651fe1c0ad8e267ded5390267a30 Signed-off-by: brunomilitzer <bruno.militzer@est.tech>
-rw-r--r--models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ControlLoops.java3
-rw-r--r--models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ControlLoopProvider.java34
-rw-r--r--models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/rest/instantiation/InstancePropertiesResponse.java3
-rw-r--r--runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java49
-rw-r--r--runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java253
-rw-r--r--runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/CommissioningController.java7
-rw-r--r--runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/InstantiationController.java75
-rw-r--r--runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationUtils.java19
-rw-r--r--runtime/src/main/resources/clds/camel/rest/clamp-api-v2.xml91
-rw-r--r--runtime/src/main/resources/clds/camel/routes/controlloop-flows.xml70
10 files changed, 530 insertions, 74 deletions
diff --git a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ControlLoops.java b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ControlLoops.java
index 691ce95db..4ab406f3b 100644
--- a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ControlLoops.java
+++ b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ControlLoops.java
@@ -18,6 +18,7 @@
package org.onap.policy.clamp.controlloop.models.controlloop.concepts;
+import java.util.ArrayList;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
@@ -34,7 +35,7 @@ import org.onap.policy.models.base.PfUtils;
@AllArgsConstructor
@EqualsAndHashCode
public class ControlLoops {
- private List<ControlLoop> controlLoopList;
+ private List<ControlLoop> controlLoopList = new ArrayList<>();
/**
* Copy constructor, does a deep copy.
diff --git a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ControlLoopProvider.java b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ControlLoopProvider.java
index 762b927ab..b4f99a51e 100644
--- a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ControlLoopProvider.java
+++ b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ControlLoopProvider.java
@@ -45,6 +45,7 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
import org.onap.policy.models.tosca.authorative.concepts.ToscaTypedEntityFilter;
import org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTemplate;
+import org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTemplates;
import org.springframework.stereotype.Component;
/**
@@ -197,18 +198,39 @@ public class ControlLoopProvider extends AbstractModelsProvider {
Map<String, ToscaNodeTemplate> savedNodeTemplates = new HashMap<>();
- serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().forEach((key, template) -> {
- var jpaToscaNodeTemplate = new JpaToscaNodeTemplate(template);
-
- getPfDao().create(jpaToscaNodeTemplate);
+ var jpaToscaNodeTemplates = new JpaToscaNodeTemplates();
+ jpaToscaNodeTemplates.fromAuthorative(Collections.singletonList(serviceTemplate.getToscaTopologyTemplate()
+ .getNodeTemplates()));
- savedNodeTemplates.put(key, template);
- });
+ getPfDao().create(jpaToscaNodeTemplates);
+ serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().forEach(savedNodeTemplates::put);
return savedNodeTemplates;
}
/**
+ * Deletes Instance Properties on the database.
+ *
+ * @param filteredToscaNodeTemplateMap filtered node templates map to delete
+ * @param filteredToscaNodeTemplateList filtered node template list to delete
+ */
+ public void deleteInstanceProperties(
+ Map<String, ToscaNodeTemplate> filteredToscaNodeTemplateMap,
+ List<ToscaNodeTemplate> filteredToscaNodeTemplateList) {
+
+ var jpaToscaNodeTemplates = new JpaToscaNodeTemplates();
+ jpaToscaNodeTemplates.fromAuthorative(Collections.singletonList(filteredToscaNodeTemplateMap));
+
+ getPfDao().create(jpaToscaNodeTemplates);
+
+ filteredToscaNodeTemplateList.forEach(template -> {
+ var jpaToscaNodeTemplate = new JpaToscaNodeTemplate(template);
+
+ getPfDao().delete(jpaToscaNodeTemplate);
+ });
+ }
+
+ /**
* Get Node Templates.
*
* @param name the name of the node template to get, null to get all node templates
diff --git a/models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/rest/instantiation/InstancePropertiesResponse.java b/models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/rest/instantiation/InstancePropertiesResponse.java
index eed339447..d8974d6e3 100644
--- a/models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/rest/instantiation/InstancePropertiesResponse.java
+++ b/models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/rest/instantiation/InstancePropertiesResponse.java
@@ -19,6 +19,7 @@
package org.onap.policy.clamp.controlloop.models.messages.rest.instantiation;
+import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
@@ -33,5 +34,5 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
@Setter
@ToString(callSuper = true)
public class InstancePropertiesResponse extends SimpleResponse {
- private List<ToscaConceptIdentifier> affectedInstanceProperties;
+ private List<ToscaConceptIdentifier> affectedInstanceProperties = new ArrayList<>();
}
diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java
index fbfc1de69..0b7bc9a26 100644
--- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java
+++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java
@@ -34,7 +34,6 @@ import java.util.stream.Collectors;
import javax.ws.rs.core.Response.Status;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
-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.controlloop.persistence.provider.ControlLoopProvider;
import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantProvider;
@@ -64,6 +63,7 @@ import org.springframework.stereotype.Component;
@Component
public class CommissioningProvider {
public static final String CONTROL_LOOP_NODE_TYPE = "org.onap.policy.clamp.controlloop.ControlLoop";
+ private static final String INSTANCE_TEXT = "_Instance";
private final PolicyModelsProvider modelsProvider;
private final ControlLoopProvider clProvider;
@@ -98,10 +98,10 @@ public class CommissioningProvider {
* @throws PfModelException on creation errors
*/
public CommissioningResponse createControlLoopDefinitions(ToscaServiceTemplate serviceTemplate)
- throws PfModelException, ControlLoopException {
+ throws PfModelException {
if (verifyIfInstancePropertiesExists()) {
- throw new ControlLoopException(Status.BAD_REQUEST,
+ throw new PfModelException(Status.BAD_REQUEST,
"Delete instances, to commission control loop definitions");
}
@@ -148,10 +148,10 @@ public class CommissioningProvider {
* @throws PfModelException on deletion errors
*/
public CommissioningResponse deleteControlLoopDefinition(String name, String version)
- throws PfModelException, ControlLoopException {
+ throws PfModelException {
if (verifyIfInstancePropertiesExists()) {
- throw new ControlLoopException(Status.BAD_REQUEST,
+ throw new PfModelException(Status.BAD_REQUEST,
"Delete instances, to commission control loop definitions");
}
@@ -395,10 +395,17 @@ public class CommissioningProvider {
public Map<String, ToscaNodeTemplate> getNodeTemplatesWithCommonOrInstanceProperties(boolean common, String name,
String version) throws PfModelException {
- var commonOrInstanceNodeTypeProps = this.getCommonOrInstancePropertiesFromNodeTypes(common, name, version);
+ if (common && verifyIfInstancePropertiesExists()) {
+ throw new PfModelException(Status.BAD_REQUEST,
+ "Cannot create or edit common properties, delete all the instantiations first");
+ }
+
+ var commonOrInstanceNodeTypeProps =
+ this.getCommonOrInstancePropertiesFromNodeTypes(common, name, version);
var serviceTemplates = new ToscaServiceTemplates();
- serviceTemplates.setServiceTemplates(modelsProvider.getServiceTemplateList(name, version));
+ serviceTemplates.setServiceTemplates(filterToscaNodeTemplateInstance(
+ modelsProvider.getServiceTemplateList(name, version)));
return this.getDerivedCommonOrInstanceNodeTemplates(
serviceTemplates.getServiceTemplates().get(0).getToscaTopologyTemplate().getNodeTemplates(),
@@ -433,7 +440,8 @@ public class CommissioningProvider {
var serviceTemplates = new ToscaServiceTemplates();
serviceTemplates.setServiceTemplates(modelsProvider.getServiceTemplateList(name, version));
- ToscaServiceTemplate fullTemplate = serviceTemplates.getServiceTemplates().get(0);
+ ToscaServiceTemplate fullTemplate = filterToscaNodeTemplateInstance(
+ serviceTemplates.getServiceTemplates()).get(0);
var template = new HashMap<String, Object>();
template.put("tosca_definitions_version", fullTemplate.getToscaDefinitionsVersion());
@@ -496,6 +504,29 @@ public class CommissioningProvider {
}
}
+ private List<ToscaServiceTemplate> filterToscaNodeTemplateInstance(List<ToscaServiceTemplate> serviceTemplates) {
+
+ List<ToscaServiceTemplate> toscaServiceTemplates = new ArrayList<>();
+
+ serviceTemplates.stream().forEach(serviceTemplate -> {
+
+ Map<String, ToscaNodeTemplate> toscaNodeTemplates = new HashMap<>();
+
+ serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().forEach((key, nodeTemplate) -> {
+ if (!nodeTemplate.getName().contains(INSTANCE_TEXT)) {
+ toscaNodeTemplates.put(key, nodeTemplate);
+ }
+ });
+
+ serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().clear();
+ serviceTemplate.getToscaTopologyTemplate().setNodeTemplates(toscaNodeTemplates);
+
+ toscaServiceTemplates.add(serviceTemplate);
+ });
+
+ return toscaServiceTemplates;
+ }
+
/**
* Validates to see if there is any instance properties saved.
*
@@ -503,7 +534,7 @@ public class CommissioningProvider {
*/
private boolean verifyIfInstancePropertiesExists() {
return clProvider.getNodeTemplates(null, null).stream()
- .anyMatch(nodeTemplate -> nodeTemplate.getKey().getName().contains("_Instance"));
+ .anyMatch(nodeTemplate -> nodeTemplate.getKey().getName().contains(INSTANCE_TEXT));
}
}
diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java
index a71772624..dc40cc274 100644
--- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java
+++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java
@@ -21,18 +21,27 @@
package org.onap.policy.clamp.controlloop.runtime.instantiation;
+import com.google.gson.Gson;
+import com.google.gson.internal.LinkedTreeMap;
+import com.google.gson.reflect.TypeToken;
+import java.lang.reflect.Type;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.UUID;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import lombok.AllArgsConstructor;
import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException;
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.models.controlloop.concepts.ControlLoops;
import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider;
@@ -49,6 +58,7 @@ import org.onap.policy.common.parameters.ValidationResult;
import org.onap.policy.common.parameters.ValidationStatus;
import org.onap.policy.models.base.PfModelException;
import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaNameVersion;
import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
import org.springframework.stereotype.Component;
@@ -59,48 +69,102 @@ import org.springframework.stereotype.Component;
@Component
@AllArgsConstructor
public class ControlLoopInstantiationProvider {
+ private static final String CONTROL_LOOP_NODE_TYPE = "org.onap.policy.clamp.controlloop.ControlLoop";
+ private static final String CONTROL_LOOP_NODE_ELEMENT_TYPE = "ControlLoopElement";
+ private static final String PARTICIPANT_ID_PROPERTY_KEY = "participant_id";
+ private static final String CL_ELEMENT_NAME = "name";
+ private static final String CL_ELEMENT_VERSION = "version";
private static final String INSTANCE_TEXT = "_Instance";
+ private static final Gson GSON = new Gson();
+
private final ControlLoopProvider controlLoopProvider;
private final CommissioningProvider commissioningProvider;
private final SupervisionHandler supervisionHandler;
private static final Object lockit = new Object();
- private static final String CL_ELEMENT_NAME = "name";
-
/**
- * Create Instance Properties.
+ * Creates Instance Properties and Control Loop.
*
* @param serviceTemplate the service template
* @return the result of the instantiation operation
* @throws PfModelException on creation errors
*/
- public InstancePropertiesResponse saveInstanceProperties(ToscaServiceTemplate serviceTemplate) {
+ public InstancePropertiesResponse createInstanceProperties(ToscaServiceTemplate serviceTemplate)
+ throws PfModelException {
String instanceName = generateSequentialInstanceName();
+ ControlLoop controlLoop = new ControlLoop();
+ Map<UUID, ControlLoopElement> controlLoopElements = new HashMap<>();
+
+ ToscaServiceTemplate toscaServiceTemplate = commissioningProvider
+ .getToscaServiceTemplate(null, null);
- Map<String, ToscaNodeTemplate> nodeTemplates = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates();
+ Map<String, ToscaNodeTemplate> persistedNodeTemplateMap = toscaServiceTemplate
+ .getToscaTopologyTemplate().getNodeTemplates();
+
+ Map<String, ToscaNodeTemplate> nodeTemplates =
+ deepCloneNodeTemplate(serviceTemplate);
nodeTemplates.forEach((key, template) -> {
+ ToscaNodeTemplate newNodeTemplate = new ToscaNodeTemplate();
String name = key + instanceName;
+ String version = template.getVersion();
String description = template.getDescription() + instanceName;
- template.setName(name);
- template.setDescription(description);
+ newNodeTemplate.setName(name);
+ newNodeTemplate.setVersion(version);
+ newNodeTemplate.setDescription(description);
+ newNodeTemplate.setProperties(new HashMap<>(template.getProperties()));
+ newNodeTemplate.setType(template.getType());
+ newNodeTemplate.setTypeVersion(template.getTypeVersion());
+ newNodeTemplate.setMetadata(template.getMetadata());
- changeInstanceElementsName(template, instanceName);
+ crateNewControlLoopInstance(instanceName, controlLoop, controlLoopElements, template, newNodeTemplate);
+ persistedNodeTemplateMap.put(name, newNodeTemplate);
});
- Map<String, ToscaNodeTemplate> toscaSavedNodeTemplate = controlLoopProvider
- .saveInstanceProperties(serviceTemplate);
+ ControlLoops controlLoops = new ControlLoops();
- var response = new InstancePropertiesResponse();
+ serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().putAll(persistedNodeTemplateMap);
+
+ controlLoop.setElements(controlLoopElements);
+ controlLoops.getControlLoopList().add(controlLoop);
+
+ return saveInstancePropertiesAndControlLoop(serviceTemplate, controlLoops);
+ }
+
+ /**
+ * Deletes Instance Properties.
+ *
+ * @param name the name of the control loop to delete
+ * @param version the version of the control loop to delete
+ * @return the result of the deletion
+ * @throws PfModelException on deletion errors
+ */
+ public InstantiationResponse deleteInstanceProperties(String name, String version) throws PfModelException {
+
+ String instanceName = getInstancePropertyName(name, version);
+
+ Map<String, ToscaNodeTemplate> filteredToscaNodeTemplateMap = new HashMap<>();
- // @formatter:off
- response.setAffectedInstanceProperties(toscaSavedNodeTemplate.values().stream().map(template ->
- template.getKey().asIdentifier()).collect(Collectors.toList()));
- // @formatter:on
+ ToscaServiceTemplate toscaServiceTemplate = commissioningProvider.getToscaServiceTemplate(name, version);
+
+ toscaServiceTemplate.getToscaTopologyTemplate()
+ .getNodeTemplates().forEach((key, nodeTemplate) -> {
+ if (!nodeTemplate.getName().contains(instanceName)) {
+ filteredToscaNodeTemplateMap.put(key, nodeTemplate);
+ }
+ });
+
+ List<ToscaNodeTemplate> filteredToscaNodeTemplateList =
+ toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates().values().stream()
+ .filter(nodeTemplate -> nodeTemplate.getName().contains(instanceName)).collect(Collectors.toList());
+
+ InstantiationResponse response = this.deleteControlLoop(name, version);
+
+ controlLoopProvider.deleteInstanceProperties(filteredToscaNodeTemplateMap, filteredToscaNodeTemplateList);
return response;
}
@@ -116,7 +180,8 @@ public class ControlLoopInstantiationProvider {
synchronized (lockit) {
for (ControlLoop controlLoop : controlLoops.getControlLoopList()) {
- var checkControlLoop = controlLoopProvider.getControlLoop(controlLoop.getKey().asIdentifier());
+ var checkControlLoop = controlLoopProvider
+ .getControlLoop(controlLoop.getKey().asIdentifier());
if (checkControlLoop != null) {
throw new PfModelException(Response.Status.BAD_REQUEST,
controlLoop.getKey().asIdentifier() + " already defined");
@@ -323,27 +388,102 @@ public class ControlLoopInstantiationProvider {
}
/**
- * Creates instance element name.
+ * Saves Instance Properties and Control Loop.
*
- * @param serviceTemplate the service serviceTemplate
- * @param instanceName to amend to the element name
+ * @param serviceTemplate the service template
+ * @param controlLoops a list of control loops
+ * @return the result of the instance properties and instantiation operation
+ * @throws PfModelException on creation errors
*/
- private void changeInstanceElementsName(ToscaNodeTemplate serviceTemplate, String instanceName) {
+ private InstancePropertiesResponse saveInstancePropertiesAndControlLoop(
+ ToscaServiceTemplate serviceTemplate, ControlLoops controlLoops) throws PfModelException {
- @SuppressWarnings("unchecked")
- List<Map<String, String>> controlLoopElements = (List<Map<String, String>>) serviceTemplate.getProperties()
- .get("elements");
+ var response = new InstancePropertiesResponse();
- if (controlLoopElements != null) {
- controlLoopElements.forEach(clElement -> {
- String name = clElement.get(CL_ELEMENT_NAME) + instanceName;
- clElement.replace(CL_ELEMENT_NAME, name);
- });
+ Map<String, ToscaNodeTemplate> toscaSavedNodeTemplate;
+
+ synchronized (lockit) {
+ for (ControlLoop controlLoop : controlLoops.getControlLoopList()) {
+ var checkControlLoop = controlLoopProvider.getControlLoop(controlLoop.getKey().asIdentifier());
+ if (checkControlLoop != null) {
+ throw new PfModelException(Response.Status.BAD_REQUEST,
+ controlLoop.getKey().asIdentifier() + " already defined");
+ }
+ }
+
+ toscaSavedNodeTemplate = controlLoopProvider.saveInstanceProperties(serviceTemplate);
+
+ controlLoopProvider.createControlLoops(controlLoops.getControlLoopList());
+
+ }
+
+ List<ToscaConceptIdentifier> affectedControlLoops = controlLoops.getControlLoopList().stream()
+ .map(cl -> cl.getKey().asIdentifier()).collect(Collectors.toList());
+
+ List<ToscaConceptIdentifier> toscaAffectedProperties = toscaSavedNodeTemplate.values().stream()
+ .map(template -> template.getKey().asIdentifier()).collect(Collectors.toList());
+
+ response.setAffectedInstanceProperties(Stream.of(affectedControlLoops, toscaAffectedProperties)
+ .flatMap(Collection::stream).collect(Collectors.toList()));
+
+ return response;
+ }
+
+ /**
+ * Crates a new Control Loop instance.
+ * @param instanceName Control Loop Instance name
+ * @param controlLoop empty Control Loop
+ * @param controlLoopElements new Control Loop Element map
+ * @param template original Cloned Tosca Node Template
+ * @param newNodeTemplate new Tosca Node Template
+ */
+ private void crateNewControlLoopInstance(String instanceName, ControlLoop controlLoop,
+ Map<UUID, ControlLoopElement> controlLoopElements,
+ ToscaNodeTemplate template,
+ ToscaNodeTemplate newNodeTemplate) {
+ if (template.getType().equals(CONTROL_LOOP_NODE_TYPE)) {
+ controlLoop.setDefinition(getControlLoopDefinition(newNodeTemplate));
+ }
+
+ if (template.getType().contains(CONTROL_LOOP_NODE_ELEMENT_TYPE)) {
+ ControlLoopElement controlLoopElement = getControlLoopElement(instanceName, newNodeTemplate);
+ controlLoopElements.put(controlLoopElement.getId(), controlLoopElement);
}
+
+ controlLoop.setName("PMSH" + instanceName);
+ controlLoop.setVersion(template.getVersion());
+ controlLoop.setDescription("PMSH control loop " + instanceName);
+ controlLoop.setState(ControlLoopState.UNINITIALISED);
+ controlLoop.setOrderedState(ControlLoopOrderedState.UNINITIALISED);
}
/**
+ * Get's the instance property name of the control loop.
+ *
+ * @param name the name of the control loop to get, null for all control loops
+ * @param version the version of the control loop to get, null for all control loops
+ * @return the instance name of the control loop instance properties
+ * @throws PfModelException on errors getting control loops
+ */
+ private String getInstancePropertyName(String name, String version) throws PfModelException {
+ List<String> toscaDefinitionsNames =
+ controlLoopProvider.getControlLoops(name, version).stream().map(ControlLoop::getDefinition)
+ .map(ToscaNameVersion::getName).collect(Collectors.toList());
+
+ return toscaDefinitionsNames.stream().reduce("", (s1, s2) -> {
+
+ if (s2.contains(INSTANCE_TEXT)) {
+ String[] instances = s2.split(INSTANCE_TEXT);
+
+ return INSTANCE_TEXT + instances[1];
+ }
+
+ return s1;
+ });
+ }
+
+ /**
* Generates Instance Name in sequential order and return it to append to the Node Template Name.
*
* @return instanceName
@@ -361,4 +501,61 @@ public class ControlLoopInstantiationProvider {
return INSTANCE_TEXT + (instanceNumber + 1);
}
+
+ /**
+ * Retrieves Control Loop Definition.
+ *
+ * @param template tosca node template
+ * @return control loop definition
+ */
+ private ToscaConceptIdentifier getControlLoopDefinition(ToscaNodeTemplate template) {
+ ToscaConceptIdentifier definition = new ToscaConceptIdentifier();
+ definition.setName(template.getName());
+ definition.setVersion(template.getVersion());
+
+ return definition;
+ }
+
+ /**
+ * Retrieves Control Loop Element.
+ *
+ * @param instanceName instance name to be appended to participant name
+ * @param template tosca node template
+ * @return a control loop element
+ */
+ @SuppressWarnings("unchecked")
+ private ControlLoopElement getControlLoopElement(String instanceName, ToscaNodeTemplate template) {
+ ControlLoopElement controlLoopElement = new ControlLoopElement();
+ ToscaConceptIdentifier definition = new ToscaConceptIdentifier();
+ definition.setName(template.getName());
+ definition.setVersion(template.getVersion());
+ controlLoopElement.setDefinition(definition);
+
+ LinkedTreeMap<String, Object> participantId = (LinkedTreeMap<String, Object>) template.getProperties()
+ .get(PARTICIPANT_ID_PROPERTY_KEY);
+
+ ToscaConceptIdentifier participantIdAndType = new ToscaConceptIdentifier();
+ participantIdAndType.setName(participantId.get(CL_ELEMENT_NAME) + instanceName);
+ participantIdAndType.setVersion(String.valueOf(participantId.get(CL_ELEMENT_VERSION)));
+
+ controlLoopElement.setParticipantType(participantIdAndType);
+ controlLoopElement.setParticipantId(participantIdAndType);
+
+ return controlLoopElement;
+ }
+
+ /**
+ * Deep clones ToscaNodeTemplate.
+ *
+ * @param serviceTemplate ToscaServiceTemplate
+ * @return a cloned Hash Map of ToscaNodeTemplate
+ */
+ private Map<String, ToscaNodeTemplate> deepCloneNodeTemplate(ToscaServiceTemplate serviceTemplate) {
+ String jsonString = GSON.toJson(serviceTemplate.getToscaTopologyTemplate().getNodeTemplates());
+
+ Type type = new TypeToken<HashMap<String, ToscaNodeTemplate>>() {}.getType();
+
+ return GSON.fromJson(jsonString, type);
+ }
+
}
diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/CommissioningController.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/CommissioningController.java
index 2c3a41e26..fcb5aed97 100644
--- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/CommissioningController.java
+++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/CommissioningController.java
@@ -121,7 +121,7 @@ public class CommissioningController extends AbstractRestController {
name = REQUEST_ID_NAME,
required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
@ApiParam(value = "Entity Body of Control Loop", required = true) @RequestBody ToscaServiceTemplate body)
- throws PfModelException, ControlLoopException {
+ throws PfModelException {
return ResponseEntity.ok().body(provider.createControlLoopDefinitions(body));
}
@@ -188,7 +188,7 @@ public class CommissioningController extends AbstractRestController {
@ApiParam(
value = "Control Loop definition version",
required = true) @RequestParam("version") String version)
- throws PfModelException, ControlLoopException {
+ throws PfModelException {
return ResponseEntity.ok().body(provider.deleteControlLoopDefinition(name, version));
}
@@ -385,6 +385,7 @@ public class CommissioningController extends AbstractRestController {
* @param version the version of the tosca service template to get
* @return the specified tosca service template or section Json Schema
* @throws PfModelException on errors getting the Common or Instance Properties
+ * @throws ControlLoopException on error getting the Common or Instance Properties
*/
// @formatter:off
@GetMapping(value = "/commission/getCommonOrInstanceProperties",
@@ -438,7 +439,7 @@ public class CommissioningController extends AbstractRestController {
@ApiParam(value = "Tosca service template version", required = false) @RequestParam(
value = "version",
required = false) String version)
- throws PfModelException {
+ throws PfModelException {
return ResponseEntity.ok().body(provider.getNodeTemplatesWithCommonOrInstanceProperties(common, name, version));
}
diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/InstantiationController.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/InstantiationController.java
index 5a8275f8a..91958f97a 100644
--- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/InstantiationController.java
+++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/InstantiationController.java
@@ -187,9 +187,76 @@ public class InstantiationController extends AbstractRestController {
@RequestHeader(
name = REQUEST_ID_NAME,
required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
- @ApiParam(value = "Body of instance properties", required = true) @RequestBody ToscaServiceTemplate body) {
+ @ApiParam(value = "Body of instance properties", required = true) @RequestBody ToscaServiceTemplate body)
+ throws PfModelException {
+
+ return ResponseEntity.ok().body(provider.createInstanceProperties(body));
+ }
+
+ /**
+ * Deletes a control loop definition and instance properties.
+ *
+ * @param requestId request ID used in ONAP logging
+ * @param name the name of the control loop to delete
+ * @param version the version of the control loop to delete
+ * @return a response
+ * @throws PfModelException on errors deleting of control loop and instance properties
+ */
+ // @formatter:off
+ @DeleteMapping(value = "/instanceProperties",
+ produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML})
+ @ApiOperation(value = "Delete a control loop and instance properties",
+ notes = "Deletes a control loop and instance properties, returning optional error details",
+ response = InstantiationResponse.class,
+ tags = {TAGS},
+ authorizations = @Authorization(value = AUTHORIZATION_TYPE),
+ responseHeaders = {
+ @ResponseHeader(
+ name = VERSION_MINOR_NAME,
+ description = VERSION_MINOR_DESCRIPTION,
+ response = String.class),
+ @ResponseHeader(
+ name = VERSION_PATCH_NAME,
+ description = VERSION_PATCH_DESCRIPTION,
+ response = String.class),
+ @ResponseHeader(
+ name = VERSION_LATEST_NAME,
+ description = VERSION_LATEST_DESCRIPTION,
+ response = String.class),
+ @ResponseHeader(
+ name = REQUEST_ID_NAME,
+ description = REQUEST_ID_HDR_DESCRIPTION,
+ response = UUID.class)},
+ extensions = {
+ @Extension
+ (
+ name = EXTENSION_NAME,
+ properties = {
+ @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
+ @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
+ }
+ )
+ }
+ )
+ @ApiResponses(
+ value = {
+ @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
+ @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
+ @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
+ }
+ )
+ // @formatter:on
+
+ public ResponseEntity<InstantiationResponse> deleteInstanceProperties(
+ @RequestHeader(
+ name = REQUEST_ID_NAME,
+ required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
+ @ApiParam(value = "Control Loop definition name", required = true) @RequestParam("name") String name,
+ @ApiParam(value = "Control Loop definition version") @RequestParam(
+ value = "version",
+ required = true) String version) throws PfModelException {
- return ResponseEntity.ok().body(provider.saveInstanceProperties(body));
+ return ResponseEntity.ok().body(provider.deleteInstanceProperties(name, version));
}
/**
@@ -494,10 +561,10 @@ public class InstantiationController extends AbstractRestController {
@RequestHeader(
name = REQUEST_ID_NAME,
required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
- @ApiParam(value = "Control Loop definition name", required = false) @RequestParam(
+ @ApiParam(value = "Control Loop name", required = false) @RequestParam(
value = "name",
required = false) String name,
- @ApiParam(value = "Control Loop definition version", required = false) @RequestParam(
+ @ApiParam(value = "Control Loop version", required = false) @RequestParam(
value = "version",
required = false) String version)
throws PfModelException {
diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationUtils.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationUtils.java
index 8529c0c9b..c107986a5 100644
--- a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationUtils.java
+++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationUtils.java
@@ -144,23 +144,4 @@ public class InstantiationUtils {
commissioningProvider.createControlLoopDefinitions(template);
}
-
- /**
- * Assert that instance properties has been properly saved.
- *
- * @param response InstancePropertiesResponse
- * @throws PfModelException if an error occurs
- */
- public static void assertInstancePropertiesResponse(InstancePropertiesResponse response) throws PfModelException {
-
- assertThat(response).isNotNull();
- assertThat(response.getErrorDetails()).isNull();
- assertThat(response.getAffectedInstanceProperties()).hasSize(8);
-
- boolean containsInstance = response.getAffectedInstanceProperties().stream()
- .anyMatch(identifier -> identifier.getName().contains("_Instance"));
-
- assertThat(containsInstance).isTrue();
-
- }
}
diff --git a/runtime/src/main/resources/clds/camel/rest/clamp-api-v2.xml b/runtime/src/main/resources/clds/camel/rest/clamp-api-v2.xml
index f800efe8d..55e1f8ad1 100644
--- a/runtime/src/main/resources/clds/camel/rest/clamp-api-v2.xml
+++ b/runtime/src/main/resources/clds/camel/rest/clamp-api-v2.xml
@@ -1587,6 +1587,50 @@
</route>
</delete>
+ <delete uri="/v2/toscaControlLoop/deleteToscaInstantiation"
+ type="java.lang.String"
+ consumes="plain/text"
+ outType="java.lang.String"
+ produces="application/json"
+ bindingMode="off">
+ <route>
+ <removeHeaders pattern="*"
+ excludePattern="name|version|requestId"/>
+ <setProperty name="raiseHttpExceptionFlag">
+ <simple resultType="java.lang.Boolean">false</simple>
+ </setProperty>
+ <setHeader name="Content-Type">
+ <constant>application/json</constant>
+ </setHeader>
+ <doTry>
+ <to
+ uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=startLog(*, 'Delete Tosca Service Template')"/>
+ <to
+ uri="bean:org.onap.policy.clamp.authorization.AuthorizationController?method=authorize(*,'cl','','update')"/>
+ <to uri="direct:delete-tosca-instantiation"/>
+ <to
+ uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=endLog()"/>
+ <doCatch>
+ <exception>java.lang.Exception</exception>
+ <handled>
+ <constant>true</constant>
+ </handled>
+ <to
+ uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=errorLog()"/>
+ <log loggingLevel="ERROR"
+ message="Deleting Tosca Instantiation FAILED"/>
+
+ <setHeader name="CamelHttpResponseCode">
+ <constant>500</constant>
+ </setHeader>
+ <setBody>
+ <simple>Deleting Tosca Instantiation FAILED</simple>
+ </setBody>
+ </doCatch>
+ </doTry>
+ </route>
+ </delete>
+
<get uri="/v2/toscaControlLoop/getToscaInstantiation" outType="java.lang.String" bindingMode="off" produces="application/json">
<route>
<removeHeaders pattern="*"
@@ -1644,12 +1688,12 @@
<to
uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=errorLog()"/>
<log loggingLevel="ERROR"
- message="GET Tosca Instantiation JSON request failed: ${exception.stacktrace}"/>
+ message="GET Tosca Instantiation Order State JSON request failed: ${exception.stacktrace}"/>
<setHeader name="CamelHttpResponseCode">
<constant>500</constant>
</setHeader>
<setBody>
- <simple>GET Tosca Instantiation JSON FAILED</simple>
+ <simple>GET Tosca Instantiation Order State JSON FAILED</simple>
</setBody>
</doCatch>
</doTry>
@@ -1802,6 +1846,49 @@
</doTry>
</route>
</post>
+ <delete uri="/v2/toscaControlLoop/deleteToscaInstanceProperties"
+ type="java.lang.String"
+ consumes="plain/text"
+ outType="java.lang.String"
+ produces="application/json"
+ bindingMode="off">
+ <route>
+ <removeHeaders pattern="*"
+ excludePattern="name|version|requestId"/>
+ <setProperty name="raiseHttpExceptionFlag">
+ <simple resultType="java.lang.Boolean">false</simple>
+ </setProperty>
+ <setHeader name="Content-Type">
+ <constant>application/json</constant>
+ </setHeader>
+ <doTry>
+ <to
+ uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=startLog(*, 'Delete Tosca Service Template')"/>
+ <to
+ uri="bean:org.onap.policy.clamp.authorization.AuthorizationController?method=authorize(*,'cl','','update')"/>
+ <to uri="direct:delete-tosca-instance-properties"/>
+ <to
+ uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=endLog()"/>
+ <doCatch>
+ <exception>java.lang.Exception</exception>
+ <handled>
+ <constant>true</constant>
+ </handled>
+ <to
+ uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=errorLog()"/>
+ <log loggingLevel="ERROR"
+ message="Deleting Tosca Instance Properties FAILED"/>
+
+ <setHeader name="CamelHttpResponseCode">
+ <constant>500</constant>
+ </setHeader>
+ <setBody>
+ <simple>Deleting Tosca Instance Properties FAILED</simple>
+ </setBody>
+ </doCatch>
+ </doTry>
+ </route>
+ </delete>
<get uri="/v2/toscaControlLoop/getCommonOrInstanceProperties" outType="java.lang.String" bindingMode="off" produces="application/json">
<route>
diff --git a/runtime/src/main/resources/clds/camel/routes/controlloop-flows.xml b/runtime/src/main/resources/clds/camel/routes/controlloop-flows.xml
index 12b43dd9f..ac83ffd7a 100644
--- a/runtime/src/main/resources/clds/camel/routes/controlloop-flows.xml
+++ b/runtime/src/main/resources/clds/camel/routes/controlloop-flows.xml
@@ -110,6 +110,37 @@
</doFinally>
</doTry>
</route>
+ <route id="delete-tosca-instantiation">
+ <from uri="direct:delete-tosca-instantiation"/>
+ <doTry>
+ <log loggingLevel="INFO"
+ message="Deleting Tosca Instantiation"/>
+ <to
+ uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=invokeLog('Controlloop', 'Deleting Tosca Instantiation')"/>
+ <setHeader name="CamelHttpMethod">
+ <constant>DELETE</constant>
+ </setHeader>
+ <setHeader name="Content-Type">
+ <constant>application/json</constant>
+ </setHeader>
+ <setProperty name="name">
+ <simple>${header.name}</simple>
+ </setProperty>
+ <setProperty name="version">
+ <simple>${header.version}</simple>
+ </setProperty>
+ <log loggingLevel="INFO"
+ message="Endpoint to delete Tosca Instantiation: {{clamp.config.controlloop.runtime.url}}/onap/controlloop/v2/instantiation"></log>
+ <toD
+ uri="{{clamp.config.controlloop.runtime.url}}/onap/controlloop/v2/instantiation?name=${exchangeProperty[name]}&amp;version=${exchangeProperty[version]}&amp;bridgeEndpoint=true&amp;useSystemProperties=true&amp;throwExceptionOnFailure=${exchangeProperty[raiseHttpExceptionFlag]}&amp;authMethod=Basic&amp;authUsername={{clamp.config.controlloop.runtime.userName}}&amp;authPassword={{clamp.config.controlloop.runtime.password}}&amp;authenticationPreemptive=true&amp;connectionClose=true"/>
+ <convertBodyTo type="java.lang.String"/>
+ <doFinally>
+ <to uri="direct:reset-raise-http-exception-flag"/>
+ <to
+ uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=invokeReturnLog()"/>
+ </doFinally>
+ </doTry>
+ </route>
<route id="post-tosca-instance-properties">
<from uri="direct:post-tosca-instance-properties"/>
<doTry>
@@ -135,6 +166,37 @@
</doFinally>
</doTry>
</route>
+ <route id="delete-tosca-instance-properties">
+ <from uri="direct:delete-tosca-instance-properties"/>
+ <doTry>
+ <log loggingLevel="INFO"
+ message="Deleting Tosca Instance Properties"/>
+ <to
+ uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=invokeLog('Controlloop', 'Deleting Tosca Instance Properties')"/>
+ <setHeader name="CamelHttpMethod">
+ <constant>DELETE</constant>
+ </setHeader>
+ <setHeader name="Content-Type">
+ <constant>application/json</constant>
+ </setHeader>
+ <setProperty name="name">
+ <simple>${header.name}</simple>
+ </setProperty>
+ <setProperty name="version">
+ <simple>${header.version}</simple>
+ </setProperty>
+ <log loggingLevel="INFO"
+ message="Endpoint to delete Tosca Instance Properties: {{clamp.config.controlloop.runtime.url}}/onap/controlloop/v2/instanceProperties"></log>
+ <toD
+ uri="{{clamp.config.controlloop.runtime.url}}/onap/controlloop/v2/instanceProperties?name=${exchangeProperty[name]}&amp;version=${exchangeProperty[version]}&amp;bridgeEndpoint=true&amp;useSystemProperties=true&amp;throwExceptionOnFailure=${exchangeProperty[raiseHttpExceptionFlag]}&amp;authMethod=Basic&amp;authUsername={{clamp.config.controlloop.runtime.userName}}&amp;authPassword={{clamp.config.controlloop.runtime.password}}&amp;authenticationPreemptive=true&amp;connectionClose=true"/>
+ <convertBodyTo type="java.lang.String"/>
+ <doFinally>
+ <to uri="direct:reset-raise-http-exception-flag"/>
+ <to
+ uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=invokeReturnLog()"/>
+ </doFinally>
+ </doTry>
+ </route>
<route id="post-tosca-instantiation">
<from uri="direct:post-tosca-instantiation"/>
<doTry>
@@ -198,10 +260,16 @@
<setHeader name="Content-Type">
<constant>application/json</constant>
</setHeader>
+ <setProperty name="name">
+ <simple>${header.name}</simple>
+ </setProperty>
+ <setProperty name="version">
+ <simple>${header.version}</simple>
+ </setProperty>
<log loggingLevel="INFO"
message="Endpoint to get Tosca Instantiation Order State: {{clamp.config.controlloop.runtime.url}}/onap/controlloop/v2/instantiationState"></log>
<toD
- uri="{{clamp.config.controlloop.runtime.url}}/onap/controlloop/v2/instantiationState?bridgeEndpoint=true&amp;useSystemProperties=true&amp;throwExceptionOnFailure=${exchangeProperty[raiseHttpExceptionFlag]}&amp;authMethod=Basic&amp;authUsername={{clamp.config.controlloop.runtime.userName}}&amp;authPassword={{clamp.config.controlloop.runtime.password}}&amp;authenticationPreemptive=true&amp;connectionClose=true"/>
+ uri="{{clamp.config.controlloop.runtime.url}}/onap/controlloop/v2/instantiationState?name=${exchangeProperty[name]}&amp;version=${exchangeProperty[version]}&amp;bridgeEndpoint=true&amp;useSystemProperties=true&amp;throwExceptionOnFailure=${exchangeProperty[raiseHttpExceptionFlag]}&amp;authMethod=Basic&amp;authUsername={{clamp.config.controlloop.runtime.userName}}&amp;authPassword={{clamp.config.controlloop.runtime.password}}&amp;authenticationPreemptive=true&amp;connectionClose=true"/>
<convertBodyTo type="java.lang.String"/>
<doFinally>
<to uri="direct:reset-raise-http-exception-flag"/>