Add support for instance properties 37/132637/1
authorFrancescoFioraEst <francesco.fiora@est.tech>
Thu, 8 Dec 2022 12:41:49 +0000 (12:41 +0000)
committerFrancesco Fiora <francesco.fiora@est.tech>
Thu, 8 Dec 2022 13:53:38 +0000 (13:53 +0000)
Issue-ID: POLICY-4483
Change-Id: I6ca953e05e74d68262507b393fb6415573fa3eab
Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionElement.java
models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionElement.java
models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/StringToMapConverter.java [new file with mode: 0644]
models/src/test/java/org/onap/policy/clamp/models/acm/messages/dmaap/participant/AutomationCompositionUpdateTest.java
models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionElementTest.java
models/src/test/resources/META-INF/persistence.xml
models/src/test/resources/json/AutomationCompositionElementNoOrderedState.json
participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java
participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandlerTest.java

index 7033aba..e5c85dd 100644 (file)
@@ -31,7 +31,6 @@ import lombok.ToString;
 import org.onap.policy.models.base.PfConceptKey;
 import org.onap.policy.models.base.PfUtils;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
-import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 
 /**
@@ -65,7 +64,7 @@ public class AutomationCompositionElement {
 
     // A map indexed by the property name. Each map entry is the serialized value of the property,
     // which can be deserialized into an instance of the type of the property.
-    private Map<String, ToscaProperty> propertiesMap = new LinkedHashMap<>();
+    private Map<String, Object> properties = new LinkedHashMap<>();
 
     /**
      * Copy constructor, does a deep copy but as all fields here are immutable, it's just a regular copy.
@@ -81,6 +80,6 @@ public class AutomationCompositionElement {
         this.orderedState = otherElement.orderedState;
         this.toscaServiceTemplateFragment = otherElement.toscaServiceTemplateFragment;
         this.description = otherElement.description;
-        this.propertiesMap = PfUtils.mapMap(otherElement.propertiesMap, UnaryOperator.identity());
+        this.properties = PfUtils.mapMap(otherElement.properties, UnaryOperator.identity());
     }
 }
index 08d8ee0..d8e4237 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation.
+ * Copyright (C) 2021-2022 Nordix Foundation.
  * ================================================================================
  * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
  * ================================================================================
 
 package org.onap.policy.clamp.models.acm.persistence.concepts;
 
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.UUID;
+import java.util.function.UnaryOperator;
 import javax.persistence.AttributeOverride;
 import javax.persistence.Column;
+import javax.persistence.Convert;
 import javax.persistence.EmbeddedId;
 import javax.persistence.Entity;
 import javax.persistence.Inheritance;
 import javax.persistence.InheritanceType;
+import javax.persistence.Lob;
 import javax.persistence.Table;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
@@ -39,11 +44,13 @@ import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement;
 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState;
 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState;
 import org.onap.policy.common.parameters.annotations.NotNull;
+import org.onap.policy.common.parameters.annotations.Valid;
 import org.onap.policy.models.base.PfAuthorative;
 import org.onap.policy.models.base.PfConcept;
 import org.onap.policy.models.base.PfConceptKey;
 import org.onap.policy.models.base.PfKey;
 import org.onap.policy.models.base.PfReferenceKey;
+import org.onap.policy.models.base.PfUtils;
 import org.onap.policy.models.base.validation.annotations.VerifyKey;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 
@@ -95,6 +102,12 @@ public class JpaAutomationCompositionElement extends PfConcept implements PfAuth
     @Column
     private String description;
 
+    @Lob
+    @NotNull
+    @Valid
+    @Convert(converter = StringToMapConverter.class)
+    private Map<String, Object> properties;
+
     /**
      * The Default Constructor creates a {@link JpaAutomationCompositionElement} object with a null key.
      */
@@ -141,6 +154,7 @@ public class JpaAutomationCompositionElement extends PfConcept implements PfAuth
         this.state = copyConcept.state;
         this.orderedState = copyConcept.orderedState;
         this.description = copyConcept.description;
