aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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"/>