From 5eb632de67f90a92e3032f97da1dcc25d53e8110 Mon Sep 17 00:00:00 2001 From: aribeiro Date: Tue, 17 Nov 2020 10:52:41 +0000 Subject: Fix import VFC with attributes Fix import VFC with default attribute value Fix Update, create and delete attribute action Make attribute definition tosca compliant Issue-ID: SDC-3381 Signed-off-by: aribeiro Change-Id: Ibbd36b105b8c86d1e750f3b6d55752d63fe6530e (cherry picked from commit 2f74a4ac81f228bdb0bf0f509e9c0ef296d28d82) --- .../sdc/be/model/AttributeDefinition.java | 3 +- .../sdc/be/model/ComponentInstanceAttribute.java | 1 - .../java/org/openecomp/sdc/be/model/Resource.java | 3 - .../operations/NodeTypeOperation.java | 23 +- .../operations/ToscaElementOperation.java | 30 +- .../operations/ToscaOperationFacade.java | 89 ++++- .../model/operations/impl/AbstractOperation.java | 4 +- .../model/operations/impl/AttributeOperation.java | 392 +++++++++++++++++++++ 8 files changed, 506 insertions(+), 39 deletions(-) create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AttributeOperation.java (limited to 'catalog-model/src/main/java/org') diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/AttributeDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/AttributeDefinition.java index a353ae9033..20ad0ad01f 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/AttributeDefinition.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/AttributeDefinition.java @@ -20,7 +20,6 @@ package org.openecomp.sdc.be.model; import lombok.Getter; -import lombok.NoArgsConstructor; import lombok.Setter; import lombok.ToString; import org.onap.sdc.tosca.datatypes.model.EntrySchema; @@ -31,7 +30,7 @@ import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition; @ToString public class AttributeDefinition extends AttributeDataDefinition implements IOperationParameter, IComplexDefaultValue { - // All names are according to TOSCA spec from + // All names are according to TOSCA spec from // https://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.3/os/TOSCA-Simple-Profile-YAML-v1.3-os.html#DEFN_ELEMENT_ATTRIBUTE_DEFN private String type; private String description; diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceAttribute.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceAttribute.java index 91a7b9c14f..6583bf46c4 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceAttribute.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceAttribute.java @@ -24,7 +24,6 @@ import java.util.List; import lombok.Getter; import lombok.Setter; import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.PropertyRule; @Getter diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Resource.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Resource.java index a3d871a511..6f120dc4ca 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Resource.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Resource.java @@ -28,15 +28,12 @@ import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import lombok.ToString; - import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.dao.utils.MapUtil; import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; -import org.openecomp.sdc.be.model.category.CategoryDefinition; -import org.openecomp.sdc.be.model.category.SubCategoryDefinition; @Getter @Setter diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeTypeOperation.java index 004451c667..43b74870e9 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeTypeOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeTypeOperation.java @@ -21,6 +21,17 @@ package org.openecomp.sdc.be.model.jsonjanusgraph.operations; import fj.data.Either; +import java.util.ArrayList; +import java.util.Collection; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; +import java.util.stream.Collectors; import org.apache.tinkerpop.gremlin.structure.Direction; import org.apache.tinkerpop.gremlin.structure.Edge; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; @@ -28,7 +39,13 @@ import org.openecomp.sdc.be.dao.jsongraph.GraphVertex; import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum; import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum; -import org.openecomp.sdc.be.datatypes.elements.*; +import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum; import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition; @@ -46,10 +63,6 @@ import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum; import org.openecomp.sdc.common.log.wrappers.Logger; import org.springframework.beans.factory.annotation.Qualifier; -import java.util.*; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - @org.springframework.stereotype.Component("node-type-operation") public class NodeTypeOperation extends ToscaElementOperation { public static final Pattern uuidNewVersion = Pattern.compile("^\\d+.1"); diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaElementOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaElementOperation.java index 6798af42db..bc77d20ed5 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaElementOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaElementOperation.java @@ -22,9 +22,20 @@ package org.openecomp.sdc.be.model.jsonjanusgraph.operations; import static org.openecomp.sdc.be.utils.TypeUtils.setField; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import fj.data.Either; import java.lang.reflect.Type; -import java.util.*; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.MapUtils; @@ -33,6 +44,7 @@ import org.apache.tinkerpop.gremlin.structure.Edge; import org.apache.tinkerpop.gremlin.structure.Vertex; import org.apache.tinkerpop.gremlin.structure.VertexProperty; import org.janusgraph.core.JanusGraphVertex; +import org.onap.sdc.tosca.datatypes.model.EntrySchema; import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; import org.openecomp.sdc.be.dao.jsongraph.GraphVertex; @@ -52,7 +64,6 @@ import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum; import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition; -import org.openecomp.sdc.be.model.AttributeDefinition; import org.openecomp.sdc.be.model.ComponentParametersView; import org.openecomp.sdc.be.model.DataTypeDefinition; import org.openecomp.sdc.be.model.LifecycleStateEnum; @@ -75,11 +86,6 @@ import org.openecomp.sdc.common.util.ValidationUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.StopWatch; -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; - -import fj.data.Either; - public abstract class ToscaElementOperation extends BaseOperation { private static final String FAILED_TO_FETCH_FOR_TOSCA_ELEMENT_WITH_ID_ERROR = "failed to fetch {} for tosca element with id {}, error {}"; @@ -1003,15 +1009,21 @@ public abstract class ToscaElementOperation extends BaseOperation { if (attributes instanceof Map) { final Map map = (Map) attributes; attributeDataDefinitionMap.putAll(map.values().stream().map(attributeMap -> { - final AttributeDefinition attributeDef = new AttributeDefinition(); + final AttributeDataDefinition attributeDef = new AttributeDataDefinition(); final String name = (String) ((Map) attributeMap).get("name"); attributeDef.setName(name); final String type = (String) ((Map) attributeMap).get("type"); attributeDef.setType(type); final String description = (String) ((Map) attributeMap).get("description"); attributeDef.setDescription(description); + final Object _default = ((Map) attributeMap).get("_default"); + attributeDef.set_default(_default); + final String status = (String) ((Map) attributeMap).get("status"); + attributeDef.setStatus(status); + final EntrySchema entry_schema = (EntrySchema) ((Map) attributeMap).get("entry_schema"); + attributeDef.setEntry_schema(entry_schema); return attributeDef; - }).collect(Collectors.toMap(AttributeDefinition::getName, a -> a))); + }).collect(Collectors.toMap(AttributeDataDefinition::getName, a -> a))); } } return attributeDataDefinitionMap; diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaOperationFacade.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaOperationFacade.java index 50b2ae45b4..957c5f9d66 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaOperationFacade.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaOperationFacade.java @@ -20,7 +20,27 @@ package org.openecomp.sdc.be.model.jsonjanusgraph.operations; +import static java.util.Objects.requireNonNull; +import static org.apache.commons.collections.CollectionUtils.isEmpty; +import static org.apache.commons.collections.CollectionUtils.isNotEmpty; + import fj.data.Either; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; +import java.util.function.BiPredicate; +import java.util.stream.Collectors; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; @@ -29,21 +49,61 @@ import org.apache.tinkerpop.gremlin.structure.Direction; import org.apache.tinkerpop.gremlin.structure.Edge; import org.openecomp.sdc.be.config.Configuration; import org.openecomp.sdc.be.config.ConfigurationManager; -import org.openecomp.sdc.be.model.jsonjanusgraph.config.ContainerInstanceTypesData; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; import org.openecomp.sdc.be.dao.jsongraph.GraphVertex; import org.openecomp.sdc.be.dao.jsongraph.HealingJanusGraphDao; import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum; import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum; -import org.openecomp.sdc.be.datatypes.elements.*; -import org.openecomp.sdc.be.datatypes.elements.MapInterfaceDataDefinition; -import org.openecomp.sdc.be.datatypes.enums.*; -import org.openecomp.sdc.be.model.*; +import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.DataTypeDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.MapArtifactDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.MapAttributesDataDefinition; import org.openecomp.sdc.be.datatypes.elements.MapCapabilityProperty; +import org.openecomp.sdc.be.datatypes.elements.MapInterfaceDataDefinition; import org.openecomp.sdc.be.datatypes.elements.MapListCapabilityDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.MapListRequirementDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum; +import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; +import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.PromoteVersionEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.CapabilityDefinition; import org.openecomp.sdc.be.model.CatalogUpdateTimestamp; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceAttribute; +import org.openecomp.sdc.be.model.ComponentInstanceInput; +import org.openecomp.sdc.be.model.ComponentInstanceInterface; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.ComponentParametersView; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.DistributionStatusEnum; +import org.openecomp.sdc.be.model.GroupDefinition; +import org.openecomp.sdc.be.model.GroupInstance; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.PolicyDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.RelationshipInfo; +import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; import org.openecomp.sdc.be.model.catalog.CatalogComponent; +import org.openecomp.sdc.be.model.jsonjanusgraph.config.ContainerInstanceTypesData; import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.TopologyTemplate; import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.ToscaElement; import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter; @@ -59,15 +119,6 @@ import org.openecomp.sdc.common.log.wrappers.Logger; import org.openecomp.sdc.common.util.ValidationUtils; import org.springframework.beans.factory.annotation.Autowired; -import java.util.*; -import java.util.Map.Entry; -import java.util.function.BiPredicate; -import java.util.stream.Collectors; - -import static java.util.Objects.requireNonNull; -import static org.apache.commons.collections.CollectionUtils.isEmpty; -import static org.apache.commons.collections.CollectionUtils.isNotEmpty; - @org.springframework.stereotype.Component("tosca-operation-facade") public class ToscaOperationFacade { @@ -1592,7 +1643,8 @@ public class ToscaOperationFacade { for (Entry> entry : instArttributes.entrySet()) { final List value = entry.getValue(); attributesMap = new MapAttributesDataDefinition(); - attributesMap.setMapToscaDataDefinition(value.stream().map(AttributeDataDefinition::new).collect(Collectors.toMap(AttributeDataDefinition::getName, e -> e))); + attributesMap.setMapToscaDataDefinition(value.stream().map(AttributeDataDefinition::new) + .collect(Collectors.toMap(AttributeDataDefinition::getName, e -> e))); instAttr.put(entry.getKey(), attributesMap); } } @@ -2492,6 +2544,7 @@ public class ToscaOperationFacade { if (newAttributeDef.getUniqueId() == null || newAttributeDef.getUniqueId().isEmpty()) { String attUniqueId = UniqueIdBuilder.buildAttributeUid(component.getUniqueId(), newAttributeDef.getName()); newAttributeDef.setUniqueId(attUniqueId); + newAttributeDef.setOwnerId(component.getUniqueId()); } StorageOperationStatus status = getToscaElementOperation(component).addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.ATTRIBUTES, VertexTypeEnum.ATTRIBUTES, newAttributeDef, JsonPresentationFields.NAME); @@ -2509,7 +2562,8 @@ public class ToscaOperationFacade { } } if (result == null) { - Optional newAttribute = ((Resource) getUpdatedComponentRes.left().value()).getAttributes().stream().filter(p -> p.getName().equals(newAttributeDef.getName())).findAny(); + Optional newAttribute = ((Resource) getUpdatedComponentRes.left().value()) + .getAttributes().stream().filter(p -> p.getName().equals(newAttributeDef.getName())).findAny(); if (newAttribute.isPresent()) { result = Either.left(newAttribute.get()); } else { @@ -2539,7 +2593,8 @@ public class ToscaOperationFacade { } } if (result == null) { - Optional newProperty = ((Resource) getUpdatedComponentRes.left().value()).getAttributes().stream().filter(p -> p.getName().equals(newAttributeDef.getName())).findAny(); + Optional newProperty = ((Resource) getUpdatedComponentRes.left().value()) + .getAttributes().stream().filter(p -> p.getName().equals(newAttributeDef.getName())).findAny(); if (newProperty.isPresent()) { result = Either.left(newProperty.get()); } else { diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AbstractOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AbstractOperation.java index 427ad4314a..a51eb33c03 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AbstractOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AbstractOperation.java @@ -7,9 +7,9 @@ * 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. diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AttributeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AttributeOperation.java new file mode 100644 index 0000000000..0bbaa0ecb2 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AttributeOperation.java @@ -0,0 +1,392 @@ +/* + * ============LICENSE_START======================================================= + * SDC + * Copyright (C) 2020 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.openecomp.sdc.be.model.operations.impl; + +import com.google.gson.JsonElement; +import fj.data.Either; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.janusgraph.HealingJanusGraphGenericDao; +import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter; +import org.openecomp.sdc.be.resources.data.DataTypeData; +import org.openecomp.sdc.be.resources.data.PropertyData; +import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + + +@Component("attribute-operation") +public class AttributeOperation extends AbstractOperation { + + private static Logger log = Logger.getLogger(AttributeOperation.class.getName()); + + private static final String FAILED_TO_FETCH_ATTRIBUTES_OF_DATA_TYPE = "Failed to fetch attributes of data type {}"; + private static final String DATA_TYPE_CANNOT_BE_FOUND_IN_GRAPH_STATUS_IS = "Data type {} cannot be found in graph. status is {}"; + private static final String THE_VALUE_OF_ATTRIBUTE_FROM_TYPE_IS_INVALID = "The value {} of attribute from type {} is invalid"; + + + @Autowired + public AttributeOperation(HealingJanusGraphGenericDao janusGraphGenericDao) { + this.janusGraphGenericDao = janusGraphGenericDao; + } + + public boolean isAttributeTypeValid(final AttributeDataDefinition attributeDefinition) { + + if (attributeDefinition == null) { + return false; + } + + if (ToscaPropertyType.isValidType(attributeDefinition.getType()) == null) { + final Either definedInDataTypes = isDefinedInDataTypes( + attributeDefinition.getType()); + + if (definedInDataTypes.isRight()) { + return false; + } else { + Boolean isExist = definedInDataTypes.left().value(); + return isExist.booleanValue(); + } + + } + return true; + } + + public Either isDefinedInDataTypes(final String propertyType) { + + final String dataTypeUid = UniqueIdBuilder.buildDataTypeUid(propertyType); + final Either dataTypeByUid = getDataTypeByUid(dataTypeUid); + if (dataTypeByUid.isRight()) { + final JanusGraphOperationStatus status = dataTypeByUid.right().value(); + if (status == JanusGraphOperationStatus.NOT_FOUND) { + return Either.left(false); + } + return Either.right(status); + } + + return Either.left(true); + + } + + /** + * Build Data type object from graph by unique id + */ + public Either getDataTypeByUid(final String uniqueId) { + + final Either dataTypesRes = janusGraphGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, DataTypeData.class); + + if (dataTypesRes.isRight()) { + JanusGraphOperationStatus status = dataTypesRes.right().value(); + log.debug(DATA_TYPE_CANNOT_BE_FOUND_IN_GRAPH_STATUS_IS, uniqueId, status); + return Either.right(status); + } + + final DataTypeData ctData = dataTypesRes.left().value(); + final DataTypeDefinition dataTypeDefinition = new DataTypeDefinition(ctData.getDataTypeDataDefinition()); + + final JanusGraphOperationStatus propertiesStatus = fillProperties(uniqueId, dataTypeDefinition); + if (propertiesStatus != JanusGraphOperationStatus.OK) { + log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, FAILED_TO_FETCH_ATTRIBUTES_OF_DATA_TYPE, uniqueId); + return Either.right(propertiesStatus); + } + + final Either, JanusGraphOperationStatus> parentNode = janusGraphGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, GraphEdgeLabels.DERIVED_FROM, + NodeTypeEnum.DataType, + DataTypeData.class); + log.debug("After retrieving DERIVED_FROM node of {}. status is {}", uniqueId, parentNode); + if (parentNode.isRight()) { + final JanusGraphOperationStatus janusGraphOperationStatus = parentNode.right().value(); + if (janusGraphOperationStatus != JanusGraphOperationStatus.NOT_FOUND) { + log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, + "Failed to find the parent data type of data type {}. status is {}", uniqueId, + janusGraphOperationStatus); + return Either.right(janusGraphOperationStatus); + } + } else { + // derived from node was found + final ImmutablePair immutablePair = parentNode.left().value(); + final DataTypeData parentCT = immutablePair.getKey(); + + final String parentUniqueId = parentCT.getUniqueId(); + final Either dataTypeByUid = getDataTypeByUid( + parentUniqueId); + + if (dataTypeByUid.isRight()) { + return Either.right(dataTypeByUid.right().value()); + } + + final DataTypeDefinition parentDataTypeDefinition = dataTypeByUid.left().value(); + + dataTypeDefinition.setDerivedFrom(parentDataTypeDefinition); + } + + return Either.left(dataTypeDefinition); + } + + private JanusGraphOperationStatus fillProperties(final String uniqueId, + final DataTypeDefinition dataTypeDefinition) { + + final Either, JanusGraphOperationStatus> findPropertiesOfNode = this + .findPropertiesOfNode(NodeTypeEnum.DataType, uniqueId); + if (findPropertiesOfNode.isRight()) { + final JanusGraphOperationStatus janusGraphOperationStatus = findPropertiesOfNode.right().value(); + log.debug("After looking for properties of vertex {}. status is {}", uniqueId, + janusGraphOperationStatus); + if (JanusGraphOperationStatus.NOT_FOUND.equals(janusGraphOperationStatus)) { + return JanusGraphOperationStatus.OK; + } else { + return janusGraphOperationStatus; + } + } else { + final Map properties = findPropertiesOfNode.left().value(); + if (properties != null && !properties.isEmpty()) { + List listOfProps = new ArrayList<>(); + + for (final Entry entry : properties.entrySet()) { + final String propName = entry.getKey(); + final PropertyDefinition propertyDefinition = entry.getValue(); + final PropertyDefinition newPropertyDefinition = new PropertyDefinition(propertyDefinition); + newPropertyDefinition.setName(propName); + listOfProps.add(newPropertyDefinition); + } + dataTypeDefinition.setProperties(listOfProps); + } + return JanusGraphOperationStatus.OK; + } + } + + public Either, JanusGraphOperationStatus> findPropertiesOfNode( + final NodeTypeEnum nodeType, final String uniqueId) { + + final Map resourceProps = new HashMap<>(); + + final Either>, JanusGraphOperationStatus> childrenNodes = janusGraphGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.PROPERTY, + NodeTypeEnum.Property, + PropertyData.class); + + if (childrenNodes.isRight()) { + final JanusGraphOperationStatus operationStatus = childrenNodes.right().value(); + return Either.right(operationStatus); + } + + final List> values = childrenNodes.left().value(); + if (values != null) { + for (final ImmutablePair immutablePair : values) { + final GraphEdge edge = immutablePair.getValue(); + final String propertyName = (String) edge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty()); + log.debug("Attribute {} is associated to node {}", propertyName, uniqueId); + final PropertyData propertyData = immutablePair.getKey(); + final PropertyDefinition propertyDefinition = this + .convertPropertyDataToPropertyDefinition(propertyData, propertyName); + resourceProps.put(propertyName, propertyDefinition); + } + + } + + log.debug("The properties associated to node {} are {}", uniqueId, resourceProps); + return Either.left(resourceProps); + } + + public PropertyDefinition convertPropertyDataToPropertyDefinition(final PropertyData propertyDataResult, + final String propertyName) { + log.debug("The object returned after create property is {}", propertyDataResult); + + final PropertyDefinition propertyDefResult = new PropertyDefinition(propertyDataResult.getPropertyDataDefinition()); + propertyDefResult.setConstraints(convertConstraints(propertyDataResult.getConstraints())); + propertyDefResult.setName(propertyName); + + return propertyDefResult; + } + + + public ImmutablePair isAttributeInnerTypeValid(final AttributeDataDefinition attributeDefinition, + final Map dataTypes) { + + if (attributeDefinition == null) { + return new ImmutablePair<>(null, false); + } + + SchemaDefinition schema; + PropertyDataDefinition innerProp; + String innerType = null; + if ((schema = attributeDefinition.getSchema()) != null && ((innerProp = schema.getProperty()) != null)) { + innerType = innerProp.getType(); + } + + final ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType); + + if (innerToscaType == null) { + final DataTypeDefinition dataTypeDefinition = dataTypes.get(innerType); + if (dataTypeDefinition == null) { + log.debug("The inner type {} is not a data type.", innerType); + return new ImmutablePair<>(innerType, false); + } else { + log.debug("The inner type {} is a data type. Data type definition is {}", innerType, + dataTypeDefinition); + } + } + return new ImmutablePair<>(innerType, true); + } + + + public boolean isAttributeDefaultValueValid(final AttributeDataDefinition attributeDefinition, + final Map dataTypes) { + if (attributeDefinition == null) { + return false; + } + boolean isValid; + String innerType = null; + final String propertyType = attributeDefinition.getType(); + final ToscaPropertyType type = getType(propertyType); + if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) { + final SchemaDefinition def = attributeDefinition.getSchema(); + if (def == null) { + return false; + } + final PropertyDataDefinition propDef = def.getProperty(); + if (propDef == null) { + return false; + } + innerType = propDef.getType(); + } + final String value = (String) attributeDefinition.get_default(); + if (type != null) { + isValid = isValidValue(type, value, innerType, dataTypes); + } else { + log.trace("The given type {} is not a pre defined one.", propertyType); + + final DataTypeDefinition foundDt = dataTypes.get(propertyType); + if (foundDt != null) { + isValid = isValidComplexValue(foundDt, value, dataTypes); + } else { + isValid = false; + } + } + return isValid; + } + + private boolean isValidComplexValue(final DataTypeDefinition foundDt, final String value, + final Map dataTypes) { + final ImmutablePair validateAndUpdate = dataTypeValidatorConverter + .validateAndUpdate(value, foundDt, dataTypes); + + log.trace("The result after validating complex value of type {} is {}", foundDt.getName(), validateAndUpdate); + + return validateAndUpdate.right.booleanValue(); + + } + + + public StorageOperationStatus validateAndUpdateAttribute(final AttributeDataDefinition attributeDefinition, + final Map dataTypes) { + + log.trace("Going to validate attribute type and value. {}", attributeDefinition); + + final String attributeDefinitionType = attributeDefinition.getType(); + final String value = (String) attributeDefinition.get_default(); + + final ToscaPropertyType type = getType(attributeDefinitionType); + + if (type == null) { + + final DataTypeDefinition dataTypeDefinition = dataTypes.get(attributeDefinitionType); + if (dataTypeDefinition == null) { + log.debug("The type {} of attribute cannot be found.", attributeDefinitionType); + return StorageOperationStatus.INVALID_TYPE; + } + + return validateAndUpdateAttributeComplexValue(attributeDefinition, attributeDefinitionType, value, + dataTypeDefinition, dataTypes); + + } + String innerType; + + final Either checkInnerType = getInnerType(type, attributeDefinition::getSchema); + if (checkInnerType.isRight()) { + return StorageOperationStatus.INVALID_TYPE; + } + innerType = checkInnerType.left().value(); + + log.trace("After validating property type {}", attributeDefinitionType); + + if (!isValidValue(type, value, innerType, dataTypes)) { + log.info(THE_VALUE_OF_ATTRIBUTE_FROM_TYPE_IS_INVALID, value, type); + return StorageOperationStatus.INVALID_VALUE; + } + + final PropertyValueConverter converter = type.getConverter(); + + if (isEmptyValue(value)) { + log.debug("Default value was not sent for attribute {}. Set default value to {}", + attributeDefinition.getName(), EMPTY_VALUE); + attributeDefinition.set_default(EMPTY_VALUE); + } else if (!isEmptyValue(value)) { + attributeDefinition.set_default(converter.convert(value, innerType, dataTypes)); + } + return StorageOperationStatus.OK; + } + + private StorageOperationStatus validateAndUpdateAttributeComplexValue( + final AttributeDataDefinition attributeDefinition, + final String attributeType, + final String value, + final DataTypeDefinition dataTypeDefinition, + final Map dataTypes) { + + final ImmutablePair validateResult = dataTypeValidatorConverter + .validateAndUpdate(value, dataTypeDefinition, dataTypes); + if (!validateResult.right.booleanValue()) { + log.debug(THE_VALUE_OF_ATTRIBUTE_FROM_TYPE_IS_INVALID, attributeType, attributeType); + return StorageOperationStatus.INVALID_VALUE; + } + final JsonElement jsonElement = validateResult.left; + if (log.isTraceEnabled()) { + log.trace("Going to update value in attribute definition {} {}", attributeDefinition.getName(), + (jsonElement != null ? jsonElement.toString() : null)); + } + updateAttributeValue(attributeDefinition, jsonElement); + return StorageOperationStatus.OK; + } + + private void updateAttributeValue(final AttributeDataDefinition attributeDefinition, + final JsonElement jsonElement) { + attributeDefinition.set_default(jsonElement); + } +} -- cgit 1.2.3-korg