+        this.properties = (copyConcept.properties != null ? new LinkedHashMap<>(copyConcept.properties) : null);
     }
 
     /**
@@ -163,6 +177,7 @@ public class JpaAutomationCompositionElement extends PfConcept implements PfAuth
         element.setState(state);
         element.setOrderedState(orderedState != null ? orderedState : state.asOrderedState());
         element.setDescription(description);
+        element.setProperties(PfUtils.mapMap(properties, UnaryOperator.identity()));
 
         return element;
     }
@@ -180,6 +195,7 @@ public class JpaAutomationCompositionElement extends PfConcept implements PfAuth
         this.state = element.getState();
         this.orderedState = element.getOrderedState();
         this.description = element.getDescription();
+        properties = PfUtils.mapMap(element.getProperties(), UnaryOperator.identity());
     }
 
     @Override
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/StringToMapConverter.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/StringToMapConverter.java
new file mode 100644 (file)
index 0000000..5dccd08
--- /dev/null
@@ -0,0 +1,58 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  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.clamp.models.acm.persistence.concepts;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.AttributeConverter;
+import javax.persistence.Converter;
+import javax.ws.rs.core.Response;
+import org.onap.policy.common.utils.coder.Coder;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.coder.StandardCoder;
+import org.onap.policy.models.base.PfModelRuntimeException;
+
+@Converter(autoApply = true)
+public class StringToMapConverter implements AttributeConverter<Map<String, Object>, String> {
+
+    private static final Coder coder = new StandardCoder();
+
+    @Override
+    public String convertToDatabaseColumn(Map<String, Object> map) {
+        try {
+            return map == null ? null : coder.encode(map);
+        } catch (CoderException e) {
+            throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, e.getMessage(), e);
+        }
+    }
+
+    @Override
+    public Map<String, Object> convertToEntityAttribute(String dbData) {
+        if (dbData == null) {
+            return new HashMap<>();
+        }
+        try {
+            return coder.decode(dbData, Map.class);
+        } catch (CoderException e) {
+            throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, e.getMessage(), e);
+        }
+    }
+}
index 1d56bc9..a2417df 100644 (file)
@@ -35,6 +35,7 @@ import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedSta
 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState;
 import org.onap.policy.clamp.models.acm.concepts.ParticipantUpdates;
 import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.coder.StandardCoder;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty;
 
@@ -46,15 +47,15 @@ class AutomationCompositionUpdateTest {
     void testCopyConstructor() throws CoderException {
         assertThatThrownBy(() -> new AutomationCompositionUpdate(null)).isInstanceOf(NullPointerException.class);
 
-        AutomationCompositionUpdate orig = new AutomationCompositionUpdate();
+        var orig = new AutomationCompositionUpdate();
         // verify with all values
-        ToscaConceptIdentifier id = new ToscaConceptIdentifier("id", "1.2.3");
+        var id = new ToscaConceptIdentifier("id", "1.2.3");
         orig.setAutomationCompositionId(id);
         orig.setParticipantId(null);
         orig.setMessageId(UUID.randomUUID());
         orig.setTimestamp(Instant.ofEpochMilli(3000));
 
-        AutomationCompositionElement acElement = new AutomationCompositionElement();
+        var acElement = new AutomationCompositionElement();
         acElement.setId(UUID.randomUUID());
         acElement.setDefinition(id);
         acElement.setDescription("Description");
@@ -63,18 +64,20 @@ class AutomationCompositionUpdateTest {
         acElement.setParticipantId(id);
         acElement.setParticipantType(id);
 
-        ToscaProperty property = new ToscaProperty();
+        var property = new ToscaProperty();
         property.setName("test");
         property.setType("testType");
-        Map<String, ToscaProperty> propertiesMap = Map.of("Prop1", property);
-        acElement.setPropertiesMap(propertiesMap);
+        var standardCoder = new StandardCoder();
+        var json = standardCoder.encode(property);
+        var propertiesMap = Map.of("Prop1", (Object) json);
+        acElement.setProperties(propertiesMap);
 
-        ParticipantUpdates participantUpdates = new ParticipantUpdates();
+        var participantUpdates = new ParticipantUpdates();
         participantUpdates.setParticipantId(id);
         participantUpdates.setAutomationCompositionElementList(List.of(acElement));
         orig.setParticipantUpdatesList(List.of(participantUpdates));
 
-        AutomationCompositionUpdate other = new AutomationCompositionUpdate(orig);
+        var other = new AutomationCompositionUpdate(orig);
 
         assertEquals(removeVariableFields(orig.toString()), removeVariableFields(other.toString()));
         assertSerializable(orig, AutomationCompositionUpdate.class);
index 7103f7f..d38aaf7 100644 (file)
@@ -29,6 +29,7 @@ import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.File;
+import java.util.Map;
 import java.util.UUID;
 import org.junit.jupiter.api.Test;
 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement;
@@ -299,6 +300,7 @@ class JpaAutomationCompositionElementTest {
         testJpaAutomationCompositionElement.fromAuthorative(testAce);
         testJpaAutomationCompositionElement.setKey(PfReferenceKey.getNullKey());
         testJpaAutomationCompositionElement.fromAuthorative(testAce);
+        testJpaAutomationCompositionElement.setProperties(Map.of("key", "{}"));
 
         return testJpaAutomationCompositionElement;
     }
@@ -308,6 +310,7 @@ class JpaAutomationCompositionElementTest {
         automationCompositionElement.setId(UUID.fromString("a95757ba-b34a-4049-a2a8-46773abcbe5e"));
         automationCompositionElement.setDefinition(new ToscaConceptIdentifier("aceDef", "0.0.1"));
         automationCompositionElement.setParticipantType(new ToscaConceptIdentifier("participantType", "0.0.1"));
+        automationCompositionElement.setProperties(Map.of("key", "{}"));
 
         return automationCompositionElement;
     }
index 1e1d893..6f9cb61 100644 (file)
@@ -29,6 +29,7 @@
         <class>org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationCompositionDefinition</class>
         <class>org.onap.policy.clamp.models.acm.persistence.concepts.StringToServiceTemplateConverter</class>
         <class>org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationCompositionElement</class>
+        <class>org.onap.policy.clamp.models.acm.persistence.concepts.StringToMapConverter</class>
         <class>org.onap.policy.clamp.models.acm.persistence.concepts.JpaParticipant</class>
 
         <properties>
index 872499a..934535a 100644 (file)
@@ -9,5 +9,6 @@
         "version": "0.0.1"
     },
     "state": "UNINITIALISED",
-    "orderedState": null
+    "orderedState": null,
+    "properties":{"key":"{}"}
 }
index 4512155..cb5b572 100644 (file)
@@ -22,7 +22,6 @@
 package org.onap.policy.clamp.acm.participant.intermediary.handler;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -48,7 +47,6 @@ import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMe
 import org.onap.policy.models.base.PfModelException;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
-import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
@@ -441,21 +439,4 @@ public class AutomationCompositionHandler {
         automationCompositions.setAutomationCompositionList(new ArrayList<>(automationCompositionMap.values()));
         return automationCompositions;
     }
-
-    /**
-     * Get properties of a automation composition element.
-     *
-     * @param id the automation composition element id
-     * @return the instance properties
-     */
-    public Map<String, ToscaProperty> getAcElementInstanceProperties(UUID id) {
-        Map<String, ToscaProperty> propertiesMap = new HashMap<>();
-        for (var automationComposition : automationCompositionMap.values()) {
-            var element = automationComposition.getElements().get(id);
-            if (element != null) {
-                propertiesMap.putAll(element.getPropertiesMap());
-            }
-        }
-        return propertiesMap;
-    }
 }
index 06b4256..95f16d3 100644 (file)
@@ -135,7 +135,6 @@ class AutomationCompositionHandlerTest {
         assertDoesNotThrow(() -> ach.handleAutomationCompositionUpdate(updateMsg, acElementDefinitions));
         updateMsg.setStartPhase(1);
         assertDoesNotThrow(() -> ach.handleAutomationCompositionUpdate(updateMsg, acElementDefinitions));
-        assertThat(ach.getAcElementInstanceProperties(uuid)).isEmpty();
 
         ach.getAutomationCompositionMap().clear();
         updateMsg.setStartPhase(0);