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 java.io.IOException;
24 import java.lang.reflect.Type;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.HashMap;
28 import java.util.Iterator;
29 import java.util.List;
31 import java.util.Map.Entry;
33 import java.util.StringJoiner;
34 import java.util.function.Consumer;
35 import java.util.regex.Matcher;
36 import java.util.regex.Pattern;
37 import java.util.stream.Collectors;
39 import org.apache.commons.collections.CollectionUtils;
40 import org.apache.commons.lang3.tuple.ImmutablePair;
41 import org.apache.tinkerpop.gremlin.structure.Edge;
42 import org.codehaus.jackson.JsonNode;
43 import org.codehaus.jackson.JsonProcessingException;
44 import org.codehaus.jackson.ObjectCodec;
45 import org.codehaus.jackson.map.DeserializationContext;
46 import org.openecomp.sdc.be.config.BeEcompErrorManager;
47 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
48 import org.openecomp.sdc.be.dao.graph.GraphElementFactory;
49 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
50 import org.openecomp.sdc.be.dao.graph.datatype.GraphElementTypeEnum;
51 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
52 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
53 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
54 import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
55 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
56 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
57 import org.openecomp.sdc.be.datatypes.elements.PropertyRule;
58 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
59 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
60 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
61 import org.openecomp.sdc.be.model.DataTypeDefinition;
62 import org.openecomp.sdc.be.model.IComplexDefaultValue;
63 import org.openecomp.sdc.be.model.PropertyConstraint;
64 import org.openecomp.sdc.be.model.PropertyDefinition;
65 import org.openecomp.sdc.be.model.operations.api.IPropertyOperation;
66 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
67 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
68 import org.openecomp.sdc.be.model.tosca.constraints.ConstraintType;
69 import org.openecomp.sdc.be.model.tosca.constraints.GreaterOrEqualConstraint;
70 import org.openecomp.sdc.be.model.tosca.constraints.GreaterThanConstraint;
71 import org.openecomp.sdc.be.model.tosca.constraints.InRangeConstraint;
72 import org.openecomp.sdc.be.model.tosca.constraints.LessOrEqualConstraint;
73 import org.openecomp.sdc.be.model.tosca.constraints.LessThanConstraint;
74 import org.openecomp.sdc.be.model.tosca.constraints.MinLengthConstraint;
75 import org.openecomp.sdc.be.model.tosca.constraints.ValidValuesConstraint;
76 import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter;
77 import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator;
78 import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
79 import org.openecomp.sdc.be.resources.data.DataTypeData;
80 import org.openecomp.sdc.be.resources.data.PropertyData;
81 import org.openecomp.sdc.be.resources.data.PropertyValueData;
82 import org.openecomp.sdc.be.resources.data.ResourceMetadataData;
83 import org.openecomp.sdc.be.resources.data.UniqueIdData;
84 import org.slf4j.Logger;
85 import org.slf4j.LoggerFactory;
86 import org.springframework.beans.factory.annotation.Qualifier;
87 import org.springframework.stereotype.Component;
89 import com.google.gson.JsonArray;
90 import com.google.gson.JsonDeserializationContext;
91 import com.google.gson.JsonDeserializer;
92 import com.google.gson.JsonElement;
93 import com.google.gson.JsonObject;
94 import com.google.gson.JsonParseException;
95 import com.google.gson.JsonParser;
96 import com.google.gson.JsonSerializationContext;
97 import com.google.gson.JsonSerializer;
98 import com.thinkaurelius.titan.core.TitanVertex;
100 import fj.data.Either;
102 @Component("property-operation")
103 public class PropertyOperation extends AbstractOperation implements IPropertyOperation {
105 private TitanGenericDao titanGenericDao;
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(@Qualifier("titan-generic-dao") TitanGenericDao titanGenericDao) {
124 this.titanGenericDao = titanGenericDao;
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;
158 public Either<PropertyDefinition, StorageOperationStatus> getPropertyOfResource(String propertyName, String resourceId) {
160 String propertyId = UniqueIdBuilder.buildComponentPropertyUniqueId(resourceId, propertyName);
162 Either<PropertyData, TitanOperationStatus> getResult = this.titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class);
163 if (getResult.isLeft()) {
164 PropertyData propertyData = getResult.left().value();
165 return Either.left(convertPropertyDataToPropertyDefinition(propertyData, propertyName, resourceId));
167 TitanOperationStatus titanStatus = getResult.right().value();
168 log.debug("Node with id {} was not found in the graph. status: {}", propertyId, titanStatus);
169 StorageOperationStatus storageOperationStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus);
170 return Either.right(storageOperationStatus);
178 * @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)
181 * @Override public Either<PropertyDefinition, StorageOperationStatus> addPropertyToResource( String propertyName, PropertyDefinition propertyDefinition, NodeTypeEnum nodeType, String resourceId) {
183 * StorageOperationStatus isValidProperty = isTypeExistsAndValid(propertyDefinition); if (isValidProperty != StorageOperationStatus.OK) { return Either.right(isValidProperty); }
185 * Either<PropertyData, TitanOperationStatus> status = addPropertyToGraph(propertyName, propertyDefinition, resourceId);
187 * if (status.isRight()) { titanGenericDao.rollback();
188 * log.error("Failed to add property {} to resource {}, propertyName, resourceId);
189 * return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status. right().value())); } else
190 * { titanGenericDao.commit(); PropertyData propertyData = status.left().value();
192 * PropertyDefinition propertyDefResult = convertPropertyDataToPropertyDefinition(propertyData, propertyName, resourceId); log.debug("The returned PropertyDefintion is " + propertyDefinition); return Either.left(propertyDefResult); }
197 private StorageOperationStatus isTypeExistsAndValid(PropertyDefinition propertyDefinition) {
199 ToscaPropertyType type = ToscaPropertyType.isValidType(propertyDefinition.getType());
202 return StorageOperationStatus.INVALID_TYPE;
205 String propertyType = propertyDefinition.getType();
206 String innerType = null;
207 String value = propertyDefinition.getDefaultValue();
209 if (propertyType.equals(ToscaPropertyType.LIST) || propertyType.equals(ToscaPropertyType.MAP)) {
210 SchemaDefinition schema;
211 if ((schema = propertyDefinition.getSchema()) != null) {
212 PropertyDataDefinition property;
213 if ((property = schema.getProperty()) != null) {
214 innerType = property.getType();
220 PropertyTypeValidator validator = type.getValidator();
222 if (value == null || (EMPTY_VALUE != null && EMPTY_VALUE.equals(propertyDefinition.getDefaultValue()))) {
223 return StorageOperationStatus.OK;
225 boolean isValid = validator.isValid(value, innerType, null);
226 if (true == isValid) {
227 return StorageOperationStatus.OK;
229 return StorageOperationStatus.INVALID_VALUE;
235 public PropertyDefinition convertPropertyDataToPropertyDefinition(PropertyData propertyDataResult, String propertyName, String resourceId) {
236 log.debug("The object returned after create property is {}", propertyDataResult);
238 PropertyDefinition propertyDefResult = new PropertyDefinition(propertyDataResult.getPropertyDataDefinition());
239 propertyDefResult.setConstraints(convertConstraints(propertyDataResult.getConstraints()));
240 propertyDefResult.setName(propertyName);
241 // propertyDefResult.setParentUniqueId(resourceId);
243 return propertyDefResult;
246 public static class PropertyConstraintSerialiser implements JsonSerializer<PropertyConstraint> {
249 public JsonElement serialize(PropertyConstraint src, Type typeOfSrc, JsonSerializationContext context) {
250 JsonParser parser = new JsonParser();
251 JsonObject result = new JsonObject();
252 JsonArray jsonArray = new JsonArray();
253 if (src instanceof InRangeConstraint) {
254 InRangeConstraint rangeConstraint = (InRangeConstraint) src;
255 jsonArray.add(parser.parse(rangeConstraint.getRangeMinValue()));
256 jsonArray.add(parser.parse(rangeConstraint.getRangeMaxValue()));
257 result.add("inRange", jsonArray);
258 } else if (src instanceof GreaterThanConstraint) {
259 GreaterThanConstraint greaterThanConstraint = (GreaterThanConstraint) src;
260 jsonArray.add(parser.parse(greaterThanConstraint.getGreaterThan()));
261 result.add("greaterThan", jsonArray);
262 } else if (src instanceof LessOrEqualConstraint) {
263 LessOrEqualConstraint lessOrEqualConstraint = (LessOrEqualConstraint) src;
264 jsonArray.add(parser.parse(lessOrEqualConstraint.getLessOrEqual()));
265 result.add("lessOrEqual", jsonArray);
267 log.warn("PropertyConstraint {} is not supported. Ignored.", src.getClass().getName());
275 public static class PropertyConstraintDeserialiser implements JsonDeserializer<PropertyConstraint> {
278 public PropertyConstraint deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
280 PropertyConstraint propertyConstraint = null;
282 Set<Entry<String, JsonElement>> set = json.getAsJsonObject().entrySet();
284 if (set.size() == 1) {
285 Entry<String, JsonElement> element = set.iterator().next();
286 String key = element.getKey();
287 JsonElement value = element.getValue();
289 ConstraintType constraintType = ConstraintType.getByType(key);
290 if (constraintType == null) {
291 log.warn("ConstraintType was not found for constraint name:{}", key);
293 switch (constraintType) {
297 if (value instanceof JsonArray) {
298 JsonArray rangeArray = (JsonArray) value;
299 if (rangeArray.size() != 2) {
300 log.error("The range constraint content is invalid. value = {}", value);
302 InRangeConstraint rangeConstraint = new InRangeConstraint();
303 String minValue = rangeArray.get(0).getAsString();
304 String maxValue = rangeArray.get(1).getAsString();
305 rangeConstraint.setRangeMinValue(minValue);
306 rangeConstraint.setRangeMaxValue(maxValue);
307 propertyConstraint = rangeConstraint;
312 log.warn("The value of GreaterThanConstraint is null");
317 String asString = value.getAsString();
318 log.debug("Before adding value to GreaterThanConstraint object. value = {}", asString);
319 propertyConstraint = new GreaterThanConstraint(asString);
322 log.warn("The value of GreaterThanConstraint is null");
328 String asString = value.getAsString();
329 log.debug("Before adding value to LessThanConstraint object. value = {}", asString);
330 propertyConstraint = new LessThanConstraint(asString);
333 log.warn("The value of LessThanConstraint is null");
336 case GREATER_OR_EQUAL:
338 String asString = value.getAsString();
339 log.debug("Before adding value to GreaterThanConstraint object. value = {}", asString);
340 propertyConstraint = new GreaterOrEqualConstraint(asString);
343 log.warn("The value of GreaterOrEqualConstraint is null");
349 String asString = value.getAsString();
350 log.debug("Before adding value to LessOrEqualConstraint object. value = {}", asString);
351 propertyConstraint = new LessOrEqualConstraint(asString);
353 log.warn("The value of GreaterThanConstraint is null");
360 if (value instanceof JsonArray) {
361 JsonArray rangeArray = (JsonArray) value;
362 if (rangeArray.size() == 0) {
363 log.error("The valid values constraint content is invalid. value = {}", value);
365 ValidValuesConstraint vvConstraint = new ValidValuesConstraint();
366 List<String> validValues = new ArrayList<String>();
367 for (JsonElement jsonElement : rangeArray) {
368 String item = jsonElement.getAsString();
369 validValues.add(item);
371 vvConstraint.setValidValues(validValues);
372 propertyConstraint = vvConstraint;
377 log.warn("The value of ValidValuesConstraint is null");
383 int asInt = value.getAsInt();
384 log.debug("Before adding value to Min Length object. value = {}", asInt);
385 propertyConstraint = new MinLengthConstraint(asInt);
388 log.warn("The value of MinLengthConstraint is null");
392 log.warn("Key {} is not supported. Ignored.", key);
397 return propertyConstraint;
402 public TitanOperationStatus addPropertiesToGraph(Map<String, PropertyDefinition> properties, String resourceId, Map<String, DataTypeDefinition> dataTypes) {
404 ResourceMetadataData resourceData = new ResourceMetadataData();
405 resourceData.getMetadataDataDefinition().setUniqueId(resourceId);
407 if (properties != null) {
408 for (Entry<String, PropertyDefinition> entry : properties.entrySet()) {
410 String propertyName = entry.getKey();
411 PropertyDefinition propertyDefinition = entry.getValue();
413 StorageOperationStatus validateAndUpdateProperty = validateAndUpdateProperty(propertyDefinition, dataTypes);
414 if (validateAndUpdateProperty != StorageOperationStatus.OK) {
415 log.error("Property {} is invalid. Status is {}", propertyDefinition, validateAndUpdateProperty);
416 return TitanOperationStatus.ILLEGAL_ARGUMENT;
419 Either<PropertyData, TitanOperationStatus> addPropertyToGraph = addPropertyToGraph(propertyName, propertyDefinition, resourceId);
421 if (addPropertyToGraph.isRight()) {
422 return addPropertyToGraph.right().value();
427 return TitanOperationStatus.OK;
431 public TitanOperationStatus addPropertiesToGraph(TitanVertex metadataVertex, Map<String, PropertyDefinition> properties, Map<String, DataTypeDefinition> dataTypes, String resourceId) {
433 if (properties != null) {
434 for (Entry<String, PropertyDefinition> entry : properties.entrySet()) {
436 String propertyName = entry.getKey();
437 PropertyDefinition propertyDefinition = entry.getValue();
439 StorageOperationStatus validateAndUpdateProperty = validateAndUpdateProperty(propertyDefinition, dataTypes);
440 if (validateAndUpdateProperty != StorageOperationStatus.OK) {
441 log.error("Property {} is invalid. Status is {}", propertyDefinition, validateAndUpdateProperty);
442 return TitanOperationStatus.ILLEGAL_ARGUMENT;
445 TitanOperationStatus addPropertyToGraph = addPropertyToGraphByVertex(metadataVertex, propertyName, propertyDefinition, resourceId);
447 if (!addPropertyToGraph.equals(TitanOperationStatus.OK)) {
448 return addPropertyToGraph;
453 return TitanOperationStatus.OK;
457 public Either<PropertyData, StorageOperationStatus> addProperty(String propertyName, PropertyDefinition propertyDefinition, String resourceId) {
459 Either<PropertyData, TitanOperationStatus> either = addPropertyToGraph(propertyName, propertyDefinition, resourceId);
460 if (either.isRight()) {
461 StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value());
462 return Either.right(storageStatus);
464 return Either.left(either.left().value());
468 * @param propertyDefinition
472 public StorageOperationStatus validateAndUpdateProperty(IComplexDefaultValue propertyDefinition, Map<String, DataTypeDefinition> dataTypes) {
474 log.trace("Going to validate property type and value. {}", propertyDefinition);
476 String propertyType = propertyDefinition.getType();
477 String value = propertyDefinition.getDefaultValue();
479 ToscaPropertyType type = getType(propertyType);
483 DataTypeDefinition dataTypeDefinition = dataTypes.get(propertyType);
484 if (dataTypeDefinition == null) {
485 log.debug("The type {} of property cannot be found.", propertyType);
486 return StorageOperationStatus.INVALID_TYPE;
489 StorageOperationStatus status = validateAndUpdateComplexValue(propertyDefinition, propertyType, value, dataTypeDefinition, dataTypes);
494 String innerType = null;
496 Either<String, TitanOperationStatus> checkInnerType = getInnerType(type, () -> propertyDefinition.getSchema());
497 if (checkInnerType.isRight()) {
498 return StorageOperationStatus.INVALID_TYPE;
500 innerType = checkInnerType.left().value();
502 log.trace("After validating property type {}", propertyType);
504 boolean isValidProperty = isValidValue(type, value, innerType, dataTypes);
505 if (false == isValidProperty) {
506 log.info("The value {} of property from type {} is invalid", value, type);
507 return StorageOperationStatus.INVALID_VALUE;
510 PropertyValueConverter converter = type.getConverter();
512 if (isEmptyValue(value)) {
513 log.debug("Default value was not sent for property {}. Set default value to {}", propertyDefinition.getName(), EMPTY_VALUE);
514 propertyDefinition.setDefaultValue(EMPTY_VALUE);
515 } else if (false == isEmptyValue(value)) {
516 String convertedValue = converter.convert(value, innerType, dataTypes);
517 propertyDefinition.setDefaultValue(convertedValue);
519 return StorageOperationStatus.OK;
523 * public Either<Object, Boolean> validateAndUpdatePropertyValue(String propertyType, String value, String innerType) {
525 * log. trace("Going to validate property value and its type. type = {}, value = {}" ,propertyType, value);
527 * ToscaPropertyType type = getType(propertyType);
529 * if (type == null) {
531 * Either<DataTypeDefinition, TitanOperationStatus> externalDataType = getExternalDataType(propertyType); if (externalDataType.isRight()) { TitanOperationStatus status = externalDataType.right().value(); log.debug("The type " + propertyType +
532 * " 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); }
534 * DataTypeDefinition dataTypeDefinition = externalDataType.left().value();
536 * Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypesRes = getAllDataTypes(); if (allDataTypesRes.isRight()) { TitanOperationStatus status = allDataTypesRes.right().value(); return Either.right(false); }
538 * Map<String, DataTypeDefinition> allDataTypes = allDataTypesRes.left().value();
540 * ImmutablePair<JsonElement, Boolean> validateResult = dataTypeValidatorConverter.validateAndUpdate(value, dataTypeDefinition, allDataTypes);
542 * if (validateResult.right.booleanValue() == false) {
543 * log.debug("The value {} of property from type {} is invalid", value, propertyType);
544 * return Either.right(false); }
546 * JsonElement jsonElement = validateResult.left;
548 * String valueFromJsonElement = getValueFromJsonElement(jsonElement);
550 * return Either.left(valueFromJsonElement);
554 * log.trace("After validating property type {}", propertyType);
556 * 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); }
559 * Object convertedValue = value; if (false == isEmptyValue(value)) { PropertyValueConverter converter = type.getConverter(); convertedValue = converter.convert(value, null); }
561 * return Either.left(convertedValue); }
564 public Either<PropertyData, TitanOperationStatus> addPropertyToGraph(String propertyName, PropertyDefinition propertyDefinition, String resourceId) {
566 ResourceMetadataData resourceData = new ResourceMetadataData();
567 resourceData.getMetadataDataDefinition().setUniqueId(resourceId);
569 List<PropertyConstraint> constraints = propertyDefinition.getConstraints();
571 propertyDefinition.setUniqueId(UniqueIdBuilder.buildComponentPropertyUniqueId(resourceId, propertyName));
572 PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints));
574 log.debug("Before adding property to graph {}", propertyData);
575 Either<PropertyData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyData, PropertyData.class);
576 log.debug("After adding property to graph {}", propertyData);
577 if (createNodeResult.isRight()) {
578 TitanOperationStatus operationStatus = createNodeResult.right().value();
579 log.error("Failed to add property {} to graph. status is {}", propertyName, operationStatus);
580 return Either.right(operationStatus);
583 Map<String, Object> props = new HashMap<String, Object>();
584 props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName);
585 Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(resourceData, propertyData, GraphEdgeLabels.PROPERTY, props);
586 if (createRelResult.isRight()) {
587 TitanOperationStatus operationStatus = createNodeResult.right().value();
588 log.error("Failed to associate resource {} to property {} in graph. status is {}", resourceId, propertyName, operationStatus);
589 return Either.right(operationStatus);
592 return Either.left(createNodeResult.left().value());
596 public TitanOperationStatus addPropertyToGraphByVertex(TitanVertex metadataVertex, String propertyName, PropertyDefinition propertyDefinition, String resourceId) {
598 List<PropertyConstraint> constraints = propertyDefinition.getConstraints();
600 propertyDefinition.setUniqueId(UniqueIdBuilder.buildComponentPropertyUniqueId(resourceId, propertyName));
601 PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints));
603 log.debug("Before adding property to graph {}", propertyData);
604 Either<TitanVertex, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyData);
605 log.debug("After adding property to graph {}", propertyData);
606 if (createNodeResult.isRight()) {
607 TitanOperationStatus operationStatus = createNodeResult.right().value();
608 log.error("Failed to add property {} to graph. status is ", propertyName, operationStatus);
609 return operationStatus;
612 Map<String, Object> props = new HashMap<String, Object>();
613 props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName);
614 TitanVertex propertyVertex = createNodeResult.left().value();
615 TitanOperationStatus createRelResult = titanGenericDao.createEdge(metadataVertex, propertyVertex, GraphEdgeLabels.PROPERTY, props);
616 if (!createRelResult.equals(TitanOperationStatus.OK)) {
617 log.error("Failed to associate resource {} to property {} in graph. status is {}", resourceId, propertyName, createRelResult);
618 return createRelResult;
621 return createRelResult;
625 public TitanGenericDao getTitanGenericDao() {
626 return titanGenericDao;
629 // public Either<PropertyData, StorageOperationStatus>
630 // deletePropertyFromGraphFromBl(String propertyId) {
634 public Either<PropertyData, StorageOperationStatus> deleteProperty(String propertyId) {
635 Either<PropertyData, TitanOperationStatus> either = deletePropertyFromGraph(propertyId);
636 if (either.isRight()) {
637 StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value());
638 return Either.right(storageStatus);
640 return Either.left(either.left().value());
643 public Either<PropertyData, TitanOperationStatus> deletePropertyFromGraph(String propertyId) {
644 log.debug("Before deleting property from graph {}", propertyId);
645 return titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class);
648 public Either<PropertyData, StorageOperationStatus> updateProperty(String propertyId, PropertyDefinition newPropertyDefinition, Map<String, DataTypeDefinition> dataTypes) {
650 StorageOperationStatus validateAndUpdateProperty = validateAndUpdateProperty(newPropertyDefinition, dataTypes);
651 if (validateAndUpdateProperty != StorageOperationStatus.OK) {
652 return Either.right(validateAndUpdateProperty);
655 Either<PropertyData, TitanOperationStatus> either = updatePropertyFromGraph(propertyId, newPropertyDefinition);
656 if (either.isRight()) {
657 StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value());
658 return Either.right(storageStatus);
660 return Either.left(either.left().value());
663 public Either<PropertyData, TitanOperationStatus> updatePropertyFromGraph(String propertyId, PropertyDefinition propertyDefinition) {
664 if (log.isDebugEnabled())
665 log.debug("Before updating property on graph {}", propertyId);
667 // get the original property data
668 Either<PropertyData, TitanOperationStatus> statusProperty = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class);
669 if (statusProperty.isRight()) {
670 log.debug("Problem while get property with id {}. Reason - {}", propertyId, statusProperty.right().value().name());
671 return Either.right(statusProperty.right().value());
673 PropertyData orgPropertyData = statusProperty.left().value();
674 PropertyDataDefinition orgPropertyDataDefinition = orgPropertyData.getPropertyDataDefinition();
676 // create new property data to update
677 PropertyData newPropertyData = new PropertyData();
678 newPropertyData.setPropertyDataDefinition(propertyDefinition);
679 PropertyDataDefinition newPropertyDataDefinition = newPropertyData.getPropertyDataDefinition();
681 // update the original property data with new values
682 if (orgPropertyDataDefinition.getDefaultValue() == null) {
683 orgPropertyDataDefinition.setDefaultValue(newPropertyDataDefinition.getDefaultValue());
685 if (!orgPropertyDataDefinition.getDefaultValue().equals(newPropertyDataDefinition.getDefaultValue())) {
686 orgPropertyDataDefinition.setDefaultValue(newPropertyDataDefinition.getDefaultValue());
689 if (orgPropertyDataDefinition.getDescription() == null) {
690 orgPropertyDataDefinition.setDescription(newPropertyDataDefinition.getDescription());
692 if (!orgPropertyDataDefinition.getDescription().equals(newPropertyDataDefinition.getDescription())) {
693 orgPropertyDataDefinition.setDescription(newPropertyDataDefinition.getDescription());
696 if (!orgPropertyDataDefinition.getType().equals(newPropertyDataDefinition.getType())) {
697 orgPropertyDataDefinition.setType(newPropertyDataDefinition.getType());
699 if (newPropertyData.getConstraints() != null) {
700 orgPropertyData.setConstraints(newPropertyData.getConstraints());
702 orgPropertyDataDefinition.setSchema(newPropertyDataDefinition.getSchema());
704 return titanGenericDao.updateNode(orgPropertyData, PropertyData.class);
710 * @param titanGenericDao
712 public void setTitanGenericDao(TitanGenericDao titanGenericDao) {
713 this.titanGenericDao = titanGenericDao;
716 public Either<PropertyData, TitanOperationStatus> addPropertyToNodeType(String propertyName, PropertyDefinition propertyDefinition, NodeTypeEnum nodeType, String uniqueId) {
718 List<PropertyConstraint> constraints = propertyDefinition.getConstraints();
720 propertyDefinition.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(uniqueId, propertyName));
721 PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints));
723 if (log.isDebugEnabled())
724 log.debug("Before adding property to graph {}", propertyData);
725 Either<PropertyData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyData, PropertyData.class);
726 if (log.isDebugEnabled())
727 log.debug("After adding property to graph {}", propertyData);
728 if (createNodeResult.isRight()) {
729 TitanOperationStatus operationStatus = createNodeResult.right().value();
730 log.error("Failed to add property {} to graph. status is {}", propertyName, operationStatus);
731 return Either.right(operationStatus);
734 Map<String, Object> props = new HashMap<String, Object>();
735 props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName);
737 UniqueIdData uniqueIdData = new UniqueIdData(nodeType, uniqueId);
738 log.debug("Before associating {} to property {}", uniqueIdData, propertyName);
739 Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(uniqueIdData, propertyData, GraphEdgeLabels.PROPERTY, props);
740 if (createRelResult.isRight()) {
741 TitanOperationStatus operationStatus = createNodeResult.right().value();
742 log.error("Failed to associate resource {} to property {} in graph. status is {}", uniqueId, propertyName, operationStatus);
743 return Either.right(operationStatus);
746 return Either.left(createNodeResult.left().value());
750 public TitanOperationStatus addPropertyToNodeType(TitanVertex elementVertex, String propertyName, PropertyDefinition propertyDefinition, NodeTypeEnum nodeType, String uniqueId) {
752 List<PropertyConstraint> constraints = propertyDefinition.getConstraints();
754 propertyDefinition.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(uniqueId, propertyName));
755 PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints));
757 if (log.isDebugEnabled())
758 log.debug("Before adding property to graph {}", propertyData);
759 Either<TitanVertex, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyData);
760 if (log.isDebugEnabled())
761 log.debug("After adding property to graph {}", propertyData);
762 if (createNodeResult.isRight()) {
763 TitanOperationStatus operationStatus = createNodeResult.right().value();
764 log.error("Failed to add property {} to graph. status is {} ", propertyName, operationStatus);
765 return operationStatus;
768 Map<String, Object> props = new HashMap<String, Object>();
769 props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName);
771 TitanOperationStatus createRelResult = titanGenericDao.createEdge(elementVertex, propertyData, GraphEdgeLabels.PROPERTY, props);
772 if (!createRelResult.equals(TitanOperationStatus.OK)) {
773 log.error("Failed to associate resource {} to property {} in graph. status is {}", uniqueId, propertyName, createRelResult);
774 return createRelResult;
777 return createRelResult;
781 public Either<Map<String, PropertyDefinition>, TitanOperationStatus> findPropertiesOfNode(NodeTypeEnum nodeType, String uniqueId) {
783 Map<String, PropertyDefinition> resourceProps = new HashMap<String, PropertyDefinition>();
785 Either<List<ImmutablePair<PropertyData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.PROPERTY, NodeTypeEnum.Property,
788 if (childrenNodes.isRight()) {
789 TitanOperationStatus operationStatus = childrenNodes.right().value();
790 return Either.right(operationStatus);
793 List<ImmutablePair<PropertyData, GraphEdge>> values = childrenNodes.left().value();
794 if (values != null) {
796 for (ImmutablePair<PropertyData, GraphEdge> immutablePair : values) {
797 GraphEdge edge = immutablePair.getValue();
798 String propertyName = (String) edge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty());
799 log.debug("Property {} is associated to node {}", propertyName, uniqueId);
800 PropertyData propertyData = immutablePair.getKey();
801 PropertyDefinition propertyDefinition = this.convertPropertyDataToPropertyDefinition(propertyData, propertyName, uniqueId);
802 resourceProps.put(propertyName, propertyDefinition);
807 log.debug("The properties associated to node {} are {}", uniqueId, resourceProps);
808 return Either.left(resourceProps);
811 public Either<Map<String, PropertyDefinition>, StorageOperationStatus> deleteAllPropertiesAssociatedToNode(NodeTypeEnum nodeType, String uniqueId) {
813 Either<Map<String, PropertyDefinition>, TitanOperationStatus> propertiesOfNodeRes = findPropertiesOfNode(nodeType, uniqueId);
815 if (propertiesOfNodeRes.isRight()) {
816 TitanOperationStatus status = propertiesOfNodeRes.right().value();
817 if (status == TitanOperationStatus.NOT_FOUND) {
818 return Either.right(StorageOperationStatus.OK);
820 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
823 Map<String, PropertyDefinition> value = propertiesOfNodeRes.left().value();
824 for (PropertyDefinition propertyDefinition : value.values()) {
826 String propertyUid = propertyDefinition.getUniqueId();
827 Either<PropertyData, TitanOperationStatus> deletePropertyRes = deletePropertyFromGraph(propertyUid);
828 if (deletePropertyRes.isRight()) {
829 log.error("Failed to delete property with id {}", propertyUid);
830 TitanOperationStatus status = deletePropertyRes.right().value();
831 if (status == TitanOperationStatus.NOT_FOUND) {
832 status = TitanOperationStatus.INVALID_ID;
834 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
839 log.debug("The properties deleted from node {} are {}", uniqueId, value);
840 return Either.left(value);
844 * fetch all properties under a given resource(includes its parents' resources)
850 public TitanOperationStatus findAllResourcePropertiesRecursively(String resourceId, List<PropertyDefinition> properties) {
851 final NodeElementFetcher<PropertyDefinition> singleNodeFetcher = (resourceIdParam, attributesParam) -> findPropertiesOfNode(NodeTypeEnum.Resource, resourceIdParam, attributesParam);
852 return findAllResourceElementsDefinitionRecursively(resourceId, properties, singleNodeFetcher);
863 protected TitanOperationStatus findPropertiesOfNode(NodeTypeEnum nodeType, String uniqueId, List<PropertyDefinition> properties) {
865 Either<List<ImmutablePair<PropertyData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.PROPERTY, NodeTypeEnum.Property,
868 if (childrenNodes.isRight()) {
869 TitanOperationStatus status = childrenNodes.right().value();
870 if (status == TitanOperationStatus.NOT_FOUND) {
871 status = TitanOperationStatus.OK;
876 List<ImmutablePair<PropertyData, GraphEdge>> values = childrenNodes.left().value();
877 if (values != null) {
879 for (ImmutablePair<PropertyData, GraphEdge> immutablePair : values) {
880 GraphEdge edge = immutablePair.getValue();
881 String propertyName = (String) edge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty());
882 if (log.isDebugEnabled())
883 log.debug("Property {} is associated to node {}", propertyName, uniqueId);
884 PropertyData propertyData = immutablePair.getKey();
885 PropertyDefinition propertyDefinition = this.convertPropertyDataToPropertyDefinition(propertyData, propertyName, uniqueId);
886 //Adds parent property to List if it hasn't been overrided in one of the children
887 if(!properties.stream().filter(p -> p.getName().equals(propertyDefinition.getName())).findAny().isPresent()){
888 properties.add(propertyDefinition);
891 if (log.isTraceEnabled())
892 log.trace("findPropertiesOfNode - property {} associated to node {}", propertyDefinition, uniqueId);
897 return TitanOperationStatus.OK;
900 * Checks existence of a property with the same name belonging to the same resource
901 * or existence of property with the same name and different type (including derived from hierarchy)
904 * @param propertyName
905 * @param propertyType
908 public boolean isPropertyExist(List<PropertyDefinition> properties, String resourceUid, String propertyName, String propertyType) {
909 boolean result = false;
910 if (!CollectionUtils.isEmpty(properties)) {
911 for (PropertyDefinition propertyDefinition : properties) {
913 if ( propertyDefinition.getName().equals(propertyName) &&
914 (propertyDefinition.getParentUniqueId().equals(resourceUid) || !propertyDefinition.getType().equals(propertyType)) ) {
924 * add property to resource instance
927 * TODO // * @param resourceInstanceProperty // * @param resourceInstanceId // * @param index
932 * public Either<PropertyValueData, TitanOperationStatus> addPropertyToResourceInstance( ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, Integer index) {
934 * Either<ComponentInstanceData, TitanOperationStatus> findResInstanceRes = titanGenericDao .getNode(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, ComponentInstanceData.class);
936 * if (findResInstanceRes.isRight()) { TitanOperationStatus status = findResInstanceRes.right().value(); if (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); }
938 * String propertyId = resourceInstanceProperty.getUniqueId(); Either<PropertyData, TitanOperationStatus> findPropertyDefRes = titanGenericDao .getNode(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class);
940 * if (findPropertyDefRes.isRight()) { TitanOperationStatus status = findPropertyDefRes.right().value(); if (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); }
942 * String valueUniqueUid = resourceInstanceProperty.getValueUniqueUid(); if (valueUniqueUid == null) {
944 * PropertyData propertyData = findPropertyDefRes.left().value(); ComponentInstanceData resourceInstanceData = findResInstanceRes.left().value();
946 * ImmutablePair<TitanOperationStatus, String> isPropertyValueExists = findPropertyValue(resourceInstanceId, propertyId); if (isPropertyValueExists.getLeft() == TitanOperationStatus.ALREADY_EXIST) { log.debug("The property " + propertyId +
947 * " already added to the resource instance " + resourceInstanceId); resourceInstanceProperty.setValueUniqueUid(isPropertyValueExists.getRight ()); Either<PropertyValueData, TitanOperationStatus> updatePropertyOfResourceInstance =
948 * updatePropertyOfResourceInstance(resourceInstanceProperty, resourceInstanceId); if (updatePropertyOfResourceInstance.isRight()) { BeEcompErrorManager.getInstance().logInternalFlowError( "UpdatePropertyValueOnComponentInstance",
949 * "Failed to update property value on instance. Status is " + updatePropertyOfResourceInstance.right().value(), ErrorSeverity.ERROR); return Either.right(updatePropertyOfResourceInstance.right().value()); } return
950 * Either.left(updatePropertyOfResourceInstance.left().value()); }
952 * if (isPropertyValueExists.getLeft() != TitanOperationStatus.NOT_FOUND) {
953 * log.debug("After finding property value of {} on componenet instance {}", propertyId, resourceInstanceId);
954 * return Either.right(isPropertyValueExists.getLeft()); }
956 * String propertyType = propertyData.getPropertyDataDefinition().getType(); String value = resourceInstanceProperty.getValue(); Either<Object, Boolean> isValid = validateAndUpdatePropertyValue(propertyType, value);
958 * 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) {
959 * newValue = object.toString(); } }
961 * String uniqueId = UniqueIdBuilder.buildResourceInstancePropertyValueUid( resourceInstanceData.getUniqueId(), index); PropertyValueData propertyValueData = new PropertyValueData(); propertyValueData.setUniqueId(uniqueId);
962 * propertyValueData.setValue(newValue);
964 * ImmutablePair<String, Boolean> pair = validateAndUpdateRules(propertyType, resourceInstanceProperty.getRules()); if (pair.getRight() != null && pair.getRight() == false) { BeEcompErrorManager.getInstance().
965 * logBeInvalidValueError("Add property value", pair.getLeft(), resourceInstanceProperty.getName(), propertyType); return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); } addRulesToNewPropertyValue(propertyValueData,
966 * resourceInstanceProperty, resourceInstanceId);
968 * log.debug("Before adding property value to graph {}", propertyValueData);
969 * Either<PropertyValueData, TitanOperationStatus> createNodeResult = titanGenericDao .createNode(propertyValueData, PropertyValueData.class);
970 * log.debug("After adding property value to graph {}", propertyValueData);
972 * Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao .createRelation(propertyValueData, propertyData, GraphEdgeLabels.PROPERTY_IMPL, null);
974 * if (createRelResult.isRight()) { TitanOperationStatus operationStatus = createNodeResult.right() .value(); //TODO: change logger log.error("Failed to associate property value " + uniqueId + " to property " + propertyId +
975 * " in graph. status is " + operationStatus); return Either.right(operationStatus); }
977 * createRelResult = titanGenericDao .createRelation(resourceInstanceData, propertyValueData, GraphEdgeLabels.PROPERTY_VALUE, null);
979 * if (createRelResult.isRight()) { TitanOperationStatus operationStatus = createNodeResult.right() .value(); //TODO: change logger log.error("Failed to associate resource instance " + resourceInstanceId + " property value " + uniqueId +
980 * " in graph. status is " + operationStatus); return Either.right(operationStatus); }
982 * return Either.left(createNodeResult.left().value()); } else { log.error("property value already exists."); return Either.right(TitanOperationStatus.ALREADY_EXIST); }
986 public ImmutablePair<String, Boolean> validateAndUpdateRules(String propertyType, List<PropertyRule> rules, String innerType, Map<String, DataTypeDefinition> dataTypes, boolean isValidate) {
988 if (rules == null || rules.isEmpty() == true) {
989 return new ImmutablePair<String, Boolean>(null, true);
992 for (PropertyRule rule : rules) {
993 String value = rule.getValue();
994 Either<Object, Boolean> updateResult = validateAndUpdatePropertyValue(propertyType, value, isValidate, innerType, dataTypes);
995 if (updateResult.isRight()) {
996 Boolean status = updateResult.right().value();
997 if (status == false) {
998 return new ImmutablePair<String, Boolean>(value, status);
1001 String newValue = null;
1002 Object object = updateResult.left().value();
1003 if (object != null) {
1004 newValue = object.toString();
1006 rule.setValue(newValue);
1010 return new ImmutablePair<String, Boolean>(null, true);
1013 public void addRulesToNewPropertyValue(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId) {
1015 List<PropertyRule> rules = resourceInstanceProperty.getRules();
1016 if (rules == null) {
1017 PropertyRule propertyRule = buildRuleFromPath(propertyValueData, resourceInstanceProperty, resourceInstanceId);
1018 rules = new ArrayList<>();
1019 rules.add(propertyRule);
1021 rules = sortRules(rules);
1024 propertyValueData.setRules(rules);
1027 private PropertyRule buildRuleFromPath(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId) {
1028 List<String> path = resourceInstanceProperty.getPath();
1029 // FOR BC. Since old Property values on VFC/VF does not have rules on
1031 // Update could be done on one level only, thus we can use this
1032 // operation to avoid migration.
1033 if (path == null || path.isEmpty() == true) {
1034 path = new ArrayList<>();
1035 path.add(resourceInstanceId);
1037 PropertyRule propertyRule = new PropertyRule();
1038 propertyRule.setRule(path);
1039 propertyRule.setValue(propertyValueData.getValue());
1040 return propertyRule;
1043 private List<PropertyRule> sortRules(List<PropertyRule> rules) {
1045 // TODO: sort the rules by size and binary representation.
1046 // (x, y, .+) --> 110 6 priority 1
1047 // (x, .+, z) --> 101 5 priority 2
1052 public ImmutablePair<TitanOperationStatus, String> findPropertyValue(String resourceInstanceId, String propertyId) {
1054 log.debug("Going to check whether the property {} already added to resource instance {}", propertyId, resourceInstanceId);
1056 Either<List<ComponentInstanceProperty>, TitanOperationStatus> getAllRes = this.getAllPropertiesOfResourceInstanceOnlyPropertyDefId(resourceInstanceId);
1057 if (getAllRes.isRight()) {
1058 TitanOperationStatus status = getAllRes.right().value();
1059 log.trace("After fetching all properties of resource instance {}. Status is {}", resourceInstanceId, status);
1060 return new ImmutablePair<TitanOperationStatus, String>(status, null);
1063 List<ComponentInstanceProperty> list = getAllRes.left().value();
1065 for (ComponentInstanceProperty instanceProperty : list) {
1066 String propertyUniqueId = instanceProperty.getUniqueId();
1067 String valueUniqueUid = instanceProperty.getValueUniqueUid();
1068 log.trace("Go over property {} under resource instance {}. valueUniqueId = {}", propertyUniqueId, resourceInstanceId, valueUniqueUid);
1069 if (propertyId.equals(propertyUniqueId) && valueUniqueUid != null) {
1070 log.debug("The property {} already created under resource instance {}", propertyId, resourceInstanceId);
1071 return new ImmutablePair<TitanOperationStatus, String>(TitanOperationStatus.ALREADY_EXIST, valueUniqueUid);
1076 return new ImmutablePair<TitanOperationStatus, String>(TitanOperationStatus.NOT_FOUND, null);
1080 * update value of property on resource instance
1082 * @param resourceInstanceProperty
1083 * @param resourceInstanceId
1087 * public Either<PropertyValueData, TitanOperationStatus> updatePropertyOfResourceInstance( ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId) {
1089 * /// #RULES SUPPORT /// Ignore rules received from client till support resourceInstanceProperty.setRules(null); /// /// Either<ComponentInstanceData, TitanOperationStatus> findResInstanceRes = titanGenericDao .getNode(UniqueIdBuilder
1090 * .getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, ComponentInstanceData.class);
1092 * if (findResInstanceRes.isRight()) { TitanOperationStatus status = findResInstanceRes.right().value(); if (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); }
1094 * String propertyId = resourceInstanceProperty.getUniqueId(); Either<PropertyData, TitanOperationStatus> findPropertyDefRes = titanGenericDao .getNode(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class);
1096 * if (findPropertyDefRes.isRight()) { TitanOperationStatus status = findPropertyDefRes.right().value(); return Either.right(status); }
1098 * String valueUniqueUid = resourceInstanceProperty.getValueUniqueUid(); if (valueUniqueUid == null) { return Either.right(TitanOperationStatus.INVALID_ID); } else { Either<PropertyValueData, TitanOperationStatus> findPropertyValueRes =
1099 * titanGenericDao .getNode(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.PropertyValue), valueUniqueUid, PropertyValueData.class); if (findPropertyValueRes.isRight()) { TitanOperationStatus status = findPropertyValueRes.right().value(); if
1100 * (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); }
1102 * String value = resourceInstanceProperty.getValue();
1104 * Either<ImmutablePair<PropertyData, GraphEdge>, TitanOperationStatus> child = titanGenericDao.getChild(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.PropertyValue), valueUniqueUid, GraphEdgeLabels.PROPERTY_IMPL, NodeTypeEnum.Property,
1105 * PropertyData.class);
1107 * if (child.isRight()) { TitanOperationStatus status = child.right().value(); if (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); }
1109 * PropertyData propertyData = child.left().value().left; String propertyType = propertyData.getPropertyDataDefinition().getType();
1111 * log.debug("The type of the property {} is {}", propertyData.getUniqueId(), propertyType);
1113 * Either<Object, Boolean> isValid = validateAndUpdatePropertyValue(propertyType, value);
1115 * 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) {
1116 * newValue = object.toString(); } } PropertyValueData propertyValueData = findPropertyValueRes.left().value(); log.debug("Going to update property value from " + propertyValueData.getValue() + " to " + newValue);
1117 * propertyValueData.setValue(newValue);
1119 * ImmutablePair<String, Boolean> pair = validateAndUpdateRules(propertyType, resourceInstanceProperty.getRules()); if (pair.getRight() != null && pair.getRight() == false) { BeEcompErrorManager.getInstance().
1120 * logBeInvalidValueError("Add property value", pair.getLeft(), resourceInstanceProperty.getName(), propertyType); return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); } updateRulesInPropertyValue(propertyValueData,
1121 * resourceInstanceProperty, resourceInstanceId);
1123 * Either<PropertyValueData, TitanOperationStatus> updateRes = titanGenericDao.updateNode(propertyValueData, PropertyValueData.class); if (updateRes.isRight()) { TitanOperationStatus status = updateRes.right().value(); return
1124 * Either.right(status); } else { return Either.left(updateRes.left().value()); } }
1129 public void updateRulesInPropertyValue(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId) {
1131 List<PropertyRule> currentRules = propertyValueData.getRules();
1133 List<PropertyRule> rules = resourceInstanceProperty.getRules();
1134 // if rules are not supported.
1135 if (rules == null) {
1137 PropertyRule propertyRule = buildRuleFromPath(propertyValueData, resourceInstanceProperty, resourceInstanceId);
1138 rules = new ArrayList<>();
1139 rules.add(propertyRule);
1141 if (currentRules != null) {
1142 rules = mergeRules(currentRules, rules);
1146 // Full mode. all rules are sent in update operation.
1147 rules = sortRules(rules);
1150 propertyValueData.setRules(rules);
1154 private List<PropertyRule> mergeRules(List<PropertyRule> currentRules, List<PropertyRule> newRules) {
1156 List<PropertyRule> mergedRules = new ArrayList<>();
1158 if (newRules == null || newRules.isEmpty() == true) {
1159 return currentRules;
1162 for (PropertyRule rule : currentRules) {
1163 PropertyRule propertyRule = new PropertyRule(rule.getRule(), rule.getValue());
1164 mergedRules.add(propertyRule);
1167 for (PropertyRule rule : newRules) {
1168 PropertyRule foundRule = findRuleInList(rule, mergedRules);
1169 if (foundRule != null) {
1170 foundRule.setValue(rule.getValue());
1172 mergedRules.add(rule);
1179 private PropertyRule findRuleInList(PropertyRule rule, List<PropertyRule> rules) {
1181 if (rules == null || rules.isEmpty() == true || rule.getRule() == null || rule.getRule().isEmpty() == true) {
1185 PropertyRule foundRule = null;
1186 for (PropertyRule propertyRule : rules) {
1187 if (rule.getRuleSize() != propertyRule.getRuleSize()) {
1190 boolean equals = propertyRule.compareRule(rule);
1191 if (equals == true) {
1192 foundRule = propertyRule;
1201 * return all properties associated to resource instance. The result does contains the property unique id but not its type, default value...
1203 * @param resourceInstanceUid
1206 public Either<List<ComponentInstanceProperty>, TitanOperationStatus> getAllPropertiesOfResourceInstanceOnlyPropertyDefId(String resourceInstanceUid) {
1208 return getAllPropertiesOfResourceInstanceOnlyPropertyDefId(resourceInstanceUid, NodeTypeEnum.ResourceInstance);
1213 * public Either<ComponentInstanceProperty, StorageOperationStatus> addPropertyValueToResourceInstance( ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, Integer index, boolean inTransaction) {
1215 * /// #RULES SUPPORT /// Ignore rules received from client till support resourceInstanceProperty.setRules(null); /// ///
1217 * Either<ComponentInstanceProperty, StorageOperationStatus> result = null;
1221 * Either<PropertyValueData, TitanOperationStatus> eitherStatus = this .addPropertyToResourceInstance(resourceInstanceProperty, resourceInstanceId, index);
1223 * if (eitherStatus.isRight()) { log.error( "Failed to add property value {} to resource instance {} in Graph. status is {}" , resourceInstanceProperty, resourceInstanceId, eitherStatus.right().value().name()); result =
1224 * Either.right(DaoStatusConverter .convertTitanStatusToStorageStatus(eitherStatus.right() .value())); return result; } else { PropertyValueData propertyValueData = eitherStatus.left() .value();
1226 * ComponentInstanceProperty propertyValueResult = buildResourceInstanceProperty( propertyValueData, resourceInstanceProperty);
1228 * log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult); result = Either.left(propertyValueResult); return result; } }
1230 * 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();
1235 * public Either<ComponentInstanceProperty, StorageOperationStatus> updatePropertyValueInResourceInstance( ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, boolean inTransaction) {
1237 * Either<ComponentInstanceProperty, StorageOperationStatus> result = null;
1239 * try { //TODO: verify validUniqueId exists Either<PropertyValueData, TitanOperationStatus> eitherStatus = this .updatePropertyOfResourceInstance(resourceInstanceProperty, resourceInstanceId);
1241 * if (eitherStatus.isRight()) { log.error( "Failed to add property value {} to resource instance {} in Graph. status is {}" , resourceInstanceProperty, resourceInstanceId, eitherStatus.right().value().name()); result =
1242 * Either.right(DaoStatusConverter .convertTitanStatusToStorageStatus(eitherStatus.right() .value())); return result; } else { PropertyValueData propertyValueData = eitherStatus.left() .value();
1244 * ComponentInstanceProperty propertyValueResult = buildResourceInstanceProperty( propertyValueData, resourceInstanceProperty);
1246 * log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult); result = Either.left(propertyValueResult); return result; } }
1248 * 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();
1254 public Either<PropertyValueData, TitanOperationStatus> removePropertyOfResourceInstance(String propertyValueUid, String resourceInstanceId) {
1256 Either<ComponentInstanceData, TitanOperationStatus> findResInstanceRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, ComponentInstanceData.class);
1258 if (findResInstanceRes.isRight()) {
1259 TitanOperationStatus status = findResInstanceRes.right().value();
1260 if (status == TitanOperationStatus.NOT_FOUND) {
1261 status = TitanOperationStatus.INVALID_ID;
1263 return Either.right(status);
1266 Either<PropertyValueData, TitanOperationStatus> findPropertyDefRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.PropertyValue), propertyValueUid, PropertyValueData.class);
1268 if (findPropertyDefRes.isRight()) {
1269 TitanOperationStatus status = findPropertyDefRes.right().value();
1270 if (status == TitanOperationStatus.NOT_FOUND) {
1271 status = TitanOperationStatus.INVALID_ID;
1273 return Either.right(status);
1276 Either<GraphRelation, TitanOperationStatus> relation = titanGenericDao.getRelation(findResInstanceRes.left().value(), findPropertyDefRes.left().value(), GraphEdgeLabels.PROPERTY_VALUE);
1277 if (relation.isRight()) {
1278 // TODO: add error in case of error
1279 TitanOperationStatus status = relation.right().value();
1280 if (status == TitanOperationStatus.NOT_FOUND) {
1281 status = TitanOperationStatus.INVALID_ID;
1283 return Either.right(status);
1286 Either<PropertyValueData, TitanOperationStatus> deleteNode = titanGenericDao.deleteNode(findPropertyDefRes.left().value(), PropertyValueData.class);
1287 if (deleteNode.isRight()) {
1288 return Either.right(deleteNode.right().value());
1290 PropertyValueData value = deleteNode.left().value();
1291 return Either.left(value);
1295 public Either<ComponentInstanceProperty, StorageOperationStatus> removePropertyValueFromResourceInstance(String propertyValueUid, String resourceInstanceId, boolean inTransaction) {
1297 Either<ComponentInstanceProperty, StorageOperationStatus> result = null;
1301 Either<PropertyValueData, TitanOperationStatus> eitherStatus = this.removePropertyOfResourceInstance(propertyValueUid, resourceInstanceId);
1303 if (eitherStatus.isRight()) {
1304 log.error("Failed to remove property value {} from resource instance {} in Graph. status is {}", propertyValueUid, resourceInstanceId, eitherStatus.right().value().name());
1305 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value()));
1308 PropertyValueData propertyValueData = eitherStatus.left().value();
1310 ComponentInstanceProperty propertyValueResult = new ComponentInstanceProperty();
1311 propertyValueResult.setUniqueId(resourceInstanceId);
1312 propertyValueResult.setValue(propertyValueData.getValue());
1314 log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult);
1315 result = Either.left(propertyValueResult);
1321 if (false == inTransaction) {
1322 if (result == null || result.isRight()) {
1323 log.error("Going to execute rollback on graph.");
1324 titanGenericDao.rollback();
1326 log.debug("Going to execute commit on graph.");
1327 titanGenericDao.commit();
1334 public ComponentInstanceProperty buildResourceInstanceProperty(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty) {
1336 String value = propertyValueData.getValue();
1337 String uid = propertyValueData.getUniqueId();
1338 ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty(resourceInstanceProperty, value, uid);
1339 instanceProperty.setPath(resourceInstanceProperty.getPath());
1341 return instanceProperty;
1344 public static class PropertyConstraintJacksonDeserialiser extends org.codehaus.jackson.map.JsonDeserializer<PropertyConstraint> {
1347 public PropertyConstraint deserialize(org.codehaus.jackson.JsonParser json, DeserializationContext context) throws IOException, JsonProcessingException {
1349 ObjectCodec oc = json.getCodec();
1350 JsonNode node = oc.readTree(json);
1356 public boolean isPropertyDefaultValueValid(IComplexDefaultValue propertyDefinition, Map<String, DataTypeDefinition> dataTypes) {
1357 if (propertyDefinition == null) {
1360 boolean isValid = false;
1361 String innerType = null;
1362 String propertyType = propertyDefinition.getType();
1363 ToscaPropertyType type = getType(propertyType);
1364 if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
1365 SchemaDefinition def = propertyDefinition.getSchema();
1369 PropertyDataDefinition propDef = def.getProperty();
1370 if (propDef == null) {
1373 innerType = propDef.getType();
1375 String value = propertyDefinition.getDefaultValue();
1377 isValid = isValidValue(type, value, innerType, dataTypes);
1379 log.trace("The given type {} is not a pre defined one.", propertyType);
1381 DataTypeDefinition foundDt = dataTypes.get(propertyType);
1382 if (foundDt != null) {
1383 isValid = isValidComplexValue(foundDt, value, dataTypes);
1391 public boolean isPropertyTypeValid(IComplexDefaultValue property) {
1393 if (property == null) {
1397 if (ToscaPropertyType.isValidType(property.getType()) == null) {
1399 Either<Boolean, TitanOperationStatus> definedInDataTypes = isDefinedInDataTypes(property.getType());
1401 if (definedInDataTypes.isRight()) {
1404 Boolean isExist = definedInDataTypes.left().value();
1405 return isExist.booleanValue();
1413 public ImmutablePair<String, Boolean> isPropertyInnerTypeValid(IComplexDefaultValue property, Map<String, DataTypeDefinition> dataTypes) {
1415 if (property == null) {
1416 return new ImmutablePair<String, Boolean>(null, false);
1419 SchemaDefinition schema;
1420 PropertyDataDefinition innerProp;
1421 String innerType = null;
1422 if ((schema = property.getSchema()) != null) {
1423 if ((innerProp = schema.getProperty()) != null) {
1424 innerType = innerProp.getType();
1428 ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType);
1430 if (innerToscaType == null) {
1431 DataTypeDefinition dataTypeDefinition = dataTypes.get(innerType);
1432 if (dataTypeDefinition == null) {
1433 log.debug("The inner type {} is not a data type.", innerType);
1434 return new ImmutablePair<String, Boolean>(innerType, false);
1436 log.debug("The inner type {} is a data type. Data type definition is {}", innerType, dataTypeDefinition);
1440 return new ImmutablePair<String, Boolean>(innerType, true);
1443 private boolean isValidComplexValue(DataTypeDefinition foundDt, String value, Map<String, DataTypeDefinition> dataTypes) {
1445 * Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypesRes = getAllDataTypes(); if (allDataTypesRes.isRight()) { TitanOperationStatus status = allDataTypesRes.right().value();
1448 * Map<String, DataTypeDefinition> allDataTypes = allDataTypesRes.left().value();
1450 ImmutablePair<JsonElement, Boolean> validateAndUpdate = dataTypeValidatorConverter.validateAndUpdate(value, foundDt, dataTypes);
1452 log.trace("The result after validating complex value of type {} is {}", foundDt.getName(), validateAndUpdate);
1454 return validateAndUpdate.right.booleanValue();
1458 private Either<Map<String, DataTypeDefinition>, TitanOperationStatus> findAllDataTypeDefinition(DataTypeDefinition dataTypeDefinition) {
1460 Map<String, DataTypeDefinition> nameToDataTypeDef = new HashMap<>();
1462 DataTypeDefinition typeDefinition = dataTypeDefinition;
1464 while (typeDefinition != null) {
1466 List<PropertyDefinition> properties = typeDefinition.getProperties();
1467 if (properties != null) {
1468 for (PropertyDefinition propertyDefinition : properties) {
1469 String type = propertyDefinition.getType();
1470 Either<DataTypeDefinition, TitanOperationStatus> dataTypeByName = this.getDataTypeUsingName(type);
1471 if (dataTypeByName.isRight()) {
1472 return Either.right(dataTypeByName.right().value());
1474 DataTypeDefinition value = dataTypeByName.left().value();
1475 if (false == nameToDataTypeDef.containsKey(type)) {
1476 nameToDataTypeDef.put(type, value);
1483 typeDefinition = typeDefinition.getDerivedFrom();
1486 return Either.left(nameToDataTypeDef);
1489 public Either<List<ComponentInstanceProperty>, TitanOperationStatus> getAllPropertiesOfResourceInstanceOnlyPropertyDefId(String resourceInstanceUid, NodeTypeEnum instanceNodeType) {
1491 Either<TitanVertex, TitanOperationStatus> findResInstanceRes = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(instanceNodeType), resourceInstanceUid);
1493 if (findResInstanceRes.isRight()) {
1494 TitanOperationStatus status = findResInstanceRes.right().value();
1495 if (status == TitanOperationStatus.NOT_FOUND) {
1496 status = TitanOperationStatus.INVALID_ID;
1498 return Either.right(status);
1501 Either<List<ImmutablePair<TitanVertex, Edge>>, TitanOperationStatus> propertyImplNodes = titanGenericDao.getChildrenVertecies(UniqueIdBuilder.getKeyByNodeType(instanceNodeType), resourceInstanceUid, GraphEdgeLabels.PROPERTY_VALUE);
1503 if (propertyImplNodes.isRight()) {
1504 TitanOperationStatus status = propertyImplNodes.right().value();
1505 return Either.right(status);
1508 List<ImmutablePair<TitanVertex, Edge>> list = propertyImplNodes.left().value();
1509 if (list == null || true == list.isEmpty()) {
1510 return Either.right(TitanOperationStatus.NOT_FOUND);
1513 List<ComponentInstanceProperty> result = new ArrayList<>();
1514 for (ImmutablePair<TitanVertex, Edge> propertyValue : list) {
1515 TitanVertex propertyValueDataVertex = propertyValue.getLeft();
1516 String propertyValueUid = (String) titanGenericDao.getProperty(propertyValueDataVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty());
1517 String value = (String) titanGenericDao.getProperty(propertyValueDataVertex, GraphPropertiesDictionary.VALUE.getProperty());
1519 ImmutablePair<TitanVertex, Edge> propertyDefPair = titanGenericDao.getChildVertex(propertyValueDataVertex, GraphEdgeLabels.PROPERTY_IMPL);
1520 if (propertyDefPair == null) {
1521 return Either.right(TitanOperationStatus.NOT_FOUND);
1524 Map<String, Object> properties = titanGenericDao.getProperties(propertyValueDataVertex);
1525 PropertyValueData propertyValueData = GraphElementFactory.createElement(NodeTypeEnum.PropertyValue.getName(), GraphElementTypeEnum.Node, properties, PropertyValueData.class);
1526 String propertyUniqueId = (String) titanGenericDao.getProperty(propertyDefPair.left, GraphPropertiesDictionary.UNIQUE_ID.getProperty());
1528 ComponentInstanceProperty resourceInstanceProperty = new ComponentInstanceProperty();
1529 // set property original unique id
1530 resourceInstanceProperty.setUniqueId(propertyUniqueId);
1532 // TODO: esofer add resource id
1533 resourceInstanceProperty.setParentUniqueId(null);
1535 resourceInstanceProperty.setValue(value);
1536 // set property value unique id
1537 resourceInstanceProperty.setValueUniqueUid(propertyValueUid);
1539 resourceInstanceProperty.setRules(propertyValueData.getRules());
1541 result.add(resourceInstanceProperty);
1544 return Either.left(result);
1548 * Find the default value from the list of component instances. Start the search from the second component instance
1550 * @param pathOfComponentInstances
1551 * @param propertyUniqueId
1552 * @param defaultValue
1555 public Either<String, TitanOperationStatus> findDefaultValueFromSecondPosition(List<String> pathOfComponentInstances, String propertyUniqueId, String defaultValue) {
1557 log.trace("In find default value: path= {} propertyUniqId={} defaultValue= {}", pathOfComponentInstances, propertyUniqueId, defaultValue);
1559 if (pathOfComponentInstances == null || pathOfComponentInstances.size() < 2) {
1560 return Either.left(defaultValue);
1563 String result = defaultValue;
1565 for (int i = 1; i < pathOfComponentInstances.size(); i++) {
1566 String compInstanceId = pathOfComponentInstances.get(i);
1568 Either<List<ComponentInstanceProperty>, TitanOperationStatus> propertyValuesResult = this.getAllPropertiesOfResourceInstanceOnlyPropertyDefId(compInstanceId, NodeTypeEnum.ResourceInstance);
1570 log.trace("After fetching properties values of component instance {}. {}", compInstanceId, propertyValuesResult);
1572 if (propertyValuesResult.isRight()) {
1573 TitanOperationStatus status = propertyValuesResult.right().value();
1574 if (status != TitanOperationStatus.NOT_FOUND) {
1575 return Either.right(status);
1581 ComponentInstanceProperty foundCompInstanceProperty = fetchByPropertyUid(propertyValuesResult.left().value(), propertyUniqueId);
1582 log.trace("After finding the component instance property on{} . {}", compInstanceId, foundCompInstanceProperty);
1584 if (foundCompInstanceProperty == null) {
1588 List<PropertyRule> rules = getOrBuildRulesIfNotExists(pathOfComponentInstances.size() - i, pathOfComponentInstances.get(i), foundCompInstanceProperty.getRules(), foundCompInstanceProperty.getValue());
1590 log.trace("Rules of property {} on component instance {} are {}", propertyUniqueId, compInstanceId, rules);
1591 PropertyRule matchedRule = findMatchRule(pathOfComponentInstances, i, rules);
1592 log.trace("Match rule is {}", matchedRule);
1594 if (matchedRule != null) {
1595 result = matchedRule.getValue();
1601 return Either.left(result);
1605 private ComponentInstanceProperty fetchByPropertyUid(List<ComponentInstanceProperty> list, String propertyUniqueId) {
1607 ComponentInstanceProperty result = null;
1613 for (ComponentInstanceProperty instProperty : list) {
1614 if (instProperty.getUniqueId().equals(propertyUniqueId)) {
1615 result = instProperty;
1623 private List<PropertyRule> getOrBuildRulesIfNotExists(int ruleSize, String compInstanceId, List<PropertyRule> rules, String value) {
1625 if (rules != null) {
1629 rules = buildDefaultRule(compInstanceId, ruleSize, value);
1635 private List<PropertyRule> getRulesOfPropertyValue(int size, String instanceId, ComponentInstanceProperty componentInstanceProperty) {
1636 List<PropertyRule> rules = componentInstanceProperty.getRules();
1637 if (rules == null) {
1638 rules = buildDefaultRule(instanceId, size, componentInstanceProperty.getValue());
1643 private List<PropertyRule> buildDefaultRule(String componentInstanceId, int size, String value) {
1645 List<PropertyRule> rules = new ArrayList<>();
1646 List<String> rule = new ArrayList<>();
1647 rule.add(componentInstanceId);
1648 for (int i = 0; i < size - 1; i++) {
1649 rule.add(PropertyRule.RULE_ANY_MATCH);
1651 PropertyRule propertyRule = new PropertyRule(rule, value);
1652 rules.add(propertyRule);
1658 private PropertyRule findMatchRule(List<String> pathOfInstances, int level, List<PropertyRule> rules) {
1660 PropertyRule propertyRule = null;
1662 String stringForMatch = buildStringForMatch(pathOfInstances, level);
1664 String firstCompInstance = pathOfInstances.get(level);
1666 if (rules != null) {
1668 for (PropertyRule rule : rules) {
1670 int ruleSize = rule.getRule().size();
1671 // check the length of the rule equals to the length of the
1673 if (ruleSize != pathOfInstances.size() - level) {
1676 // check that the rule starts with correct component instance id
1677 if (false == checkFirstItem(firstCompInstance, rule.getFirstToken())) {
1681 String secondToken = rule.getToken(2);
1682 if (secondToken != null && (secondToken.equals(PropertyRule.FORCE_ALL) || secondToken.equals(PropertyRule.ALL))) {
1683 propertyRule = rule;
1687 String patternStr = buildStringForMatch(rule.getRule(), 0);
1689 Pattern pattern = Pattern.compile(patternStr);
1691 Matcher matcher = pattern.matcher(stringForMatch);
1693 if (matcher.matches()) {
1694 if (log.isTraceEnabled()) {
1695 log.trace("{} matches the rule {}", stringForMatch, patternStr);
1697 propertyRule = rule;
1704 return propertyRule;
1707 private boolean checkFirstItem(String left, String right) {
1708 if (left != null && left.equals(right)) {
1714 private String buildStringForMatch(List<String> pathOfInstances, int level) {
1715 StringBuilder builder = new StringBuilder();
1717 for (int i = level; i < pathOfInstances.size(); i++) {
1718 builder.append(pathOfInstances.get(i));
1719 if (i < pathOfInstances.size() - 1) {
1720 builder.append("#");
1723 return builder.toString();
1726 public void updatePropertyByBestMatch(String propertyUniqueId, ComponentInstanceProperty instanceProperty, Map<String, ComponentInstanceProperty> instanceIdToValue) {
1728 List<String> pathOfInstances = instanceProperty.getPath();
1730 int size = pathOfInstances.size();
1731 int numberOfMatches = 0;
1732 for (String instanceId : pathOfInstances) {
1733 ComponentInstanceProperty componentInstanceProperty = instanceIdToValue.get(instanceId);
1735 if (componentInstanceProperty != null) {
1737 List<PropertyRule> rules = getRulesOfPropertyValue(size - level, instanceId, componentInstanceProperty);
1738 // If it is the first level instance, then update valueUniuqeId
1739 // parameter in order to know on update that
1740 // we should update and not create new node on graph.
1742 instanceProperty.setValueUniqueUid(componentInstanceProperty.getValueUniqueUid());
1743 instanceProperty.setRules(rules);
1746 PropertyRule rule = findMatchRule(pathOfInstances, level, rules);
1749 String value = rule.getValue();
1750 if (numberOfMatches == 1) {
1751 instanceProperty.setValue(value);
1752 if (log.isDebugEnabled()) {
1753 log.debug("Set the value of property {} {} on path {} to be {}", propertyUniqueId, instanceProperty.getName(), pathOfInstances, value);
1755 } else if (numberOfMatches == 2) {
1756 // In case of another property value match, then use the
1757 // value to be the default value of the property.
1758 instanceProperty.setDefaultValue(value);
1759 if (log.isDebugEnabled()) {
1760 log.debug("Set the default value of property {} {} on path {} to be {}", propertyUniqueId, instanceProperty.getName(), pathOfInstances, value);
1771 public void updatePropertiesByPropertyValues(Map<String, List<ComponentInstanceProperty>> resourceInstancesProperties, Map<String, Map<String, ComponentInstanceProperty>> values) {
1773 if (resourceInstancesProperties == null) {
1777 List<ComponentInstanceProperty> allProperties = new ArrayList<>();
1778 Collection<List<ComponentInstanceProperty>> properties = resourceInstancesProperties.values();
1779 if (properties != null) {
1780 Iterator<List<ComponentInstanceProperty>> iterator = properties.iterator();
1781 while (iterator.hasNext()) {
1782 List<ComponentInstanceProperty> compInstancePropertyList = iterator.next();
1783 allProperties.addAll(compInstancePropertyList);
1787 // Go over each property and check whether there is a rule which updates
1789 for (ComponentInstanceProperty instanceProperty : allProperties) {
1791 String propertyUniqueId = instanceProperty.getUniqueId();
1793 // get the changes per componentInstanceId.
1794 Map<String, ComponentInstanceProperty> instanceIdToValue = values.get(propertyUniqueId);
1796 if (instanceIdToValue == null) {
1800 this.updatePropertyByBestMatch(propertyUniqueId, instanceProperty, instanceIdToValue);
1808 * Add data type to graph.
1810 * 1. Add data type node
1812 * 2. Add edge between the former node to its parent(if exists)
1814 * 3. Add property node and associate it to the node created at #1. (per property & if exists)
1816 * @param dataTypeDefinition
1819 private Either<DataTypeData, TitanOperationStatus> addDataTypeToGraph(DataTypeDefinition dataTypeDefinition) {
1821 log.debug("Got data type {}", dataTypeDefinition);
1823 String dtUniqueId = UniqueIdBuilder.buildDataTypeUid(dataTypeDefinition.getName());
1825 DataTypeData dataTypeData = buildDataTypeData(dataTypeDefinition, dtUniqueId);
1827 log.debug("Before adding data type to graph. dataTypeData = {}", dataTypeData);
1828 Either<DataTypeData, TitanOperationStatus> createDataTypeResult = titanGenericDao.createNode(dataTypeData, DataTypeData.class);
1829 log.debug("After adding data type to graph. status is = {}", createDataTypeResult);
1831 if (createDataTypeResult.isRight()) {
1832 TitanOperationStatus operationStatus = createDataTypeResult.right().value();
1833 log.debug("Failed to data type {} to graph. status is {}", dataTypeDefinition.getName(), operationStatus);
1834 BeEcompErrorManager.getInstance().logBeFailedAddingNodeTypeError("AddDataType", NodeTypeEnum.DataType.getName());
1835 return Either.right(operationStatus);
1838 DataTypeData resultCTD = createDataTypeResult.left().value();
1839 List<PropertyDefinition> properties = dataTypeDefinition.getProperties();
1840 Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToDataType = addPropertiesToDataType(resultCTD.getUniqueId(), properties);
1841 if (addPropertiesToDataType.isRight()) {
1842 log.debug("Failed add properties {} to data type {}", properties, dataTypeDefinition.getName());
1843 return Either.right(addPropertiesToDataType.right().value());
1846 String derivedFrom = dataTypeDefinition.getDerivedFromName();
1847 if (derivedFrom != null) {
1848 log.debug("Before creating relation between data type {} to its parent {}", dtUniqueId, derivedFrom);
1849 UniqueIdData from = new UniqueIdData(NodeTypeEnum.DataType, dtUniqueId);
1851 String deriveFromUid = UniqueIdBuilder.buildDataTypeUid(derivedFrom);
1852 UniqueIdData to = new UniqueIdData(NodeTypeEnum.DataType, deriveFromUid);
1853 Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(from, to, GraphEdgeLabels.DERIVED_FROM, null);
1854 log.debug("After create relation between capability type {} to its parent {}. status is {}", dtUniqueId, derivedFrom, createRelation);
1855 if (createRelation.isRight()) {
1856 return Either.right(createRelation.right().value());
1860 return Either.left(createDataTypeResult.left().value());
1864 private DataTypeData buildDataTypeData(DataTypeDefinition dataTypeDefinition, String ctUniqueId) {
1866 DataTypeData dataTypeData = new DataTypeData(dataTypeDefinition);
1868 dataTypeData.getDataTypeDataDefinition().setUniqueId(ctUniqueId);
1869 Long creationDate = dataTypeData.getDataTypeDataDefinition().getCreationTime();
1870 if (creationDate == null) {
1871 creationDate = System.currentTimeMillis();
1873 dataTypeData.getDataTypeDataDefinition().setCreationTime(creationDate);
1874 dataTypeData.getDataTypeDataDefinition().setModificationTime(creationDate);
1876 return dataTypeData;
1880 * add properties to capability type.
1882 * Per property, add a property node and associate it to the capability type
1888 private Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToDataType(String uniqueId, List<PropertyDefinition> properties) {
1890 Map<String, PropertyData> propertiesData = new HashMap<String, PropertyData>();
1892 if (properties != null && false == properties.isEmpty()) {
1893 for (PropertyDefinition propertyDefinition : properties) {
1894 String propertyName = propertyDefinition.getName();
1896 String propertyType = propertyDefinition.getType();
1897 Either<Boolean, TitanOperationStatus> validPropertyType = isValidPropertyType(propertyType);
1898 if (validPropertyType.isRight()) {
1899 log.debug("Data type {} contains invalid property type {}", uniqueId, propertyType);
1900 return Either.right(validPropertyType.right().value());
1902 Boolean isValid = validPropertyType.left().value();
1903 if (isValid == null || isValid.booleanValue() == false) {
1904 log.debug("Data type {} contains invalid property type {}", uniqueId, propertyType);
1905 return Either.right(TitanOperationStatus.INVALID_TYPE);
1908 Either<PropertyData, TitanOperationStatus> addPropertyToNodeType = this.addPropertyToNodeType(propertyName, propertyDefinition, NodeTypeEnum.DataType, uniqueId);
1909 if (addPropertyToNodeType.isRight()) {
1910 TitanOperationStatus operationStatus = addPropertyToNodeType.right().value();
1911 log.debug("Failed to associate data type {} to property {} in graph. status is {}", uniqueId, propertyName, operationStatus);
1912 BeEcompErrorManager.getInstance().logInternalFlowError("AddPropertyToDataType", "Failed to associate property to data type. Status is " + operationStatus, ErrorSeverity.ERROR);
1913 return Either.right(operationStatus);
1915 propertiesData.put(propertyName, addPropertyToNodeType.left().value());
1918 DataTypeData dataTypeData = new DataTypeData();
1919 dataTypeData.getDataTypeDataDefinition().setUniqueId(uniqueId);
1920 long modificationTime = System.currentTimeMillis();
1921 dataTypeData.getDataTypeDataDefinition().setModificationTime(modificationTime);
1923 Either<DataTypeData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(dataTypeData, DataTypeData.class);
1924 if (updateNode.isRight()) {
1925 TitanOperationStatus operationStatus = updateNode.right().value();
1926 log.debug("Failed to update modification time data type {} from graph. status is {}", uniqueId, operationStatus);
1927 BeEcompErrorManager.getInstance().logInternalFlowError("AddPropertyToDataType", "Failed to fetch data type. Status is " + operationStatus, ErrorSeverity.ERROR);
1928 return Either.right(operationStatus);
1930 log.debug("Update data type uid {}. Set modification time to {}", uniqueId, modificationTime);
1935 return Either.left(propertiesData);
1940 * Build Data type object from graph by unique id
1945 public Either<DataTypeDefinition, TitanOperationStatus> getDataTypeByUid(String uniqueId) {
1947 Either<DataTypeDefinition, TitanOperationStatus> result = null;
1949 Either<DataTypeData, TitanOperationStatus> dataTypesRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, DataTypeData.class);
1951 if (dataTypesRes.isRight()) {
1952 TitanOperationStatus status = dataTypesRes.right().value();
1953 log.debug("Data type {} cannot be found in graph. status is {}", uniqueId, status);
1954 return Either.right(status);
1957 DataTypeData ctData = dataTypesRes.left().value();
1958 DataTypeDefinition dataTypeDefinition = new DataTypeDefinition(ctData.getDataTypeDataDefinition());
1960 TitanOperationStatus propertiesStatus = fillProperties(uniqueId, dataTypeDefinition);
1961 if (propertiesStatus != TitanOperationStatus.OK) {
1962 log.error("Failed to fetch properties of data type {}", uniqueId);
1963 return Either.right(propertiesStatus);
1966 Either<ImmutablePair<DataTypeData, GraphEdge>, TitanOperationStatus> parentNode = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.DataType,
1967 DataTypeData.class);
1968 log.debug("After retrieving DERIVED_FROM node of {}. status is {}", uniqueId, parentNode);
1969 if (parentNode.isRight()) {
1970 TitanOperationStatus titanOperationStatus = parentNode.right().value();
1971 if (titanOperationStatus != TitanOperationStatus.NOT_FOUND) {
1972 log.error("Failed to find the parent data type of data type {}. status is {}", uniqueId, titanOperationStatus);
1973 result = Either.right(titanOperationStatus);
1977 // derived from node was found
1978 ImmutablePair<DataTypeData, GraphEdge> immutablePair = parentNode.left().value();
1979 DataTypeData parentCT = immutablePair.getKey();
1981 String parentUniqueId = parentCT.getUniqueId();
1982 Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = getDataTypeByUid(parentUniqueId);
1984 if (dataTypeByUid.isRight()) {
1985 return Either.right(dataTypeByUid.right().value());
1988 DataTypeDefinition parentDataTypeDefinition = dataTypeByUid.left().value();
1990 dataTypeDefinition.setDerivedFrom(parentDataTypeDefinition);
1993 result = Either.left(dataTypeDefinition);
1998 private TitanOperationStatus fillProperties(String uniqueId, DataTypeDefinition dataTypeDefinition) {
2000 Either<Map<String, PropertyDefinition>, TitanOperationStatus> findPropertiesOfNode = this.findPropertiesOfNode(NodeTypeEnum.DataType, uniqueId);
2001 if (findPropertiesOfNode.isRight()) {
2002 TitanOperationStatus titanOperationStatus = findPropertiesOfNode.right().value();
2003 log.debug("After looking for properties of vertex {}. status is {}", uniqueId, titanOperationStatus);
2004 if (TitanOperationStatus.NOT_FOUND.equals(titanOperationStatus)) {
2005 return TitanOperationStatus.OK;
2007 return titanOperationStatus;
2010 Map<String, PropertyDefinition> properties = findPropertiesOfNode.left().value();
2011 if (properties != null && properties.isEmpty() == false) {
2012 List<PropertyDefinition> listOfProps = new ArrayList<>();
2014 for (Entry<String, PropertyDefinition> entry : properties.entrySet()) {
2015 String propName = entry.getKey();
2016 PropertyDefinition propertyDefinition = entry.getValue();
2017 PropertyDefinition newPropertyDefinition = new PropertyDefinition(propertyDefinition);
2018 newPropertyDefinition.setName(propName);
2019 listOfProps.add(newPropertyDefinition);
2021 dataTypeDefinition.setProperties(listOfProps);
2023 return TitanOperationStatus.OK;
2028 public Either<DataTypeDefinition, StorageOperationStatus> addDataType(DataTypeDefinition dataTypeDefinition, boolean inTransaction) {
2030 Either<DataTypeDefinition, StorageOperationStatus> result = null;
2034 Either<DataTypeData, TitanOperationStatus> eitherStatus = addDataTypeToGraph(dataTypeDefinition);
2036 if (eitherStatus.isRight()) {
2037 log.debug("Failed to add data type {} to Graph. status is {}", dataTypeDefinition, eitherStatus.right().value().name());
2038 BeEcompErrorManager.getInstance().logBeFailedAddingNodeTypeError("AddDataType", "DataType");
2039 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value()));
2042 DataTypeData capabilityTypeData = eitherStatus.left().value();
2044 DataTypeDefinition dataTypeDefResult = convertDTDataToDTDefinition(capabilityTypeData);
2045 log.debug("The returned CapabilityTypeDefinition is {}", dataTypeDefResult);
2046 result = Either.left(dataTypeDefResult);
2050 if (false == inTransaction) {
2051 if (result == null || result.isRight()) {
2052 log.error("Going to execute rollback on graph.");
2053 titanGenericDao.rollback();
2055 log.debug("Going to execute commit on graph.");
2056 titanGenericDao.commit();
2064 public Either<DataTypeDefinition, StorageOperationStatus> addDataType(DataTypeDefinition dataTypeDefinition) {
2065 return addDataType(dataTypeDefinition, true);
2069 public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByName(String name, boolean inTransaction) {
2071 Either<DataTypeDefinition, StorageOperationStatus> result = null;
2074 String dtUid = UniqueIdBuilder.buildDataTypeUid(name);
2075 Either<DataTypeDefinition, TitanOperationStatus> ctResult = this.getDataTypeByUid(dtUid);
2077 if (ctResult.isRight()) {
2078 TitanOperationStatus status = ctResult.right().value();
2079 if (status != TitanOperationStatus.NOT_FOUND) {
2080 log.error("Failed to retrieve information on capability type {} status is {}", name, status);
2082 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(ctResult.right().value()));
2086 result = Either.left(ctResult.left().value());
2090 if (false == inTransaction) {
2091 if (result == null || result.isRight()) {
2092 log.error("Going to execute rollback on graph.");
2093 titanGenericDao.rollback();
2095 log.debug("Going to execute commit on graph.");
2096 titanGenericDao.commit();
2104 public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByName(String name) {
2105 return getDataTypeByName(name, true);
2109 public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByNameWithoutDerived(String name) {
2110 return getDataTypeByNameWithoutDerived(name, true);
2114 public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByNameWithoutDerived(String name, boolean inTransaction) {
2116 Either<DataTypeDefinition, StorageOperationStatus> result = null;
2119 String uid = UniqueIdBuilder.buildDataTypeUid(name);
2120 Either<DataTypeDefinition, TitanOperationStatus> ctResult = this.getDataTypeByUidWithoutDerivedDataTypes(uid);
2122 if (ctResult.isRight()) {
2123 TitanOperationStatus status = ctResult.right().value();
2124 if (status != TitanOperationStatus.NOT_FOUND) {
2125 log.error("Failed to retrieve information on capability type {} status is {}", name, status);
2127 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(ctResult.right().value()));
2131 result = Either.left(ctResult.left().value());
2135 if (false == inTransaction) {
2136 if (result == null || result.isRight()) {
2137 log.error("Going to execute rollback on graph.");
2138 titanGenericDao.rollback();
2140 log.debug("Going to execute commit on graph.");
2141 titanGenericDao.commit();
2148 public Either<DataTypeDefinition, TitanOperationStatus> getDataTypeByUidWithoutDerivedDataTypes(String uniqueId) {
2150 Either<DataTypeData, TitanOperationStatus> dataTypesRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, DataTypeData.class);
2152 if (dataTypesRes.isRight()) {
2153 TitanOperationStatus status = dataTypesRes.right().value();
2154 log.debug("Data type {} cannot be found in graph. status is {}", uniqueId, status);
2155 return Either.right(status);
2158 DataTypeData ctData = dataTypesRes.left().value();
2159 DataTypeDefinition dataTypeDefinition = new DataTypeDefinition(ctData.getDataTypeDataDefinition());
2161 TitanOperationStatus propertiesStatus = fillProperties(uniqueId, dataTypeDefinition);
2162 if (propertiesStatus != TitanOperationStatus.OK) {
2163 log.error("Failed to fetch properties of data type {}", uniqueId);
2164 return Either.right(propertiesStatus);
2167 return Either.left(dataTypeDefinition);
2170 public Either<DataTypeDefinition, TitanOperationStatus> getDataTypeByNameWithoutDerivedDataTypes(String name) {
2172 String uid = UniqueIdBuilder.buildDataTypeUid(name);
2173 return getDataTypeByUidWithoutDerivedDataTypes(uid);
2179 * convert between graph Node object to Java object
2181 * @param dataTypeData
2184 protected DataTypeDefinition convertDTDataToDTDefinition(DataTypeData dataTypeData) {
2185 log.debug("The object returned after create data type is {}", dataTypeData);
2187 DataTypeDefinition dataTypeDefResult = new DataTypeDefinition(dataTypeData.getDataTypeDataDefinition());
2189 return dataTypeDefResult;
2192 private Either<Boolean, TitanOperationStatus> isValidPropertyType(String propertyType) {
2194 if (propertyType == null || propertyType.isEmpty()) {
2195 return Either.left(false);
2198 ToscaPropertyType toscaPropertyType = ToscaPropertyType.isValidType(propertyType);
2199 if (toscaPropertyType == null) {
2200 Either<Boolean, TitanOperationStatus> definedInDataTypes = isDefinedInDataTypes(propertyType);
2201 return definedInDataTypes;
2203 return Either.left(true);
2207 public Either<Boolean, TitanOperationStatus> isDefinedInDataTypes(String propertyType) {
2209 String dataTypeUid = UniqueIdBuilder.buildDataTypeUid(propertyType);
2210 Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = getDataTypeByUid(dataTypeUid);
2211 if (dataTypeByUid.isRight()) {
2212 TitanOperationStatus status = dataTypeByUid.right().value();
2213 if (status == TitanOperationStatus.NOT_FOUND) {
2214 return Either.left(false);
2216 return Either.right(status);
2219 return Either.left(true);
2223 private Either<DataTypeDefinition, TitanOperationStatus> getExternalDataType(String propertyType) {
2225 String dataTypeUid = UniqueIdBuilder.buildDataTypeUid(propertyType);
2226 Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = getDataTypeByUid(dataTypeUid);
2227 if (dataTypeByUid.isRight()) {
2228 TitanOperationStatus status = dataTypeByUid.right().value();
2229 return Either.right(status);
2232 return Either.left(dataTypeByUid.left().value());
2236 public Either<Map<String, DataTypeDefinition>, TitanOperationStatus> getAllDataTypes() {
2238 Map<String, DataTypeDefinition> dataTypes = new HashMap<>();
2239 Either<Map<String, DataTypeDefinition>, TitanOperationStatus> result = Either.left(dataTypes);
2241 Either<List<DataTypeData>, TitanOperationStatus> getAllDataTypes = titanGenericDao.getByCriteria(NodeTypeEnum.DataType, null, DataTypeData.class);
2242 if (getAllDataTypes.isRight()) {
2243 TitanOperationStatus status = getAllDataTypes.right().value();
2244 if (status != TitanOperationStatus.NOT_FOUND) {
2245 return Either.right(status);
2251 List<DataTypeData> list = getAllDataTypes.left().value();
2254 log.trace("Number of data types to load is {}" , list.size());
2256 List<String> collect = list.stream().map(p -> p.getDataTypeDataDefinition().getName()).collect(Collectors.toList());
2257 log.trace("The data types to load are {}" , collect);
2259 for (DataTypeData dataTypeData : list) {
2261 log.trace("Going to fetch data type {}. uid is {}", dataTypeData.getDataTypeDataDefinition().getName(), dataTypeData.getUniqueId());
2262 Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = this.getAndAddDataTypeByUid(dataTypeData.getUniqueId(), dataTypes);
2263 if (dataTypeByUid.isRight()) {
2264 TitanOperationStatus status = dataTypeByUid.right().value();
2265 if (status == TitanOperationStatus.NOT_FOUND) {
2266 status = TitanOperationStatus.INVALID_ID;
2268 return Either.right(status);
2273 if (log.isTraceEnabled()) {
2274 if (result.isRight()) {
2275 log.trace("After fetching all data types {}" , result);
2277 Map<String, DataTypeDefinition> map = result.left().value();
2279 String types = map.keySet().stream().collect(Collectors.joining(",", "[", "]"));
2280 log.trace("After fetching all data types {} " , types);
2289 * Build Data type object from graph by unique id
2294 public Either<DataTypeDefinition, TitanOperationStatus> getAndAddDataTypeByUid(String uniqueId, Map<String, DataTypeDefinition> allDataTypes) {
2296 Either<DataTypeDefinition, TitanOperationStatus> result = null;
2298 if (allDataTypes.containsKey(uniqueId)) {
2299 return Either.left(allDataTypes.get(uniqueId));
2302 Either<DataTypeData, TitanOperationStatus> dataTypesRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, DataTypeData.class);
2304 if (dataTypesRes.isRight()) {
2305 TitanOperationStatus status = dataTypesRes.right().value();
2306 log.debug("Data type {} cannot be found in graph. status is {}", uniqueId, status);
2307 return Either.right(status);
2310 DataTypeData ctData = dataTypesRes.left().value();
2311 DataTypeDefinition dataTypeDefinition = new DataTypeDefinition(ctData.getDataTypeDataDefinition());
2313 TitanOperationStatus propertiesStatus = fillProperties(uniqueId, dataTypeDefinition);
2314 if (propertiesStatus != TitanOperationStatus.OK) {
2315 log.error("Failed to fetch properties of data type {}", uniqueId);
2316 return Either.right(propertiesStatus);
2319 allDataTypes.put(dataTypeDefinition.getName(), dataTypeDefinition);
2321 String derivedFrom = dataTypeDefinition.getDerivedFromName();
2322 if (allDataTypes.containsKey(derivedFrom)) {
2323 DataTypeDefinition parentDataTypeDefinition = allDataTypes.get(derivedFrom);
2325 dataTypeDefinition.setDerivedFrom(parentDataTypeDefinition);
2327 return Either.left(dataTypeDefinition);
2330 Either<ImmutablePair<DataTypeData, GraphEdge>, TitanOperationStatus> parentNode = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.DataType,
2331 DataTypeData.class);
2332 log.debug("After retrieving DERIVED_FROM node of {}. status is {}", uniqueId, parentNode);
2333 if (parentNode.isRight()) {
2334 TitanOperationStatus titanOperationStatus = parentNode.right().value();
2335 if (titanOperationStatus != TitanOperationStatus.NOT_FOUND) {
2336 log.error("Failed to find the parent data type of data type {}. status is {}", uniqueId, titanOperationStatus);
2337 result = Either.right(titanOperationStatus);
2341 // derived from node was found
2342 ImmutablePair<DataTypeData, GraphEdge> immutablePair = parentNode.left().value();
2343 DataTypeData parentCT = immutablePair.getKey();
2345 String parentUniqueId = parentCT.getUniqueId();
2346 Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = getDataTypeByUid(parentUniqueId);
2348 if (dataTypeByUid.isRight()) {
2349 return Either.right(dataTypeByUid.right().value());
2352 DataTypeDefinition parentDataTypeDefinition = dataTypeByUid.left().value();
2354 dataTypeDefinition.setDerivedFrom(parentDataTypeDefinition);
2357 result = Either.left(dataTypeDefinition);
2362 public Either<DataTypeDefinition, TitanOperationStatus> getDataTypeUsingName(String name) {
2364 String uid = UniqueIdBuilder.buildDataTypeUid(name);
2366 Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = getDataTypeByUid(uid);
2368 return dataTypeByUid;
2371 public Either<String, TitanOperationStatus> checkInnerType(PropertyDataDefinition propDataDef) {
2373 String propertyType = propDataDef.getType();
2375 ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
2377 Either<String, TitanOperationStatus> result = getInnerType(type, () -> propDataDef.getSchema());
2382 public Either<List<DataTypeData>, TitanOperationStatus> getAllDataTypeNodes() {
2383 Either<List<DataTypeData>, TitanOperationStatus> getAllDataTypes = titanGenericDao.getByCriteria(NodeTypeEnum.DataType, null, DataTypeData.class);
2384 if (getAllDataTypes.isRight()) {
2385 TitanOperationStatus status = getAllDataTypes.right().value();
2386 if (status == TitanOperationStatus.NOT_FOUND) {
2387 status = TitanOperationStatus.OK;
2388 return Either.right(status);
2391 return getAllDataTypes;
2394 public Either<Object, Boolean> validateAndUpdatePropertyValue(String propertyType, String value, boolean isValidate, String innerType, Map<String, DataTypeDefinition> dataTypes) {
2395 log.trace("Going to validate property value and its type. type = {}, value = {}", propertyType, value);
2396 ToscaPropertyType type = getType(propertyType);
2401 DataTypeDefinition dataTypeDefinition = dataTypes.get(propertyType);
2402 ImmutablePair<JsonElement, Boolean> validateResult = dataTypeValidatorConverter.validateAndUpdate(value, dataTypeDefinition, dataTypes);
2403 if (validateResult.right.booleanValue() == false) {
2404 log.debug("The value {} of property from type {} is invalid", value, propertyType);
2405 return Either.right(false);
2407 JsonElement jsonElement = validateResult.left;
2408 String valueFromJsonElement = getValueFromJsonElement(jsonElement);
2409 return Either.left(valueFromJsonElement);
2411 log.trace("before validating property type {}", propertyType);
2412 boolean isValidProperty = isValidValue(type, value, innerType, dataTypes);
2413 if (false == isValidProperty) {
2414 log.debug("The value {} of property from type {} is invalid", value, type);
2415 return Either.right(false);
2418 Object convertedValue = value;
2419 if (false == isEmptyValue(value) && isValidate) {
2420 PropertyValueConverter converter = type.getConverter();
2421 convertedValue = converter.convert(value, innerType, dataTypes);
2423 return Either.left(convertedValue);
2426 public Either<Object, Boolean> validateAndUpdatePropertyValue(String propertyType, String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
2427 return validateAndUpdatePropertyValue(propertyType, value, true, innerType, dataTypes);
2431 * @Override public PropertyOperation getPropertyOperation() { return this; }
2433 protected TitanOperationStatus fillProperties(String uniqueId, Consumer<List<PropertyDefinition>> propertySetter) {
2434 Either<Map<String, PropertyDefinition>, TitanOperationStatus> findPropertiesOfNode = this.findPropertiesOfNode(NodeTypeEnum.GroupType, uniqueId);
2435 if (findPropertiesOfNode.isRight()) {
2436 TitanOperationStatus titanOperationStatus = findPropertiesOfNode.right().value();
2437 log.debug("After looking for properties of vertex {}. status is {}", uniqueId, titanOperationStatus);
2438 if (TitanOperationStatus.NOT_FOUND.equals(titanOperationStatus)) {
2439 return TitanOperationStatus.OK;
2441 return titanOperationStatus;
2444 Map<String, PropertyDefinition> properties = findPropertiesOfNode.left().value();
2446 if (properties != null) {
2447 List<PropertyDefinition> propertiesAsList = properties.entrySet().stream().map(p -> p.getValue()).collect(Collectors.toList());
2448 propertySetter.accept(propertiesAsList);
2451 return TitanOperationStatus.OK;
2456 * add properties to element type.
2458 * Per property, add a property node and associate it to the element type
2461 * @param propertiesMap
2465 protected Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToElementType(String uniqueId, NodeTypeEnum nodeType, Map<String, PropertyDefinition> propertiesMap) {
2467 Map<String, PropertyData> propertiesData = new HashMap<String, PropertyData>();
2469 if (propertiesMap != null) {
2471 for (Entry<String, PropertyDefinition> propertyDefinitionEntry : propertiesMap.entrySet()) {
2472 String propertyName = propertyDefinitionEntry.getKey();
2474 Either<PropertyData, TitanOperationStatus> addPropertyToNodeType = this.addPropertyToNodeType(propertyName, propertyDefinitionEntry.getValue(), nodeType, uniqueId);
2476 if (addPropertyToNodeType.isRight()) {
2477 TitanOperationStatus operationStatus = addPropertyToNodeType.right().value();
2478 log.error("Failed to associate {} {} to property {} in graph. status is {}", nodeType.getName(), uniqueId, propertyName, operationStatus);
2479 return Either.right(operationStatus);
2481 propertiesData.put(propertyName, addPropertyToNodeType.left().value());
2486 return Either.left(propertiesData);
2490 protected TitanOperationStatus addPropertiesToElementType(String uniqueId, NodeTypeEnum nodeType, Map<String, PropertyDefinition> propertiesMap, TitanVertex elementVertex) {
2492 if (propertiesMap != null) {
2494 for (Entry<String, PropertyDefinition> propertyDefinitionEntry : propertiesMap.entrySet()) {
2495 String propertyName = propertyDefinitionEntry.getKey();
2497 TitanOperationStatus operationStatus = this.addPropertyToNodeType(elementVertex, propertyName, propertyDefinitionEntry.getValue(), nodeType, uniqueId);
2499 if (!operationStatus.equals(TitanOperationStatus.OK)) {
2500 log.error("Failed to associate {} {} to property {} in graph. status is {}", nodeType.getName(), uniqueId, propertyName, operationStatus);
2501 return operationStatus;
2506 return TitanOperationStatus.OK;
2510 public Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToElementType(String uniqueId, NodeTypeEnum elementType, List<PropertyDefinition> properties) {
2512 Map<String, PropertyDefinition> propMap;
2513 if (properties == null) {
2516 propMap = properties.stream().collect(Collectors.toMap(propDef -> propDef.getName(), propDef -> propDef));
2518 return addPropertiesToElementType(uniqueId, elementType, propMap);
2521 public TitanOperationStatus addPropertiesToElementType(TitanVertex elementVertex, String uniqueId, NodeTypeEnum elementType, List<PropertyDefinition> properties) {
2523 Map<String, PropertyDefinition> propMap;
2524 if (properties == null) {
2527 propMap = properties.stream().collect(Collectors.toMap(propDef -> propDef.getName(), propDef -> propDef));
2529 return addPropertiesToElementType(uniqueId, elementType, propMap, elementVertex);
2533 public Either<DataTypeDefinition, StorageOperationStatus> updateDataType(DataTypeDefinition newDataTypeDefinition, DataTypeDefinition oldDataTypeDefinition) {
2534 return updateDataType(newDataTypeDefinition, oldDataTypeDefinition, true);
2538 public Either<DataTypeDefinition, StorageOperationStatus> updateDataType(DataTypeDefinition newDataTypeDefinition, DataTypeDefinition oldDataTypeDefinition, boolean inTransaction) {
2540 Either<DataTypeDefinition, StorageOperationStatus> result = null;
2544 List<PropertyDefinition> newProperties = newDataTypeDefinition.getProperties();
2546 List<PropertyDefinition> oldProperties = oldDataTypeDefinition.getProperties();
2548 String newDerivedFromName = getDerivedFromName(newDataTypeDefinition);
2550 String oldDerivedFromName = getDerivedFromName(oldDataTypeDefinition);
2552 String dataTypeName = newDataTypeDefinition.getName();
2554 List<PropertyDefinition> propertiesToAdd = new ArrayList<>();
2555 if (isPropertyOmitted(newProperties, oldProperties, dataTypeName) || isPropertyTypeChanged(dataTypeName, newProperties, oldProperties, propertiesToAdd) || isDerivedFromNameChanged(dataTypeName, newDerivedFromName, oldDerivedFromName)) {
2557 log.debug("The new data type {} is invalid.", dataTypeName);
2559 result = Either.right(StorageOperationStatus.CANNOT_UPDATE_EXISTING_ENTITY);
2563 if (propertiesToAdd == null || propertiesToAdd.isEmpty()) {
2564 log.debug("No new properties has been defined in the new data type {}", newDataTypeDefinition);
2565 result = Either.right(StorageOperationStatus.OK);
2569 Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToDataType = addPropertiesToDataType(oldDataTypeDefinition.getUniqueId(), propertiesToAdd);
2571 if (addPropertiesToDataType.isRight()) {
2572 log.debug("Failed to update data type {} to Graph. Status is {}", oldDataTypeDefinition, addPropertiesToDataType.right().value().name());
2573 BeEcompErrorManager.getInstance().logBeFailedAddingNodeTypeError("UpdateDataType", "Property");
2574 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(addPropertiesToDataType.right().value()));
2578 Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = this.getDataTypeByUid(oldDataTypeDefinition.getUniqueId());
2579 if (dataTypeByUid.isRight()) {
2580 TitanOperationStatus status = addPropertiesToDataType.right().value();
2581 log.debug("Failed to get data type {} after update. Status is {}", oldDataTypeDefinition.getUniqueId(), status.name());
2582 BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("UpdateDataType", "Property", status.name());
2583 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
2585 result = Either.left(dataTypeByUid.left().value());
2592 if (false == inTransaction) {
2593 if (result == null || result.isRight()) {
2594 log.error("Going to execute rollback on graph.");
2595 titanGenericDao.rollback();
2597 log.debug("Going to execute commit on graph.");
2598 titanGenericDao.commit();
2605 private String getDerivedFromName(DataTypeDefinition dataTypeDefinition) {
2606 String derivedFromName = dataTypeDefinition.getDerivedFromName();
2607 return derivedFromName;
2610 private boolean isPropertyTypeChanged(String dataTypeName, List<PropertyDefinition> newProperties, List<PropertyDefinition> oldProperties, List<PropertyDefinition> outputPropertiesToAdd) {
2612 if (newProperties != null && oldProperties != null) {
2614 Map<String, PropertyDefinition> newPropsMapper = newProperties.stream().collect(Collectors.toMap(p -> p.getName(), p -> p));
2615 Map<String, PropertyDefinition> oldPropsMapper = oldProperties.stream().collect(Collectors.toMap(p -> p.getName(), p -> p));
2617 for (Entry<String, PropertyDefinition> newPropertyEntry : newPropsMapper.entrySet()) {
2619 String propName = newPropertyEntry.getKey();
2620 PropertyDefinition propDef = newPropertyEntry.getValue();
2622 PropertyDefinition oldPropertyDefinition = oldPropsMapper.get(propName);
2623 if (oldPropertyDefinition == null) {
2624 log.debug("New property {} received in the data type {}", propName, dataTypeName);
2625 outputPropertiesToAdd.add(propDef);
2629 String oldType = oldPropertyDefinition.getType();
2630 String oldEntryType = getEntryType(oldPropertyDefinition);
2632 String newType = propDef.getType();
2633 String newEntryType = getEntryType(propDef);
2635 if (false == oldType.equals(newType)) {
2636 log.debug("Existing property {} in data type {} has a differnet type {} than the new one {}", propName, dataTypeName, oldType, newType);
2640 if (false == equalsEntryTypes(oldEntryType, newEntryType)) {
2641 log.debug("Existing property {} in data type {} has a differnet entry type {} than the new one {}", propName, dataTypeName, oldEntryType, newEntryType);
2652 private boolean equalsEntryTypes(String oldEntryType, String newEntryType) {
2654 if (oldEntryType == null && newEntryType == null) {
2656 } else if (oldEntryType != null && newEntryType != null) {
2657 return oldEntryType.equals(newEntryType);
2663 private String getEntryType(PropertyDefinition oldPropertyDefinition) {
2664 String entryType = null;
2665 SchemaDefinition schema = oldPropertyDefinition.getSchema();
2666 if (schema != null) {
2667 PropertyDataDefinition schemaProperty = schema.getProperty();
2668 if (schemaProperty != null) {
2669 entryType = schemaProperty.getType();
2675 private boolean isPropertyOmitted(List<PropertyDefinition> newProperties, List<PropertyDefinition> oldProperties, String dataTypeName) {
2677 boolean isValid = validateChangeInCaseOfEmptyProperties(newProperties, oldProperties, dataTypeName);
2678 if (false == isValid) {
2679 log.debug("At least one property is missing in the new data type {}", dataTypeName);
2683 if (newProperties != null && oldProperties != null) {
2685 List<String> newProps = newProperties.stream().map(p -> p.getName()).collect(Collectors.toList());
2686 List<String> oldProps = oldProperties.stream().map(p -> p.getName()).collect(Collectors.toList());
2688 if (false == newProps.containsAll(oldProps)) {
2689 StringJoiner joiner = new StringJoiner(",", "[", "]");
2690 newProps.forEach(p -> joiner.add(p));
2691 log.debug("Properties {} in data type {} are missing, but they already defined in the existing data type", joiner.toString(), dataTypeName);
2699 private boolean validateChangeInCaseOfEmptyProperties(List<PropertyDefinition> newProperties, List<PropertyDefinition> oldProperties, String dataTypeName) {
2701 if (newProperties != null) {
2702 if (newProperties.isEmpty()) {
2703 newProperties = null;
2707 if (oldProperties != null) {
2708 if (oldProperties.isEmpty()) {
2709 oldProperties = null;
2713 if ((newProperties == null && oldProperties == null) || (newProperties != null && oldProperties != null)) {
2720 private boolean isDerivedFromNameChanged(String dataTypeName, String newDerivedFromName, String oldDerivedFromName) {
2722 if (newDerivedFromName != null) {
2723 boolean isEqual = newDerivedFromName.equals(oldDerivedFromName);
2724 if (false == isEqual) {
2725 log.debug("The new datatype {} derived from another data type {} than the existing one {}", dataTypeName, newDerivedFromName, oldDerivedFromName);
2728 } else if (oldDerivedFromName == null) {
2730 } else {// new=null, old != null
2731 log.debug("The new datatype {} derived from another data type {} than the existing one {}", dataTypeName, newDerivedFromName, oldDerivedFromName);
2739 * Future - unfinished
2745 public boolean isValueToscaFunction(String type, String value) {
2747 boolean result = false;
2749 if (ToscaPropertyType.STRING.getType().equals(type) || isScalarDerivedFromString(type)) {
2753 String[] functions = { "get_input" };
2755 if (value != null) {
2757 for (String function : functions) {
2768 * Future - unfinished
2773 private boolean isScalarDerivedFromString(String type) {
2774 // TODO Auto-generated method stub