2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.sdc.be.model.operations.impl;
23 import com.fasterxml.jackson.core.ObjectCodec;
24 import com.fasterxml.jackson.databind.DeserializationContext;
25 import com.fasterxml.jackson.databind.JsonNode;
26 import com.google.gson.JsonArray;
27 import com.google.gson.JsonDeserializationContext;
28 import com.google.gson.JsonDeserializer;
29 import com.google.gson.JsonElement;
30 import com.google.gson.JsonObject;
31 import com.google.gson.JsonParseException;
32 import com.google.gson.JsonParser;
33 import com.google.gson.JsonSerializationContext;
34 import com.google.gson.JsonSerializer;
35 import com.thinkaurelius.titan.core.TitanVertex;
36 import fj.data.Either;
37 import org.apache.commons.collections.CollectionUtils;
38 import org.apache.commons.lang3.tuple.ImmutablePair;
39 import org.apache.tinkerpop.gremlin.structure.Edge;
40 import org.openecomp.sdc.be.config.BeEcompErrorManager;
41 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
42 import org.openecomp.sdc.be.dao.graph.GraphElementFactory;
43 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
44 import org.openecomp.sdc.be.dao.graph.datatype.GraphElementTypeEnum;
45 import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
46 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
47 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
48 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
49 import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
50 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
51 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
52 import org.openecomp.sdc.be.datatypes.elements.PropertyRule;
53 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
54 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
55 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
56 import org.openecomp.sdc.be.model.DataTypeDefinition;
57 import org.openecomp.sdc.be.model.IComplexDefaultValue;
58 import org.openecomp.sdc.be.model.PropertyConstraint;
59 import org.openecomp.sdc.be.model.PropertyDefinition;
60 import org.openecomp.sdc.be.model.operations.api.DerivedFromOperation;
61 import org.openecomp.sdc.be.model.operations.api.IPropertyOperation;
62 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
63 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
64 import org.openecomp.sdc.be.model.tosca.constraints.ConstraintType;
65 import org.openecomp.sdc.be.model.tosca.constraints.GreaterOrEqualConstraint;
66 import org.openecomp.sdc.be.model.tosca.constraints.GreaterThanConstraint;
67 import org.openecomp.sdc.be.model.tosca.constraints.InRangeConstraint;
68 import org.openecomp.sdc.be.model.tosca.constraints.LessOrEqualConstraint;
69 import org.openecomp.sdc.be.model.tosca.constraints.LessThanConstraint;
70 import org.openecomp.sdc.be.model.tosca.constraints.MinLengthConstraint;
71 import org.openecomp.sdc.be.model.tosca.constraints.ValidValuesConstraint;
72 import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter;
73 import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator;
74 import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
75 import org.openecomp.sdc.be.resources.data.DataTypeData;
76 import org.openecomp.sdc.be.resources.data.PropertyData;
77 import org.openecomp.sdc.be.resources.data.PropertyValueData;
78 import org.openecomp.sdc.be.resources.data.ResourceMetadataData;
79 import org.openecomp.sdc.be.resources.data.UniqueIdData;
80 import org.slf4j.Logger;
81 import org.slf4j.LoggerFactory;
82 import org.springframework.stereotype.Component;
84 import java.io.IOException;
85 import java.lang.reflect.Type;
86 import java.util.ArrayList;
87 import java.util.Collection;
88 import java.util.Collections;
89 import java.util.HashMap;
90 import java.util.Iterator;
91 import java.util.List;
93 import java.util.Map.Entry;
95 import java.util.StringJoiner;
96 import java.util.function.Consumer;
97 import java.util.regex.Matcher;
98 import java.util.regex.Pattern;
99 import java.util.stream.Collectors;
101 @Component("property-operation")
102 public class PropertyOperation extends AbstractOperation implements IPropertyOperation {
104 private TitanGenericDao titanGenericDao;
105 private DerivedFromOperation derivedFromOperation;
107 public static void main(String[] args) {
109 List<Pattern> buildFunctionPatterns = buildFunctionPatterns();
111 for (Pattern pattern : buildFunctionPatterns) {
113 String[] strs = { "str_replace", "{ str_replace:", " {str_replace:", " { str_replace:", "{str_replace:" };
114 for (String str : strs) {
115 Matcher m = pattern.matcher(str);
116 System.out.println(pattern.pattern() + " " + str + " " + m.find());
122 public PropertyOperation(TitanGenericDao titanGenericDao, DerivedFromOperation derivedFromOperation) {
123 this.titanGenericDao = titanGenericDao;
124 this.derivedFromOperation = derivedFromOperation;
127 private static Logger log = LoggerFactory.getLogger(PropertyOperation.class.getName());
129 private static List<Pattern> functionPatterns = null;
133 functionPatterns = buildFunctionPatterns();
137 * The value of functions is in a json format. Build pattern for each function name
139 * { str_replace: .... } {str_replace: .... } {str_replace: .... } { str_replace: .... }
143 private static List<Pattern> buildFunctionPatterns() {
145 List<Pattern> functionPatterns = new ArrayList<>();
147 String[] functions = { "get_input", "get_property" };
149 for (String function : functions) {
150 Pattern pattern = Pattern.compile("^[ ]*\\{[ ]*" + function + ":");
151 functionPatterns.add(pattern);
154 return functionPatterns;
160 * @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)
163 * @Override public Either<PropertyDefinition, StorageOperationStatus> addPropertyToResource( String propertyName, PropertyDefinition propertyDefinition, NodeTypeEnum nodeType, String resourceId) {
165 * StorageOperationStatus isValidProperty = isTypeExistsAndValid(propertyDefinition); if (isValidProperty != StorageOperationStatus.OK) { return Either.right(isValidProperty); }
167 * Either<PropertyData, TitanOperationStatus> status = addPropertyToGraph(propertyName, propertyDefinition, resourceId);
169 * if (status.isRight()) { titanGenericDao.rollback();
170 * log.error("Failed to add property {} to resource {}, propertyName, resourceId);
171 * return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status. right().value())); } else
172 * { titanGenericDao.commit(); PropertyData propertyData = status.left().value();
174 * PropertyDefinition propertyDefResult = convertPropertyDataToPropertyDefinition(propertyData, propertyName, resourceId); log.debug("The returned PropertyDefintion is " + propertyDefinition); return Either.left(propertyDefResult); }
179 private StorageOperationStatus isTypeExistsAndValid(PropertyDefinition propertyDefinition) {
181 ToscaPropertyType type = ToscaPropertyType.isValidType(propertyDefinition.getType());
184 return StorageOperationStatus.INVALID_TYPE;
187 String propertyType = propertyDefinition.getType();
188 String innerType = null;
189 String value = propertyDefinition.getDefaultValue();
191 if (propertyType.equals(ToscaPropertyType.LIST) || propertyType.equals(ToscaPropertyType.MAP)) {
192 SchemaDefinition schema;
193 if ((schema = propertyDefinition.getSchema()) != null) {
194 PropertyDataDefinition property;
195 if ((property = schema.getProperty()) != null) {
196 innerType = property.getType();
202 PropertyTypeValidator validator = type.getValidator();
204 if (value == null || (EMPTY_VALUE != null && EMPTY_VALUE.equals(propertyDefinition.getDefaultValue()))) {
205 return StorageOperationStatus.OK;
207 boolean isValid = validator.isValid(value, innerType, null);
208 if (true == isValid) {
209 return StorageOperationStatus.OK;
211 return StorageOperationStatus.INVALID_VALUE;
217 public PropertyDefinition convertPropertyDataToPropertyDefinition(PropertyData propertyDataResult, String propertyName, String resourceId) {
218 log.debug("The object returned after create property is {}", propertyDataResult);
220 PropertyDefinition propertyDefResult = new PropertyDefinition(propertyDataResult.getPropertyDataDefinition());
221 propertyDefResult.setConstraints(convertConstraints(propertyDataResult.getConstraints()));
222 propertyDefResult.setName(propertyName);
223 // propertyDefResult.setParentUniqueId(resourceId);
225 return propertyDefResult;
228 public static class PropertyConstraintSerialiser implements JsonSerializer<PropertyConstraint> {
231 public JsonElement serialize(PropertyConstraint src, Type typeOfSrc, JsonSerializationContext context) {
232 JsonParser parser = new JsonParser();
233 JsonObject result = new JsonObject();
234 JsonArray jsonArray = new JsonArray();
235 if (src instanceof InRangeConstraint) {
236 InRangeConstraint rangeConstraint = (InRangeConstraint) src;
237 jsonArray.add(parser.parse(rangeConstraint.getRangeMinValue()));
238 jsonArray.add(parser.parse(rangeConstraint.getRangeMaxValue()));
239 result.add("inRange", jsonArray);
240 } else if (src instanceof GreaterThanConstraint) {
241 GreaterThanConstraint greaterThanConstraint = (GreaterThanConstraint) src;
242 jsonArray.add(parser.parse(greaterThanConstraint.getGreaterThan()));
243 result.add("greaterThan", jsonArray);
244 } else if (src instanceof LessOrEqualConstraint) {
245 LessOrEqualConstraint lessOrEqualConstraint = (LessOrEqualConstraint) src;
246 jsonArray.add(parser.parse(lessOrEqualConstraint.getLessOrEqual()));
247 result.add("lessOrEqual", jsonArray);
249 log.warn("PropertyConstraint {} is not supported. Ignored.", src.getClass().getName());
257 public static class PropertyConstraintDeserialiser implements JsonDeserializer<PropertyConstraint> {
260 public PropertyConstraint deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
262 PropertyConstraint propertyConstraint = null;
264 Set<Entry<String, JsonElement>> set = json.getAsJsonObject().entrySet();
266 if (set.size() == 1) {
267 Entry<String, JsonElement> element = set.iterator().next();
268 String key = element.getKey();
269 JsonElement value = element.getValue();
271 ConstraintType constraintType = ConstraintType.getByType(key);
272 if (constraintType == null) {
273 log.warn("ConstraintType was not found for constraint name:{}", key);
275 switch (constraintType) {
279 if (value instanceof JsonArray) {
280 JsonArray rangeArray = (JsonArray) value;
281 if (rangeArray.size() != 2) {
282 log.error("The range constraint content is invalid. value = {}", value);
284 InRangeConstraint rangeConstraint = new InRangeConstraint();
285 String minValue = rangeArray.get(0).getAsString();
286 String maxValue = rangeArray.get(1).getAsString();
287 rangeConstraint.setRangeMinValue(minValue);
288 rangeConstraint.setRangeMaxValue(maxValue);
289 propertyConstraint = rangeConstraint;
294 log.warn("The value of GreaterThanConstraint is null");
299 String asString = value.getAsString();
300 log.debug("Before adding value to GreaterThanConstraint object. value = {}", asString);
301 propertyConstraint = new GreaterThanConstraint(asString);
304 log.warn("The value of GreaterThanConstraint is null");
310 String asString = value.getAsString();
311 log.debug("Before adding value to LessThanConstraint object. value = {}", asString);
312 propertyConstraint = new LessThanConstraint(asString);
315 log.warn("The value of LessThanConstraint is null");
318 case GREATER_OR_EQUAL:
320 String asString = value.getAsString();
321 log.debug("Before adding value to GreaterThanConstraint object. value = {}", asString);
322 propertyConstraint = new GreaterOrEqualConstraint(asString);
325 log.warn("The value of GreaterOrEqualConstraint is null");
331 String asString = value.getAsString();
332 log.debug("Before adding value to LessOrEqualConstraint object. value = {}", asString);
333 propertyConstraint = new LessOrEqualConstraint(asString);
335 log.warn("The value of GreaterThanConstraint is null");
342 if (value instanceof JsonArray) {
343 JsonArray rangeArray = (JsonArray) value;
344 if (rangeArray.size() == 0) {
345 log.error("The valid values constraint content is invalid. value = {}", value);
347 ValidValuesConstraint vvConstraint = new ValidValuesConstraint();
348 List<String> validValues = new ArrayList<String>();
349 for (JsonElement jsonElement : rangeArray) {
350 String item = jsonElement.getAsString();
351 validValues.add(item);
353 vvConstraint.setValidValues(validValues);
354 propertyConstraint = vvConstraint;
359 log.warn("The value of ValidValuesConstraint is null");
365 int asInt = value.getAsInt();
366 log.debug("Before adding value to Min Length object. value = {}", asInt);
367 propertyConstraint = new MinLengthConstraint(asInt);
370 log.warn("The value of MinLengthConstraint is null");
374 log.warn("Key {} is not supported. Ignored.", key);
379 return propertyConstraint;
384 public TitanOperationStatus addPropertiesToGraph(Map<String, PropertyDefinition> properties, String resourceId, Map<String, DataTypeDefinition> dataTypes) {
386 ResourceMetadataData resourceData = new ResourceMetadataData();
387 resourceData.getMetadataDataDefinition().setUniqueId(resourceId);
389 if (properties != null) {
390 for (Entry<String, PropertyDefinition> entry : properties.entrySet()) {
392 String propertyName = entry.getKey();
393 PropertyDefinition propertyDefinition = entry.getValue();
395 StorageOperationStatus validateAndUpdateProperty = validateAndUpdateProperty(propertyDefinition, dataTypes);
396 if (validateAndUpdateProperty != StorageOperationStatus.OK) {
397 log.error("Property {} is invalid. Status is {}", propertyDefinition, validateAndUpdateProperty);
398 return TitanOperationStatus.ILLEGAL_ARGUMENT;
401 Either<PropertyData, TitanOperationStatus> addPropertyToGraph = addPropertyToGraph(propertyName, propertyDefinition, resourceId);
403 if (addPropertyToGraph.isRight()) {
404 return addPropertyToGraph.right().value();
409 return TitanOperationStatus.OK;
413 public TitanOperationStatus addPropertiesToGraph(TitanVertex metadataVertex, Map<String, PropertyDefinition> properties, Map<String, DataTypeDefinition> dataTypes, String resourceId) {
415 if (properties != null) {
416 for (Entry<String, PropertyDefinition> entry : properties.entrySet()) {
418 String propertyName = entry.getKey();
419 PropertyDefinition propertyDefinition = entry.getValue();
421 StorageOperationStatus validateAndUpdateProperty = validateAndUpdateProperty(propertyDefinition, dataTypes);
422 if (validateAndUpdateProperty != StorageOperationStatus.OK) {
423 log.error("Property {} is invalid. Status is {}", propertyDefinition, validateAndUpdateProperty);
424 return TitanOperationStatus.ILLEGAL_ARGUMENT;
427 TitanOperationStatus addPropertyToGraph = addPropertyToGraphByVertex(metadataVertex, propertyName, propertyDefinition, resourceId);
429 if (!addPropertyToGraph.equals(TitanOperationStatus.OK)) {
430 return addPropertyToGraph;
435 return TitanOperationStatus.OK;
439 public Either<PropertyData, StorageOperationStatus> addProperty(String propertyName, PropertyDefinition propertyDefinition, String resourceId) {
441 Either<PropertyData, TitanOperationStatus> either = addPropertyToGraph(propertyName, propertyDefinition, resourceId);
442 if (either.isRight()) {
443 StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value());
444 return Either.right(storageStatus);
446 return Either.left(either.left().value());
450 * @param propertyDefinition
454 public StorageOperationStatus validateAndUpdateProperty(IComplexDefaultValue propertyDefinition, Map<String, DataTypeDefinition> dataTypes) {
456 log.trace("Going to validate property type and value. {}", propertyDefinition);
458 String propertyType = propertyDefinition.getType();
459 String value = propertyDefinition.getDefaultValue();
461 ToscaPropertyType type = getType(propertyType);
465 DataTypeDefinition dataTypeDefinition = dataTypes.get(propertyType);
466 if (dataTypeDefinition == null) {
467 log.debug("The type {} of property cannot be found.", propertyType);
468 return StorageOperationStatus.INVALID_TYPE;
471 StorageOperationStatus status = validateAndUpdateComplexValue(propertyDefinition, propertyType, value, dataTypeDefinition, dataTypes);
476 String innerType = null;
478 Either<String, TitanOperationStatus> checkInnerType = getInnerType(type, () -> propertyDefinition.getSchema());
479 if (checkInnerType.isRight()) {
480 return StorageOperationStatus.INVALID_TYPE;
482 innerType = checkInnerType.left().value();
484 log.trace("After validating property type {}", propertyType);
486 boolean isValidProperty = isValidValue(type, value, innerType, dataTypes);
487 if (false == isValidProperty) {
488 log.info("The value {} of property from type {} is invalid", value, type);
489 return StorageOperationStatus.INVALID_VALUE;
492 PropertyValueConverter converter = type.getConverter();
494 if (isEmptyValue(value)) {
495 log.debug("Default value was not sent for property {}. Set default value to {}", propertyDefinition.getName(), EMPTY_VALUE);
496 propertyDefinition.setDefaultValue(EMPTY_VALUE);
497 } else if (false == isEmptyValue(value)) {
498 String convertedValue = converter.convert(value, innerType, dataTypes);
499 propertyDefinition.setDefaultValue(convertedValue);
501 return StorageOperationStatus.OK;
505 * public Either<Object, Boolean> validateAndUpdatePropertyValue(String propertyType, String value, String innerType) {
507 * log. trace("Going to validate property value and its type. type = {}, value = {}" ,propertyType, value);
509 * ToscaPropertyType type = getType(propertyType);
511 * if (type == null) {
513 * Either<DataTypeDefinition, TitanOperationStatus> externalDataType = getExternalDataType(propertyType); if (externalDataType.isRight()) { TitanOperationStatus status = externalDataType.right().value(); log.debug("The type " + propertyType +
514 * " 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); }
516 * DataTypeDefinition dataTypeDefinition = externalDataType.left().value();
518 * Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypesRes = getAllDataTypes(); if (allDataTypesRes.isRight()) { TitanOperationStatus status = allDataTypesRes.right().value(); return Either.right(false); }
520 * Map<String, DataTypeDefinition> allDataTypes = allDataTypesRes.left().value();
522 * ImmutablePair<JsonElement, Boolean> validateResult = dataTypeValidatorConverter.validateAndUpdate(value, dataTypeDefinition, allDataTypes);
524 * if (validateResult.right.booleanValue() == false) {
525 * log.debug("The value {} of property from type {} is invalid", value, propertyType);
526 * return Either.right(false); }
528 * JsonElement jsonElement = validateResult.left;
530 * String valueFromJsonElement = getValueFromJsonElement(jsonElement);
532 * return Either.left(valueFromJsonElement);
536 * log.trace("After validating property type {}", propertyType);
538 * boolean isValidProperty = isValidValue(type, value, innerType); if (false == isValidProperty) { log.debug("The value " + value + " of property from type " + type + " is invalid"); return Either.right(false); }
541 * Object convertedValue = value; if (false == isEmptyValue(value)) { PropertyValueConverter converter = type.getConverter(); convertedValue = converter.convert(value, null); }
543 * return Either.left(convertedValue); }
546 public Either<PropertyData, TitanOperationStatus> addPropertyToGraph(String propertyName, PropertyDefinition propertyDefinition, String resourceId) {
548 ResourceMetadataData resourceData = new ResourceMetadataData();
549 resourceData.getMetadataDataDefinition().setUniqueId(resourceId);
551 List<PropertyConstraint> constraints = propertyDefinition.getConstraints();
553 propertyDefinition.setUniqueId(UniqueIdBuilder.buildComponentPropertyUniqueId(resourceId, propertyName));
554 PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints));
556 log.debug("Before adding property to graph {}", propertyData);
557 Either<PropertyData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyData, PropertyData.class);
558 log.debug("After adding property to graph {}", propertyData);
559 if (createNodeResult.isRight()) {
560 TitanOperationStatus operationStatus = createNodeResult.right().value();
561 log.error("Failed to add property {} to graph. status is {}", propertyName, operationStatus);
562 return Either.right(operationStatus);
565 Map<String, Object> props = new HashMap<String, Object>();
566 props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName);
567 Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(resourceData, propertyData, GraphEdgeLabels.PROPERTY, props);
568 if (createRelResult.isRight()) {
569 TitanOperationStatus operationStatus = createNodeResult.right().value();
570 log.error("Failed to associate resource {} to property {} in graph. status is {}", resourceId, propertyName, operationStatus);
571 return Either.right(operationStatus);
574 return Either.left(createNodeResult.left().value());
578 public TitanOperationStatus addPropertyToGraphByVertex(TitanVertex metadataVertex, String propertyName, PropertyDefinition propertyDefinition, String resourceId) {
580 List<PropertyConstraint> constraints = propertyDefinition.getConstraints();
582 propertyDefinition.setUniqueId(UniqueIdBuilder.buildComponentPropertyUniqueId(resourceId, propertyName));
583 PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints));
585 log.debug("Before adding property to graph {}", propertyData);
586 Either<TitanVertex, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyData);
587 log.debug("After adding property to graph {}", propertyData);
588 if (createNodeResult.isRight()) {
589 TitanOperationStatus operationStatus = createNodeResult.right().value();
590 log.error("Failed to add property {} to graph. status is ", propertyName, operationStatus);
591 return operationStatus;
594 Map<String, Object> props = new HashMap<String, Object>();
595 props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName);
596 TitanVertex propertyVertex = createNodeResult.left().value();
597 TitanOperationStatus createRelResult = titanGenericDao.createEdge(metadataVertex, propertyVertex, GraphEdgeLabels.PROPERTY, props);
598 if (!createRelResult.equals(TitanOperationStatus.OK)) {
599 log.error("Failed to associate resource {} to property {} in graph. status is {}", resourceId, propertyName, createRelResult);
600 return createRelResult;
603 return createRelResult;
607 public TitanGenericDao getTitanGenericDao() {
608 return titanGenericDao;
611 // public Either<PropertyData, StorageOperationStatus>
612 // deletePropertyFromGraphFromBl(String propertyId) {
616 public Either<PropertyData, StorageOperationStatus> deleteProperty(String propertyId) {
617 Either<PropertyData, TitanOperationStatus> either = deletePropertyFromGraph(propertyId);
618 if (either.isRight()) {
619 StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value());
620 return Either.right(storageStatus);
622 return Either.left(either.left().value());
625 public Either<PropertyData, TitanOperationStatus> deletePropertyFromGraph(String propertyId) {
626 log.debug("Before deleting property from graph {}", propertyId);
627 return titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class);
630 public Either<PropertyData, StorageOperationStatus> updateProperty(String propertyId, PropertyDefinition newPropertyDefinition, Map<String, DataTypeDefinition> dataTypes) {
632 StorageOperationStatus validateAndUpdateProperty = validateAndUpdateProperty(newPropertyDefinition, dataTypes);
633 if (validateAndUpdateProperty != StorageOperationStatus.OK) {
634 return Either.right(validateAndUpdateProperty);
637 Either<PropertyData, TitanOperationStatus> either = updatePropertyFromGraph(propertyId, newPropertyDefinition);
638 if (either.isRight()) {
639 StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value());
640 return Either.right(storageStatus);
642 return Either.left(either.left().value());
645 public Either<PropertyData, TitanOperationStatus> updatePropertyFromGraph(String propertyId, PropertyDefinition propertyDefinition) {
646 if (log.isDebugEnabled())
647 log.debug("Before updating property on graph {}", propertyId);
649 // get the original property data
650 Either<PropertyData, TitanOperationStatus> statusProperty = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class);
651 if (statusProperty.isRight()) {
652 log.debug("Problem while get property with id {}. Reason - {}", propertyId, statusProperty.right().value().name());
653 return Either.right(statusProperty.right().value());
655 PropertyData orgPropertyData = statusProperty.left().value();
656 PropertyDataDefinition orgPropertyDataDefinition = orgPropertyData.getPropertyDataDefinition();
658 // create new property data to update
659 PropertyData newPropertyData = new PropertyData();
660 newPropertyData.setPropertyDataDefinition(propertyDefinition);
661 PropertyDataDefinition newPropertyDataDefinition = newPropertyData.getPropertyDataDefinition();
663 // update the original property data with new values
664 if (orgPropertyDataDefinition.getDefaultValue() == null) {
665 orgPropertyDataDefinition.setDefaultValue(newPropertyDataDefinition.getDefaultValue());
667 if (!orgPropertyDataDefinition.getDefaultValue().equals(newPropertyDataDefinition.getDefaultValue())) {
668 orgPropertyDataDefinition.setDefaultValue(newPropertyDataDefinition.getDefaultValue());
671 if (orgPropertyDataDefinition.getDescription() == null) {
672 orgPropertyDataDefinition.setDescription(newPropertyDataDefinition.getDescription());
674 if (!orgPropertyDataDefinition.getDescription().equals(newPropertyDataDefinition.getDescription())) {
675 orgPropertyDataDefinition.setDescription(newPropertyDataDefinition.getDescription());
678 if (!orgPropertyDataDefinition.getType().equals(newPropertyDataDefinition.getType())) {
679 orgPropertyDataDefinition.setType(newPropertyDataDefinition.getType());
681 if (newPropertyData.getConstraints() != null) {
682 orgPropertyData.setConstraints(newPropertyData.getConstraints());
684 orgPropertyDataDefinition.setSchema(newPropertyDataDefinition.getSchema());
686 return titanGenericDao.updateNode(orgPropertyData, PropertyData.class);
692 * @param titanGenericDao
694 public void setTitanGenericDao(TitanGenericDao titanGenericDao) {
695 this.titanGenericDao = titanGenericDao;
698 public Either<PropertyData, TitanOperationStatus> addPropertyToNodeType(String propertyName, PropertyDefinition propertyDefinition, NodeTypeEnum nodeType, String uniqueId) {
700 List<PropertyConstraint> constraints = propertyDefinition.getConstraints();
702 propertyDefinition.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(uniqueId, propertyName));
703 PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints));
705 if (log.isDebugEnabled())
706 log.debug("Before adding property to graph {}", propertyData);
707 Either<PropertyData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyData, PropertyData.class);
708 if (log.isDebugEnabled())
709 log.debug("After adding property to graph {}", propertyData);
710 if (createNodeResult.isRight()) {
711 TitanOperationStatus operationStatus = createNodeResult.right().value();
712 log.error("Failed to add property {} to graph. status is {}", propertyName, operationStatus);
713 return Either.right(operationStatus);
716 Map<String, Object> props = new HashMap<String, Object>();
717 props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName);
719 UniqueIdData uniqueIdData = new UniqueIdData(nodeType, uniqueId);
720 log.debug("Before associating {} to property {}", uniqueIdData, propertyName);
721 Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(uniqueIdData, propertyData, GraphEdgeLabels.PROPERTY, props);
722 if (createRelResult.isRight()) {
723 TitanOperationStatus operationStatus = createNodeResult.right().value();
724 log.error("Failed to associate resource {} to property {} in graph. status is {}", uniqueId, propertyName, operationStatus);
725 return Either.right(operationStatus);
728 return Either.left(createNodeResult.left().value());
732 public TitanOperationStatus addPropertyToNodeType(TitanVertex elementVertex, String propertyName, PropertyDefinition propertyDefinition, NodeTypeEnum nodeType, String uniqueId) {
734 List<PropertyConstraint> constraints = propertyDefinition.getConstraints();
736 propertyDefinition.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(uniqueId, propertyName));
737 PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints));
739 if (log.isDebugEnabled())
740 log.debug("Before adding property to graph {}", propertyData);
741 Either<TitanVertex, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyData);
742 if (log.isDebugEnabled())
743 log.debug("After adding property to graph {}", propertyData);
744 if (createNodeResult.isRight()) {
745 TitanOperationStatus operationStatus = createNodeResult.right().value();
746 log.error("Failed to add property {} to graph. status is {} ", propertyName, operationStatus);
747 return operationStatus;
750 Map<String, Object> props = new HashMap<String, Object>();
751 props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName);
753 TitanOperationStatus createRelResult = titanGenericDao.createEdge(elementVertex, propertyData, GraphEdgeLabels.PROPERTY, props);
754 if (!createRelResult.equals(TitanOperationStatus.OK)) {
755 log.error("Failed to associate resource {} to property {} in graph. status is {}", uniqueId, propertyName, createRelResult);
756 return createRelResult;
759 return createRelResult;
763 public Either<Map<String, PropertyDefinition>, TitanOperationStatus> findPropertiesOfNode(NodeTypeEnum nodeType, String uniqueId) {
765 Map<String, PropertyDefinition> resourceProps = new HashMap<String, PropertyDefinition>();
767 Either<List<ImmutablePair<PropertyData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.PROPERTY, NodeTypeEnum.Property,
770 if (childrenNodes.isRight()) {
771 TitanOperationStatus operationStatus = childrenNodes.right().value();
772 return Either.right(operationStatus);
775 List<ImmutablePair<PropertyData, GraphEdge>> values = childrenNodes.left().value();
776 if (values != null) {
778 for (ImmutablePair<PropertyData, GraphEdge> immutablePair : values) {
779 GraphEdge edge = immutablePair.getValue();
780 String propertyName = (String) edge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty());
781 log.debug("Property {} is associated to node {}", propertyName, uniqueId);
782 PropertyData propertyData = immutablePair.getKey();
783 PropertyDefinition propertyDefinition = this.convertPropertyDataToPropertyDefinition(propertyData, propertyName, uniqueId);
784 resourceProps.put(propertyName, propertyDefinition);
789 log.debug("The properties associated to node {} are {}", uniqueId, resourceProps);
790 return Either.left(resourceProps);
793 public Either<Map<String, PropertyDefinition>, StorageOperationStatus> deletePropertiesAssociatedToNode(NodeTypeEnum nodeType, String uniqueId) {
794 return deleteAllPropertiesAssociatedToNode(nodeType, uniqueId)
796 .bind(err -> err == StorageOperationStatus.OK ? Either.left(Collections.emptyMap()) : Either.right(err));
799 public Either<Map<String, PropertyDefinition>, StorageOperationStatus> deleteAllPropertiesAssociatedToNode(NodeTypeEnum nodeType, String uniqueId) {
801 Either<Map<String, PropertyDefinition>, TitanOperationStatus> propertiesOfNodeRes = findPropertiesOfNode(nodeType, uniqueId);
803 if (propertiesOfNodeRes.isRight()) {
804 TitanOperationStatus status = propertiesOfNodeRes.right().value();
805 if (status == TitanOperationStatus.NOT_FOUND) {
806 return Either.right(StorageOperationStatus.OK);
808 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
811 Map<String, PropertyDefinition> value = propertiesOfNodeRes.left().value();
812 for (PropertyDefinition propertyDefinition : value.values()) {
814 String propertyUid = propertyDefinition.getUniqueId();
815 Either<PropertyData, TitanOperationStatus> deletePropertyRes = deletePropertyFromGraph(propertyUid);
816 if (deletePropertyRes.isRight()) {
817 log.error("Failed to delete property with id {}", propertyUid);
818 TitanOperationStatus status = deletePropertyRes.right().value();
819 if (status == TitanOperationStatus.NOT_FOUND) {
820 status = TitanOperationStatus.INVALID_ID;
822 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
827 log.debug("The properties deleted from node {} are {}", uniqueId, value);
828 return Either.left(value);
839 protected TitanOperationStatus findPropertiesOfNode(NodeTypeEnum nodeType, String uniqueId, List<PropertyDefinition> properties) {
841 Either<List<ImmutablePair<PropertyData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.PROPERTY, NodeTypeEnum.Property,
844 if (childrenNodes.isRight()) {
845 TitanOperationStatus status = childrenNodes.right().value();
846 if (status == TitanOperationStatus.NOT_FOUND) {
847 status = TitanOperationStatus.OK;
852 List<ImmutablePair<PropertyData, GraphEdge>> values = childrenNodes.left().value();
853 if (values != null) {
855 for (ImmutablePair<PropertyData, GraphEdge> immutablePair : values) {
856 GraphEdge edge = immutablePair.getValue();
857 String propertyName = (String) edge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty());
858 if (log.isDebugEnabled())
859 log.debug("Property {} is associated to node {}", propertyName, uniqueId);
860 PropertyData propertyData = immutablePair.getKey();
861 PropertyDefinition propertyDefinition = this.convertPropertyDataToPropertyDefinition(propertyData, propertyName, uniqueId);
862 //Adds parent property to List if it hasn't been overrided in one of the children
863 if(!properties.stream().filter(p -> p.getName().equals(propertyDefinition.getName())).findAny().isPresent()){
864 properties.add(propertyDefinition);
867 if (log.isTraceEnabled())
868 log.trace("findPropertiesOfNode - property {} associated to node {}", propertyDefinition, uniqueId);
873 return TitanOperationStatus.OK;
876 * Checks existence of a property with the same name belonging to the same resource
877 * or existence of property with the same name and different type (including derived from hierarchy)
880 * @param propertyName
881 * @param propertyType
884 public boolean isPropertyExist(List<PropertyDefinition> properties, String resourceUid, String propertyName, String propertyType) {
885 boolean result = false;
886 if (!CollectionUtils.isEmpty(properties)) {
887 for (PropertyDefinition propertyDefinition : properties) {
889 if ( propertyDefinition.getName().equals(propertyName) &&
890 (propertyDefinition.getParentUniqueId().equals(resourceUid) || !propertyDefinition.getType().equals(propertyType)) ) {
900 * add property to resource instance
903 * TODO // * @param resourceInstanceProperty // * @param resourceInstanceId // * @param index
908 * public Either<PropertyValueData, TitanOperationStatus> addPropertyToResourceInstance( ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, Integer index) {
910 * Either<ComponentInstanceData, TitanOperationStatus> findResInstanceRes = titanGenericDao .getNode(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, ComponentInstanceData.class);
912 * if (findResInstanceRes.isRight()) { TitanOperationStatus status = findResInstanceRes.right().value(); if (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); }
914 * String propertyId = resourceInstanceProperty.getUniqueId(); Either<PropertyData, TitanOperationStatus> findPropertyDefRes = titanGenericDao .getNode(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class);
916 * if (findPropertyDefRes.isRight()) { TitanOperationStatus status = findPropertyDefRes.right().value(); if (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); }
918 * String valueUniqueUid = resourceInstanceProperty.getValueUniqueUid(); if (valueUniqueUid == null) {
920 * PropertyData propertyData = findPropertyDefRes.left().value(); ComponentInstanceData resourceInstanceData = findResInstanceRes.left().value();
922 * ImmutablePair<TitanOperationStatus, String> isPropertyValueExists = findPropertyValue(resourceInstanceId, propertyId); if (isPropertyValueExists.getLeft() == TitanOperationStatus.ALREADY_EXIST) { log.debug("The property " + propertyId +
923 * " already added to the resource instance " + resourceInstanceId); resourceInstanceProperty.setValueUniqueUid(isPropertyValueExists.getRight ()); Either<PropertyValueData, TitanOperationStatus> updatePropertyOfResourceInstance =
924 * updatePropertyOfResourceInstance(resourceInstanceProperty, resourceInstanceId); if (updatePropertyOfResourceInstance.isRight()) { BeEcompErrorManager.getInstance().logInternalFlowError( "UpdatePropertyValueOnComponentInstance",
925 * "Failed to update property value on instance. Status is " + updatePropertyOfResourceInstance.right().value(), ErrorSeverity.ERROR); return Either.right(updatePropertyOfResourceInstance.right().value()); } return
926 * Either.left(updatePropertyOfResourceInstance.left().value()); }
928 * if (isPropertyValueExists.getLeft() != TitanOperationStatus.NOT_FOUND) {
929 * log.debug("After finding property value of {} on componenet instance {}", propertyId, resourceInstanceId);
930 * return Either.right(isPropertyValueExists.getLeft()); }
932 * String propertyType = propertyData.getPropertyDataDefinition().getType(); String value = resourceInstanceProperty.getValue(); Either<Object, Boolean> isValid = validateAndUpdatePropertyValue(propertyType, value);
934 * 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) {
935 * newValue = object.toString(); } }
937 * String uniqueId = UniqueIdBuilder.buildResourceInstancePropertyValueUid( resourceInstanceData.getUniqueId(), index); PropertyValueData propertyValueData = new PropertyValueData(); propertyValueData.setUniqueId(uniqueId);
938 * propertyValueData.setValue(newValue);
940 * ImmutablePair<String, Boolean> pair = validateAndUpdateRules(propertyType, resourceInstanceProperty.getRules()); if (pair.getRight() != null && pair.getRight() == false) { BeEcompErrorManager.getInstance().
941 * logBeInvalidValueError("Add property value", pair.getLeft(), resourceInstanceProperty.getName(), propertyType); return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); } addRulesToNewPropertyValue(propertyValueData,
942 * resourceInstanceProperty, resourceInstanceId);
944 * log.debug("Before adding property value to graph {}", propertyValueData);
945 * Either<PropertyValueData, TitanOperationStatus> createNodeResult = titanGenericDao .createNode(propertyValueData, PropertyValueData.class);
946 * log.debug("After adding property value to graph {}", propertyValueData);
948 * Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao .createRelation(propertyValueData, propertyData, GraphEdgeLabels.PROPERTY_IMPL, null);
950 * if (createRelResult.isRight()) { TitanOperationStatus operationStatus = createNodeResult.right() .value(); //TODO: change logger log.error("Failed to associate property value " + uniqueId + " to property " + propertyId +
951 * " in graph. status is " + operationStatus); return Either.right(operationStatus); }
953 * createRelResult = titanGenericDao .createRelation(resourceInstanceData, propertyValueData, GraphEdgeLabels.PROPERTY_VALUE, null);
955 * if (createRelResult.isRight()) { TitanOperationStatus operationStatus = createNodeResult.right() .value(); //TODO: change logger log.error("Failed to associate resource instance " + resourceInstanceId + " property value " + uniqueId +
956 * " in graph. status is " + operationStatus); return Either.right(operationStatus); }
958 * return Either.left(createNodeResult.left().value()); } else { log.error("property value already exists."); return Either.right(TitanOperationStatus.ALREADY_EXIST); }
962 public ImmutablePair<String, Boolean> validateAndUpdateRules(String propertyType, List<PropertyRule> rules, String innerType, Map<String, DataTypeDefinition> dataTypes, boolean isValidate) {
964 if (rules == null || rules.isEmpty() == true) {
965 return new ImmutablePair<String, Boolean>(null, true);
968 for (PropertyRule rule : rules) {
969 String value = rule.getValue();
970 Either<Object, Boolean> updateResult = validateAndUpdatePropertyValue(propertyType, value, isValidate, innerType, dataTypes);
971 if (updateResult.isRight()) {
972 Boolean status = updateResult.right().value();
973 if (status == false) {
974 return new ImmutablePair<String, Boolean>(value, status);
977 String newValue = null;
978 Object object = updateResult.left().value();
979 if (object != null) {
980 newValue = object.toString();
982 rule.setValue(newValue);
986 return new ImmutablePair<String, Boolean>(null, true);
989 public void addRulesToNewPropertyValue(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId) {
991 List<PropertyRule> rules = resourceInstanceProperty.getRules();
993 PropertyRule propertyRule = buildRuleFromPath(propertyValueData, resourceInstanceProperty, resourceInstanceId);
994 rules = new ArrayList<>();
995 rules.add(propertyRule);
997 rules = sortRules(rules);
1000 propertyValueData.setRules(rules);
1003 private PropertyRule buildRuleFromPath(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId) {
1004 List<String> path = resourceInstanceProperty.getPath();
1005 // FOR BC. Since old Property values on VFC/VF does not have rules on
1007 // Update could be done on one level only, thus we can use this
1008 // operation to avoid migration.
1009 if (path == null || path.isEmpty() == true) {
1010 path = new ArrayList<>();
1011 path.add(resourceInstanceId);
1013 PropertyRule propertyRule = new PropertyRule();
1014 propertyRule.setRule(path);
1015 propertyRule.setValue(propertyValueData.getValue());
1016 return propertyRule;
1019 private List<PropertyRule> sortRules(List<PropertyRule> rules) {
1021 // TODO: sort the rules by size and binary representation.
1022 // (x, y, .+) --> 110 6 priority 1
1023 // (x, .+, z) --> 101 5 priority 2
1028 public ImmutablePair<TitanOperationStatus, String> findPropertyValue(String resourceInstanceId, String propertyId) {
1030 log.debug("Going to check whether the property {} already added to resource instance {}", propertyId, resourceInstanceId);
1032 Either<List<ComponentInstanceProperty>, TitanOperationStatus> getAllRes = this.getAllPropertiesOfResourceInstanceOnlyPropertyDefId(resourceInstanceId);
1033 if (getAllRes.isRight()) {
1034 TitanOperationStatus status = getAllRes.right().value();
1035 log.trace("After fetching all properties of resource instance {}. Status is {}", resourceInstanceId, status);
1036 return new ImmutablePair<TitanOperationStatus, String>(status, null);
1039 List<ComponentInstanceProperty> list = getAllRes.left().value();
1041 for (ComponentInstanceProperty instanceProperty : list) {
1042 String propertyUniqueId = instanceProperty.getUniqueId();
1043 String valueUniqueUid = instanceProperty.getValueUniqueUid();
1044 log.trace("Go over property {} under resource instance {}. valueUniqueId = {}", propertyUniqueId, resourceInstanceId, valueUniqueUid);
1045 if (propertyId.equals(propertyUniqueId) && valueUniqueUid != null) {
1046 log.debug("The property {} already created under resource instance {}", propertyId, resourceInstanceId);
1047 return new ImmutablePair<TitanOperationStatus, String>(TitanOperationStatus.ALREADY_EXIST, valueUniqueUid);
1052 return new ImmutablePair<TitanOperationStatus, String>(TitanOperationStatus.NOT_FOUND, null);
1056 * update value of property on resource instance
1058 * @param resourceInstanceProperty
1059 * @param resourceInstanceId
1063 * public Either<PropertyValueData, TitanOperationStatus> updatePropertyOfResourceInstance( ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId) {
1065 * /// #RULES SUPPORT /// Ignore rules received from client till support resourceInstanceProperty.setRules(null); /// /// Either<ComponentInstanceData, TitanOperationStatus> findResInstanceRes = titanGenericDao .getNode(UniqueIdBuilder
1066 * .getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, ComponentInstanceData.class);
1068 * if (findResInstanceRes.isRight()) { TitanOperationStatus status = findResInstanceRes.right().value(); if (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); }
1070 * String propertyId = resourceInstanceProperty.getUniqueId(); Either<PropertyData, TitanOperationStatus> findPropertyDefRes = titanGenericDao .getNode(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class);
1072 * if (findPropertyDefRes.isRight()) { TitanOperationStatus status = findPropertyDefRes.right().value(); return Either.right(status); }
1074 * String valueUniqueUid = resourceInstanceProperty.getValueUniqueUid(); if (valueUniqueUid == null) { return Either.right(TitanOperationStatus.INVALID_ID); } else { Either<PropertyValueData, TitanOperationStatus> findPropertyValueRes =
1075 * titanGenericDao .getNode(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.PropertyValue), valueUniqueUid, PropertyValueData.class); if (findPropertyValueRes.isRight()) { TitanOperationStatus status = findPropertyValueRes.right().value(); if
1076 * (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); }
1078 * String value = resourceInstanceProperty.getValue();
1080 * Either<ImmutablePair<PropertyData, GraphEdge>, TitanOperationStatus> child = titanGenericDao.getChild(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.PropertyValue), valueUniqueUid, GraphEdgeLabels.PROPERTY_IMPL, NodeTypeEnum.Property,
1081 * PropertyData.class);
1083 * if (child.isRight()) { TitanOperationStatus status = child.right().value(); if (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); }
1085 * PropertyData propertyData = child.left().value().left; String propertyType = propertyData.getPropertyDataDefinition().getType();
1087 * log.debug("The type of the property {} is {}", propertyData.getUniqueId(), propertyType);
1089 * Either<Object, Boolean> isValid = validateAndUpdatePropertyValue(propertyType, value);
1091 * 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) {
1092 * newValue = object.toString(); } } PropertyValueData propertyValueData = findPropertyValueRes.left().value(); log.debug("Going to update property value from " + propertyValueData.getValue() + " to " + newValue);
1093 * propertyValueData.setValue(newValue);
1095 * ImmutablePair<String, Boolean> pair = validateAndUpdateRules(propertyType, resourceInstanceProperty.getRules()); if (pair.getRight() != null && pair.getRight() == false) { BeEcompErrorManager.getInstance().
1096 * logBeInvalidValueError("Add property value", pair.getLeft(), resourceInstanceProperty.getName(), propertyType); return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); } updateRulesInPropertyValue(propertyValueData,
1097 * resourceInstanceProperty, resourceInstanceId);
1099 * Either<PropertyValueData, TitanOperationStatus> updateRes = titanGenericDao.updateNode(propertyValueData, PropertyValueData.class); if (updateRes.isRight()) { TitanOperationStatus status = updateRes.right().value(); return
1100 * Either.right(status); } else { return Either.left(updateRes.left().value()); } }
1105 public void updateRulesInPropertyValue(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId) {
1107 List<PropertyRule> currentRules = propertyValueData.getRules();
1109 List<PropertyRule> rules = resourceInstanceProperty.getRules();
1110 // if rules are not supported.
1111 if (rules == null) {
1113 PropertyRule propertyRule = buildRuleFromPath(propertyValueData, resourceInstanceProperty, resourceInstanceId);
1114 rules = new ArrayList<>();
1115 rules.add(propertyRule);
1117 if (currentRules != null) {
1118 rules = mergeRules(currentRules, rules);
1122 // Full mode. all rules are sent in update operation.
1123 rules = sortRules(rules);
1126 propertyValueData.setRules(rules);
1130 private List<PropertyRule> mergeRules(List<PropertyRule> currentRules, List<PropertyRule> newRules) {
1132 List<PropertyRule> mergedRules = new ArrayList<>();
1134 if (newRules == null || newRules.isEmpty() == true) {
1135 return currentRules;
1138 for (PropertyRule rule : currentRules) {
1139 PropertyRule propertyRule = new PropertyRule(rule.getRule(), rule.getValue());
1140 mergedRules.add(propertyRule);
1143 for (PropertyRule rule : newRules) {
1144 PropertyRule foundRule = findRuleInList(rule, mergedRules);
1145 if (foundRule != null) {
1146 foundRule.setValue(rule.getValue());
1148 mergedRules.add(rule);
1155 private PropertyRule findRuleInList(PropertyRule rule, List<PropertyRule> rules) {
1157 if (rules == null || rules.isEmpty() == true || rule.getRule() == null || rule.getRule().isEmpty() == true) {
1161 PropertyRule foundRule = null;
1162 for (PropertyRule propertyRule : rules) {
1163 if (rule.getRuleSize() != propertyRule.getRuleSize()) {
1166 boolean equals = propertyRule.compareRule(rule);
1167 if (equals == true) {
1168 foundRule = propertyRule;
1177 * return all properties associated to resource instance. The result does contains the property unique id but not its type, default value...
1179 * @param resourceInstanceUid
1182 public Either<List<ComponentInstanceProperty>, TitanOperationStatus> getAllPropertiesOfResourceInstanceOnlyPropertyDefId(String resourceInstanceUid) {
1184 return getAllPropertiesOfResourceInstanceOnlyPropertyDefId(resourceInstanceUid, NodeTypeEnum.ResourceInstance);
1189 * public Either<ComponentInstanceProperty, StorageOperationStatus> addPropertyValueToResourceInstance( ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, Integer index, boolean inTransaction) {
1191 * /// #RULES SUPPORT /// Ignore rules received from client till support resourceInstanceProperty.setRules(null); /// ///
1193 * Either<ComponentInstanceProperty, StorageOperationStatus> result = null;
1197 * Either<PropertyValueData, TitanOperationStatus> eitherStatus = this .addPropertyToResourceInstance(resourceInstanceProperty, resourceInstanceId, index);
1199 * if (eitherStatus.isRight()) { log.error( "Failed to add property value {} to resource instance {} in Graph. status is {}" , resourceInstanceProperty, resourceInstanceId, eitherStatus.right().value().name()); result =
1200 * Either.right(DaoStatusConverter .convertTitanStatusToStorageStatus(eitherStatus.right() .value())); return result; } else { PropertyValueData propertyValueData = eitherStatus.left() .value();
1202 * ComponentInstanceProperty propertyValueResult = buildResourceInstanceProperty( propertyValueData, resourceInstanceProperty);
1204 * log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult); result = Either.left(propertyValueResult); return result; } }
1206 * 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();
1211 * public Either<ComponentInstanceProperty, StorageOperationStatus> updatePropertyValueInResourceInstance( ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, boolean inTransaction) {
1213 * Either<ComponentInstanceProperty, StorageOperationStatus> result = null;
1215 * try { //TODO: verify validUniqueId exists Either<PropertyValueData, TitanOperationStatus> eitherStatus = this .updatePropertyOfResourceInstance(resourceInstanceProperty, resourceInstanceId);
1217 * if (eitherStatus.isRight()) { log.error( "Failed to add property value {} to resource instance {} in Graph. status is {}" , resourceInstanceProperty, resourceInstanceId, eitherStatus.right().value().name()); result =
1218 * Either.right(DaoStatusConverter .convertTitanStatusToStorageStatus(eitherStatus.right() .value())); return result; } else { PropertyValueData propertyValueData = eitherStatus.left() .value();
1220 * ComponentInstanceProperty propertyValueResult = buildResourceInstanceProperty( propertyValueData, resourceInstanceProperty);
1222 * log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult); result = Either.left(propertyValueResult); return result; } }
1224 * 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();
1230 public Either<PropertyValueData, TitanOperationStatus> removePropertyOfResourceInstance(String propertyValueUid, String resourceInstanceId) {
1232 Either<ComponentInstanceData, TitanOperationStatus> findResInstanceRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, ComponentInstanceData.class);
1234 if (findResInstanceRes.isRight()) {
1235 TitanOperationStatus status = findResInstanceRes.right().value();
1236 if (status == TitanOperationStatus.NOT_FOUND) {
1237 status = TitanOperationStatus.INVALID_ID;
1239 return Either.right(status);
1242 Either<PropertyValueData, TitanOperationStatus> findPropertyDefRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.PropertyValue), propertyValueUid, PropertyValueData.class);
1244 if (findPropertyDefRes.isRight()) {
1245 TitanOperationStatus status = findPropertyDefRes.right().value();
1246 if (status == TitanOperationStatus.NOT_FOUND) {
1247 status = TitanOperationStatus.INVALID_ID;
1249 return Either.right(status);
1252 Either<GraphRelation, TitanOperationStatus> relation = titanGenericDao.getRelation(findResInstanceRes.left().value(), findPropertyDefRes.left().value(), GraphEdgeLabels.PROPERTY_VALUE);
1253 if (relation.isRight()) {
1254 // TODO: add error in case of error
1255 TitanOperationStatus status = relation.right().value();
1256 if (status == TitanOperationStatus.NOT_FOUND) {
1257 status = TitanOperationStatus.INVALID_ID;
1259 return Either.right(status);
1262 Either<PropertyValueData, TitanOperationStatus> deleteNode = titanGenericDao.deleteNode(findPropertyDefRes.left().value(), PropertyValueData.class);
1263 if (deleteNode.isRight()) {
1264 return Either.right(deleteNode.right().value());
1266 PropertyValueData value = deleteNode.left().value();
1267 return Either.left(value);
1271 public Either<ComponentInstanceProperty, StorageOperationStatus> removePropertyValueFromResourceInstance(String propertyValueUid, String resourceInstanceId, boolean inTransaction) {
1273 Either<ComponentInstanceProperty, StorageOperationStatus> result = null;
1277 Either<PropertyValueData, TitanOperationStatus> eitherStatus = this.removePropertyOfResourceInstance(propertyValueUid, resourceInstanceId);
1279 if (eitherStatus.isRight()) {
1280 log.error("Failed to remove property value {} from resource instance {} in Graph. status is {}", propertyValueUid, resourceInstanceId, eitherStatus.right().value().name());
1281 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value()));
1284 PropertyValueData propertyValueData = eitherStatus.left().value();
1286 ComponentInstanceProperty propertyValueResult = new ComponentInstanceProperty();
1287 propertyValueResult.setUniqueId(resourceInstanceId);
1288 propertyValueResult.setValue(propertyValueData.getValue());
1290 log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult);
1291 result = Either.left(propertyValueResult);
1297 if (false == inTransaction) {
1298 if (result == null || result.isRight()) {
1299 log.error("Going to execute rollback on graph.");
1300 titanGenericDao.rollback();
1302 log.debug("Going to execute commit on graph.");
1303 titanGenericDao.commit();
1310 public ComponentInstanceProperty buildResourceInstanceProperty(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty) {
1312 String value = propertyValueData.getValue();
1313 String uid = propertyValueData.getUniqueId();
1314 ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty(resourceInstanceProperty, value, uid);
1315 instanceProperty.setPath(resourceInstanceProperty.getPath());
1317 return instanceProperty;
1321 public static class PropertyConstraintJacksonDeserializer extends com.fasterxml.jackson.databind.JsonDeserializer<PropertyConstraint> {
1324 public PropertyConstraint deserialize(com.fasterxml.jackson.core.JsonParser json, DeserializationContext context) throws IOException {
1325 ObjectCodec oc = json.getCodec();
1326 JsonNode node = oc.readTree(json);
1332 public boolean isPropertyDefaultValueValid(IComplexDefaultValue propertyDefinition, Map<String, DataTypeDefinition> dataTypes) {
1333 if (propertyDefinition == null) {
1336 boolean isValid = false;
1337 String innerType = null;
1338 String propertyType = propertyDefinition.getType();
1339 ToscaPropertyType type = getType(propertyType);
1340 if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
1341 SchemaDefinition def = propertyDefinition.getSchema();
1345 PropertyDataDefinition propDef = def.getProperty();
1346 if (propDef == null) {
1349 innerType = propDef.getType();
1351 String value = propertyDefinition.getDefaultValue();
1353 isValid = isValidValue(type, value, innerType, dataTypes);
1355 log.trace("The given type {} is not a pre defined one.", propertyType);
1357 DataTypeDefinition foundDt = dataTypes.get(propertyType);
1358 if (foundDt != null) {
1359 isValid = isValidComplexValue(foundDt, value, dataTypes);
1367 public boolean isPropertyTypeValid(IComplexDefaultValue property) {
1369 if (property == null) {
1373 if (ToscaPropertyType.isValidType(property.getType()) == null) {
1375 Either<Boolean, TitanOperationStatus> definedInDataTypes = isDefinedInDataTypes(property.getType());
1377 if (definedInDataTypes.isRight()) {
1380 Boolean isExist = definedInDataTypes.left().value();
1381 return isExist.booleanValue();
1389 public ImmutablePair<String, Boolean> isPropertyInnerTypeValid(IComplexDefaultValue property, Map<String, DataTypeDefinition> dataTypes) {
1391 if (property == null) {
1392 return new ImmutablePair<String, Boolean>(null, false);
1395 SchemaDefinition schema;
1396 PropertyDataDefinition innerProp;
1397 String innerType = null;
1398 if ((schema = property.getSchema()) != null) {
1399 if ((innerProp = schema.getProperty()) != null) {
1400 innerType = innerProp.getType();
1404 ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType);
1406 if (innerToscaType == null) {
1407 DataTypeDefinition dataTypeDefinition = dataTypes.get(innerType);
1408 if (dataTypeDefinition == null) {
1409 log.debug("The inner type {} is not a data type.", innerType);
1410 return new ImmutablePair<String, Boolean>(innerType, false);
1412 log.debug("The inner type {} is a data type. Data type definition is {}", innerType, dataTypeDefinition);
1416 return new ImmutablePair<String, Boolean>(innerType, true);
1419 private boolean isValidComplexValue(DataTypeDefinition foundDt, String value, Map<String, DataTypeDefinition> dataTypes) {
1421 * Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypesRes = getAllDataTypes(); if (allDataTypesRes.isRight()) { TitanOperationStatus status = allDataTypesRes.right().value();
1424 * Map<String, DataTypeDefinition> allDataTypes = allDataTypesRes.left().value();
1426 ImmutablePair<JsonElement, Boolean> validateAndUpdate = dataTypeValidatorConverter.validateAndUpdate(value, foundDt, dataTypes);
1428 log.trace("The result after validating complex value of type {} is {}", foundDt.getName(), validateAndUpdate);
1430 return validateAndUpdate.right.booleanValue();
1434 private Either<Map<String, DataTypeDefinition>, TitanOperationStatus> findAllDataTypeDefinition(DataTypeDefinition dataTypeDefinition) {
1436 Map<String, DataTypeDefinition> nameToDataTypeDef = new HashMap<>();
1438 DataTypeDefinition typeDefinition = dataTypeDefinition;
1440 while (typeDefinition != null) {
1442 List<PropertyDefinition> properties = typeDefinition.getProperties();
1443 if (properties != null) {
1444 for (PropertyDefinition propertyDefinition : properties) {
1445 String type = propertyDefinition.getType();
1446 Either<DataTypeDefinition, TitanOperationStatus> dataTypeByName = this.getDataTypeUsingName(type);
1447 if (dataTypeByName.isRight()) {
1448 return Either.right(dataTypeByName.right().value());
1450 DataTypeDefinition value = dataTypeByName.left().value();
1451 if (false == nameToDataTypeDef.containsKey(type)) {
1452 nameToDataTypeDef.put(type, value);
1459 typeDefinition = typeDefinition.getDerivedFrom();
1462 return Either.left(nameToDataTypeDef);
1465 public Either<List<ComponentInstanceProperty>, TitanOperationStatus> getAllPropertiesOfResourceInstanceOnlyPropertyDefId(String resourceInstanceUid, NodeTypeEnum instanceNodeType) {
1467 Either<TitanVertex, TitanOperationStatus> findResInstanceRes = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(instanceNodeType), resourceInstanceUid);
1469 if (findResInstanceRes.isRight()) {
1470 TitanOperationStatus status = findResInstanceRes.right().value();
1471 if (status == TitanOperationStatus.NOT_FOUND) {
1472 status = TitanOperationStatus.INVALID_ID;
1474 return Either.right(status);
1477 Either<List<ImmutablePair<TitanVertex, Edge>>, TitanOperationStatus> propertyImplNodes = titanGenericDao.getChildrenVertecies(UniqueIdBuilder.getKeyByNodeType(instanceNodeType), resourceInstanceUid, GraphEdgeLabels.PROPERTY_VALUE);
1479 if (propertyImplNodes.isRight()) {
1480 TitanOperationStatus status = propertyImplNodes.right().value();
1481 return Either.right(status);
1484 List<ImmutablePair<TitanVertex, Edge>> list = propertyImplNodes.left().value();
1485 if (list == null || true == list.isEmpty()) {
1486 return Either.right(TitanOperationStatus.NOT_FOUND);
1489 List<ComponentInstanceProperty> result = new ArrayList<>();
1490 for (ImmutablePair<TitanVertex, Edge> propertyValue : list) {
1491 TitanVertex propertyValueDataVertex = propertyValue.getLeft();
1492 String propertyValueUid = (String) titanGenericDao.getProperty(propertyValueDataVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty());
1493 String value = (String) titanGenericDao.getProperty(propertyValueDataVertex, GraphPropertiesDictionary.VALUE.getProperty());
1495 ImmutablePair<TitanVertex, Edge> propertyDefPair = titanGenericDao.getChildVertex(propertyValueDataVertex, GraphEdgeLabels.PROPERTY_IMPL);
1496 if (propertyDefPair == null) {
1497 return Either.right(TitanOperationStatus.NOT_FOUND);
1500 Map<String, Object> properties = titanGenericDao.getProperties(propertyValueDataVertex);
1501 PropertyValueData propertyValueData = GraphElementFactory.createElement(NodeTypeEnum.PropertyValue.getName(), GraphElementTypeEnum.Node, properties, PropertyValueData.class);
1502 String propertyUniqueId = (String) titanGenericDao.getProperty(propertyDefPair.left, GraphPropertiesDictionary.UNIQUE_ID.getProperty());
1504 ComponentInstanceProperty resourceInstanceProperty = new ComponentInstanceProperty();
1505 // set property original unique id
1506 resourceInstanceProperty.setUniqueId(propertyUniqueId);
1508 // TODO: esofer add resource id
1509 resourceInstanceProperty.setParentUniqueId(null);
1511 resourceInstanceProperty.setValue(value);
1512 // set property value unique id
1513 resourceInstanceProperty.setValueUniqueUid(propertyValueUid);
1515 resourceInstanceProperty.setRules(propertyValueData.getRules());
1517 result.add(resourceInstanceProperty);
1520 return Either.left(result);
1524 * Find the default value from the list of component instances. Start the search from the second component instance
1526 * @param pathOfComponentInstances
1527 * @param propertyUniqueId
1528 * @param defaultValue
1531 public Either<String, TitanOperationStatus> findDefaultValueFromSecondPosition(List<String> pathOfComponentInstances, String propertyUniqueId, String defaultValue) {
1533 log.trace("In find default value: path= {} propertyUniqId={} defaultValue= {}", pathOfComponentInstances, propertyUniqueId, defaultValue);
1535 if (pathOfComponentInstances == null || pathOfComponentInstances.size() < 2) {
1536 return Either.left(defaultValue);
1539 String result = defaultValue;
1541 for (int i = 1; i < pathOfComponentInstances.size(); i++) {
1542 String compInstanceId = pathOfComponentInstances.get(i);
1544 Either<List<ComponentInstanceProperty>, TitanOperationStatus> propertyValuesResult = this.getAllPropertiesOfResourceInstanceOnlyPropertyDefId(compInstanceId, NodeTypeEnum.ResourceInstance);
1546 log.trace("After fetching properties values of component instance {}. {}", compInstanceId, propertyValuesResult);
1548 if (propertyValuesResult.isRight()) {
1549 TitanOperationStatus status = propertyValuesResult.right().value();
1550 if (status != TitanOperationStatus.NOT_FOUND) {
1551 return Either.right(status);
1557 ComponentInstanceProperty foundCompInstanceProperty = fetchByPropertyUid(propertyValuesResult.left().value(), propertyUniqueId);
1558 log.trace("After finding the component instance property on{} . {}", compInstanceId, foundCompInstanceProperty);
1560 if (foundCompInstanceProperty == null) {
1564 List<PropertyRule> rules = getOrBuildRulesIfNotExists(pathOfComponentInstances.size() - i, pathOfComponentInstances.get(i), foundCompInstanceProperty.getRules(), foundCompInstanceProperty.getValue());
1566 log.trace("Rules of property {} on component instance {} are {}", propertyUniqueId, compInstanceId, rules);
1567 PropertyRule matchedRule = findMatchRule(pathOfComponentInstances, i, rules);
1568 log.trace("Match rule is {}", matchedRule);
1570 if (matchedRule != null) {
1571 result = matchedRule.getValue();
1577 return Either.left(result);
1581 private ComponentInstanceProperty fetchByPropertyUid(List<ComponentInstanceProperty> list, String propertyUniqueId) {
1583 ComponentInstanceProperty result = null;
1589 for (ComponentInstanceProperty instProperty : list) {
1590 if (instProperty.getUniqueId().equals(propertyUniqueId)) {
1591 result = instProperty;
1599 private List<PropertyRule> getOrBuildRulesIfNotExists(int ruleSize, String compInstanceId, List<PropertyRule> rules, String value) {
1601 if (rules != null) {
1605 rules = buildDefaultRule(compInstanceId, ruleSize, value);
1611 private List<PropertyRule> getRulesOfPropertyValue(int size, String instanceId, ComponentInstanceProperty componentInstanceProperty) {
1612 List<PropertyRule> rules = componentInstanceProperty.getRules();
1613 if (rules == null) {
1614 rules = buildDefaultRule(instanceId, size, componentInstanceProperty.getValue());
1619 private List<PropertyRule> buildDefaultRule(String componentInstanceId, int size, String value) {
1621 List<PropertyRule> rules = new ArrayList<>();
1622 List<String> rule = new ArrayList<>();
1623 rule.add(componentInstanceId);
1624 for (int i = 0; i < size - 1; i++) {
1625 rule.add(PropertyRule.RULE_ANY_MATCH);
1627 PropertyRule propertyRule = new PropertyRule(rule, value);
1628 rules.add(propertyRule);
1634 private PropertyRule findMatchRule(List<String> pathOfInstances, int level, List<PropertyRule> rules) {
1636 PropertyRule propertyRule = null;
1638 String stringForMatch = buildStringForMatch(pathOfInstances, level);
1640 String firstCompInstance = pathOfInstances.get(level);
1642 if (rules != null) {
1644 for (PropertyRule rule : rules) {
1646 int ruleSize = rule.getRule().size();
1647 // check the length of the rule equals to the length of the
1649 if (ruleSize != pathOfInstances.size() - level) {
1652 // check that the rule starts with correct component instance id
1653 if (false == checkFirstItem(firstCompInstance, rule.getFirstToken())) {
1657 String secondToken = rule.getToken(2);
1658 if (secondToken != null && (secondToken.equals(PropertyRule.FORCE_ALL) || secondToken.equals(PropertyRule.ALL))) {
1659 propertyRule = rule;
1663 String patternStr = buildStringForMatch(rule.getRule(), 0);
1665 Pattern pattern = Pattern.compile(patternStr);
1667 Matcher matcher = pattern.matcher(stringForMatch);
1669 if (matcher.matches()) {
1670 if (log.isTraceEnabled()) {
1671 log.trace("{} matches the rule {}", stringForMatch, patternStr);
1673 propertyRule = rule;
1680 return propertyRule;
1683 private boolean checkFirstItem(String left, String right) {
1684 if (left != null && left.equals(right)) {
1690 private String buildStringForMatch(List<String> pathOfInstances, int level) {
1691 StringBuilder builder = new StringBuilder();
1693 for (int i = level; i < pathOfInstances.size(); i++) {
1694 builder.append(pathOfInstances.get(i));
1695 if (i < pathOfInstances.size() - 1) {
1696 builder.append("#");
1699 return builder.toString();
1702 public void updatePropertyByBestMatch(String propertyUniqueId, ComponentInstanceProperty instanceProperty, Map<String, ComponentInstanceProperty> instanceIdToValue) {
1704 List<String> pathOfInstances = instanceProperty.getPath();
1706 int size = pathOfInstances.size();
1707 int numberOfMatches = 0;
1708 for (String instanceId : pathOfInstances) {
1709 ComponentInstanceProperty componentInstanceProperty = instanceIdToValue.get(instanceId);
1711 if (componentInstanceProperty != null) {
1713 List<PropertyRule> rules = getRulesOfPropertyValue(size - level, instanceId, componentInstanceProperty);
1714 // If it is the first level instance, then update valueUniuqeId
1715 // parameter in order to know on update that
1716 // we should update and not create new node on graph.
1718 instanceProperty.setValueUniqueUid(componentInstanceProperty.getValueUniqueUid());
1719 instanceProperty.setRules(rules);
1722 PropertyRule rule = findMatchRule(pathOfInstances, level, rules);
1725 String value = rule.getValue();
1726 if (numberOfMatches == 1) {
1727 instanceProperty.setValue(value);
1728 if (log.isDebugEnabled()) {
1729 log.debug("Set the value of property {} {} on path {} to be {}", propertyUniqueId, instanceProperty.getName(), pathOfInstances, value);
1731 } else if (numberOfMatches == 2) {
1732 // In case of another property value match, then use the
1733 // value to be the default value of the property.
1734 instanceProperty.setDefaultValue(value);
1735 if (log.isDebugEnabled()) {
1736 log.debug("Set the default value of property {} {} on path {} to be {}", propertyUniqueId, instanceProperty.getName(), pathOfInstances, value);
1747 public void updatePropertiesByPropertyValues(Map<String, List<ComponentInstanceProperty>> resourceInstancesProperties, Map<String, Map<String, ComponentInstanceProperty>> values) {
1749 if (resourceInstancesProperties == null) {
1753 List<ComponentInstanceProperty> allProperties = new ArrayList<>();
1754 Collection<List<ComponentInstanceProperty>> properties = resourceInstancesProperties.values();
1755 if (properties != null) {
1756 Iterator<List<ComponentInstanceProperty>> iterator = properties.iterator();
1757 while (iterator.hasNext()) {
1758 List<ComponentInstanceProperty> compInstancePropertyList = iterator.next();
1759 allProperties.addAll(compInstancePropertyList);
1763 // Go over each property and check whether there is a rule which updates
1765 for (ComponentInstanceProperty instanceProperty : allProperties) {
1767 String propertyUniqueId = instanceProperty.getUniqueId();
1769 // get the changes per componentInstanceId.
1770 Map<String, ComponentInstanceProperty> instanceIdToValue = values.get(propertyUniqueId);
1772 if (instanceIdToValue == null) {
1776 this.updatePropertyByBestMatch(propertyUniqueId, instanceProperty, instanceIdToValue);
1784 * Add data type to graph.
1786 * 1. Add data type node
1788 * 2. Add edge between the former node to its parent(if exists)
1790 * 3. Add property node and associate it to the node created at #1. (per property & if exists)
1792 * @param dataTypeDefinition
1795 private Either<DataTypeData, TitanOperationStatus> addDataTypeToGraph(DataTypeDefinition dataTypeDefinition) {
1797 log.debug("Got data type {}", dataTypeDefinition);
1799 String dtUniqueId = UniqueIdBuilder.buildDataTypeUid(dataTypeDefinition.getName());
1801 DataTypeData dataTypeData = buildDataTypeData(dataTypeDefinition, dtUniqueId);
1803 log.debug("Before adding data type to graph. dataTypeData = {}", dataTypeData);
1804 Either<DataTypeData, TitanOperationStatus> createDataTypeResult = titanGenericDao.createNode(dataTypeData, DataTypeData.class);
1805 log.debug("After adding data type to graph. status is = {}", createDataTypeResult);
1807 if (createDataTypeResult.isRight()) {
1808 TitanOperationStatus operationStatus = createDataTypeResult.right().value();
1809 log.debug("Failed to data type {} to graph. status is {}", dataTypeDefinition.getName(), operationStatus);
1810 BeEcompErrorManager.getInstance().logBeFailedAddingNodeTypeError("AddDataType", NodeTypeEnum.DataType.getName());
1811 return Either.right(operationStatus);
1814 DataTypeData resultCTD = createDataTypeResult.left().value();
1815 List<PropertyDefinition> properties = dataTypeDefinition.getProperties();
1816 Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToDataType = addPropertiesToDataType(resultCTD.getUniqueId(), properties);
1817 if (addPropertiesToDataType.isRight()) {
1818 log.debug("Failed add properties {} to data type {}", properties, dataTypeDefinition.getName());
1819 return Either.right(addPropertiesToDataType.right().value());
1822 String derivedFrom = dataTypeDefinition.getDerivedFromName();
1823 if (derivedFrom != null) {
1824 log.debug("Before creating relation between data type {} to its parent {}", dtUniqueId, derivedFrom);
1825 UniqueIdData from = new UniqueIdData(NodeTypeEnum.DataType, dtUniqueId);
1827 String deriveFromUid = UniqueIdBuilder.buildDataTypeUid(derivedFrom);
1828 UniqueIdData to = new UniqueIdData(NodeTypeEnum.DataType, deriveFromUid);
1829 Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(from, to, GraphEdgeLabels.DERIVED_FROM, null);
1830 log.debug("After create relation between capability type {} to its parent {}. status is {}", dtUniqueId, derivedFrom, createRelation);
1831 if (createRelation.isRight()) {
1832 return Either.right(createRelation.right().value());
1836 return Either.left(createDataTypeResult.left().value());
1840 private DataTypeData buildDataTypeData(DataTypeDefinition dataTypeDefinition, String ctUniqueId) {
1842 DataTypeData dataTypeData = new DataTypeData(dataTypeDefinition);
1844 dataTypeData.getDataTypeDataDefinition().setUniqueId(ctUniqueId);
1845 Long creationDate = dataTypeData.getDataTypeDataDefinition().getCreationTime();
1846 if (creationDate == null) {
1847 creationDate = System.currentTimeMillis();
1849 dataTypeData.getDataTypeDataDefinition().setCreationTime(creationDate);
1850 dataTypeData.getDataTypeDataDefinition().setModificationTime(creationDate);
1852 return dataTypeData;
1856 * add properties to capability type.
1858 * Per property, add a property node and associate it to the capability type
1864 private Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToDataType(String uniqueId, List<PropertyDefinition> properties) {
1866 Map<String, PropertyData> propertiesData = new HashMap<String, PropertyData>();
1868 if (properties != null && false == properties.isEmpty()) {
1869 for (PropertyDefinition propertyDefinition : properties) {
1870 String propertyName = propertyDefinition.getName();
1872 String propertyType = propertyDefinition.getType();
1873 Either<Boolean, TitanOperationStatus> validPropertyType = isValidPropertyType(propertyType);
1874 if (validPropertyType.isRight()) {
1875 log.debug("Data type {} contains invalid property type {}", uniqueId, propertyType);
1876 return Either.right(validPropertyType.right().value());
1878 Boolean isValid = validPropertyType.left().value();
1879 if (isValid == null || isValid.booleanValue() == false) {
1880 log.debug("Data type {} contains invalid property type {}", uniqueId, propertyType);
1881 return Either.right(TitanOperationStatus.INVALID_TYPE);
1884 Either<PropertyData, TitanOperationStatus> addPropertyToNodeType = this.addPropertyToNodeType(propertyName, propertyDefinition, NodeTypeEnum.DataType, uniqueId);
1885 if (addPropertyToNodeType.isRight()) {
1886 TitanOperationStatus operationStatus = addPropertyToNodeType.right().value();
1887 log.debug("Failed to associate data type {} to property {} in graph. status is {}", uniqueId, propertyName, operationStatus);
1888 BeEcompErrorManager.getInstance().logInternalFlowError("AddPropertyToDataType", "Failed to associate property to data type. Status is " + operationStatus, ErrorSeverity.ERROR);
1889 return Either.right(operationStatus);
1891 propertiesData.put(propertyName, addPropertyToNodeType.left().value());
1894 DataTypeData dataTypeData = new DataTypeData();
1895 dataTypeData.getDataTypeDataDefinition().setUniqueId(uniqueId);
1896 long modificationTime = System.currentTimeMillis();
1897 dataTypeData.getDataTypeDataDefinition().setModificationTime(modificationTime);
1899 Either<DataTypeData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(dataTypeData, DataTypeData.class);
1900 if (updateNode.isRight()) {
1901 TitanOperationStatus operationStatus = updateNode.right().value();
1902 log.debug("Failed to update modification time data type {} from graph. status is {}", uniqueId, operationStatus);
1903 BeEcompErrorManager.getInstance().logInternalFlowError("AddPropertyToDataType", "Failed to fetch data type. Status is " + operationStatus, ErrorSeverity.ERROR);
1904 return Either.right(operationStatus);
1906 log.debug("Update data type uid {}. Set modification time to {}", uniqueId, modificationTime);
1911 return Either.left(propertiesData);
1916 * Build Data type object from graph by unique id
1921 public Either<DataTypeDefinition, TitanOperationStatus> getDataTypeByUid(String uniqueId) {
1923 Either<DataTypeDefinition, TitanOperationStatus> result = null;
1925 Either<DataTypeData, TitanOperationStatus> dataTypesRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, DataTypeData.class);
1927 if (dataTypesRes.isRight()) {
1928 TitanOperationStatus status = dataTypesRes.right().value();
1929 log.debug("Data type {} cannot be found in graph. status is {}", uniqueId, status);
1930 return Either.right(status);
1933 DataTypeData ctData = dataTypesRes.left().value();
1934 DataTypeDefinition dataTypeDefinition = new DataTypeDefinition(ctData.getDataTypeDataDefinition());
1936 TitanOperationStatus propertiesStatus = fillProperties(uniqueId, dataTypeDefinition);
1937 if (propertiesStatus != TitanOperationStatus.OK) {
1938 log.error("Failed to fetch properties of data type {}", uniqueId);
1939 return Either.right(propertiesStatus);
1942 Either<ImmutablePair<DataTypeData, GraphEdge>, TitanOperationStatus> parentNode = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.DataType,
1943 DataTypeData.class);
1944 log.debug("After retrieving DERIVED_FROM node of {}. status is {}", uniqueId, parentNode);
1945 if (parentNode.isRight()) {
1946 TitanOperationStatus titanOperationStatus = parentNode.right().value();
1947 if (titanOperationStatus != TitanOperationStatus.NOT_FOUND) {
1948 log.error("Failed to find the parent data type of data type {}. status is {}", uniqueId, titanOperationStatus);
1949 result = Either.right(titanOperationStatus);
1953 // derived from node was found
1954 ImmutablePair<DataTypeData, GraphEdge> immutablePair = parentNode.left().value();
1955 DataTypeData parentCT = immutablePair.getKey();
1957 String parentUniqueId = parentCT.getUniqueId();
1958 Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = getDataTypeByUid(parentUniqueId);
1960 if (dataTypeByUid.isRight()) {
1961 return Either.right(dataTypeByUid.right().value());
1964 DataTypeDefinition parentDataTypeDefinition = dataTypeByUid.left().value();
1966 dataTypeDefinition.setDerivedFrom(parentDataTypeDefinition);
1969 result = Either.left(dataTypeDefinition);
1974 private TitanOperationStatus fillProperties(String uniqueId, DataTypeDefinition dataTypeDefinition) {
1976 Either<Map<String, PropertyDefinition>, TitanOperationStatus> findPropertiesOfNode = this.findPropertiesOfNode(NodeTypeEnum.DataType, uniqueId);
1977 if (findPropertiesOfNode.isRight()) {
1978 TitanOperationStatus titanOperationStatus = findPropertiesOfNode.right().value();
1979 log.debug("After looking for properties of vertex {}. status is {}", uniqueId, titanOperationStatus);
1980 if (TitanOperationStatus.NOT_FOUND.equals(titanOperationStatus)) {
1981 return TitanOperationStatus.OK;
1983 return titanOperationStatus;
1986 Map<String, PropertyDefinition> properties = findPropertiesOfNode.left().value();
1987 if (properties != null && properties.isEmpty() == false) {
1988 List<PropertyDefinition> listOfProps = new ArrayList<>();
1990 for (Entry<String, PropertyDefinition> entry : properties.entrySet()) {
1991 String propName = entry.getKey();
1992 PropertyDefinition propertyDefinition = entry.getValue();
1993 PropertyDefinition newPropertyDefinition = new PropertyDefinition(propertyDefinition);
1994 newPropertyDefinition.setName(propName);
1995 listOfProps.add(newPropertyDefinition);
1997 dataTypeDefinition.setProperties(listOfProps);
1999 return TitanOperationStatus.OK;
2003 private Either<DataTypeDefinition, StorageOperationStatus> addDataType(DataTypeDefinition dataTypeDefinition, boolean inTransaction) {
2005 Either<DataTypeDefinition, StorageOperationStatus> result = null;
2009 Either<DataTypeData, TitanOperationStatus> eitherStatus = addDataTypeToGraph(dataTypeDefinition);
2011 if (eitherStatus.isRight()) {
2012 log.debug("Failed to add data type {} to Graph. status is {}", dataTypeDefinition, eitherStatus.right().value().name());
2013 BeEcompErrorManager.getInstance().logBeFailedAddingNodeTypeError("AddDataType", "DataType");
2014 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value()));
2017 DataTypeData capabilityTypeData = eitherStatus.left().value();
2019 DataTypeDefinition dataTypeDefResult = convertDTDataToDTDefinition(capabilityTypeData);
2020 log.debug("The returned CapabilityTypeDefinition is {}", dataTypeDefResult);
2021 result = Either.left(dataTypeDefResult);
2025 if (false == inTransaction) {
2026 if (result == null || result.isRight()) {
2027 log.error("Going to execute rollback on graph.");
2028 titanGenericDao.rollback();
2030 log.debug("Going to execute commit on graph.");
2031 titanGenericDao.commit();
2039 public Either<DataTypeDefinition, StorageOperationStatus> addDataType(DataTypeDefinition dataTypeDefinition) {
2040 return addDataType(dataTypeDefinition, true);
2044 public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByName(String name, boolean inTransaction) {
2046 Either<DataTypeDefinition, StorageOperationStatus> result = null;
2049 String dtUid = UniqueIdBuilder.buildDataTypeUid(name);
2050 Either<DataTypeDefinition, TitanOperationStatus> ctResult = this.getDataTypeByUid(dtUid);
2052 if (ctResult.isRight()) {
2053 TitanOperationStatus status = ctResult.right().value();
2054 if (status != TitanOperationStatus.NOT_FOUND) {
2055 log.error("Failed to retrieve information on capability type {} status is {}", name, status);
2057 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(ctResult.right().value()));
2061 result = Either.left(ctResult.left().value());
2065 if (false == inTransaction) {
2066 if (result == null || result.isRight()) {
2067 log.error("Going to execute rollback on graph.");
2068 titanGenericDao.rollback();
2070 log.debug("Going to execute commit on graph.");
2071 titanGenericDao.commit();
2079 public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByName(String name) {
2080 return getDataTypeByName(name, true);
2084 public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByNameWithoutDerived(String name) {
2085 return getDataTypeByNameWithoutDerived(name, true);
2088 private Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByNameWithoutDerived(String name, boolean inTransaction) {
2090 Either<DataTypeDefinition, StorageOperationStatus> result = null;
2093 String uid = UniqueIdBuilder.buildDataTypeUid(name);
2094 Either<DataTypeDefinition, TitanOperationStatus> ctResult = this.getDataTypeByUidWithoutDerivedDataTypes(uid);
2096 if (ctResult.isRight()) {
2097 TitanOperationStatus status = ctResult.right().value();
2098 if (status != TitanOperationStatus.NOT_FOUND) {
2099 log.error("Failed to retrieve information on capability type {} status is {}", name, status);
2101 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(ctResult.right().value()));
2105 result = Either.left(ctResult.left().value());
2109 if (false == inTransaction) {
2110 if (result == null || result.isRight()) {
2111 log.error("Going to execute rollback on graph.");
2112 titanGenericDao.rollback();
2114 log.debug("Going to execute commit on graph.");
2115 titanGenericDao.commit();
2122 public Either<DataTypeDefinition, TitanOperationStatus> getDataTypeByUidWithoutDerivedDataTypes(String uniqueId) {
2124 Either<DataTypeData, TitanOperationStatus> dataTypesRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, DataTypeData.class);
2126 if (dataTypesRes.isRight()) {
2127 TitanOperationStatus status = dataTypesRes.right().value();
2128 log.debug("Data type {} cannot be found in graph. status is {}", uniqueId, status);
2129 return Either.right(status);
2132 DataTypeData ctData = dataTypesRes.left().value();
2133 DataTypeDefinition dataTypeDefinition = new DataTypeDefinition(ctData.getDataTypeDataDefinition());
2135 TitanOperationStatus propertiesStatus = fillProperties(uniqueId, dataTypeDefinition);
2136 if (propertiesStatus != TitanOperationStatus.OK) {
2137 log.error("Failed to fetch properties of data type {}", uniqueId);
2138 return Either.right(propertiesStatus);
2141 return Either.left(dataTypeDefinition);
2146 * convert between graph Node object to Java object
2148 * @param dataTypeData
2151 protected DataTypeDefinition convertDTDataToDTDefinition(DataTypeData dataTypeData) {
2152 log.debug("The object returned after create data type is {}", dataTypeData);
2154 DataTypeDefinition dataTypeDefResult = new DataTypeDefinition(dataTypeData.getDataTypeDataDefinition());
2156 return dataTypeDefResult;
2159 private Either<Boolean, TitanOperationStatus> isValidPropertyType(String propertyType) {
2161 if (propertyType == null || propertyType.isEmpty()) {
2162 return Either.left(false);
2165 ToscaPropertyType toscaPropertyType = ToscaPropertyType.isValidType(propertyType);
2166 if (toscaPropertyType == null) {
2167 Either<Boolean, TitanOperationStatus> definedInDataTypes = isDefinedInDataTypes(propertyType);
2168 return definedInDataTypes;
2170 return Either.left(true);
2174 public Either<Boolean, TitanOperationStatus> isDefinedInDataTypes(String propertyType) {
2176 String dataTypeUid = UniqueIdBuilder.buildDataTypeUid(propertyType);
2177 Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = getDataTypeByUid(dataTypeUid);
2178 if (dataTypeByUid.isRight()) {
2179 TitanOperationStatus status = dataTypeByUid.right().value();
2180 if (status == TitanOperationStatus.NOT_FOUND) {
2181 return Either.left(false);
2183 return Either.right(status);
2186 return Either.left(true);
2190 private Either<DataTypeDefinition, TitanOperationStatus> getExternalDataType(String propertyType) {
2192 String dataTypeUid = UniqueIdBuilder.buildDataTypeUid(propertyType);
2193 Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = getDataTypeByUid(dataTypeUid);
2194 if (dataTypeByUid.isRight()) {
2195 TitanOperationStatus status = dataTypeByUid.right().value();
2196 return Either.right(status);
2199 return Either.left(dataTypeByUid.left().value());
2203 public Either<Map<String, DataTypeDefinition>, TitanOperationStatus> getAllDataTypes() {
2205 Map<String, DataTypeDefinition> dataTypes = new HashMap<>();
2206 Either<Map<String, DataTypeDefinition>, TitanOperationStatus> result = Either.left(dataTypes);
2208 Either<List<DataTypeData>, TitanOperationStatus> getAllDataTypes = titanGenericDao.getByCriteria(NodeTypeEnum.DataType, null, DataTypeData.class);
2209 if (getAllDataTypes.isRight()) {
2210 TitanOperationStatus status = getAllDataTypes.right().value();
2211 if (status != TitanOperationStatus.NOT_FOUND) {
2212 return Either.right(status);
2218 List<DataTypeData> list = getAllDataTypes.left().value();
2221 log.trace("Number of data types to load is {}" , list.size());
2223 List<String> collect = list.stream().map(p -> p.getDataTypeDataDefinition().getName()).collect(Collectors.toList());
2224 log.trace("The data types to load are {}" , collect);
2226 for (DataTypeData dataTypeData : list) {
2228 log.trace("Going to fetch data type {}. uid is {}", dataTypeData.getDataTypeDataDefinition().getName(), dataTypeData.getUniqueId());
2229 Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = this.getAndAddDataTypeByUid(dataTypeData.getUniqueId(), dataTypes);
2230 if (dataTypeByUid.isRight()) {
2231 TitanOperationStatus status = dataTypeByUid.right().value();
2232 if (status == TitanOperationStatus.NOT_FOUND) {
2233 status = TitanOperationStatus.INVALID_ID;
2235 return Either.right(status);
2240 if (log.isTraceEnabled()) {
2241 if (result.isRight()) {
2242 log.trace("After fetching all data types {}" , result);
2244 Map<String, DataTypeDefinition> map = result.left().value();
2246 String types = map.keySet().stream().collect(Collectors.joining(",", "[", "]"));
2247 log.trace("After fetching all data types {} " , types);
2256 * Build Data type object from graph by unique id
2261 private Either<DataTypeDefinition, TitanOperationStatus> getAndAddDataTypeByUid(String uniqueId, Map<String, DataTypeDefinition> allDataTypes) {
2263 Either<DataTypeDefinition, TitanOperationStatus> result = null;
2265 if (allDataTypes.containsKey(uniqueId)) {
2266 return Either.left(allDataTypes.get(uniqueId));
2269 Either<DataTypeData, TitanOperationStatus> dataTypesRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, DataTypeData.class);
2271 if (dataTypesRes.isRight()) {
2272 TitanOperationStatus status = dataTypesRes.right().value();
2273 log.debug("Data type {} cannot be found in graph. status is {}", uniqueId, status);
2274 return Either.right(status);
2277 DataTypeData ctData = dataTypesRes.left().value();
2278 DataTypeDefinition dataTypeDefinition = new DataTypeDefinition(ctData.getDataTypeDataDefinition());
2280 TitanOperationStatus propertiesStatus = fillProperties(uniqueId, dataTypeDefinition);
2281 if (propertiesStatus != TitanOperationStatus.OK) {
2282 log.error("Failed to fetch properties of data type {}", uniqueId);
2283 return Either.right(propertiesStatus);
2286 allDataTypes.put(dataTypeDefinition.getName(), dataTypeDefinition);
2288 String derivedFrom = dataTypeDefinition.getDerivedFromName();
2289 if (allDataTypes.containsKey(derivedFrom)) {
2290 DataTypeDefinition parentDataTypeDefinition = allDataTypes.get(derivedFrom);
2292 dataTypeDefinition.setDerivedFrom(parentDataTypeDefinition);
2294 return Either.left(dataTypeDefinition);
2297 Either<ImmutablePair<DataTypeData, GraphEdge>, TitanOperationStatus> parentNode = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.DataType,
2298 DataTypeData.class);
2299 log.debug("After retrieving DERIVED_FROM node of {}. status is {}", uniqueId, parentNode);
2300 if (parentNode.isRight()) {
2301 TitanOperationStatus titanOperationStatus = parentNode.right().value();
2302 if (titanOperationStatus != TitanOperationStatus.NOT_FOUND) {
2303 log.error("Failed to find the parent data type of data type {}. status is {}", uniqueId, titanOperationStatus);
2304 result = Either.right(titanOperationStatus);
2308 // derived from node was found
2309 ImmutablePair<DataTypeData, GraphEdge> immutablePair = parentNode.left().value();
2310 DataTypeData parentCT = immutablePair.getKey();
2312 String parentUniqueId = parentCT.getUniqueId();
2313 Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = getDataTypeByUid(parentUniqueId);
2315 if (dataTypeByUid.isRight()) {
2316 return Either.right(dataTypeByUid.right().value());
2319 DataTypeDefinition parentDataTypeDefinition = dataTypeByUid.left().value();
2321 dataTypeDefinition.setDerivedFrom(parentDataTypeDefinition);
2324 result = Either.left(dataTypeDefinition);
2329 private Either<DataTypeDefinition, TitanOperationStatus> getDataTypeUsingName(String name) {
2330 String uid = UniqueIdBuilder.buildDataTypeUid(name);
2331 return getDataTypeByUid(uid);
2334 public Either<String, TitanOperationStatus> checkInnerType(PropertyDataDefinition propDataDef) {
2336 String propertyType = propDataDef.getType();
2338 ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
2340 return getInnerType(type, () -> propDataDef.getSchema());
2343 public Either<List<DataTypeData>, TitanOperationStatus> getAllDataTypeNodes() {
2344 Either<List<DataTypeData>, TitanOperationStatus> getAllDataTypes = titanGenericDao.getByCriteria(NodeTypeEnum.DataType, null, DataTypeData.class);
2345 if (getAllDataTypes.isRight()) {
2346 TitanOperationStatus status = getAllDataTypes.right().value();
2347 if (status == TitanOperationStatus.NOT_FOUND) {
2348 status = TitanOperationStatus.OK;
2349 return Either.right(status);
2352 return getAllDataTypes;
2355 public Either<Object, Boolean> validateAndUpdatePropertyValue(String propertyType, String value, boolean isValidate, String innerType, Map<String, DataTypeDefinition> dataTypes) {
2356 log.trace("Going to validate property value and its type. type = {}, value = {}", propertyType, value);
2357 ToscaPropertyType type = getType(propertyType);
2362 DataTypeDefinition dataTypeDefinition = dataTypes.get(propertyType);
2363 ImmutablePair<JsonElement, Boolean> validateResult = dataTypeValidatorConverter.validateAndUpdate(value, dataTypeDefinition, dataTypes);
2364 if (Boolean.FALSE.equals(validateResult.right)) {
2365 log.debug("The value {} of property from type {} is invalid", value, propertyType);
2366 return Either.right(false);
2368 JsonElement jsonElement = validateResult.left;
2369 String valueFromJsonElement = getValueFromJsonElement(jsonElement);
2370 return Either.left(valueFromJsonElement);
2372 log.trace("before validating property type {}", propertyType);
2373 boolean isValidProperty = isValidValue(type, value, innerType, dataTypes);
2374 if (!isValidProperty) {
2375 log.debug("The value {} of property from type {} is invalid", value, type);
2376 return Either.right(false);
2379 Object convertedValue = value;
2380 if (!isEmptyValue(value) && isValidate) {
2381 PropertyValueConverter converter = type.getConverter();
2382 convertedValue = converter.convert(value, innerType, dataTypes);
2384 return Either.left(convertedValue);
2387 public Either<Object, Boolean> validateAndUpdatePropertyValue(String propertyType, String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
2388 return validateAndUpdatePropertyValue(propertyType, value, true, innerType, dataTypes);
2391 public <T extends GraphNode> Either<List<PropertyDefinition>, StorageOperationStatus> getAllPropertiesRec(String uniqueId, NodeTypeEnum nodeType, Class<T> clazz) {
2392 return this.findPropertiesOfNode(nodeType, uniqueId)
2394 .bind(this::handleNotFoundProperties)
2396 .bind(props -> getAllDerivedFromChainProperties(uniqueId, nodeType, clazz, props.values()));
2399 private Either<Map<String, PropertyDefinition>, StorageOperationStatus> handleNotFoundProperties(TitanOperationStatus titanOperationStatus) {
2400 if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) {
2401 return Either.left(new HashMap<>());
2403 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titanOperationStatus));
2406 private <T extends GraphNode> Either<List<PropertyDefinition>, StorageOperationStatus> getAllDerivedFromChainProperties(String uniqueId, NodeTypeEnum nodeType, Class<T> clazz, Collection<PropertyDefinition> nodeProps) {
2407 List<PropertyDefinition> accumulatedProps = new ArrayList<>(nodeProps);
2408 String currentNodeUid = uniqueId;
2409 Either<T, StorageOperationStatus> derivedFrom;
2410 while ((derivedFrom = derivedFromOperation.getDerivedFromChild(currentNodeUid, nodeType, clazz)).isLeft()) {
2411 currentNodeUid = derivedFrom.left().value().getUniqueId();
2412 TitanOperationStatus titanOperationStatus = fillProperties(currentNodeUid, nodeType, accumulatedProps::addAll);
2413 if (titanOperationStatus != TitanOperationStatus.OK) {
2414 log.debug("failed to fetch properties for type {} with id {}", nodeType, currentNodeUid);
2415 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titanOperationStatus));
2418 StorageOperationStatus getDerivedResult = derivedFrom.right().value();
2419 return isReachedEndOfDerivedFromChain(getDerivedResult) ? Either.left(accumulatedProps) : Either.right(getDerivedResult);
2422 private boolean isReachedEndOfDerivedFromChain(StorageOperationStatus getDerivedResult) {
2423 return getDerivedResult == StorageOperationStatus.NOT_FOUND;
2427 * @Override public PropertyOperation getPropertyOperation() { return this; }
2429 protected TitanOperationStatus fillProperties(String uniqueId, NodeTypeEnum nodeType, Consumer<List<PropertyDefinition>> propertySetter) {
2430 Either<Map<String, PropertyDefinition>, TitanOperationStatus> findPropertiesOfNode = this.findPropertiesOfNode(nodeType, uniqueId);
2431 if (findPropertiesOfNode.isRight()) {
2432 TitanOperationStatus titanOperationStatus = findPropertiesOfNode.right().value();
2433 log.debug("After looking for properties of vertex {}. status is {}", uniqueId, titanOperationStatus);
2434 if (TitanOperationStatus.NOT_FOUND.equals(titanOperationStatus)) {
2435 return TitanOperationStatus.OK;
2437 return titanOperationStatus;
2440 Map<String, PropertyDefinition> properties = findPropertiesOfNode.left().value();
2442 if (properties != null) {
2443 List<PropertyDefinition> propertiesAsList = properties.entrySet().stream().map(p -> p.getValue()).collect(Collectors.toList());
2444 propertySetter.accept(propertiesAsList);
2447 return TitanOperationStatus.OK;
2452 * add properties to element type.
2454 * Per property, add a property node and associate it to the element type
2457 * @param propertiesMap
2461 protected Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToElementType(String uniqueId, NodeTypeEnum nodeType, Map<String, PropertyDefinition> propertiesMap) {
2463 Map<String, PropertyData> propertiesData = new HashMap<String, PropertyData>();
2465 if (propertiesMap != null) {
2467 for (Entry<String, PropertyDefinition> propertyDefinitionEntry : propertiesMap.entrySet()) {
2468 String propertyName = propertyDefinitionEntry.getKey();
2470 Either<PropertyData, TitanOperationStatus> addPropertyToNodeType = this.addPropertyToNodeType(propertyName, propertyDefinitionEntry.getValue(), nodeType, uniqueId);
2472 if (addPropertyToNodeType.isRight()) {
2473 TitanOperationStatus operationStatus = addPropertyToNodeType.right().value();
2474 log.error("Failed to associate {} {} to property {} in graph. status is {}", nodeType.getName(), uniqueId, propertyName, operationStatus);
2475 return Either.right(operationStatus);
2477 propertiesData.put(propertyName, addPropertyToNodeType.left().value());
2482 return Either.left(propertiesData);
2486 protected TitanOperationStatus addPropertiesToElementType(String uniqueId, NodeTypeEnum nodeType, Map<String, PropertyDefinition> propertiesMap, TitanVertex elementVertex) {
2488 if (propertiesMap != null) {
2490 for (Entry<String, PropertyDefinition> propertyDefinitionEntry : propertiesMap.entrySet()) {
2491 String propertyName = propertyDefinitionEntry.getKey();
2493 TitanOperationStatus operationStatus = this.addPropertyToNodeType(elementVertex, propertyName, propertyDefinitionEntry.getValue(), nodeType, uniqueId);
2495 if (!operationStatus.equals(TitanOperationStatus.OK)) {
2496 log.error("Failed to associate {} {} to property {} in graph. status is {}", nodeType.getName(), uniqueId, propertyName, operationStatus);
2497 return operationStatus;
2502 return TitanOperationStatus.OK;
2506 public Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToElementType(String uniqueId, NodeTypeEnum elementType, List<PropertyDefinition> properties) {
2508 Map<String, PropertyDefinition> propMap;
2509 if (properties == null) {
2512 propMap = properties.stream().collect(Collectors.toMap(propDef -> propDef.getName(), propDef -> propDef));
2514 return addPropertiesToElementType(uniqueId, elementType, propMap);
2518 public Either<DataTypeDefinition, StorageOperationStatus> updateDataType(DataTypeDefinition newDataTypeDefinition, DataTypeDefinition oldDataTypeDefinition) {
2519 return updateDataType(newDataTypeDefinition, oldDataTypeDefinition, true);
2522 private Either<DataTypeDefinition, StorageOperationStatus> updateDataType(DataTypeDefinition newDataTypeDefinition, DataTypeDefinition oldDataTypeDefinition, boolean inTransaction) {
2524 Either<DataTypeDefinition, StorageOperationStatus> result = null;
2528 List<PropertyDefinition> newProperties = newDataTypeDefinition.getProperties();
2530 List<PropertyDefinition> oldProperties = oldDataTypeDefinition.getProperties();
2532 String newDerivedFromName = getDerivedFromName(newDataTypeDefinition);
2534 String oldDerivedFromName = getDerivedFromName(oldDataTypeDefinition);
2536 String dataTypeName = newDataTypeDefinition.getName();
2538 List<PropertyDefinition> propertiesToAdd = new ArrayList<>();
2539 if (isPropertyOmitted(newProperties, oldProperties, dataTypeName) || isPropertyTypeChanged(dataTypeName, newProperties, oldProperties, propertiesToAdd) || isDerivedFromNameChanged(dataTypeName, newDerivedFromName, oldDerivedFromName)) {
2541 log.debug("The new data type {} is invalid.", dataTypeName);
2543 result = Either.right(StorageOperationStatus.CANNOT_UPDATE_EXISTING_ENTITY);
2547 if (propertiesToAdd == null || propertiesToAdd.isEmpty()) {
2548 log.debug("No new properties has been defined in the new data type {}", newDataTypeDefinition);
2549 result = Either.right(StorageOperationStatus.OK);
2553 Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToDataType = addPropertiesToDataType(oldDataTypeDefinition.getUniqueId(), propertiesToAdd);
2555 if (addPropertiesToDataType.isRight()) {
2556 log.debug("Failed to update data type {} to Graph. Status is {}", oldDataTypeDefinition, addPropertiesToDataType.right().value().name());
2557 BeEcompErrorManager.getInstance().logBeFailedAddingNodeTypeError("UpdateDataType", "Property");
2558 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(addPropertiesToDataType.right().value()));
2562 Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = this.getDataTypeByUid(oldDataTypeDefinition.getUniqueId());
2563 if (dataTypeByUid.isRight()) {
2564 TitanOperationStatus status = addPropertiesToDataType.right().value();
2565 log.debug("Failed to get data type {} after update. Status is {}", oldDataTypeDefinition.getUniqueId(), status.name());
2566 BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("UpdateDataType", "Property", status.name());
2567 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
2569 result = Either.left(dataTypeByUid.left().value());
2576 if (false == inTransaction) {
2577 if (result == null || result.isRight()) {
2578 log.error("Going to execute rollback on graph.");
2579 titanGenericDao.rollback();
2581 log.debug("Going to execute commit on graph.");
2582 titanGenericDao.commit();
2589 private String getDerivedFromName(DataTypeDefinition dataTypeDefinition) {
2590 String derivedFromName = dataTypeDefinition.getDerivedFromName();
2591 return derivedFromName;
2594 private boolean isPropertyTypeChanged(String dataTypeName, List<PropertyDefinition> newProperties, List<PropertyDefinition> oldProperties, List<PropertyDefinition> outputPropertiesToAdd) {
2596 if (newProperties != null && oldProperties != null) {
2598 Map<String, PropertyDefinition> newPropsMapper = newProperties.stream().collect(Collectors.toMap(p -> p.getName(), p -> p));
2599 Map<String, PropertyDefinition> oldPropsMapper = oldProperties.stream().collect(Collectors.toMap(p -> p.getName(), p -> p));
2601 for (Entry<String, PropertyDefinition> newPropertyEntry : newPropsMapper.entrySet()) {
2603 String propName = newPropertyEntry.getKey();
2604 PropertyDefinition propDef = newPropertyEntry.getValue();
2606 PropertyDefinition oldPropertyDefinition = oldPropsMapper.get(propName);
2607 if (oldPropertyDefinition == null) {
2608 log.debug("New property {} received in the data type {}", propName, dataTypeName);
2609 outputPropertiesToAdd.add(propDef);
2613 String oldType = oldPropertyDefinition.getType();
2614 String oldEntryType = getEntryType(oldPropertyDefinition);
2616 String newType = propDef.getType();
2617 String newEntryType = getEntryType(propDef);
2619 if (false == oldType.equals(newType)) {
2620 log.debug("Existing property {} in data type {} has a differnet type {} than the new one {}", propName, dataTypeName, oldType, newType);
2624 if (false == equalsEntryTypes(oldEntryType, newEntryType)) {
2625 log.debug("Existing property {} in data type {} has a differnet entry type {} than the new one {}", propName, dataTypeName, oldEntryType, newEntryType);
2636 private boolean equalsEntryTypes(String oldEntryType, String newEntryType) {
2638 if (oldEntryType == null && newEntryType == null) {
2640 } else if (oldEntryType != null && newEntryType != null) {
2641 return oldEntryType.equals(newEntryType);
2647 private String getEntryType(PropertyDefinition oldPropertyDefinition) {
2648 String entryType = null;
2649 SchemaDefinition schema = oldPropertyDefinition.getSchema();
2650 if (schema != null) {
2651 PropertyDataDefinition schemaProperty = schema.getProperty();
2652 if (schemaProperty != null) {
2653 entryType = schemaProperty.getType();
2659 private boolean isPropertyOmitted(List<PropertyDefinition> newProperties, List<PropertyDefinition> oldProperties, String dataTypeName) {
2661 boolean isValid = validateChangeInCaseOfEmptyProperties(newProperties, oldProperties, dataTypeName);
2662 if (false == isValid) {
2663 log.debug("At least one property is missing in the new data type {}", dataTypeName);
2667 if (newProperties != null && oldProperties != null) {
2669 List<String> newProps = newProperties.stream().map(p -> p.getName()).collect(Collectors.toList());
2670 List<String> oldProps = oldProperties.stream().map(p -> p.getName()).collect(Collectors.toList());
2672 if (false == newProps.containsAll(oldProps)) {
2673 StringJoiner joiner = new StringJoiner(",", "[", "]");
2674 newProps.forEach(p -> joiner.add(p));
2675 log.debug("Properties {} in data type {} are missing, but they already defined in the existing data type", joiner.toString(), dataTypeName);
2683 private boolean validateChangeInCaseOfEmptyProperties(List<PropertyDefinition> newProperties, List<PropertyDefinition> oldProperties, String dataTypeName) {
2685 if (newProperties != null) {
2686 if (newProperties.isEmpty()) {
2687 newProperties = null;
2691 if (oldProperties != null) {
2692 if (oldProperties.isEmpty()) {
2693 oldProperties = null;
2697 if ((newProperties == null && oldProperties == null) || (newProperties != null && oldProperties != null)) {
2704 private boolean isDerivedFromNameChanged(String dataTypeName, String newDerivedFromName, String oldDerivedFromName) {
2706 if (newDerivedFromName != null) {
2707 boolean isEqual = newDerivedFromName.equals(oldDerivedFromName);
2708 if (false == isEqual) {
2709 log.debug("The new datatype {} derived from another data type {} than the existing one {}", dataTypeName, newDerivedFromName, oldDerivedFromName);
2712 } else if (oldDerivedFromName == null) {
2714 } else {// new=null, old != null
2715 log.debug("The new datatype {} derived from another data type {} than the existing one {}", dataTypeName, newDerivedFromName, oldDerivedFromName);
2723 * Future - unfinished
2729 public boolean isValueToscaFunction(String type, String value) {
2731 boolean result = false;
2733 if (ToscaPropertyType.STRING.getType().equals(type) || isScalarDerivedFromString(type)) {
2737 String[] functions = { "get_input" };
2739 if (value != null) {
2741 for (String function : functions) {
2752 * Future - unfinished
2757 private boolean isScalarDerivedFromString(String type) {
2758 // TODO Auto-generated method stub