aboutsummaryrefslogtreecommitdiffstats
path: root/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java
diff options
context:
space:
mode:
Diffstat (limited to 'catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java')
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java2788
1 files changed, 2788 insertions, 0 deletions
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java
new file mode 100644
index 0000000000..7d775b3b3d
--- /dev/null
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java
@@ -0,0 +1,2788 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.be.model.operations.impl;
+
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.StringJoiner;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import com.thinkaurelius.titan.core.TitanTransaction;
+import com.thinkaurelius.titan.core.TitanVertex;
+
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.ObjectCodec;
+import org.codehaus.jackson.map.DeserializationContext;
+import org.openecomp.sdc.be.config.BeEcompErrorManager;
+import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
+import org.openecomp.sdc.be.dao.graph.GraphElementFactory;
+import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
+import org.openecomp.sdc.be.dao.graph.datatype.GraphElementTypeEnum;
+import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
+import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
+import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
+import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
+import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.PropertyRule;
+import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
+import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
+import org.openecomp.sdc.be.model.ComponentInstanceInput;
+import org.openecomp.sdc.be.model.ComponentInstanceProperty;
+import org.openecomp.sdc.be.model.DataTypeDefinition;
+import org.openecomp.sdc.be.model.IComplexDefaultValue;
+import org.openecomp.sdc.be.model.PropertyConstraint;
+import org.openecomp.sdc.be.model.PropertyDefinition;
+import org.openecomp.sdc.be.model.operations.api.IPropertyOperation;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
+import org.openecomp.sdc.be.model.tosca.ToscaType;
+import org.openecomp.sdc.be.model.tosca.constraints.ConstraintType;
+import org.openecomp.sdc.be.model.tosca.constraints.GreaterOrEqualConstraint;
+import org.openecomp.sdc.be.model.tosca.constraints.GreaterThanConstraint;
+import org.openecomp.sdc.be.model.tosca.constraints.InRangeConstraint;
+import org.openecomp.sdc.be.model.tosca.constraints.LessOrEqualConstraint;
+import org.openecomp.sdc.be.model.tosca.constraints.LessThanConstraint;
+import org.openecomp.sdc.be.model.tosca.constraints.MinLengthConstraint;
+import org.openecomp.sdc.be.model.tosca.constraints.ValidValuesConstraint;
+import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter;
+import org.openecomp.sdc.be.model.tosca.validators.DataTypeValidatorConverter;
+import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator;
+import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
+import org.openecomp.sdc.be.resources.data.DataTypeData;
+import org.openecomp.sdc.be.resources.data.InputValueData;
+import org.openecomp.sdc.be.resources.data.PropertyData;
+import org.openecomp.sdc.be.resources.data.PropertyValueData;
+import org.openecomp.sdc.be.resources.data.ResourceMetadataData;
+import org.openecomp.sdc.be.resources.data.UniqueIdData;
+import org.openecomp.sdc.common.api.Constants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import com.google.gson.JsonParser;
+import com.google.gson.JsonSerializationContext;
+import com.google.gson.JsonSerializer;
+import com.google.gson.reflect.TypeToken;
+
+import fj.data.Either;
+
+@Component("property-operation")
+public class PropertyOperation extends AbstractOperation implements IPropertyOperation {
+
+ public static void main(String[] args) {
+
+ List<Pattern> buildFunctionPatterns = buildFunctionPatterns();
+
+ for (Pattern pattern : buildFunctionPatterns) {
+
+ String[] strs = { "str_replace", "{ str_replace:", " {str_replace:", " { str_replace:", "{str_replace:" };
+ for (String str : strs) {
+ Matcher m = pattern.matcher(str);
+ System.out.println(pattern.pattern() + " " + str + " " + m.find());
+ }
+ }
+
+ }
+
+ public static final String PROPERTY = "property";
+
+ public PropertyOperation() {
+ super();
+ }
+
+ private static Logger log = LoggerFactory.getLogger(PropertyOperation.class.getName());
+
+ private static List<Pattern> functionPatterns = null;
+
+ static {
+
+ functionPatterns = buildFunctionPatterns();
+ }
+
+ /**
+ * The value of functions is in a json format. Build pattern for each function name
+ *
+ * { str_replace: .... } {str_replace: .... } {str_replace: .... } { str_replace: .... }
+ *
+ * @return
+ */
+ private static List<Pattern> buildFunctionPatterns() {
+
+ List<Pattern> functionPatterns = new ArrayList<>();
+
+ String[] functions = { "get_input", "get_property" };
+
+ for (String function : functions) {
+ Pattern pattern = Pattern.compile("^[ ]*\\{[ ]*" + function + ":");
+ functionPatterns.add(pattern);
+ }
+
+ return functionPatterns;
+ }
+
+ @Override
+ public Either<PropertyDefinition, StorageOperationStatus> getPropertyOfResource(String propertyName, String resourceId) {
+
+ String propertyId = UniqueIdBuilder.buildPropertyUniqueId(resourceId, propertyName);
+
+ Either<PropertyData, TitanOperationStatus> getResult = this.titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class);
+ if (getResult.isLeft()) {
+ PropertyData propertyData = getResult.left().value();
+ return Either.left(convertPropertyDataToPropertyDefinition(propertyData, propertyName, resourceId));
+ } else {
+ TitanOperationStatus titanStatus = getResult.right().value();
+ log.debug("Node with id {} was not found in the graph. Status: {}", propertyId, titanStatus);
+ StorageOperationStatus storageOperationStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus);
+ return Either.right(storageOperationStatus);
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.openecomp.sdc.be.model.operations.api.IPropertyOperation# addPropertyToResource(java.lang.String, org.openecomp.sdc.be.model.PropertyDefinition, org.openecomp.sdc.be.dao.neo4j.datatype.NodeTypeEnum, java.lang.String)
+ */
+ /*
+ * @Override public Either<PropertyDefinition, StorageOperationStatus> addPropertyToResource( String propertyName, PropertyDefinition propertyDefinition, NodeTypeEnum nodeType, String resourceId) {
+ *
+ * StorageOperationStatus isValidProperty = isTypeExistsAndValid(propertyDefinition); if (isValidProperty != StorageOperationStatus.OK) { return Either.right(isValidProperty); }
+ *
+ * Either<PropertyData, TitanOperationStatus> status = addPropertyToGraph(propertyName, propertyDefinition, resourceId);
+ *
+ * if (status.isRight()) { titanGenericDao.rollback(); log.error("Failed to add property " + propertyName + " to resource " + resourceId); return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status. right().value())); } else
+ * { titanGenericDao.commit(); PropertyData propertyData = status.left().value();
+ *
+ * PropertyDefinition propertyDefResult = convertPropertyDataToPropertyDefinition(propertyData, propertyName, resourceId); log.debug("The returned PropertyDefintion is {}", propertyDefinition); return Either.left(propertyDefResult); }
+ *
+ *
+ * }
+ */
+ private StorageOperationStatus isTypeExistsAndValid(PropertyDefinition propertyDefinition) {
+
+ ToscaPropertyType type = ToscaPropertyType.isValidType(propertyDefinition.getType());
+
+ if (type == null) {
+ return StorageOperationStatus.INVALID_TYPE;
+ }
+
+ String propertyType = propertyDefinition.getType();
+ String innerType = null;
+ String value = propertyDefinition.getDefaultValue();
+
+ if (propertyType.equals(ToscaPropertyType.LIST) || propertyType.equals(ToscaPropertyType.MAP)) {
+ SchemaDefinition schema;
+ if ((schema = propertyDefinition.getSchema()) != null) {
+ PropertyDataDefinition property;
+ if ((property = schema.getProperty()) != null) {
+ innerType = property.getType();
+
+ }
+ }
+ }
+
+ PropertyTypeValidator validator = type.getValidator();
+
+ if (value == null || (EMPTY_VALUE != null && EMPTY_VALUE.equals(propertyDefinition.getDefaultValue()))) {
+ return StorageOperationStatus.OK;
+ } else {
+ boolean isValid = validator.isValid(value, innerType, null);
+ if (true == isValid) {
+ return StorageOperationStatus.OK;
+ } else {
+ return StorageOperationStatus.INVALID_VALUE;
+ }
+ }
+
+ }
+
+ public PropertyDefinition convertPropertyDataToPropertyDefinition(PropertyData propertyDataResult, String propertyName, String resourceId) {
+ log.debug("The object returned after create property is {}", propertyDataResult);
+
+ PropertyDefinition propertyDefResult = new PropertyDefinition(propertyDataResult.getPropertyDataDefinition());
+ propertyDefResult.setConstraints(convertConstraints(propertyDataResult.getConstraints()));
+ propertyDefResult.setName(propertyName);
+ propertyDefResult.setParentUniqueId(resourceId);
+
+ return propertyDefResult;
+ }
+
+ public static class PropertyConstraintSerialiser implements JsonSerializer<PropertyConstraint> {
+
+ @Override
+ public JsonElement serialize(PropertyConstraint src, Type typeOfSrc, JsonSerializationContext context) {
+ JsonParser parser = new JsonParser();
+ JsonObject result = new JsonObject();
+ JsonArray jsonArray = new JsonArray();
+ if (src instanceof InRangeConstraint) {
+ InRangeConstraint rangeConstraint = (InRangeConstraint) src;
+ jsonArray.add(parser.parse(rangeConstraint.getRangeMinValue()));
+ jsonArray.add(parser.parse(rangeConstraint.getRangeMaxValue()));
+ result.add("inRange", jsonArray);
+ } else if (src instanceof GreaterThanConstraint) {
+ GreaterThanConstraint greaterThanConstraint = (GreaterThanConstraint) src;
+ jsonArray.add(parser.parse(greaterThanConstraint.getGreaterThan()));
+ result.add("greaterThan", jsonArray);
+ } else if (src instanceof LessOrEqualConstraint) {
+ LessOrEqualConstraint lessOrEqualConstraint = (LessOrEqualConstraint) src;
+ jsonArray.add(parser.parse(lessOrEqualConstraint.getLessOrEqual()));
+ result.add("lessOrEqual", jsonArray);
+ } else {
+ log.warn("PropertyConstraint {} is not supported. Ignored.", src.getClass().getName());
+ }
+
+ return result;
+ }
+
+ }
+
+ public static class PropertyConstraintDeserialiser implements JsonDeserializer<PropertyConstraint> {
+
+ @Override
+ public PropertyConstraint deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
+
+ PropertyConstraint propertyConstraint = null;
+
+ Set<Entry<String, JsonElement>> set = json.getAsJsonObject().entrySet();
+
+ if (set.size() == 1) {
+ Entry<String, JsonElement> element = set.iterator().next();
+ String key = element.getKey();
+ JsonElement value = element.getValue();
+
+ ConstraintType constraintType = ConstraintType.getByType(key);
+ if (constraintType == null) {
+ log.warn("ConstraintType was not found for constraint name:{}", key);
+ } else {
+ switch (constraintType) {
+ case IN_RANGE:
+
+ if (value != null) {
+ if (value instanceof JsonArray) {
+ JsonArray rangeArray = (JsonArray) value;
+ if (rangeArray.size() != 2) {
+ log.error("The range constraint content is invalid. value = {}", value);
+ } else {
+ InRangeConstraint rangeConstraint = new InRangeConstraint();
+ String minValue = rangeArray.get(0).getAsString();
+ String maxValue = rangeArray.get(1).getAsString();
+ rangeConstraint.setRangeMinValue(minValue);
+ rangeConstraint.setRangeMaxValue(maxValue);
+ propertyConstraint = rangeConstraint;
+ }
+ }
+
+ } else {
+ log.warn("The value of GreaterThanConstraint is null");
+ }
+ break;
+ case GREATER_THAN:
+ if (value != null) {
+ String asString = value.getAsString();
+ log.debug("Before adding value to GreaterThanConstraint object. value = {}", asString);
+ propertyConstraint = new GreaterThanConstraint(asString);
+ break;
+ } else {
+ log.warn("The value of GreaterThanConstraint is null");
+ }
+ break;
+
+ case LESS_THAN:
+ if (value != null) {
+ String asString = value.getAsString();
+ log.debug("Before adding value to LessThanConstraint object. value = {}", asString);
+ propertyConstraint = new LessThanConstraint(asString);
+ break;
+ } else {
+ log.warn("The value of LessThanConstraint is null");
+ }
+ break;
+ case GREATER_OR_EQUAL:
+ if (value != null) {
+ String asString = value.getAsString();
+ log.debug("Before adding value to GreaterThanConstraint object. value = {}", asString);
+ propertyConstraint = new GreaterOrEqualConstraint(asString);
+ break;
+ } else {
+ log.warn("The value of GreaterOrEqualConstraint is null");
+ }
+ break;
+ case LESS_OR_EQUAL:
+
+ if (value != null) {
+ String asString = value.getAsString();
+ log.debug("Before adding value to LessOrEqualConstraint object. value = {}", asString);
+ propertyConstraint = new LessOrEqualConstraint(asString);
+ } else {
+ log.warn("The value of GreaterThanConstraint is null");
+ }
+ break;
+
+ case VALID_VALUES:
+
+ if (value != null) {
+ if (value instanceof JsonArray) {
+ JsonArray rangeArray = (JsonArray) value;
+ if (rangeArray.size() == 0) {
+ log.error("The valid values constraint content is invalid. value = {}", value);
+ } else {
+ ValidValuesConstraint vvConstraint = new ValidValuesConstraint();
+ List<String> validValues = new ArrayList<String>();
+ for (JsonElement jsonElement : rangeArray) {
+ String item = jsonElement.getAsString();
+ validValues.add(item);
+ }
+ vvConstraint.setValidValues(validValues);
+ propertyConstraint = vvConstraint;
+ }
+ }
+
+ } else {
+ log.warn("The value of ValidValuesConstraint is null");
+ }
+ break;
+
+ case MIN_LENGTH:
+ if (value != null) {
+ int asInt = value.getAsInt();
+ log.debug("Before adding value to Min Length object. value = {}", asInt);
+ propertyConstraint = new MinLengthConstraint(asInt);
+ break;
+ } else {
+ log.warn("The value of MinLengthConstraint is null");
+ }
+ break;
+ default:
+ log.warn("Key {} is not supported. Ignored.", key);
+ }
+ }
+ }
+
+ return propertyConstraint;
+ }
+
+ }
+
+ public TitanOperationStatus addPropertiesToGraph(Map<String, PropertyDefinition> properties, String resourceId, Map<String, DataTypeDefinition> dataTypes) {
+
+ ResourceMetadataData resourceData = new ResourceMetadataData();
+ resourceData.getMetadataDataDefinition().setUniqueId(resourceId);
+
+ if (properties != null) {
+ for (Entry<String, PropertyDefinition> entry : properties.entrySet()) {
+
+ String propertyName = entry.getKey();
+ PropertyDefinition propertyDefinition = entry.getValue();
+
+ StorageOperationStatus validateAndUpdateProperty = validateAndUpdateProperty(propertyDefinition, dataTypes);
+ if (validateAndUpdateProperty != StorageOperationStatus.OK) {
+ log.error("Property {} is invalid. Status is {}", propertyDefinition, validateAndUpdateProperty);
+ return TitanOperationStatus.ILLEGAL_ARGUMENT;
+ }
+
+ Either<PropertyData, TitanOperationStatus> addPropertyToGraph = addPropertyToGraph(propertyName, propertyDefinition, resourceId);
+
+ if (addPropertyToGraph.isRight()) {
+ return addPropertyToGraph.right().value();
+ }
+ }
+ }
+
+ return TitanOperationStatus.OK;
+
+ }
+
+ public TitanOperationStatus addPropertiesToGraph(TitanVertex metadataVertex, Map<String, PropertyDefinition> properties, Map<String, DataTypeDefinition> dataTypes, String resourceId) {
+
+ if (properties != null) {
+ for (Entry<String, PropertyDefinition> entry : properties.entrySet()) {
+
+ String propertyName = entry.getKey();
+ PropertyDefinition propertyDefinition = entry.getValue();
+
+ StorageOperationStatus validateAndUpdateProperty = validateAndUpdateProperty(propertyDefinition, dataTypes);
+ if (validateAndUpdateProperty != StorageOperationStatus.OK) {
+ log.error("Property {} is invalid. Status is {}", propertyDefinition, validateAndUpdateProperty);
+ return TitanOperationStatus.ILLEGAL_ARGUMENT;
+ }
+
+ TitanOperationStatus addPropertyToGraph = addPropertyToGraphByVertex(metadataVertex, propertyName, propertyDefinition, resourceId);
+
+ if (!addPropertyToGraph.equals(TitanOperationStatus.OK)) {
+ return addPropertyToGraph;
+ }
+ }
+ }
+
+ return TitanOperationStatus.OK;
+
+ }
+
+ public Either<PropertyData, StorageOperationStatus> addProperty(String propertyName, PropertyDefinition propertyDefinition, String resourceId) {
+
+ Either<PropertyData, TitanOperationStatus> either = addPropertyToGraph(propertyName, propertyDefinition, resourceId);
+ if (either.isRight()) {
+ StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value());
+ return Either.right(storageStatus);
+ }
+ return Either.left(either.left().value());
+ }
+
+ /**
+ * @param propertyDefinition
+ * @return
+ */
+ @Override
+ public StorageOperationStatus validateAndUpdateProperty(IComplexDefaultValue propertyDefinition, Map<String, DataTypeDefinition> dataTypes) {
+
+ log.trace("Going to validate property type and value. {}", propertyDefinition);
+
+ String propertyType = propertyDefinition.getType();
+ String value = propertyDefinition.getDefaultValue();
+
+ ToscaPropertyType type = getType(propertyType);
+
+ if (type == null) {
+
+ DataTypeDefinition dataTypeDefinition = dataTypes.get(propertyType);
+ if (dataTypeDefinition == null) {
+ log.debug("The type {} of property cannot be found.", propertyType);
+ return StorageOperationStatus.INVALID_TYPE;
+ }
+
+ StorageOperationStatus status = validateAndUpdateComplexValue(propertyDefinition, propertyType, value, dataTypeDefinition, dataTypes);
+
+ return status;
+
+ }
+ String innerType = null;
+
+ Either<String, TitanOperationStatus> checkInnerType = getInnerType(type, () -> propertyDefinition.getSchema());
+ if (checkInnerType.isRight()) {
+ return StorageOperationStatus.INVALID_TYPE;
+ }
+ innerType = checkInnerType.left().value();
+
+ log.trace("After validating property type {}", propertyType);
+
+ boolean isValidProperty = isValidValue(type, value, innerType, dataTypes);
+ if (false == isValidProperty) {
+ log.info("The value {} of property from type {} is invalid", value, type);
+ return StorageOperationStatus.INVALID_VALUE;
+ }
+
+ PropertyValueConverter converter = type.getConverter();
+
+ if (isEmptyValue(value)) {
+ log.debug("Default value was not sent for property {}. Set default value to {}", propertyDefinition.getName(), EMPTY_VALUE);
+ propertyDefinition.setDefaultValue(EMPTY_VALUE);
+ } else if (false == isEmptyValue(value)) {
+ String convertedValue = converter.convert(value, innerType, dataTypes);
+ propertyDefinition.setDefaultValue(convertedValue);
+ }
+ return StorageOperationStatus.OK;
+ }
+
+ /*
+ * public Either<Object, Boolean> validateAndUpdatePropertyValue(String propertyType, String value, String innerType) {
+ *
+ * log. trace("Going to validate property value and its type. type = {}, value = {}" ,propertyType, value);
+ *
+ * ToscaPropertyType type = getType(propertyType);
+ *
+ * if (type == null) {
+ *
+ * Either<DataTypeDefinition, TitanOperationStatus> externalDataType = getExternalDataType(propertyType); if (externalDataType.isRight()) { TitanOperationStatus status = externalDataType.right().value(); log.debug("The type " + propertyType +
+ * " of property cannot be found. Status is " + status); if (status != TitanOperationStatus.NOT_FOUND) { BeEcompErrorManager.getInstance(). logBeInvalidTypeError("validate property type", propertyType, "property"); } return Either.right(false); }
+ *
+ * DataTypeDefinition dataTypeDefinition = externalDataType.left().value();
+ *
+ * Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypesRes = getAllDataTypes(); if (allDataTypesRes.isRight()) { TitanOperationStatus status = allDataTypesRes.right().value(); return Either.right(false); }
+ *
+ * Map<String, DataTypeDefinition> allDataTypes = allDataTypesRes.left().value();
+ *
+ * ImmutablePair<JsonElement, Boolean> validateResult = dataTypeValidatorConverter.validateAndUpdate(value, dataTypeDefinition, allDataTypes);
+ *
+ * if (validateResult.right.booleanValue() == false) { log.debug("The value {} of property from type {} is invalid", value, propertyType); return Either.right(false); }
+ *
+ * JsonElement jsonElement = validateResult.left;
+ *
+ * String valueFromJsonElement = getValueFromJsonElement(jsonElement);
+ *
+ * return Either.left(valueFromJsonElement);
+ *
+ * }
+ *
+ * log.trace("After validating property type " + propertyType);
+ *
+ * boolean isValidProperty = isValidValue(type, value, innerType); if (false == isValidProperty) { log.debug("The value {} of property from type {} is invalid", value, type); return Either.right(false); }
+ *
+ *
+ * Object convertedValue = value; if (false == isEmptyValue(value)) { PropertyValueConverter converter = type.getConverter(); convertedValue = converter.convert(value, null); }
+ *
+ * return Either.left(convertedValue); }
+ */
+
+ public Either<PropertyData, TitanOperationStatus> addPropertyToGraph(String propertyName, PropertyDefinition propertyDefinition, String resourceId) {
+
+ ResourceMetadataData resourceData = new ResourceMetadataData();
+ resourceData.getMetadataDataDefinition().setUniqueId(resourceId);
+
+ List<PropertyConstraint> constraints = propertyDefinition.getConstraints();
+
+ propertyDefinition.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(resourceId, propertyName));
+ PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints));
+
+ log.debug("Before adding property to graph {}", propertyData);
+ Either<PropertyData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyData, PropertyData.class);
+ log.debug("After adding property to graph {}", propertyData);
+ if (createNodeResult.isRight()) {
+ TitanOperationStatus operationStatus = createNodeResult.right().value();
+ log.error("Failed to add property {} to graph. Status is {}", propertyName, operationStatus);
+ return Either.right(operationStatus);
+ }
+
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName);
+ Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(resourceData, propertyData, GraphEdgeLabels.PROPERTY, props);
+ if (createRelResult.isRight()) {
+ TitanOperationStatus operationStatus = createNodeResult.right().value();
+ log.error("Failed to associate resource {} to property {} in graph. Status is {}", resourceId, propertyName, operationStatus);
+ return Either.right(operationStatus);
+ }
+
+ return Either.left(createNodeResult.left().value());
+
+ }
+
+ public TitanOperationStatus addPropertyToGraphByVertex(TitanVertex metadataVertex, String propertyName, PropertyDefinition propertyDefinition, String resourceId) {
+
+ List<PropertyConstraint> constraints = propertyDefinition.getConstraints();
+
+ propertyDefinition.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(resourceId, propertyName));
+ PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints));
+
+ log.debug("Before adding property to graph {}", propertyData);
+ Either<TitanVertex, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyData);
+ log.debug("After adding property to graph {}", propertyData);
+ if (createNodeResult.isRight()) {
+ TitanOperationStatus operationStatus = createNodeResult.right().value();
+ log.error("Failed to add property {} to graph. status is {}", propertyName, operationStatus);
+ return operationStatus;
+ }
+
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName);
+ TitanVertex propertyVertex = createNodeResult.left().value();
+ TitanOperationStatus createRelResult = titanGenericDao.createEdge(metadataVertex, propertyVertex, GraphEdgeLabels.PROPERTY, props);
+ if (!createRelResult.equals(TitanOperationStatus.OK)) {
+ log.error("Failed to associate resource {} to property {} in graph. status is {}", resourceId, propertyName, createRelResult);
+ return createRelResult;
+ }
+
+ return createRelResult;
+
+ }
+
+ public TitanGenericDao getTitanGenericDao() {
+ return titanGenericDao;
+ }
+
+ // public Either<PropertyData, StorageOperationStatus>
+ // deletePropertyFromGraphFromBl(String propertyId) {
+ //
+ // }
+
+ public Either<PropertyData, StorageOperationStatus> deleteProperty(String propertyId) {
+ Either<PropertyData, TitanOperationStatus> either = deletePropertyFromGraph(propertyId);
+ if (either.isRight()) {
+ StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value());
+ return Either.right(storageStatus);
+ }
+ return Either.left(either.left().value());
+ }
+
+ public Either<PropertyData, TitanOperationStatus> deletePropertyFromGraph(String propertyId) {
+ log.debug("Before deleting property from graph {}", propertyId);
+ return titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class);
+ }
+
+ public Either<PropertyData, StorageOperationStatus> updateProperty(String propertyId, PropertyDefinition newPropertyDefinition, Map<String, DataTypeDefinition> dataTypes) {
+
+ StorageOperationStatus validateAndUpdateProperty = validateAndUpdateProperty(newPropertyDefinition, dataTypes);
+ if (validateAndUpdateProperty != StorageOperationStatus.OK) {
+ return Either.right(validateAndUpdateProperty);
+ }
+
+ Either<PropertyData, TitanOperationStatus> either = updatePropertyFromGraph(propertyId, newPropertyDefinition);
+ if (either.isRight()) {
+ StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value());
+ return Either.right(storageStatus);
+ }
+ return Either.left(either.left().value());
+ }
+
+ public Either<PropertyData, TitanOperationStatus> updatePropertyFromGraph(String propertyId, PropertyDefinition propertyDefinition) {
+ if (log.isDebugEnabled())
+ log.debug("Before updating property on graph {}", propertyId);
+
+ // get the original property data
+ Either<PropertyData, TitanOperationStatus> statusProperty = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class);
+ if (statusProperty.isRight()) {
+ log.debug("Problem while get property with id {}. Reason - {}", propertyId, statusProperty.right().value().name());
+ return Either.right(statusProperty.right().value());
+ }
+ PropertyData orgPropertyData = statusProperty.left().value();
+ PropertyDataDefinition orgPropertyDataDefinition = orgPropertyData.getPropertyDataDefinition();
+
+ // create new property data to update
+ PropertyData newPropertyData = new PropertyData();
+ newPropertyData.setPropertyDataDefinition(propertyDefinition);
+ PropertyDataDefinition newPropertyDataDefinition = newPropertyData.getPropertyDataDefinition();
+
+ // update the original property data with new values
+ if (orgPropertyDataDefinition.getDefaultValue() == null) {
+ orgPropertyDataDefinition.setDefaultValue(newPropertyDataDefinition.getDefaultValue());
+ } else {
+ if (!orgPropertyDataDefinition.getDefaultValue().equals(newPropertyDataDefinition.getDefaultValue())) {
+ orgPropertyDataDefinition.setDefaultValue(newPropertyDataDefinition.getDefaultValue());
+ }
+ }
+ if (orgPropertyDataDefinition.getDescription() == null) {
+ orgPropertyDataDefinition.setDescription(newPropertyDataDefinition.getDescription());
+ } else {
+ if (!orgPropertyDataDefinition.getDescription().equals(newPropertyDataDefinition.getDescription())) {
+ orgPropertyDataDefinition.setDescription(newPropertyDataDefinition.getDescription());
+ }
+ }
+ if (!orgPropertyDataDefinition.getType().equals(newPropertyDataDefinition.getType())) {
+ orgPropertyDataDefinition.setType(newPropertyDataDefinition.getType());
+ }
+ if (newPropertyData.getConstraints() != null) {
+ orgPropertyData.setConstraints(newPropertyData.getConstraints());
+ }
+ orgPropertyDataDefinition.setSchema(newPropertyDataDefinition.getSchema());
+
+ return titanGenericDao.updateNode(orgPropertyData, PropertyData.class);
+ }
+
+ /**
+ * FOR TEST ONLY
+ *
+ * @param titanGenericDao
+ */
+ public void setTitanGenericDao(TitanGenericDao titanGenericDao) {
+ this.titanGenericDao = titanGenericDao;
+ }
+
+ public Either<PropertyData, TitanOperationStatus> addPropertyToNodeType(String propertyName, PropertyDefinition propertyDefinition, NodeTypeEnum nodeType, String uniqueId) {
+
+ List<PropertyConstraint> constraints = propertyDefinition.getConstraints();
+
+ propertyDefinition.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(uniqueId, propertyName));
+ PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints));
+
+ if (log.isDebugEnabled())
+ log.debug("Before adding property to graph {}", propertyData);
+ Either<PropertyData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyData, PropertyData.class);
+ if (log.isDebugEnabled())
+ log.debug("After adding property to graph {}", propertyData);
+ if (createNodeResult.isRight()) {
+ TitanOperationStatus operationStatus = createNodeResult.right().value();
+ log.error("Failed to add property {} to graph. Status is {}", propertyName, operationStatus);
+ return Either.right(operationStatus);
+ }
+
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName);
+
+ UniqueIdData uniqueIdData = new UniqueIdData(nodeType, uniqueId);
+ log.debug("Before associating {} to property {}.", uniqueIdData, propertyName);
+ Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(uniqueIdData, propertyData, GraphEdgeLabels.PROPERTY, props);
+ if (createRelResult.isRight()) {
+ TitanOperationStatus operationStatus = createNodeResult.right().value();
+ log.error("Failed to associate resource {} to property {} in graph. Status is {}", uniqueId, propertyName, operationStatus);
+ return Either.right(operationStatus);
+ }
+
+ return Either.left(createNodeResult.left().value());
+
+ }
+
+ public TitanOperationStatus addPropertyToNodeType(TitanVertex elementVertex, String propertyName, PropertyDefinition propertyDefinition, NodeTypeEnum nodeType, String uniqueId) {
+
+ List<PropertyConstraint> constraints = propertyDefinition.getConstraints();
+
+ propertyDefinition.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(uniqueId, propertyName));
+ PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints));
+
+ if (log.isDebugEnabled())
+ log.debug("Before adding property to graph {}", propertyData);
+ Either<TitanVertex, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyData);
+ if (log.isDebugEnabled())
+ log.debug("After adding property to graph {}", propertyData);
+ if (createNodeResult.isRight()) {
+ TitanOperationStatus operationStatus = createNodeResult.right().value();
+ log.error("Failed to add property {} to graph. status is {} ", propertyName, operationStatus);
+ return operationStatus;
+ }
+
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName);
+
+ TitanOperationStatus createRelResult = titanGenericDao.createEdge(elementVertex, propertyData, GraphEdgeLabels.PROPERTY, props);
+ if (!createRelResult.equals(TitanOperationStatus.OK)) {
+ log.error("Failed to associate resource {} to property {} in graph. status is {}", uniqueId, propertyName, createRelResult);
+ return createRelResult;
+ }
+
+ return createRelResult;
+
+ }
+
+ public Either<Map<String, PropertyDefinition>, TitanOperationStatus> findPropertiesOfNode(NodeTypeEnum nodeType, String uniqueId) {
+
+ Map<String, PropertyDefinition> resourceProps = new HashMap<String, PropertyDefinition>();
+
+ Either<List<ImmutablePair<PropertyData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.PROPERTY, NodeTypeEnum.Property,
+ PropertyData.class);
+
+ if (childrenNodes.isRight()) {
+ TitanOperationStatus operationStatus = childrenNodes.right().value();
+ return Either.right(operationStatus);
+ }
+
+ List<ImmutablePair<PropertyData, GraphEdge>> values = childrenNodes.left().value();
+ if (values != null) {
+
+ for (ImmutablePair<PropertyData, GraphEdge> immutablePair : values) {
+ GraphEdge edge = immutablePair.getValue();
+ String propertyName = (String) edge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty());
+ log.debug("Property {} is associated to node {}", propertyName, uniqueId);
+ PropertyData propertyData = immutablePair.getKey();
+ PropertyDefinition propertyDefinition = this.convertPropertyDataToPropertyDefinition(propertyData, propertyName, uniqueId);
+ resourceProps.put(propertyName, propertyDefinition);
+ }
+
+ }
+
+ log.debug("The properties associated to node {} are {}", uniqueId, resourceProps);
+ return Either.left(resourceProps);
+ }
+
+ public Either<Map<String, PropertyDefinition>, StorageOperationStatus> deleteAllPropertiesAssociatedToNode(NodeTypeEnum nodeType, String uniqueId) {
+
+ Either<Map<String, PropertyDefinition>, TitanOperationStatus> propertiesOfNodeRes = findPropertiesOfNode(nodeType, uniqueId);
+
+ if (propertiesOfNodeRes.isRight()) {
+ TitanOperationStatus status = propertiesOfNodeRes.right().value();
+ if (status == TitanOperationStatus.NOT_FOUND) {
+ return Either.right(StorageOperationStatus.OK);
+ }
+ return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+ }
+
+ Map<String, PropertyDefinition> value = propertiesOfNodeRes.left().value();
+ for (PropertyDefinition propertyDefinition : value.values()) {
+
+ String propertyUid = propertyDefinition.getUniqueId();
+ Either<PropertyData, TitanOperationStatus> deletePropertyRes = deletePropertyFromGraph(propertyUid);
+ if (deletePropertyRes.isRight()) {
+ log.error("Failed to delete property with id " + propertyUid);
+ TitanOperationStatus status = deletePropertyRes.right().value();
+ if (status == TitanOperationStatus.NOT_FOUND) {
+ status = TitanOperationStatus.INVALID_ID;
+ }
+ return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+ }
+
+ }
+
+ log.debug("The properties deleted from node {} are {}", uniqueId, value);
+ return Either.left(value);
+ }
+
+ /**
+ * fetch all properties under a given resource(includes its parents' resources)
+ *
+ * @param resourceId
+ * @param properties
+ * @return
+ */
+ public TitanOperationStatus findAllResourcePropertiesRecursively(String resourceId, List<PropertyDefinition> properties) {
+ final NodeElementFetcher<PropertyDefinition> singleNodeFetcher = (resourceIdParam, attributesParam) -> findPropertiesOfNode(NodeTypeEnum.Resource, resourceIdParam, attributesParam);
+ return findAllResourceElementsDefinitionRecursively(resourceId, properties, singleNodeFetcher);
+ }
+
+ /**
+ *
+ *
+ * @param nodeType
+ * @param uniqueId
+ * @param properties
+ * @return
+ */
+ protected TitanOperationStatus findPropertiesOfNode(NodeTypeEnum nodeType, String uniqueId, List<PropertyDefinition> properties) {
+
+ Either<List<ImmutablePair<PropertyData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.PROPERTY, NodeTypeEnum.Property,
+ PropertyData.class);
+
+ if (childrenNodes.isRight()) {
+ TitanOperationStatus status = childrenNodes.right().value();
+ if (status == TitanOperationStatus.NOT_FOUND) {
+ status = TitanOperationStatus.OK;
+ }
+ return status;
+ }
+
+ List<ImmutablePair<PropertyData, GraphEdge>> values = childrenNodes.left().value();
+ if (values != null) {
+
+ for (ImmutablePair<PropertyData, GraphEdge> immutablePair : values) {
+ GraphEdge edge = immutablePair.getValue();
+ String propertyName = (String) edge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty());
+ if (log.isDebugEnabled())
+ log.debug("Property {} is associated to node {}", propertyName, uniqueId);
+ PropertyData propertyData = immutablePair.getKey();
+ PropertyDefinition propertyDefinition = this.convertPropertyDataToPropertyDefinition(propertyData, propertyName, uniqueId);
+
+ properties.add(propertyDefinition);
+
+ if (log.isTraceEnabled())
+ log.trace("findPropertiesOfNode - property {} associated to node {}", propertyDefinition, uniqueId);
+ }
+
+ }
+
+ return TitanOperationStatus.OK;
+ }
+
+ public boolean isPropertyExist(List<PropertyDefinition> properties, String resourceUid, String propertyName) {
+
+ if (properties == null) {
+ return false;
+ }
+
+ for (PropertyDefinition propertyDefinition : properties) {
+ String parentUniqueId = propertyDefinition.getParentUniqueId();
+ String name = propertyDefinition.getName();
+
+ if (parentUniqueId.equals(resourceUid) && name.equals(propertyName)) {
+ return true;
+ }
+ }
+
+ return false;
+
+ }
+
+ /**
+ * add property to resource instance
+ *
+ * @param innerType
+ * TODO // * @param resourceInstanceProperty // * @param resourceInstanceId // * @param index
+ *
+ * @return
+ */
+ /*
+ * public Either<PropertyValueData, TitanOperationStatus> addPropertyToResourceInstance( ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, Integer index) {
+ *
+ * Either<ComponentInstanceData, TitanOperationStatus> findResInstanceRes = titanGenericDao .getNode(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, ComponentInstanceData.class);
+ *
+ * if (findResInstanceRes.isRight()) { TitanOperationStatus status = findResInstanceRes.right().value(); if (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); }
+ *
+ * String propertyId = resourceInstanceProperty.getUniqueId(); Either<PropertyData, TitanOperationStatus> findPropertyDefRes = titanGenericDao .getNode(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class);
+ *
+ * if (findPropertyDefRes.isRight()) { TitanOperationStatus status = findPropertyDefRes.right().value(); if (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); }
+ *
+ * String valueUniqueUid = resourceInstanceProperty.getValueUniqueUid(); if (valueUniqueUid == null) {
+ *
+ * PropertyData propertyData = findPropertyDefRes.left().value(); ComponentInstanceData resourceInstanceData = findResInstanceRes.left().value();
+ *
+ * ImmutablePair<TitanOperationStatus, String> isPropertyValueExists = findPropertyValue(resourceInstanceId, propertyId); if (isPropertyValueExists.getLeft() == TitanOperationStatus.ALREADY_EXIST) { log.debug("The property " + propertyId +
+ * " already added to the resource instance " + resourceInstanceId); resourceInstanceProperty.setValueUniqueUid(isPropertyValueExists.getRight ()); Either<PropertyValueData, TitanOperationStatus> updatePropertyOfResourceInstance =
+ * updatePropertyOfResourceInstance(resourceInstanceProperty, resourceInstanceId); if (updatePropertyOfResourceInstance.isRight()) { BeEcompErrorManager.getInstance().logInternalFlowError( "UpdatePropertyValueOnComponentInstance",
+ * "Failed to update property value on instance. Status is " + updatePropertyOfResourceInstance.right().value(), ErrorSeverity.ERROR); return Either.right(updatePropertyOfResourceInstance.right().value()); } return
+ * Either.left(updatePropertyOfResourceInstance.left().value()); }
+ *
+ * if (isPropertyValueExists.getLeft() != TitanOperationStatus.NOT_FOUND) { log.debug("After finding property value of {} on component instance {}", propertyId, resourceInstanceId); return Either.right(isPropertyValueExists.getLeft()); }
+ *
+ * String propertyType = propertyData.getPropertyDataDefinition().getType(); String value = resourceInstanceProperty.getValue(); Either<Object, Boolean> isValid = validateAndUpdatePropertyValue(propertyType, value);
+ *
+ * String newValue = value; if (isValid.isRight()) { Boolean res = isValid.right().value(); if (res == false) { return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); } } else { Object object = isValid.left().value(); if (object != null) {
+ * newValue = object.toString(); } }
+ *
+ * String uniqueId = UniqueIdBuilder.buildResourceInstancePropertyValueUid( resourceInstanceData.getUniqueId(), index); PropertyValueData propertyValueData = new PropertyValueData(); propertyValueData.setUniqueId(uniqueId);
+ * propertyValueData.setValue(newValue);
+ *
+ * ImmutablePair<String, Boolean> pair = validateAndUpdateRules(propertyType, resourceInstanceProperty.getRules()); if (pair.getRight() != null && pair.getRight() == false) { BeEcompErrorManager.getInstance().
+ * logBeInvalidValueError("Add property value", pair.getLeft(), resourceInstanceProperty.getName(), propertyType); return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); } addRulesToNewPropertyValue(propertyValueData,
+ * resourceInstanceProperty, resourceInstanceId);
+ *
+ * log.debug("Before adding property value to graph {}", propertyValueData); Either<PropertyValueData, TitanOperationStatus> createNodeResult = titanGenericDao .createNode(propertyValueData, PropertyValueData.class);
+ * log.debug("After adding property value to graph {}", propertyValueData);
+ *
+ * Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao .createRelation(propertyValueData, propertyData, GraphEdgeLabels.PROPERTY_IMPL, null);
+ *
+ * if (createRelResult.isRight()) { TitanOperationStatus operationStatus = createNodeResult.right() .value(); //TODO: change logger log.error("Failed to associate property value " + uniqueId + " to property " + propertyId +
+ * " in graph. status is " + operationStatus); return Either.right(operationStatus); }
+ *
+ * createRelResult = titanGenericDao .createRelation(resourceInstanceData, propertyValueData, GraphEdgeLabels.PROPERTY_VALUE, null);
+ *
+ * if (createRelResult.isRight()) { TitanOperationStatus operationStatus = createNodeResult.right() .value(); //TODO: change logger log.error("Failed to associate resource instance " + resourceInstanceId + " property value " + uniqueId +
+ * " in graph. status is " + operationStatus); return Either.right(operationStatus); }
+ *
+ * return Either.left(createNodeResult.left().value()); } else { log.error("property value already exists."); return Either.right(TitanOperationStatus.ALREADY_EXIST); }
+ *
+ * }
+ */
+ public ImmutablePair<String, Boolean> validateAndUpdateRules(String propertyType, List<PropertyRule> rules, String innerType, Map<String, DataTypeDefinition> dataTypes, boolean isValidate) {
+
+ if (rules == null || rules.isEmpty() == true) {
+ return new ImmutablePair<String, Boolean>(null, true);
+ }
+
+ for (PropertyRule rule : rules) {
+ String value = rule.getValue();
+ Either<Object, Boolean> updateResult = validateAndUpdatePropertyValue(propertyType, value, isValidate, innerType, dataTypes);
+ if (updateResult.isRight()) {
+ Boolean status = updateResult.right().value();
+ if (status == false) {
+ return new ImmutablePair<String, Boolean>(value, status);
+ }
+ } else {
+ String newValue = null;
+ Object object = updateResult.left().value();
+ if (object != null) {
+ newValue = object.toString();
+ }
+ rule.setValue(newValue);
+ }
+ }
+
+ return new ImmutablePair<String, Boolean>(null, true);
+ }
+
+ public void addRulesToNewPropertyValue(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId) {
+
+ List<PropertyRule> rules = resourceInstanceProperty.getRules();
+ if (rules == null) {
+ PropertyRule propertyRule = buildRuleFromPath(propertyValueData, resourceInstanceProperty, resourceInstanceId);
+ rules = new ArrayList<>();
+ rules.add(propertyRule);
+ } else {
+ rules = sortRules(rules);
+ }
+
+ propertyValueData.setRules(rules);
+ }
+
+ private PropertyRule buildRuleFromPath(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId) {
+ List<String> path = resourceInstanceProperty.getPath();
+ // FOR BC. Since old Property values on VFC/VF does not have rules on
+ // graph.
+ // Update could be done on one level only, thus we can use this
+ // operation to avoid migration.
+ if (path == null || path.isEmpty() == true) {
+ path = new ArrayList<>();
+ path.add(resourceInstanceId);
+ }
+ PropertyRule propertyRule = new PropertyRule();
+ propertyRule.setRule(path);
+ propertyRule.setValue(propertyValueData.getValue());
+ return propertyRule;
+ }
+
+ private List<PropertyRule> sortRules(List<PropertyRule> rules) {
+
+ // TODO: sort the rules by size and binary representation.
+ // (x, y, .+) --> 110 6 priority 1
+ // (x, .+, z) --> 101 5 priority 2
+
+ return rules;
+ }
+
+ public ImmutablePair<TitanOperationStatus, String> findPropertyValue(String resourceInstanceId, String propertyId) {
+
+ log.debug("Going to check whether the property {} already added to resource instance {}", propertyId, resourceInstanceId);
+
+ Either<List<ComponentInstanceProperty>, TitanOperationStatus> getAllRes = this.getAllPropertiesOfResourceInstanceOnlyPropertyDefId(resourceInstanceId);
+ if (getAllRes.isRight()) {
+ TitanOperationStatus status = getAllRes.right().value();
+ log.trace("After fetching all properties of resource instance {}. Status is {}", resourceInstanceId, status);
+ return new ImmutablePair<TitanOperationStatus, String>(status, null);
+ }
+
+ List<ComponentInstanceProperty> list = getAllRes.left().value();
+ if (list != null) {
+ for (ComponentInstanceProperty instanceProperty : list) {
+ String propertyUniqueId = instanceProperty.getUniqueId();
+ String valueUniqueUid = instanceProperty.getValueUniqueUid();
+ log.trace("Go over property {} under resource instance {}. valueUniqueId = {}", propertyUniqueId, resourceInstanceId, valueUniqueUid);
+ if (propertyId.equals(propertyUniqueId) && valueUniqueUid != null) {
+ log.debug("The property {} already created under resource instance {}", propertyId, resourceInstanceId);
+ return new ImmutablePair<TitanOperationStatus, String>(TitanOperationStatus.ALREADY_EXIST, valueUniqueUid);
+ }
+ }
+ }
+
+ return new ImmutablePair<TitanOperationStatus, String>(TitanOperationStatus.NOT_FOUND, null);
+ }
+
+ /**
+ * update value of property on resource instance
+ *
+ * @param resourceInstanceProperty
+ * @param resourceInstanceId
+ * @return
+ */
+ /*
+ * public Either<PropertyValueData, TitanOperationStatus> updatePropertyOfResourceInstance( ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId) {
+ *
+ * /// #RULES SUPPORT /// Ignore rules received from client till support resourceInstanceProperty.setRules(null); /// /// Either<ComponentInstanceData, TitanOperationStatus> findResInstanceRes = titanGenericDao .getNode(UniqueIdBuilder
+ * .getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, ComponentInstanceData.class);
+ *
+ * if (findResInstanceRes.isRight()) { TitanOperationStatus status = findResInstanceRes.right().value(); if (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); }
+ *
+ * String propertyId = resourceInstanceProperty.getUniqueId(); Either<PropertyData, TitanOperationStatus> findPropertyDefRes = titanGenericDao .getNode(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class);
+ *
+ * if (findPropertyDefRes.isRight()) { TitanOperationStatus status = findPropertyDefRes.right().value(); return Either.right(status); }
+ *
+ * String valueUniqueUid = resourceInstanceProperty.getValueUniqueUid(); if (valueUniqueUid == null) { return Either.right(TitanOperationStatus.INVALID_ID); } else { Either<PropertyValueData, TitanOperationStatus> findPropertyValueRes =
+ * titanGenericDao .getNode(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.PropertyValue), valueUniqueUid, PropertyValueData.class); if (findPropertyValueRes.isRight()) { TitanOperationStatus status = findPropertyValueRes.right().value(); if
+ * (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); }
+ *
+ * String value = resourceInstanceProperty.getValue();
+ *
+ * Either<ImmutablePair<PropertyData, GraphEdge>, TitanOperationStatus> child = titanGenericDao.getChild(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.PropertyValue), valueUniqueUid, GraphEdgeLabels.PROPERTY_IMPL, NodeTypeEnum.Property,
+ * PropertyData.class);
+ *
+ * if (child.isRight()) { TitanOperationStatus status = child.right().value(); if (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); }
+ *
+ * PropertyData propertyData = child.left().value().left; String propertyType = propertyData.getPropertyDataDefinition().getType();
+ *
+ * log.debug("The type of the property {} is {}", propertyData.getUniqueId(), propertyType);
+ *
+ * Either<Object, Boolean> isValid = validateAndUpdatePropertyValue(propertyType, value);
+ *
+ * String newValue = value; if (isValid.isRight()) { Boolean res = isValid.right().value(); if (res == false) { return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); } } else { Object object = isValid.left().value(); if (object != null) {
+ * newValue = object.toString(); } } PropertyValueData propertyValueData = findPropertyValueRes.left().value(); log.debug("Going to update property value from {} to {}", propertyValueData.getValue(), newValue);
+ * propertyValueData.setValue(newValue);
+ *
+ * ImmutablePair<String, Boolean> pair = validateAndUpdateRules(propertyType, resourceInstanceProperty.getRules()); if (pair.getRight() != null && pair.getRight() == false) { BeEcompErrorManager.getInstance().
+ * logBeInvalidValueError("Add property value", pair.getLeft(), resourceInstanceProperty.getName(), propertyType); return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); } updateRulesInPropertyValue(propertyValueData,
+ * resourceInstanceProperty, resourceInstanceId);
+ *
+ * Either<PropertyValueData, TitanOperationStatus> updateRes = titanGenericDao.updateNode(propertyValueData, PropertyValueData.class); if (updateRes.isRight()) { TitanOperationStatus status = updateRes.right().value(); return
+ * Either.right(status); } else { return Either.left(updateRes.left().value()); } }
+ *
+ * }
+ */
+
+ public void updateRulesInPropertyValue(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId) {
+
+ List<PropertyRule> currentRules = propertyValueData.getRules();
+
+ List<PropertyRule> rules = resourceInstanceProperty.getRules();
+ // if rules are not supported.
+ if (rules == null) {
+
+ PropertyRule propertyRule = buildRuleFromPath(propertyValueData, resourceInstanceProperty, resourceInstanceId);
+ rules = new ArrayList<>();
+ rules.add(propertyRule);
+
+ if (currentRules != null) {
+ rules = mergeRules(currentRules, rules);
+ }
+
+ } else {
+ // Full mode. all rules are sent in update operation.
+ rules = sortRules(rules);
+ }
+
+ propertyValueData.setRules(rules);
+
+ }
+
+ private List<PropertyRule> mergeRules(List<PropertyRule> currentRules, List<PropertyRule> newRules) {
+
+ List<PropertyRule> mergedRules = new ArrayList<>();
+
+ if (newRules == null || newRules.isEmpty() == true) {
+ return currentRules;
+ }
+
+ for (PropertyRule rule : currentRules) {
+ PropertyRule propertyRule = new PropertyRule(rule.getRule(), rule.getValue());
+ mergedRules.add(propertyRule);
+ }
+
+ for (PropertyRule rule : newRules) {
+ PropertyRule foundRule = findRuleInList(rule, mergedRules);
+ if (foundRule != null) {
+ foundRule.setValue(rule.getValue());
+ } else {
+ mergedRules.add(rule);
+ }
+ }
+
+ return mergedRules;
+ }
+
+ private PropertyRule findRuleInList(PropertyRule rule, List<PropertyRule> rules) {
+
+ if (rules == null || rules.isEmpty() == true || rule.getRule() == null || rule.getRule().isEmpty() == true) {
+ return null;
+ }
+
+ PropertyRule foundRule = null;
+ for (PropertyRule propertyRule : rules) {
+ if (rule.getRuleSize() != propertyRule.getRuleSize()) {
+ continue;
+ }
+ boolean equals = propertyRule.compareRule(rule);
+ if (equals == true) {
+ foundRule = propertyRule;
+ break;
+ }
+ }
+
+ return foundRule;
+ }
+
+ /**
+ * return all properties associated to resource instance. The result does contains the property unique id but not its type, default value...
+ *
+ * @param resourceInstanceUid
+ * @return
+ */
+ public Either<List<ComponentInstanceProperty>, TitanOperationStatus> getAllPropertiesOfResourceInstanceOnlyPropertyDefId(String resourceInstanceUid) {
+
+ return getAllPropertiesOfResourceInstanceOnlyPropertyDefId(resourceInstanceUid, NodeTypeEnum.ResourceInstance);
+
+ }
+
+ /*
+ * public Either<ComponentInstanceProperty, StorageOperationStatus> addPropertyValueToResourceInstance( ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, Integer index, boolean inTransaction) {
+ *
+ * /// #RULES SUPPORT /// Ignore rules received from client till support resourceInstanceProperty.setRules(null); /// ///
+ *
+ * Either<ComponentInstanceProperty, StorageOperationStatus> result = null;
+ *
+ * try {
+ *
+ * Either<PropertyValueData, TitanOperationStatus> eitherStatus = this .addPropertyToResourceInstance(resourceInstanceProperty, resourceInstanceId, index);
+ *
+ * if (eitherStatus.isRight()) { log.error( "Failed to add property value {} to resource instance {} in Graph. status is {}" , resourceInstanceProperty, resourceInstanceId, eitherStatus.right().value().name()); result =
+ * Either.right(DaoStatusConverter .convertTitanStatusToStorageStatus(eitherStatus.right() .value())); return result; } else { PropertyValueData propertyValueData = eitherStatus.left() .value();
+ *
+ * ComponentInstanceProperty propertyValueResult = buildResourceInstanceProperty( propertyValueData, resourceInstanceProperty);
+ *
+ * log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult); result = Either.left(propertyValueResult); return result; } }
+ *
+ * finally { if (false == inTransaction) { if (result == null || result.isRight()) { log.error("Going to execute rollback on graph."); titanGenericDao.rollback(); } else { log.debug("Going to execute commit on graph."); titanGenericDao.commit();
+ * } } }
+ *
+ * }
+ *
+ * public Either<ComponentInstanceProperty, StorageOperationStatus> updatePropertyValueInResourceInstance( ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, boolean inTransaction) {
+ *
+ * Either<ComponentInstanceProperty, StorageOperationStatus> result = null;
+ *
+ * try { //TODO: verify validUniqueId exists Either<PropertyValueData, TitanOperationStatus> eitherStatus = this .updatePropertyOfResourceInstance(resourceInstanceProperty, resourceInstanceId);
+ *
+ * if (eitherStatus.isRight()) { log.error( "Failed to add property value {} to resource instance {} in Graph. status is {}" , resourceInstanceProperty, resourceInstanceId, eitherStatus.right().value().name()); result =
+ * Either.right(DaoStatusConverter .convertTitanStatusToStorageStatus(eitherStatus.right() .value())); return result; } else { PropertyValueData propertyValueData = eitherStatus.left() .value();
+ *
+ * ComponentInstanceProperty propertyValueResult = buildResourceInstanceProperty( propertyValueData, resourceInstanceProperty);
+ *
+ * log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult); result = Either.left(propertyValueResult); return result; } }
+ *
+ * finally { if (false == inTransaction) { if (result == null || result.isRight()) { log.error("Going to execute rollback on graph."); titanGenericDao.rollback(); } else { log.debug("Going to execute commit on graph."); titanGenericDao.commit();
+ * } } }
+ *
+ * }
+ */
+
+ public Either<PropertyValueData, TitanOperationStatus> removePropertyOfResourceInstance(String propertyValueUid, String resourceInstanceId) {
+
+ Either<ComponentInstanceData, TitanOperationStatus> findResInstanceRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, ComponentInstanceData.class);
+
+ if (findResInstanceRes.isRight()) {
+ TitanOperationStatus status = findResInstanceRes.right().value();
+ if (status == TitanOperationStatus.NOT_FOUND) {
+ status = TitanOperationStatus.INVALID_ID;
+ }
+ return Either.right(status);
+ }
+
+ Either<PropertyValueData, TitanOperationStatus> findPropertyDefRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.PropertyValue), propertyValueUid, PropertyValueData.class);
+
+ if (findPropertyDefRes.isRight()) {
+ TitanOperationStatus status = findPropertyDefRes.right().value();
+ if (status == TitanOperationStatus.NOT_FOUND) {
+ status = TitanOperationStatus.INVALID_ID;
+ }
+ return Either.right(status);
+ }
+
+ Either<GraphRelation, TitanOperationStatus> relation = titanGenericDao.getRelation(findResInstanceRes.left().value(), findPropertyDefRes.left().value(), GraphEdgeLabels.PROPERTY_VALUE);
+ if (relation.isRight()) {
+ // TODO: add error in case of error
+ TitanOperationStatus status = relation.right().value();
+ if (status == TitanOperationStatus.NOT_FOUND) {
+ status = TitanOperationStatus.INVALID_ID;
+ }
+ return Either.right(status);
+ }
+
+ Either<PropertyValueData, TitanOperationStatus> deleteNode = titanGenericDao.deleteNode(findPropertyDefRes.left().value(), PropertyValueData.class);
+ if (deleteNode.isRight()) {
+ return Either.right(deleteNode.right().value());
+ }
+ PropertyValueData value = deleteNode.left().value();
+ return Either.left(value);
+
+ }
+
+ public Either<ComponentInstanceProperty, StorageOperationStatus> removePropertyValueFromResourceInstance(String propertyValueUid, String resourceInstanceId, boolean inTransaction) {
+
+ Either<ComponentInstanceProperty, StorageOperationStatus> result = null;
+
+ try {
+
+ Either<PropertyValueData, TitanOperationStatus> eitherStatus = this.removePropertyOfResourceInstance(propertyValueUid, resourceInstanceId);
+
+ if (eitherStatus.isRight()) {
+ log.error("Failed to remove property value {} from resource instance {} in Graph. status is {}", propertyValueUid, resourceInstanceId, eitherStatus.right().value().name());
+ result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value()));
+ return result;
+ } else {
+ PropertyValueData propertyValueData = eitherStatus.left().value();
+
+ ComponentInstanceProperty propertyValueResult = new ComponentInstanceProperty();
+ propertyValueResult.setUniqueId(resourceInstanceId);
+ propertyValueResult.setValue(propertyValueData.getValue());
+
+ log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult);
+ result = Either.left(propertyValueResult);
+ return result;
+ }
+ }
+
+ finally {
+ if (false == inTransaction) {
+ if (result == null || result.isRight()) {
+ log.error("Going to execute rollback on graph.");
+ titanGenericDao.rollback();
+ } else {
+ log.debug("Going to execute commit on graph.");
+ titanGenericDao.commit();
+ }
+ }
+ }
+
+ }
+
+ public ComponentInstanceProperty buildResourceInstanceProperty(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty) {
+
+ String value = propertyValueData.getValue();
+ String uid = propertyValueData.getUniqueId();
+ ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty(resourceInstanceProperty, value, uid);
+ instanceProperty.setPath(resourceInstanceProperty.getPath());
+
+ return instanceProperty;
+ }
+
+ public static class PropertyConstraintJacksonDeserialiser extends org.codehaus.jackson.map.JsonDeserializer<PropertyConstraint> {
+
+ @Override
+ public PropertyConstraint deserialize(org.codehaus.jackson.JsonParser json, DeserializationContext context) throws IOException, JsonProcessingException {
+
+ ObjectCodec oc = json.getCodec();
+ JsonNode node = oc.readTree(json);
+ return null;
+ }
+ }
+
+ @Override
+ public boolean isPropertyDefaultValueValid(IComplexDefaultValue propertyDefinition, Map<String, DataTypeDefinition> dataTypes) {
+ if (propertyDefinition == null) {
+ return false;
+ }
+ boolean isValid = false;
+ String innerType = null;
+ String propertyType = propertyDefinition.getType();
+ ToscaPropertyType type = getType(propertyType);
+ if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
+ SchemaDefinition def = propertyDefinition.getSchema();
+ if (def == null) {
+ return false;
+ }
+ PropertyDataDefinition propDef = def.getProperty();
+ if (propDef == null) {
+ return false;
+ }
+ innerType = propDef.getType();
+ }
+ String value = propertyDefinition.getDefaultValue();
+ if (type != null) {
+ isValid = isValidValue(type, value, innerType, dataTypes);
+ } else {
+ log.trace("The given type {} is not a pre defined one.", propertyType);
+
+ DataTypeDefinition foundDt = dataTypes.get(propertyType);
+ if (foundDt != null) {
+ isValid = isValidComplexValue(foundDt, value, dataTypes);
+ } else {
+ isValid = false;
+ }
+ }
+ return isValid;
+ }
+
+ public boolean isPropertyTypeValid(IComplexDefaultValue property) {
+
+ if (property == null) {
+ return false;
+ }
+
+ if (ToscaPropertyType.isValidType(property.getType()) == null) {
+
+ Either<Boolean, TitanOperationStatus> definedInDataTypes = isDefinedInDataTypes(property.getType());
+
+ if (definedInDataTypes.isRight()) {
+ return false;
+ } else {
+ Boolean isExist = definedInDataTypes.left().value();
+ return isExist.booleanValue();
+ }
+
+ }
+ return true;
+ }
+
+ @Override
+ public ImmutablePair<String, Boolean> isPropertyInnerTypeValid(IComplexDefaultValue property, Map<String, DataTypeDefinition> dataTypes) {
+
+ if (property == null) {
+ return new ImmutablePair<String, Boolean>(null, false);
+ }
+
+ SchemaDefinition schema;
+ PropertyDataDefinition innerProp;
+ String innerType = null;
+ if ((schema = property.getSchema()) != null) {
+ if ((innerProp = schema.getProperty()) != null) {
+ innerType = innerProp.getType();
+ }
+ }
+
+ ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType);
+
+ if (innerToscaType == null) {
+ DataTypeDefinition dataTypeDefinition = dataTypes.get(innerType);
+ if (dataTypeDefinition == null) {
+ log.debug("The inner type {} is not a data type", innerType);
+ return new ImmutablePair<String, Boolean>(innerType, false);
+ } else {
+ log.debug("The inner type {} is a data type. Data type definition is {}", innerType, dataTypeDefinition);
+ }
+ }
+
+ return new ImmutablePair<String, Boolean>(innerType, true);
+ }
+
+ private boolean isValidComplexValue(DataTypeDefinition foundDt, String value, Map<String, DataTypeDefinition> dataTypes) {
+ /*
+ * Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypesRes = getAllDataTypes(); if (allDataTypesRes.isRight()) { TitanOperationStatus status = allDataTypesRes.right().value();
+ * log.debug("Failed to fetch data types from graph. Status is {}", status); return false; }
+ *
+ * Map<String, DataTypeDefinition> allDataTypes = allDataTypesRes.left().value();
+ */
+ ImmutablePair<JsonElement, Boolean> validateAndUpdate = dataTypeValidatorConverter.validateAndUpdate(value, foundDt, dataTypes);
+
+ log.trace("The result after validating complex value of type {} is {}", foundDt.getName(), validateAndUpdate);
+
+ return validateAndUpdate.right.booleanValue();
+
+ }
+
+ private Either<Map<String, DataTypeDefinition>, TitanOperationStatus> findAllDataTypeDefinition(DataTypeDefinition dataTypeDefinition) {
+
+ Map<String, DataTypeDefinition> nameToDataTypeDef = new HashMap<>();
+
+ DataTypeDefinition typeDefinition = dataTypeDefinition;
+
+ while (typeDefinition != null) {
+
+ List<PropertyDefinition> properties = typeDefinition.getProperties();
+ if (properties != null) {
+ for (PropertyDefinition propertyDefinition : properties) {
+ String type = propertyDefinition.getType();
+ Either<DataTypeDefinition, TitanOperationStatus> dataTypeByName = this.getDataTypeUsingName(type);
+ if (dataTypeByName.isRight()) {
+ return Either.right(dataTypeByName.right().value());
+ } else {
+ DataTypeDefinition value = dataTypeByName.left().value();
+ if (false == nameToDataTypeDef.containsKey(type)) {
+ nameToDataTypeDef.put(type, value);
+ }
+ }
+
+ }
+ }
+
+ typeDefinition = typeDefinition.getDerivedFrom();
+ }
+
+ return Either.left(nameToDataTypeDef);
+ }
+
+ public Either<List<ComponentInstanceProperty>, TitanOperationStatus> getAllPropertiesOfResourceInstanceOnlyPropertyDefId(String resourceInstanceUid, NodeTypeEnum instanceNodeType) {
+
+ // Either<ComponentInstanceData, TitanOperationStatus>
+ // findResInstanceRes =
+ // titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(instanceNodeType),
+ // resourceInstanceUid, ComponentInstanceData.class);
+ Either<TitanVertex, TitanOperationStatus> findResInstanceRes = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(instanceNodeType), resourceInstanceUid);
+
+ if (findResInstanceRes.isRight()) {
+ TitanOperationStatus status = findResInstanceRes.right().value();
+ if (status == TitanOperationStatus.NOT_FOUND) {
+ status = TitanOperationStatus.INVALID_ID;
+ }
+ return Either.right(status);
+ }
+
+ // Either<List<ImmutablePair<PropertyValueData, GraphEdge>>,
+ // TitanOperationStatus> propertyImplNodes =
+ // titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(instanceNodeType),
+ // resourceInstanceUid, GraphEdgeLabels.PROPERTY_VALUE,
+ // NodeTypeEnum.PropertyValue, PropertyValueData.class);
+ Either<List<ImmutablePair<TitanVertex, Edge>>, TitanOperationStatus> propertyImplNodes = titanGenericDao.getChildrenVertecies(UniqueIdBuilder.getKeyByNodeType(instanceNodeType), resourceInstanceUid, GraphEdgeLabels.PROPERTY_VALUE);
+
+ if (propertyImplNodes.isRight()) {
+ TitanOperationStatus status = propertyImplNodes.right().value();
+ return Either.right(status);
+ }
+
+ List<ImmutablePair<TitanVertex, Edge>> list = propertyImplNodes.left().value();
+ if (list == null || true == list.isEmpty()) {
+ return Either.right(TitanOperationStatus.NOT_FOUND);
+ }
+
+ List<ComponentInstanceProperty> result = new ArrayList<>();
+ for (ImmutablePair<TitanVertex, Edge> propertyValue : list) {
+ TitanVertex propertyValueDataVertex = propertyValue.getLeft();
+ String propertyValueUid = (String) titanGenericDao.getProperty(propertyValueDataVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty());
+ String value = (String) titanGenericDao.getProperty(propertyValueDataVertex, GraphPropertiesDictionary.VALUE.getProperty());
+
+ ImmutablePair<TitanVertex, Edge> propertyDefPair = titanGenericDao.getChildVertex(propertyValueDataVertex, GraphEdgeLabels.PROPERTY_IMPL);
+ if (propertyDefPair == null) {
+ return Either.right(TitanOperationStatus.NOT_FOUND);
+ }
+
+ Map<String, Object> properties = titanGenericDao.getProperties(propertyValueDataVertex);
+ PropertyValueData propertyValueData = GraphElementFactory.createElement(NodeTypeEnum.PropertyValue.getName(), GraphElementTypeEnum.Node, properties, PropertyValueData.class);
+ String propertyUniqueId = (String) titanGenericDao.getProperty(propertyDefPair.left, GraphPropertiesDictionary.UNIQUE_ID.getProperty());
+
+ ComponentInstanceProperty resourceInstanceProperty = new ComponentInstanceProperty();
+ // set property original unique id
+ resourceInstanceProperty.setUniqueId(propertyUniqueId);
+ // set resource id
+ // TODO: esofer add resource id
+ resourceInstanceProperty.setParentUniqueId(null);
+ // set value
+ resourceInstanceProperty.setValue(value);
+ // set property value unique id
+ resourceInstanceProperty.setValueUniqueUid(propertyValueUid);
+ // set rules
+ resourceInstanceProperty.setRules(propertyValueData.getRules());
+
+ result.add(resourceInstanceProperty);
+ }
+
+ return Either.left(result);
+ }
+
+ /**
+ * Find the default value from the list of component instances. Start the search from the second component instance
+ *
+ * @param pathOfComponentInstances
+ * @param propertyUniqueId
+ * @param defaultValue
+ * @return
+ */
+ public Either<String, TitanOperationStatus> findDefaultValueFromSecondPosition(List<String> pathOfComponentInstances, String propertyUniqueId, String defaultValue) {
+
+ log.trace("In find default value: path=" + pathOfComponentInstances + "propertyUniqId=" + propertyUniqueId + "defaultValue=" + defaultValue);
+
+ if (pathOfComponentInstances == null || pathOfComponentInstances.size() < 2) {
+ return Either.left(defaultValue);
+ }
+
+ String result = defaultValue;
+
+ for (int i = 1; i < pathOfComponentInstances.size(); i++) {
+ String compInstanceId = pathOfComponentInstances.get(i);
+
+ Either<List<ComponentInstanceProperty>, TitanOperationStatus> propertyValuesResult = this.getAllPropertiesOfResourceInstanceOnlyPropertyDefId(compInstanceId, NodeTypeEnum.ResourceInstance);
+
+ log.trace("After fetching properties values of component instance {}. {}", compInstanceId, propertyValuesResult);
+
+ if (propertyValuesResult.isRight()) {
+ TitanOperationStatus status = propertyValuesResult.right().value();
+ if (status != TitanOperationStatus.NOT_FOUND) {
+ return Either.right(status);
+ } else {
+ continue;
+ }
+ }
+
+ ComponentInstanceProperty foundCompInstanceProperty = fetchByPropertyUid(propertyValuesResult.left().value(), propertyUniqueId);
+ log.trace("After finding the component instance property on {}. {}", compInstanceId, foundCompInstanceProperty);
+
+ if (foundCompInstanceProperty == null) {
+ continue;
+ }
+
+ List<PropertyRule> rules = getOrBuildRulesIfNotExists(pathOfComponentInstances.size() - i, pathOfComponentInstances.get(i), foundCompInstanceProperty.getRules(), foundCompInstanceProperty.getValue());
+
+ log.trace("Rules of property {} on component instance {} are {}", propertyUniqueId, compInstanceId, rules);
+ PropertyRule matchedRule = findMatchRule(pathOfComponentInstances, i, rules);
+ log.trace("Match rule is {}", matchedRule);
+
+ if (matchedRule != null) {
+ result = matchedRule.getValue();
+ break;
+ }
+
+ }
+
+ return Either.left(result);
+
+ }
+
+ private ComponentInstanceProperty fetchByPropertyUid(List<ComponentInstanceProperty> list, String propertyUniqueId) {
+
+ ComponentInstanceProperty result = null;
+
+ if (list == null) {
+ return null;
+ }
+
+ for (ComponentInstanceProperty instProperty : list) {
+ if (instProperty.getUniqueId().equals(propertyUniqueId)) {
+ result = instProperty;
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ private List<PropertyRule> getOrBuildRulesIfNotExists(int ruleSize, String compInstanceId, List<PropertyRule> rules, String value) {
+
+ if (rules != null) {
+ return rules;
+ }
+
+ rules = buildDefaultRule(compInstanceId, ruleSize, value);
+
+ return rules;
+
+ }
+
+ private List<PropertyRule> getRulesOfPropertyValue(int size, String instanceId, ComponentInstanceProperty componentInstanceProperty) {
+ List<PropertyRule> rules = componentInstanceProperty.getRules();
+ if (rules == null) {
+ rules = buildDefaultRule(instanceId, size, componentInstanceProperty.getValue());
+ }
+ return rules;
+ }
+
+ private List<PropertyRule> buildDefaultRule(String componentInstanceId, int size, String value) {
+
+ List<PropertyRule> rules = new ArrayList<>();
+ List<String> rule = new ArrayList<>();
+ rule.add(componentInstanceId);
+ for (int i = 0; i < size - 1; i++) {
+ rule.add(PropertyRule.RULE_ANY_MATCH);
+ }
+ PropertyRule propertyRule = new PropertyRule(rule, value);
+ rules.add(propertyRule);
+
+ return rules;
+
+ }
+
+ private PropertyRule findMatchRule(List<String> pathOfInstances, int level, List<PropertyRule> rules) {
+
+ PropertyRule propertyRule = null;
+
+ String stringForMatch = buildStringForMatch(pathOfInstances, level);
+
+ String firstCompInstance = pathOfInstances.get(level);
+
+ if (rules != null) {
+
+ for (PropertyRule rule : rules) {
+
+ int ruleSize = rule.getRule().size();
+ // check the length of the rule equals to the length of the
+ // instances path.
+ if (ruleSize != pathOfInstances.size() - level) {
+ continue;
+ }
+ // check that the rule starts with correct component instance id
+ if (false == checkFirstItem(firstCompInstance, rule.getFirstToken())) {
+ continue;
+ }
+
+ String secondToken = rule.getToken(2);
+ if (secondToken != null && (secondToken.equals(PropertyRule.FORCE_ALL) || secondToken.equals(PropertyRule.ALL))) {
+ propertyRule = rule;
+ break;
+ }
+
+ String patternStr = buildStringForMatch(rule.getRule(), 0);
+
+ Pattern pattern = Pattern.compile(patternStr);
+
+ Matcher matcher = pattern.matcher(stringForMatch);
+
+ if (matcher.matches()) {
+ log.trace("{} matches the rule {}", stringForMatch, patternStr);
+ propertyRule = rule;
+ break;
+ }
+ }
+
+ }
+
+ return propertyRule;
+ }
+
+ private boolean checkFirstItem(String left, String right) {
+ if (left != null && left.equals(right)) {
+ return true;
+ }
+ return false;
+ }
+
+ private String buildStringForMatch(List<String> pathOfInstances, int level) {
+ StringBuilder builder = new StringBuilder();
+
+ for (int i = level; i < pathOfInstances.size(); i++) {
+ builder.append(pathOfInstances.get(i));
+ if (i < pathOfInstances.size() - 1) {
+ builder.append("#");
+ }
+ }
+ return builder.toString();
+ }
+
+ public void updatePropertyByBestMatch(String propertyUniqueId, ComponentInstanceProperty instanceProperty, Map<String, ComponentInstanceProperty> instanceIdToValue) {
+
+ List<String> pathOfInstances = instanceProperty.getPath();
+ int level = 0;
+ int size = pathOfInstances.size();
+ int numberOfMatches = 0;
+ for (String instanceId : pathOfInstances) {
+ ComponentInstanceProperty componentInstanceProperty = instanceIdToValue.get(instanceId);
+
+ if (componentInstanceProperty != null) {
+
+ List<PropertyRule> rules = getRulesOfPropertyValue(size - level, instanceId, componentInstanceProperty);
+ // If it is the first level instance, then update valueUniuqeId
+ // parameter in order to know on update that
+ // we should update and not create new node on graph.
+ if (level == 0) {
+ instanceProperty.setValueUniqueUid(componentInstanceProperty.getValueUniqueUid());
+ instanceProperty.setRules(rules);
+ }
+
+ PropertyRule rule = findMatchRule(pathOfInstances, level, rules);
+ if (rule != null) {
+ numberOfMatches++;
+ String value = rule.getValue();
+ if (numberOfMatches == 1) {
+ instanceProperty.setValue(value);
+ if (log.isDebugEnabled()) {
+ log.debug("Set the value of property " + propertyUniqueId + " " + instanceProperty.getName() + " on path " + pathOfInstances + " to be " + value);
+ }
+ } else if (numberOfMatches == 2) {
+ // In case of another property value match, then use the
+ // value to be the default value of the property.
+ instanceProperty.setDefaultValue(value);
+ if (log.isDebugEnabled()) {
+ log.debug("Set the default value of property " + propertyUniqueId + " " + instanceProperty.getName() + " on path " + pathOfInstances + " to be " + value);
+ }
+ break;
+ }
+ }
+ }
+ level++;
+ }
+
+ }
+
+ public void updatePropertiesByPropertyValues(Map<String, List<ComponentInstanceProperty>> resourceInstancesProperties, Map<String, Map<String, ComponentInstanceProperty>> values) {
+
+ if (resourceInstancesProperties == null) {
+ return;
+ }
+
+ List<ComponentInstanceProperty> allProperties = new ArrayList<>();
+ Collection<List<ComponentInstanceProperty>> properties = resourceInstancesProperties.values();
+ if (properties != null) {
+ Iterator<List<ComponentInstanceProperty>> iterator = properties.iterator();
+ while (iterator.hasNext()) {
+ List<ComponentInstanceProperty> compInstancePropertyList = iterator.next();
+ allProperties.addAll(compInstancePropertyList);
+ }
+ }
+
+ // Go over each property and check whether there is a rule which updates
+ // it
+ for (ComponentInstanceProperty instanceProperty : allProperties) {
+
+ String propertyUniqueId = instanceProperty.getUniqueId();
+
+ // get the changes per componentInstanceId.
+ Map<String, ComponentInstanceProperty> instanceIdToValue = values.get(propertyUniqueId);
+
+ if (instanceIdToValue == null) {
+ continue;
+ }
+
+ this.updatePropertyByBestMatch(propertyUniqueId, instanceProperty, instanceIdToValue);
+
+ }
+
+ }
+
+ /**
+ *
+ * Add data type to graph.
+ *
+ * 1. Add data type node
+ *
+ * 2. Add edge between the former node to its parent(if exists)
+ *
+ * 3. Add property node and associate it to the node created at #1. (per property & if exists)
+ *
+ * @param dataTypeDefinition
+ * @return
+ */
+ private Either<DataTypeData, TitanOperationStatus> addDataTypeToGraph(DataTypeDefinition dataTypeDefinition) {
+
+ log.debug("Got data type " + dataTypeDefinition);
+
+ String dtUniqueId = UniqueIdBuilder.buildDataTypeUid(dataTypeDefinition.getName());
+
+ DataTypeData dataTypeData = buildDataTypeData(dataTypeDefinition, dtUniqueId);
+
+ log.debug("Before adding data type to graph. dataTypeData = " + dataTypeData);
+ Either<DataTypeData, TitanOperationStatus> createDataTypeResult = titanGenericDao.createNode(dataTypeData, DataTypeData.class);
+ log.debug("After adding data type to graph. status is = {}", createDataTypeResult);
+
+ if (createDataTypeResult.isRight()) {
+ TitanOperationStatus operationStatus = createDataTypeResult.right().value();
+ log.debug("Failed to data type " + dataTypeDefinition.getName() + " to graph. status is " + operationStatus);
+ BeEcompErrorManager.getInstance().logBeFailedAddingNodeTypeError("AddDataType", NodeTypeEnum.DataType.getName());
+ return Either.right(operationStatus);
+ }
+
+ DataTypeData resultCTD = createDataTypeResult.left().value();
+ List<PropertyDefinition> properties = dataTypeDefinition.getProperties();
+ Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToDataType = addPropertiesToDataType(resultCTD.getUniqueId(), properties);
+ if (addPropertiesToDataType.isRight()) {
+ log.debug("Failed add properties " + properties + " to data type " + dataTypeDefinition.getName());
+ return Either.right(addPropertiesToDataType.right().value());
+ }
+
+ String derivedFrom = dataTypeDefinition.getDerivedFromName();
+ if (derivedFrom != null) {
+ log.debug("Before creating relation between data type " + dtUniqueId + " to its parent " + derivedFrom);
+ UniqueIdData from = new UniqueIdData(NodeTypeEnum.DataType, dtUniqueId);
+
+ String deriveFromUid = UniqueIdBuilder.buildDataTypeUid(derivedFrom);
+ UniqueIdData to = new UniqueIdData(NodeTypeEnum.DataType, deriveFromUid);
+ Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(from, to, GraphEdgeLabels.DERIVED_FROM, null);
+ log.debug("After create relation between capability type " + dtUniqueId + " to its parent " + derivedFrom + ". status is " + createRelation);
+ if (createRelation.isRight()) {
+ return Either.right(createRelation.right().value());
+ }
+ }
+
+ return Either.left(createDataTypeResult.left().value());
+
+ }
+
+ private DataTypeData buildDataTypeData(DataTypeDefinition dataTypeDefinition, String ctUniqueId) {
+
+ DataTypeData dataTypeData = new DataTypeData(dataTypeDefinition);
+
+ dataTypeData.getDataTypeDataDefinition().setUniqueId(ctUniqueId);
+ Long creationDate = dataTypeData.getDataTypeDataDefinition().getCreationTime();
+ if (creationDate == null) {
+ creationDate = System.currentTimeMillis();
+ }
+ dataTypeData.getDataTypeDataDefinition().setCreationTime(creationDate);
+ dataTypeData.getDataTypeDataDefinition().setModificationTime(creationDate);
+
+ return dataTypeData;
+ }
+
+ /**
+ * add properties to capability type.
+ *
+ * Per property, add a property node and associate it to the capability type
+ *
+ * @param uniqueId
+ * @param properties
+ * @return
+ */
+ private Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToDataType(String uniqueId, List<PropertyDefinition> properties) {
+
+ Map<String, PropertyData> propertiesData = new HashMap<String, PropertyData>();
+
+ if (properties != null && false == properties.isEmpty()) {
+ for (PropertyDefinition propertyDefinition : properties) {
+ String propertyName = propertyDefinition.getName();
+
+ String propertyType = propertyDefinition.getType();
+ Either<Boolean, TitanOperationStatus> validPropertyType = isValidPropertyType(propertyType);
+ if (validPropertyType.isRight()) {
+ log.debug("Data type " + uniqueId + " contains invalid property type " + propertyType);
+ return Either.right(validPropertyType.right().value());
+ }
+ Boolean isValid = validPropertyType.left().value();
+ if (isValid == null || isValid.booleanValue() == false) {
+ log.debug("Data type " + uniqueId + " contains invalid property type " + propertyType);
+ return Either.right(TitanOperationStatus.INVALID_TYPE);
+ }
+
+ Either<PropertyData, TitanOperationStatus> addPropertyToNodeType = this.addPropertyToNodeType(propertyName, propertyDefinition, NodeTypeEnum.DataType, uniqueId);
+ if (addPropertyToNodeType.isRight()) {
+ TitanOperationStatus operationStatus = addPropertyToNodeType.right().value();
+ log.debug("Failed to associate data type " + uniqueId + " to property " + propertyName + " in graph. status is " + operationStatus);
+ BeEcompErrorManager.getInstance().logInternalFlowError("AddPropertyToDataType", "Failed to associate property to data type. Status is " + operationStatus, ErrorSeverity.ERROR);
+ return Either.right(operationStatus);
+ }
+ propertiesData.put(propertyName, addPropertyToNodeType.left().value());
+ }
+
+ DataTypeData dataTypeData = new DataTypeData();
+ dataTypeData.getDataTypeDataDefinition().setUniqueId(uniqueId);
+ long modificationTime = System.currentTimeMillis();
+ dataTypeData.getDataTypeDataDefinition().setModificationTime(modificationTime);
+
+ Either<DataTypeData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(dataTypeData, DataTypeData.class);
+ if (updateNode.isRight()) {
+ TitanOperationStatus operationStatus = updateNode.right().value();
+ log.debug("Failed to update modification time data type " + uniqueId + " from graph. status is " + operationStatus);
+ BeEcompErrorManager.getInstance().logInternalFlowError("AddPropertyToDataType", "Failed to fetch data type. Status is " + operationStatus, ErrorSeverity.ERROR);
+ return Either.right(operationStatus);
+ } else {
+ log.debug("Update data type uid {}. Set modification time to {}", uniqueId, modificationTime);
+ }
+
+ }
+
+ return Either.left(propertiesData);
+
+ }
+
+ /**
+ * Build Data type object from graph by unique id
+ *
+ * @param uniqueId
+ * @return
+ */
+ public Either<DataTypeDefinition, TitanOperationStatus> getDataTypeByUid(String uniqueId) {
+
+ Either<DataTypeDefinition, TitanOperationStatus> result = null;
+
+ Either<DataTypeData, TitanOperationStatus> dataTypesRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, DataTypeData.class);
+
+ if (dataTypesRes.isRight()) {
+ TitanOperationStatus status = dataTypesRes.right().value();
+ log.debug("Data type " + uniqueId + " cannot be found in graph. status is " + status);
+ return Either.right(status);
+ }
+
+ DataTypeData ctData = dataTypesRes.left().value();
+ DataTypeDefinition dataTypeDefinition = new DataTypeDefinition(ctData.getDataTypeDataDefinition());
+
+ TitanOperationStatus propertiesStatus = fillProperties(uniqueId, dataTypeDefinition);
+ if (propertiesStatus != TitanOperationStatus.OK) {
+ log.error("Failed to fetch properties of data type " + uniqueId);
+ return Either.right(propertiesStatus);
+ }
+
+ Either<ImmutablePair<DataTypeData, GraphEdge>, TitanOperationStatus> parentNode = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.DataType,
+ DataTypeData.class);
+ log.debug("After retrieving DERIVED_FROM node of " + uniqueId + ". status is " + parentNode);
+ if (parentNode.isRight()) {
+ TitanOperationStatus titanOperationStatus = parentNode.right().value();
+ if (titanOperationStatus != TitanOperationStatus.NOT_FOUND) {
+ log.error("Failed to find the parent data type of data type " + uniqueId + ". status is " + titanOperationStatus);
+ result = Either.right(titanOperationStatus);
+ return result;
+ }
+ } else {
+ // derived from node was found
+ ImmutablePair<DataTypeData, GraphEdge> immutablePair = parentNode.left().value();
+ DataTypeData parentCT = immutablePair.getKey();
+
+ String parentUniqueId = parentCT.getUniqueId();
+ Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = getDataTypeByUid(parentUniqueId);
+
+ if (dataTypeByUid.isRight()) {
+ return Either.right(dataTypeByUid.right().value());
+ }
+
+ DataTypeDefinition parentDataTypeDefinition = dataTypeByUid.left().value();
+
+ dataTypeDefinition.setDerivedFrom(parentDataTypeDefinition);
+
+ }
+ result = Either.left(dataTypeDefinition);
+
+ return result;
+ }
+
+ private TitanOperationStatus fillProperties(String uniqueId, DataTypeDefinition dataTypeDefinition) {
+
+ Either<Map<String, PropertyDefinition>, TitanOperationStatus> findPropertiesOfNode = this.findPropertiesOfNode(NodeTypeEnum.DataType, uniqueId);
+ if (findPropertiesOfNode.isRight()) {
+ TitanOperationStatus titanOperationStatus = findPropertiesOfNode.right().value();
+ log.debug("After looking for properties of vertex " + uniqueId + ". status is " + titanOperationStatus);
+ if (TitanOperationStatus.NOT_FOUND.equals(titanOperationStatus)) {
+ return TitanOperationStatus.OK;
+ } else {
+ return titanOperationStatus;
+ }
+ } else {
+ Map<String, PropertyDefinition> properties = findPropertiesOfNode.left().value();
+ if (properties != null && properties.isEmpty() == false) {
+ List<PropertyDefinition> listOfProps = new ArrayList<>();
+
+ for (Entry<String, PropertyDefinition> entry : properties.entrySet()) {
+ String propName = entry.getKey();
+ PropertyDefinition propertyDefinition = entry.getValue();
+ PropertyDefinition newPropertyDefinition = new PropertyDefinition(propertyDefinition);
+ newPropertyDefinition.setName(propName);
+ listOfProps.add(newPropertyDefinition);
+ }
+ dataTypeDefinition.setProperties(listOfProps);
+ }
+ return TitanOperationStatus.OK;
+ }
+ }
+
+ @Override
+ public Either<DataTypeDefinition, StorageOperationStatus> addDataType(DataTypeDefinition dataTypeDefinition, boolean inTransaction) {
+
+ Either<DataTypeDefinition, StorageOperationStatus> result = null;
+
+ try {
+
+ Either<DataTypeData, TitanOperationStatus> eitherStatus = addDataTypeToGraph(dataTypeDefinition);
+
+ if (eitherStatus.isRight()) {
+ log.debug("Failed to add data type {} to Graph. status is {}", dataTypeDefinition, eitherStatus.right().value().name());
+ BeEcompErrorManager.getInstance().logBeFailedAddingNodeTypeError("AddDataType", "DataType");
+ result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value()));
+ return result;
+ } else {
+ DataTypeData capabilityTypeData = eitherStatus.left().value();
+
+ DataTypeDefinition dataTypeDefResult = convertDTDataToDTDefinition(capabilityTypeData);
+ log.debug("The returned CapabilityTypeDefinition is " + dataTypeDefResult);
+ result = Either.left(dataTypeDefResult);
+ return result;
+ }
+ } finally {
+ if (false == inTransaction) {
+ if (result == null || result.isRight()) {
+ log.error("Going to execute rollback on graph.");
+ titanGenericDao.rollback();
+ } else {
+ log.debug("Going to execute commit on graph.");
+ titanGenericDao.commit();
+ }
+ }
+ }
+
+ }
+
+ @Override
+ public Either<DataTypeDefinition, StorageOperationStatus> addDataType(DataTypeDefinition dataTypeDefinition) {
+ return addDataType(dataTypeDefinition, true);
+ }
+
+ @Override
+ public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByName(String name, boolean inTransaction) {
+
+ Either<DataTypeDefinition, StorageOperationStatus> result = null;
+ try {
+
+ String dtUid = UniqueIdBuilder.buildDataTypeUid(name);
+ Either<DataTypeDefinition, TitanOperationStatus> ctResult = this.getDataTypeByUid(dtUid);
+
+ if (ctResult.isRight()) {
+ TitanOperationStatus status = ctResult.right().value();
+ if (status != TitanOperationStatus.NOT_FOUND) {
+ log.error("Failed to retrieve information on capability type " + name + "status is " + status);
+ }
+ result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(ctResult.right().value()));
+ return result;
+ }
+
+ result = Either.left(ctResult.left().value());
+
+ return result;
+ } finally {
+ if (false == inTransaction) {
+ if (result == null || result.isRight()) {
+ log.error("Going to execute rollback on graph.");
+ titanGenericDao.rollback();
+ } else {
+ log.debug("Going to execute commit on graph.");
+ titanGenericDao.commit();
+ }
+ }
+ }
+
+ }
+
+ @Override
+ public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByName(String name) {
+ return getDataTypeByName(name, true);
+ }
+
+ @Override
+ public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByNameWithoutDerived(String name) {
+ return getDataTypeByNameWithoutDerived(name, true);
+ }
+
+ @Override
+ public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByNameWithoutDerived(String name, boolean inTransaction) {
+
+ Either<DataTypeDefinition, StorageOperationStatus> result = null;
+ try {
+
+ String uid = UniqueIdBuilder.buildDataTypeUid(name);
+ Either<DataTypeDefinition, TitanOperationStatus> ctResult = this.getDataTypeByUidWithoutDerivedDataTypes(uid);
+
+ if (ctResult.isRight()) {
+ TitanOperationStatus status = ctResult.right().value();
+ if (status != TitanOperationStatus.NOT_FOUND) {
+ log.error("Failed to retrieve information on capability type " + name + "status is " + status);
+ }
+ result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(ctResult.right().value()));
+ return result;
+ }
+
+ result = Either.left(ctResult.left().value());
+
+ return result;
+ } finally {
+ if (false == inTransaction) {
+ if (result == null || result.isRight()) {
+ log.error("Going to execute rollback on graph.");
+ titanGenericDao.rollback();
+ } else {
+ log.debug("Going to execute commit on graph.");
+ titanGenericDao.commit();
+ }
+ }
+ }
+
+ }
+
+ public Either<DataTypeDefinition, TitanOperationStatus> getDataTypeByUidWithoutDerivedDataTypes(String uniqueId) {
+
+ Either<DataTypeData, TitanOperationStatus> dataTypesRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, DataTypeData.class);
+
+ if (dataTypesRes.isRight()) {
+ TitanOperationStatus status = dataTypesRes.right().value();
+ log.debug("Data type " + uniqueId + " cannot be found in graph. status is " + status);
+ return Either.right(status);
+ }
+
+ DataTypeData ctData = dataTypesRes.left().value();
+ DataTypeDefinition dataTypeDefinition = new DataTypeDefinition(ctData.getDataTypeDataDefinition());
+
+ TitanOperationStatus propertiesStatus = fillProperties(uniqueId, dataTypeDefinition);
+ if (propertiesStatus != TitanOperationStatus.OK) {
+ log.error("Failed to fetch properties of data type " + uniqueId);
+ return Either.right(propertiesStatus);
+ }
+
+ return Either.left(dataTypeDefinition);
+ }
+
+ public Either<DataTypeDefinition, TitanOperationStatus> getDataTypeByNameWithoutDerivedDataTypes(String name) {
+
+ String uid = UniqueIdBuilder.buildDataTypeUid(name);
+ return getDataTypeByUidWithoutDerivedDataTypes(uid);
+
+ }
+
+ /**
+ *
+ * convert between graph Node object to Java object
+ *
+ * @param dataTypeData
+ * @return
+ */
+ protected DataTypeDefinition convertDTDataToDTDefinition(DataTypeData dataTypeData) {
+ log.debug("The object returned after create data type is " + dataTypeData);
+
+ DataTypeDefinition dataTypeDefResult = new DataTypeDefinition(dataTypeData.getDataTypeDataDefinition());
+
+ return dataTypeDefResult;
+ }
+
+ private Either<Boolean, TitanOperationStatus> isValidPropertyType(String propertyType) {
+
+ if (propertyType == null || propertyType.isEmpty()) {
+ return Either.left(false);
+ }
+
+ ToscaPropertyType toscaPropertyType = ToscaPropertyType.isValidType(propertyType);
+ if (toscaPropertyType == null) {
+ Either<Boolean, TitanOperationStatus> definedInDataTypes = isDefinedInDataTypes(propertyType);
+ return definedInDataTypes;
+ } else {
+ return Either.left(true);
+ }
+ }
+
+ private Either<Boolean, TitanOperationStatus> isDefinedInDataTypes(String propertyType) {
+
+ String dataTypeUid = UniqueIdBuilder.buildDataTypeUid(propertyType);
+ Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = getDataTypeByUid(dataTypeUid);
+ if (dataTypeByUid.isRight()) {
+ TitanOperationStatus status = dataTypeByUid.right().value();
+ if (status == TitanOperationStatus.NOT_FOUND) {
+ return Either.left(false);
+ }
+ return Either.right(status);
+ }
+
+ return Either.left(true);
+
+ }
+
+ private Either<DataTypeDefinition, TitanOperationStatus> getExternalDataType(String propertyType) {
+
+ String dataTypeUid = UniqueIdBuilder.buildDataTypeUid(propertyType);
+ Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = getDataTypeByUid(dataTypeUid);
+ if (dataTypeByUid.isRight()) {
+ TitanOperationStatus status = dataTypeByUid.right().value();
+ return Either.right(status);
+ }
+
+ return Either.left(dataTypeByUid.left().value());
+
+ }
+
+ public Either<Map<String, DataTypeDefinition>, TitanOperationStatus> getAllDataTypes() {
+
+ Map<String, DataTypeDefinition> dataTypes = new HashMap<>();
+ Either<Map<String, DataTypeDefinition>, TitanOperationStatus> result = Either.left(dataTypes);
+
+ Either<List<DataTypeData>, TitanOperationStatus> getAllDataTypes = titanGenericDao.getByCriteria(NodeTypeEnum.DataType, null, DataTypeData.class);
+ if (getAllDataTypes.isRight()) {
+ TitanOperationStatus status = getAllDataTypes.right().value();
+ if (status != TitanOperationStatus.NOT_FOUND) {
+ return Either.right(status);
+ } else {
+ return result;
+ }
+ }
+
+ List<DataTypeData> list = getAllDataTypes.left().value();
+ if (list != null) {
+
+ log.trace("Number of data types to load is " + list.size());
+
+ List<String> collect = list.stream().map(p -> p.getDataTypeDataDefinition().getName()).collect(Collectors.toList());
+ log.trace("The data types to load are " + collect);
+
+ for (DataTypeData dataTypeData : list) {
+
+ log.trace("Going to fetch data type " + dataTypeData.getDataTypeDataDefinition().getName() + ". uid is " + dataTypeData.getUniqueId());
+ Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = this.getAndAddDataTypeByUid(dataTypeData.getUniqueId(), dataTypes);
+ if (dataTypeByUid.isRight()) {
+ TitanOperationStatus status = dataTypeByUid.right().value();
+ if (status == TitanOperationStatus.NOT_FOUND) {
+ status = TitanOperationStatus.INVALID_ID;
+ }
+ return Either.right(status);
+ }
+ }
+ }
+
+ if (log.isTraceEnabled()) {
+ if (result.isRight()) {
+ log.trace("After fetching all data types " + result);
+ } else {
+ Map<String, DataTypeDefinition> map = result.left().value();
+ if (map != null) {
+ String types = map.keySet().stream().collect(Collectors.joining(",", "[", "]"));
+ log.trace("After fetching all data types " + types);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Build Data type object from graph by unique id
+ *
+ * @param uniqueId
+ * @return
+ */
+ public Either<DataTypeDefinition, TitanOperationStatus> getAndAddDataTypeByUid(String uniqueId, Map<String, DataTypeDefinition> allDataTypes) {
+
+ Either<DataTypeDefinition, TitanOperationStatus> result = null;
+
+ if (allDataTypes.containsKey(uniqueId)) {
+ return Either.left(allDataTypes.get(uniqueId));
+ }
+
+ Either<DataTypeData, TitanOperationStatus> dataTypesRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, DataTypeData.class);
+
+ if (dataTypesRes.isRight()) {
+ TitanOperationStatus status = dataTypesRes.right().value();
+ log.debug("Data type " + uniqueId + " cannot be found in graph. status is " + status);
+ return Either.right(status);
+ }
+
+ DataTypeData ctData = dataTypesRes.left().value();
+ DataTypeDefinition dataTypeDefinition = new DataTypeDefinition(ctData.getDataTypeDataDefinition());
+
+ TitanOperationStatus propertiesStatus = fillProperties(uniqueId, dataTypeDefinition);
+ if (propertiesStatus != TitanOperationStatus.OK) {
+ log.error("Failed to fetch properties of data type " + uniqueId);
+ return Either.right(propertiesStatus);
+ }
+
+ allDataTypes.put(dataTypeDefinition.getName(), dataTypeDefinition);
+
+ String derivedFrom = dataTypeDefinition.getDerivedFromName();
+ if (allDataTypes.containsKey(derivedFrom)) {
+ DataTypeDefinition parentDataTypeDefinition = allDataTypes.get(derivedFrom);
+
+ dataTypeDefinition.setDerivedFrom(parentDataTypeDefinition);
+
+ return Either.left(dataTypeDefinition);
+ }
+
+ Either<ImmutablePair<DataTypeData, GraphEdge>, TitanOperationStatus> parentNode = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.DataType,
+ DataTypeData.class);
+ log.debug("After retrieving DERIVED_FROM node of " + uniqueId + ". status is " + parentNode);
+ if (parentNode.isRight()) {
+ TitanOperationStatus titanOperationStatus = parentNode.right().value();
+ if (titanOperationStatus != TitanOperationStatus.NOT_FOUND) {
+ log.error("Failed to find the parent data type of data type " + uniqueId + ". status is " + titanOperationStatus);
+ result = Either.right(titanOperationStatus);
+ return result;
+ }
+ } else {
+ // derived from node was found
+ ImmutablePair<DataTypeData, GraphEdge> immutablePair = parentNode.left().value();
+ DataTypeData parentCT = immutablePair.getKey();
+
+ String parentUniqueId = parentCT.getUniqueId();
+ Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = getDataTypeByUid(parentUniqueId);
+
+ if (dataTypeByUid.isRight()) {
+ return Either.right(dataTypeByUid.right().value());
+ }
+
+ DataTypeDefinition parentDataTypeDefinition = dataTypeByUid.left().value();
+
+ dataTypeDefinition.setDerivedFrom(parentDataTypeDefinition);
+
+ }
+ result = Either.left(dataTypeDefinition);
+
+ return result;
+ }
+
+ public Either<DataTypeDefinition, TitanOperationStatus> getDataTypeUsingName(String name) {
+
+ String uid = UniqueIdBuilder.buildDataTypeUid(name);
+
+ Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = getDataTypeByUid(uid);
+
+ return dataTypeByUid;
+ }
+
+ public Either<String, TitanOperationStatus> checkInnerType(PropertyDataDefinition propDataDef) {
+
+ String propertyType = propDataDef.getType();
+
+ ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
+
+ Either<String, TitanOperationStatus> result = getInnerType(type, () -> propDataDef.getSchema());
+
+ return result;
+ }
+
+ public Either<List<DataTypeData>, TitanOperationStatus> getAllDataTypeNodes() {
+ Either<List<DataTypeData>, TitanOperationStatus> getAllDataTypes = titanGenericDao.getByCriteria(NodeTypeEnum.DataType, null, DataTypeData.class);
+ if (getAllDataTypes.isRight()) {
+ TitanOperationStatus status = getAllDataTypes.right().value();
+ if (status == TitanOperationStatus.NOT_FOUND) {
+ status = TitanOperationStatus.OK;
+ return Either.right(status);
+ }
+ }
+ return getAllDataTypes;
+ }
+
+ public Either<Object, Boolean> validateAndUpdatePropertyValue(String propertyType, String value, boolean isValidate, String innerType, Map<String, DataTypeDefinition> dataTypes) {
+ log.trace("Going to validate property value and its type. type = {}, value = {}", propertyType, value);
+ ToscaPropertyType type = getType(propertyType);
+
+ if (isValidate) {
+
+ if (type == null) {
+ DataTypeDefinition dataTypeDefinition = dataTypes.get(propertyType);
+ ImmutablePair<JsonElement, Boolean> validateResult = dataTypeValidatorConverter.validateAndUpdate(value, dataTypeDefinition, dataTypes);
+ if (validateResult.right.booleanValue() == false) {
+ log.debug("The value {} of property from type {} is invalid", value, propertyType);
+ return Either.right(false);
+ }
+ JsonElement jsonElement = validateResult.left;
+ String valueFromJsonElement = getValueFromJsonElement(jsonElement);
+ return Either.left(valueFromJsonElement);
+ }
+ log.trace("before validating property type {}", propertyType);
+ boolean isValidProperty = isValidValue(type, value, innerType, dataTypes);
+ if (false == isValidProperty) {
+ log.debug("The value {} of property from type {} is invalid", value, type);
+ return Either.right(false);
+ }
+ }
+ Object convertedValue = value;
+ if (false == isEmptyValue(value) && isValidate) {
+ PropertyValueConverter converter = type.getConverter();
+ convertedValue = converter.convert(value, innerType, dataTypes);
+ }
+ return Either.left(convertedValue);
+ }
+
+ public Either<Object, Boolean> validateAndUpdatePropertyValue(String propertyType, String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
+ return validateAndUpdatePropertyValue(propertyType, value, true, innerType, dataTypes);
+ }
+
+ /*
+ * @Override public PropertyOperation getPropertyOperation() { return this; }
+ */
+ protected TitanOperationStatus fillProperties(String uniqueId, Consumer<List<PropertyDefinition>> propertySetter) {
+ Either<Map<String, PropertyDefinition>, TitanOperationStatus> findPropertiesOfNode = this.findPropertiesOfNode(NodeTypeEnum.GroupType, uniqueId);
+ if (findPropertiesOfNode.isRight()) {
+ TitanOperationStatus titanOperationStatus = findPropertiesOfNode.right().value();
+ log.debug("After looking for properties of vertex " + uniqueId + ". status is " + titanOperationStatus);
+ if (TitanOperationStatus.NOT_FOUND.equals(titanOperationStatus)) {
+ return TitanOperationStatus.OK;
+ } else {
+ return titanOperationStatus;
+ }
+ } else {
+ Map<String, PropertyDefinition> properties = findPropertiesOfNode.left().value();
+
+ if (properties != null) {
+ List<PropertyDefinition> propertiesAsList = properties.entrySet().stream().map(p -> p.getValue()).collect(Collectors.toList());
+ propertySetter.accept(propertiesAsList);
+ }
+
+ return TitanOperationStatus.OK;
+ }
+ }
+
+ /**
+ * add properties to element type.
+ *
+ * Per property, add a property node and associate it to the element type
+ *
+ * @param uniqueId
+ * @param propertiesMap
+ * TODO
+ * @return
+ */
+ protected Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToElementType(String uniqueId, NodeTypeEnum nodeType, Map<String, PropertyDefinition> propertiesMap) {
+
+ Map<String, PropertyData> propertiesData = new HashMap<String, PropertyData>();
+
+ if (propertiesMap != null) {
+
+ for (Entry<String, PropertyDefinition> propertyDefinitionEntry : propertiesMap.entrySet()) {
+ String propertyName = propertyDefinitionEntry.getKey();
+
+ Either<PropertyData, TitanOperationStatus> addPropertyToNodeType = this.addPropertyToNodeType(propertyName, propertyDefinitionEntry.getValue(), nodeType, uniqueId);
+
+ if (addPropertyToNodeType.isRight()) {
+ TitanOperationStatus operationStatus = addPropertyToNodeType.right().value();
+ log.error("Failed to associate " + nodeType.getName() + " " + uniqueId + " to property " + propertyName + " in graph. status is " + operationStatus);
+ return Either.right(operationStatus);
+ }
+ propertiesData.put(propertyName, addPropertyToNodeType.left().value());
+
+ }
+ }
+
+ return Either.left(propertiesData);
+
+ }
+
+ protected TitanOperationStatus addPropertiesToElementType(String uniqueId, NodeTypeEnum nodeType, Map<String, PropertyDefinition> propertiesMap, TitanVertex elementVertex) {
+
+ if (propertiesMap != null) {
+
+ for (Entry<String, PropertyDefinition> propertyDefinitionEntry : propertiesMap.entrySet()) {
+ String propertyName = propertyDefinitionEntry.getKey();
+
+ TitanOperationStatus operationStatus = this.addPropertyToNodeType(elementVertex, propertyName, propertyDefinitionEntry.getValue(), nodeType, uniqueId);
+
+ if (!operationStatus.equals(TitanOperationStatus.OK)) {
+ log.error("Failed to associate {} {} to property {} in graph. status is {}", nodeType.getName(), uniqueId, propertyName, operationStatus);
+ return operationStatus;
+ }
+ }
+ }
+
+ return TitanOperationStatus.OK;
+
+ }
+
+ public Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToElementType(String uniqueId, NodeTypeEnum elementType, List<PropertyDefinition> properties) {
+
+ Map<String, PropertyDefinition> propMap;
+ if (properties == null) {
+ propMap = null;
+ } else {
+ propMap = properties.stream().collect(Collectors.toMap(propDef -> propDef.getName(), propDef -> propDef));
+ }
+ return addPropertiesToElementType(uniqueId, elementType, propMap);
+ }
+
+ public TitanOperationStatus addPropertiesToElementType(TitanVertex elementVertex, String uniqueId, NodeTypeEnum elementType, List<PropertyDefinition> properties) {
+
+ Map<String, PropertyDefinition> propMap;
+ if (properties == null) {
+ propMap = null;
+ } else {
+ propMap = properties.stream().collect(Collectors.toMap(propDef -> propDef.getName(), propDef -> propDef));
+ }
+ return addPropertiesToElementType(uniqueId, elementType, propMap, elementVertex);
+ }
+
+ @Override
+ public Either<DataTypeDefinition, StorageOperationStatus> updateDataType(DataTypeDefinition newDataTypeDefinition, DataTypeDefinition oldDataTypeDefinition) {
+ return updateDataType(newDataTypeDefinition, oldDataTypeDefinition, true);
+ }
+
+ @Override
+ public Either<DataTypeDefinition, StorageOperationStatus> updateDataType(DataTypeDefinition newDataTypeDefinition, DataTypeDefinition oldDataTypeDefinition, boolean inTransaction) {
+
+ Either<DataTypeDefinition, StorageOperationStatus> result = null;
+
+ try {
+
+ List<PropertyDefinition> newProperties = newDataTypeDefinition.getProperties();
+
+ List<PropertyDefinition> oldProperties = oldDataTypeDefinition.getProperties();
+
+ String newDerivedFromName = getDerivedFromName(newDataTypeDefinition);
+
+ String oldDerivedFromName = getDerivedFromName(oldDataTypeDefinition);
+
+ String dataTypeName = newDataTypeDefinition.getName();
+
+ List<PropertyDefinition> propertiesToAdd = new ArrayList<>();
+ if (isPropertyOmitted(newProperties, oldProperties, dataTypeName) || isPropertyTypeChanged(dataTypeName, newProperties, oldProperties, propertiesToAdd) || isDerivedFromNameChanged(dataTypeName, newDerivedFromName, oldDerivedFromName)) {
+
+ log.debug("The new data type " + dataTypeName + " is invalid.");
+
+ result = Either.right(StorageOperationStatus.CANNOT_UPDATE_EXISTING_ENTITY);
+ return result;
+ }
+
+ if (propertiesToAdd == null || propertiesToAdd.isEmpty()) {
+ log.debug("No new properties has been defined in the new data type " + newDataTypeDefinition);
+ result = Either.right(StorageOperationStatus.OK);
+ return result;
+ }
+
+ Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToDataType = addPropertiesToDataType(oldDataTypeDefinition.getUniqueId(), propertiesToAdd);
+
+ if (addPropertiesToDataType.isRight()) {
+ log.debug("Failed to update data type {} to Graph. Status is {}", oldDataTypeDefinition, addPropertiesToDataType.right().value().name());
+ BeEcompErrorManager.getInstance().logBeFailedAddingNodeTypeError("UpdateDataType", "Property");
+ result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(addPropertiesToDataType.right().value()));
+ return result;
+ } else {
+
+ Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = this.getDataTypeByUid(oldDataTypeDefinition.getUniqueId());
+ if (dataTypeByUid.isRight()) {
+ TitanOperationStatus status = addPropertiesToDataType.right().value();
+ log.debug("Failed to get data type {} after update. Status is {}", oldDataTypeDefinition.getUniqueId(), status.name());
+ BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("UpdateDataType", "Property", status.name());
+ result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+ } else {
+ result = Either.left(dataTypeByUid.left().value());
+ }
+ }
+
+ return result;
+
+ } finally {
+ if (false == inTransaction) {
+ if (result == null || result.isRight()) {
+ log.error("Going to execute rollback on graph.");
+ titanGenericDao.rollback();
+ } else {
+ log.debug("Going to execute commit on graph.");
+ titanGenericDao.commit();
+ }
+ }
+ }
+
+ }
+
+ private String getDerivedFromName(DataTypeDefinition dataTypeDefinition) {
+ String derivedFromName = dataTypeDefinition.getDerivedFromName();
+ // if (derivedFromName == null) {
+ // DataTypeDefinition derivedFrom = dataTypeDefinition.getDerivedFrom();
+ // if (derivedFrom != null) {
+ // log.debug("Dervied from is taken from definition");
+ // derivedFromName = derivedFrom.getName();
+ // }
+ // } else {
+ // log.debug("Dervied from is taken from field derivedFromName");
+ // }
+ return derivedFromName;
+ }
+
+ private boolean isPropertyTypeChanged(String dataTypeName, List<PropertyDefinition> newProperties, List<PropertyDefinition> oldProperties, List<PropertyDefinition> outputPropertiesToAdd) {
+
+ if (newProperties != null && oldProperties != null) {
+
+ Map<String, PropertyDefinition> newPropsMapper = newProperties.stream().collect(Collectors.toMap(p -> p.getName(), p -> p));
+ Map<String, PropertyDefinition> oldPropsMapper = oldProperties.stream().collect(Collectors.toMap(p -> p.getName(), p -> p));
+
+ for (Entry<String, PropertyDefinition> newPropertyEntry : newPropsMapper.entrySet()) {
+
+ String propName = newPropertyEntry.getKey();
+ PropertyDefinition propDef = newPropertyEntry.getValue();
+
+ PropertyDefinition oldPropertyDefinition = oldPropsMapper.get(propName);
+ if (oldPropertyDefinition == null) {
+ log.debug("New property {} received in the data type {}", propName, dataTypeName);
+ outputPropertiesToAdd.add(propDef);
+ continue;
+ }
+
+ String oldType = oldPropertyDefinition.getType();
+ String oldEntryType = getEntryType(oldPropertyDefinition);
+
+ String newType = propDef.getType();
+ String newEntryType = getEntryType(propDef);
+
+ if (false == oldType.equals(newType)) {
+ log.debug("Existing property {} in data type {} has a differnet type {} than the new one {}", propName, dataTypeName, oldType, newType);
+ return true;
+ }
+
+ if (false == equalsEntryTypes(oldEntryType, newEntryType)) {
+ log.debug("Existing property {} in data type {} has a differnet entry type {} than the new one {}", propName, dataTypeName, oldEntryType, newEntryType);
+ return true;
+ }
+
+ }
+
+ }
+
+ return false;
+ }
+
+ private boolean equalsEntryTypes(String oldEntryType, String newEntryType) {
+
+ if (oldEntryType == null && newEntryType == null) {
+ return true;
+ } else if (oldEntryType != null && newEntryType != null) {
+ return oldEntryType.equals(newEntryType);
+ } else {
+ return false;
+ }
+ }
+
+ private String getEntryType(PropertyDefinition oldPropertyDefinition) {
+ String entryType = null;
+ SchemaDefinition schema = oldPropertyDefinition.getSchema();
+ if (schema != null) {
+ PropertyDataDefinition schemaProperty = schema.getProperty();
+ if (schemaProperty != null) {
+ entryType = schemaProperty.getType();
+ }
+ }
+ return entryType;
+ }
+
+ private boolean isPropertyOmitted(List<PropertyDefinition> newProperties, List<PropertyDefinition> oldProperties, String dataTypeName) {
+
+ boolean isValid = validateChangeInCaseOfEmptyProperties(newProperties, oldProperties, dataTypeName);
+ if (false == isValid) {
+ log.debug("At least one property is missing in the new data type {}", dataTypeName);
+ return false;
+ }
+
+ if (newProperties != null && oldProperties != null) {
+
+ List<String> newProps = newProperties.stream().map(p -> p.getName()).collect(Collectors.toList());
+ List<String> oldProps = oldProperties.stream().map(p -> p.getName()).collect(Collectors.toList());
+
+ if (false == newProps.containsAll(oldProps)) {
+ StringJoiner joiner = new StringJoiner(",", "[", "]");
+ newProps.forEach(p -> joiner.add(p));
+ log.debug("Properties {} in data type {} are missing, but they already defined in the existing data type", joiner.toString(), dataTypeName);
+ return true;
+ }
+
+ }
+ return false;
+ }
+
+ private boolean validateChangeInCaseOfEmptyProperties(List<PropertyDefinition> newProperties, List<PropertyDefinition> oldProperties, String dataTypeName) {
+
+ if (newProperties != null) {
+ if (newProperties.isEmpty()) {
+ newProperties = null;
+ }
+ }
+
+ if (oldProperties != null) {
+ if (oldProperties.isEmpty()) {
+ oldProperties = null;
+ }
+ }
+
+ if ((newProperties == null && oldProperties == null) || (newProperties != null && oldProperties != null)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ private boolean isDerivedFromNameChanged(String dataTypeName, String newDerivedFromName, String oldDerivedFromName) {
+
+ if (newDerivedFromName != null) {
+ boolean isEqual = newDerivedFromName.equals(oldDerivedFromName);
+ if (false == isEqual) {
+ log.debug("The new datatype {} derived from another data type {} than the existing one {}", dataTypeName, newDerivedFromName, oldDerivedFromName);
+ }
+ return !isEqual;
+ } else if (oldDerivedFromName == null) {
+ return false;
+ } else {// new=null, old != null
+ log.debug("The new datatype {} derived from another data type {} than the existing one {}", dataTypeName, newDerivedFromName, oldDerivedFromName);
+ return true;
+ }
+
+ }
+
+ /**
+ *
+ * Future - unfinished
+ *
+ * @param type
+ * @param value
+ * @return
+ */
+ public boolean isValueToscaFunction(String type, String value) {
+
+ boolean result = false;
+
+ if (ToscaPropertyType.STRING.getType().equals(type) || isScalarDerivedFromString(type)) {
+
+ }
+
+ String[] functions = { "get_input" };
+
+ if (value != null) {
+
+ for (String function : functions) {
+
+ }
+
+ }
+
+ return result;
+
+ }
+
+ /**
+ * Future - unfinished
+ *
+ * @param type
+ * @return
+ */
+ private boolean isScalarDerivedFromString(String type) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+}