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=========================================================
20 package org.openecomp.sdc.be.model.operations.impl;
22 import com.fasterxml.jackson.core.ObjectCodec;
23 import com.fasterxml.jackson.databind.DeserializationContext;
24 import com.fasterxml.jackson.databind.JsonNode;
25 import com.google.common.collect.Maps;
26 import com.google.gson.JsonArray;
27 import com.google.gson.JsonDeserializationContext;
28 import com.google.gson.JsonDeserializer;
29 import com.google.gson.JsonElement;
30 import com.google.gson.JsonObject;
31 import com.google.gson.JsonParseException;
32 import com.google.gson.JsonParser;
33 import com.google.gson.JsonSerializationContext;
34 import com.google.gson.JsonSerializer;
35 import fj.data.Either;
36 import java.io.IOException;
37 import java.lang.reflect.Type;
38 import java.util.ArrayList;
39 import java.util.Collection;
40 import java.util.Collections;
41 import java.util.HashMap;
42 import java.util.List;
44 import java.util.Map.Entry;
46 import java.util.StringJoiner;
47 import java.util.function.Consumer;
48 import java.util.regex.Matcher;
49 import java.util.regex.Pattern;
50 import java.util.stream.Collectors;
51 import org.apache.commons.collections.CollectionUtils;
52 import org.apache.commons.collections.MapUtils;
53 import org.apache.commons.lang3.StringUtils;
54 import org.apache.commons.lang3.tuple.ImmutablePair;
55 import org.apache.tinkerpop.gremlin.structure.Edge;
56 import org.apache.tinkerpop.gremlin.structure.Vertex;
57 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
58 import org.janusgraph.core.JanusGraph;
59 import org.janusgraph.core.JanusGraphVertex;
60 import org.janusgraph.core.JanusGraphVertexProperty;
61 import org.openecomp.sdc.be.config.BeEcompErrorManager;
62 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
63 import org.openecomp.sdc.be.dao.graph.GraphElementFactory;
64 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
65 import org.openecomp.sdc.be.dao.graph.datatype.GraphElementTypeEnum;
66 import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
67 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
68 import org.openecomp.sdc.be.dao.janusgraph.HealingJanusGraphGenericDao;
69 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphGenericDao;
70 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
71 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
72 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
73 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
74 import org.openecomp.sdc.be.datatypes.elements.PropertyRule;
75 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
76 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
77 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
78 import org.openecomp.sdc.be.model.DataTypeDefinition;
79 import org.openecomp.sdc.be.model.IComplexDefaultValue;
80 import org.openecomp.sdc.be.model.PropertyConstraint;
81 import org.openecomp.sdc.be.model.PropertyDefinition;
82 import org.openecomp.sdc.be.model.operations.api.DerivedFromOperation;
83 import org.openecomp.sdc.be.model.operations.api.IPropertyOperation;
84 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
85 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
86 import org.openecomp.sdc.be.model.tosca.constraints.ConstraintType;
87 import org.openecomp.sdc.be.model.tosca.constraints.GreaterOrEqualConstraint;
88 import org.openecomp.sdc.be.model.tosca.constraints.GreaterThanConstraint;
89 import org.openecomp.sdc.be.model.tosca.constraints.InRangeConstraint;
90 import org.openecomp.sdc.be.model.tosca.constraints.LessOrEqualConstraint;
91 import org.openecomp.sdc.be.model.tosca.constraints.LessThanConstraint;
92 import org.openecomp.sdc.be.model.tosca.constraints.MinLengthConstraint;
93 import org.openecomp.sdc.be.model.tosca.constraints.ValidValuesConstraint;
94 import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter;
95 import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
96 import org.openecomp.sdc.be.resources.data.DataTypeData;
97 import org.openecomp.sdc.be.resources.data.PropertyData;
98 import org.openecomp.sdc.be.resources.data.PropertyValueData;
99 import org.openecomp.sdc.be.resources.data.ResourceMetadataData;
100 import org.openecomp.sdc.be.resources.data.UniqueIdData;
101 import org.openecomp.sdc.common.log.wrappers.Logger;
102 import org.springframework.beans.factory.annotation.Autowired;
103 import org.springframework.stereotype.Component;
105 @Component("property-operation")
106 public class PropertyOperation extends AbstractOperation implements IPropertyOperation {
108 private static final String FAILED_TO_FETCH_PROPERTIES_OF_DATA_TYPE = "Failed to fetch properties of data type {}";
109 private static final String DATA_TYPE_CANNOT_BE_FOUND_IN_GRAPH_STATUS_IS = "Data type {} cannot be found in graph. status is {}";
110 private static final String GOING_TO_EXECUTE_COMMIT_ON_GRAPH = "Going to execute commit on graph.";
111 private static final String GOING_TO_EXECUTE_ROLLBACK_ON_GRAPH = "Going to execute rollback on graph.";
112 private static final String FAILED_TO_ASSOCIATE_RESOURCE_TO_PROPERTY_IN_GRAPH_STATUS_IS = "Failed to associate resource {} to property {} in graph. status is {}";
113 private static final String AFTER_ADDING_PROPERTY_TO_GRAPH = "After adding property to graph {}";
114 private static final String BEFORE_ADDING_PROPERTY_TO_GRAPH = "Before adding property to graph {}";
115 private static final String THE_VALUE_OF_PROPERTY_FROM_TYPE_IS_INVALID = "The value {} of property from type {} is invalid";
116 private static final String PROPERTY = "Property";
117 private static final String UPDATE_DATA_TYPE = "UpdateDataType";
118 private static Logger log = Logger.getLogger(PropertyOperation.class.getName());
119 private DerivedFromOperation derivedFromOperation;
122 public PropertyOperation(HealingJanusGraphGenericDao janusGraphGenericDao, DerivedFromOperation derivedFromOperation) {
123 this.janusGraphGenericDao = janusGraphGenericDao;
124 this.derivedFromOperation = derivedFromOperation;
127 public PropertyDefinition convertPropertyDataToPropertyDefinition(PropertyData propertyDataResult, String propertyName, String resourceId) {
128 log.debug("The object returned after create property is {}", propertyDataResult);
129 PropertyDefinition propertyDefResult = new PropertyDefinition(propertyDataResult.getPropertyDataDefinition());
130 propertyDefResult.setConstraints(convertConstraints(propertyDataResult.getConstraints()));
131 propertyDefResult.setName(propertyName);
132 return propertyDefResult;
135 public Either<PropertyData, StorageOperationStatus> addProperty(String propertyName, PropertyDefinition propertyDefinition, String resourceId) {
136 Either<PropertyData, JanusGraphOperationStatus> either = addPropertyToGraph(propertyName, propertyDefinition, resourceId);
137 if (either.isRight()) {
138 StorageOperationStatus storageStatus = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(either.right().value());
139 return Either.right(storageStatus);
141 return Either.left(either.left().value());
145 * @param propertyDefinition
149 public StorageOperationStatus validateAndUpdateProperty(IComplexDefaultValue propertyDefinition, Map<String, DataTypeDefinition> dataTypes) {
150 log.trace("Going to validate property type and value. {}", propertyDefinition);
151 String propertyType = propertyDefinition.getType();
152 String value = propertyDefinition.getDefaultValue();
153 ToscaPropertyType type = getType(propertyType);
155 DataTypeDefinition dataTypeDefinition = dataTypes.get(propertyType);
156 if (dataTypeDefinition == null) {
157 log.debug("The type {} of property cannot be found.", propertyType);
158 return StorageOperationStatus.INVALID_TYPE;
160 return validateAndUpdateComplexValue(propertyDefinition, propertyType, value, dataTypeDefinition, dataTypes);
162 String innerType = null;
163 Either<String, JanusGraphOperationStatus> checkInnerType = getInnerType(type, propertyDefinition::getSchema);
164 if (checkInnerType.isRight()) {
165 return StorageOperationStatus.INVALID_TYPE;
167 innerType = checkInnerType.left().value();
168 log.trace("After validating property type {}", propertyType);
169 boolean isValidProperty = isValidValue(type, value, innerType, dataTypes);
170 if (!isValidProperty) {
171 log.info(THE_VALUE_OF_PROPERTY_FROM_TYPE_IS_INVALID, value, type);
172 return StorageOperationStatus.INVALID_VALUE;
174 PropertyValueConverter converter = type.getConverter();
175 if (isEmptyValue(value)) {
176 log.debug("Default value was not sent for property {}. Set default value to {}", propertyDefinition.getName(), EMPTY_VALUE);
177 propertyDefinition.setDefaultValue(EMPTY_VALUE);
178 } else if (!isEmptyValue(value)) {
179 String convertedValue = converter.convert(value, innerType, dataTypes);
180 propertyDefinition.setDefaultValue(convertedValue);
182 return StorageOperationStatus.OK;
185 public Either<PropertyData, JanusGraphOperationStatus> addPropertyToGraph(String propertyName, PropertyDefinition propertyDefinition,
187 ResourceMetadataData resourceData = new ResourceMetadataData();
188 resourceData.getMetadataDataDefinition().setUniqueId(resourceId);
189 List<PropertyConstraint> constraints = propertyDefinition.getConstraints();
190 propertyDefinition.setUniqueId(UniqueIdBuilder.buildComponentPropertyUniqueId(resourceId, propertyName));
191 PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints));
192 log.debug(BEFORE_ADDING_PROPERTY_TO_GRAPH, propertyData);
193 Either<PropertyData, JanusGraphOperationStatus> createNodeResult = janusGraphGenericDao.createNode(propertyData, PropertyData.class);
194 log.debug(AFTER_ADDING_PROPERTY_TO_GRAPH, propertyData);
195 if (createNodeResult.isRight()) {
196 JanusGraphOperationStatus operationStatus = createNodeResult.right().value();
197 log.error("Failed to add property {} to graph. status is {}", propertyName, operationStatus);
198 return Either.right(operationStatus);
200 Map<String, Object> props = new HashMap<>();
201 props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName);
202 Either<GraphRelation, JanusGraphOperationStatus> createRelResult = janusGraphGenericDao
203 .createRelation(resourceData, propertyData, GraphEdgeLabels.PROPERTY, props);
204 if (createRelResult.isRight()) {
205 JanusGraphOperationStatus operationStatus = createNodeResult.right().value();
206 log.error(FAILED_TO_ASSOCIATE_RESOURCE_TO_PROPERTY_IN_GRAPH_STATUS_IS, resourceId, propertyName, operationStatus);
207 return Either.right(operationStatus);
209 return Either.left(createNodeResult.left().value());
212 public JanusGraphOperationStatus addPropertyToGraphByVertex(JanusGraphVertex metadataVertex, String propertyName,
213 PropertyDefinition propertyDefinition, String resourceId) {
214 List<PropertyConstraint> constraints = propertyDefinition.getConstraints();
215 propertyDefinition.setUniqueId(UniqueIdBuilder.buildComponentPropertyUniqueId(resourceId, propertyName));
216 PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints));
217 log.debug(BEFORE_ADDING_PROPERTY_TO_GRAPH, propertyData);
218 Either<JanusGraphVertex, JanusGraphOperationStatus> createNodeResult = janusGraphGenericDao.createNode(propertyData);
219 log.debug(AFTER_ADDING_PROPERTY_TO_GRAPH, propertyData);
220 if (createNodeResult.isRight()) {
221 JanusGraphOperationStatus operationStatus = createNodeResult.right().value();
222 log.error("Failed to add property {} to graph. status is ", propertyName, operationStatus);
223 return operationStatus;
225 Map<String, Object> props = new HashMap<>();
226 props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName);
227 JanusGraphVertex propertyVertex = createNodeResult.left().value();
228 JanusGraphOperationStatus createRelResult = janusGraphGenericDao.createEdge(metadataVertex, propertyVertex, GraphEdgeLabels.PROPERTY, props);
229 if (!createRelResult.equals(JanusGraphOperationStatus.OK)) {
230 log.error(FAILED_TO_ASSOCIATE_RESOURCE_TO_PROPERTY_IN_GRAPH_STATUS_IS, resourceId, propertyName, createRelResult);
231 return createRelResult;
233 return createRelResult;
236 public JanusGraphGenericDao getJanusGraphGenericDao() {
237 return janusGraphGenericDao;
243 * @param janusGraphGenericDao
245 public void setJanusGraphGenericDao(HealingJanusGraphGenericDao janusGraphGenericDao) {
246 this.janusGraphGenericDao = janusGraphGenericDao;
249 public Either<PropertyData, JanusGraphOperationStatus> deletePropertyFromGraph(String propertyId) {
250 log.debug("Before deleting property from graph {}", propertyId);
251 return janusGraphGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class);
254 public Either<PropertyData, StorageOperationStatus> updateProperty(String propertyId, PropertyDefinition newPropertyDefinition,
255 Map<String, DataTypeDefinition> dataTypes) {
256 StorageOperationStatus validateAndUpdateProperty = validateAndUpdateProperty(newPropertyDefinition, dataTypes);
257 if (validateAndUpdateProperty != StorageOperationStatus.OK) {
258 return Either.right(validateAndUpdateProperty);
260 Either<PropertyData, JanusGraphOperationStatus> either = updatePropertyFromGraph(propertyId, newPropertyDefinition);
261 if (either.isRight()) {
262 StorageOperationStatus storageStatus = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(either.right().value());
263 return Either.right(storageStatus);
265 return Either.left(either.left().value());
268 public Either<PropertyData, JanusGraphOperationStatus> updatePropertyFromGraph(String propertyId, PropertyDefinition propertyDefinition) {
269 if (log.isDebugEnabled()) {
270 log.debug("Before updating property on graph {}", propertyId);
272 // get the original property data
273 Either<PropertyData, JanusGraphOperationStatus> statusProperty = janusGraphGenericDao
274 .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class);
275 if (statusProperty.isRight()) {
276 log.debug("Problem while get property with id {}. Reason - {}", propertyId, statusProperty.right().value().name());
277 return Either.right(statusProperty.right().value());
279 PropertyData orgPropertyData = statusProperty.left().value();
280 PropertyDataDefinition orgPropertyDataDefinition = orgPropertyData.getPropertyDataDefinition();
281 // create new property data to update
282 PropertyData newPropertyData = new PropertyData();
283 newPropertyData.setPropertyDataDefinition(propertyDefinition);
284 PropertyDataDefinition newPropertyDataDefinition = newPropertyData.getPropertyDataDefinition();
285 // update the original property data with new values
286 if (orgPropertyDataDefinition.getDefaultValue() == null) {
287 orgPropertyDataDefinition.setDefaultValue(newPropertyDataDefinition.getDefaultValue());
289 if (!orgPropertyDataDefinition.getDefaultValue().equals(newPropertyDataDefinition.getDefaultValue())) {
290 orgPropertyDataDefinition.setDefaultValue(newPropertyDataDefinition.getDefaultValue());
293 if (orgPropertyDataDefinition.getDescription() == null) {
294 orgPropertyDataDefinition.setDescription(newPropertyDataDefinition.getDescription());
296 if (!orgPropertyDataDefinition.getDescription().equals(newPropertyDataDefinition.getDescription())) {
297 orgPropertyDataDefinition.setDescription(newPropertyDataDefinition.getDescription());
300 if (!orgPropertyDataDefinition.getType().equals(newPropertyDataDefinition.getType())) {
301 orgPropertyDataDefinition.setType(newPropertyDataDefinition.getType());
303 if (newPropertyData.getConstraints() != null) {
304 orgPropertyData.setConstraints(newPropertyData.getConstraints());
306 orgPropertyDataDefinition.setSchema(newPropertyDataDefinition.getSchema());
307 return janusGraphGenericDao.updateNode(orgPropertyData, PropertyData.class);
310 public Either<PropertyData, JanusGraphOperationStatus> addPropertyToNodeType(String propertyName, PropertyDefinition propertyDefinition,
311 NodeTypeEnum nodeType, String uniqueId) {
312 List<PropertyConstraint> constraints = propertyDefinition.getConstraints();
313 propertyDefinition.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(uniqueId, propertyName));
314 PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints));
315 if (log.isDebugEnabled()) {
316 log.debug(BEFORE_ADDING_PROPERTY_TO_GRAPH, propertyData);
318 Either<PropertyData, JanusGraphOperationStatus> createNodeResult = janusGraphGenericDao.createNode(propertyData, PropertyData.class);
319 if (log.isDebugEnabled()) {
320 log.debug(AFTER_ADDING_PROPERTY_TO_GRAPH, propertyData);
322 if (createNodeResult.isRight()) {
323 JanusGraphOperationStatus operationStatus = createNodeResult.right().value();
324 log.error("Failed to add property {} to graph. status is {}", propertyName, operationStatus);
325 return Either.right(operationStatus);
327 Map<String, Object> props = new HashMap<>();
328 props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName);
329 UniqueIdData uniqueIdData = new UniqueIdData(nodeType, uniqueId);
330 log.debug("Before associating {} to property {}", uniqueIdData, propertyName);
331 Either<GraphRelation, JanusGraphOperationStatus> createRelResult = janusGraphGenericDao
332 .createRelation(uniqueIdData, propertyData, GraphEdgeLabels.PROPERTY, props);
333 if (createRelResult.isRight()) {
334 JanusGraphOperationStatus operationStatus = createNodeResult.right().value();
335 log.error(FAILED_TO_ASSOCIATE_RESOURCE_TO_PROPERTY_IN_GRAPH_STATUS_IS, uniqueId, propertyName, operationStatus);
336 return Either.right(operationStatus);
338 return Either.left(createNodeResult.left().value());
341 public Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> findPropertiesOfNode(NodeTypeEnum nodeType, String uniqueId) {
342 Map<String, PropertyDefinition> resourceProps = new HashMap<>();
343 Either<List<ImmutablePair<PropertyData, GraphEdge>>, JanusGraphOperationStatus> childrenNodes = janusGraphGenericDao
344 .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.PROPERTY, NodeTypeEnum.Property,
346 if (childrenNodes.isRight()) {
347 JanusGraphOperationStatus operationStatus = childrenNodes.right().value();
348 return Either.right(operationStatus);
350 List<ImmutablePair<PropertyData, GraphEdge>> values = childrenNodes.left().value();
351 if (values != null) {
352 for (ImmutablePair<PropertyData, GraphEdge> immutablePair : values) {
353 GraphEdge edge = immutablePair.getValue();
354 String propertyName = (String) edge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty());
355 log.debug("Property {} is associated to node {}", propertyName, uniqueId);
356 PropertyData propertyData = immutablePair.getKey();
357 PropertyDefinition propertyDefinition = this.convertPropertyDataToPropertyDefinition(propertyData, propertyName, uniqueId);
358 resourceProps.put(propertyName, propertyDefinition);
361 log.debug("The properties associated to node {} are {}", uniqueId, resourceProps);
362 return Either.left(resourceProps);
365 public Either<Map<String, PropertyDefinition>, StorageOperationStatus> deletePropertiesAssociatedToNode(NodeTypeEnum nodeType, String uniqueId) {
366 return deleteAllPropertiesAssociatedToNode(nodeType, uniqueId).right()
367 .bind(err -> err == StorageOperationStatus.OK ? Either.left(Collections.emptyMap()) : Either.right(err));
370 public Either<Map<String, PropertyData>, JanusGraphOperationStatus> mergePropertiesAssociatedToNode(NodeTypeEnum nodeType, String uniqueId,
371 Map<String, PropertyDefinition> newProperties) {
372 Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> oldPropertiesRes = findPropertiesOfNode(nodeType, uniqueId);
373 Map<String, PropertyDefinition> reallyNewProperties;
374 Map<String, PropertyData> unchangedPropsData;
375 if (oldPropertiesRes.isRight()) {
376 JanusGraphOperationStatus err = oldPropertiesRes.right().value();
377 if (err == JanusGraphOperationStatus.NOT_FOUND) {
378 reallyNewProperties = newProperties;
379 unchangedPropsData = Collections.emptyMap();
381 return Either.right(err);
384 Map<String, PropertyDefinition> oldProperties = oldPropertiesRes.left().value();
385 reallyNewProperties = collectReallyNewProperties(newProperties, oldProperties);
386 for (Entry<String, PropertyDefinition> oldEntry : oldProperties.entrySet()) {
387 String key = oldEntry.getKey();
388 PropertyDefinition newPropDef = newProperties != null ? newProperties.get(key) : null;
389 PropertyDefinition oldPropDef = oldEntry.getValue();
390 JanusGraphOperationStatus status = updateOldProperty(newPropDef, oldPropDef);
391 if (status != JanusGraphOperationStatus.OK) {
392 return Either.right(status);
395 unchangedPropsData = oldProperties.entrySet().stream()
396 .collect(Collectors.toMap(Entry::getKey, e -> new PropertyData(e.getValue(), null)));
398 // add other properties
399 return addPropertiesToElementType(nodeType, uniqueId, reallyNewProperties, unchangedPropsData);
403 * @param newProperties
404 * @param oldProperties
407 private Map<String, PropertyDefinition> collectReallyNewProperties(Map<String, PropertyDefinition> newProperties,
408 Map<String, PropertyDefinition> oldProperties) {
409 return newProperties != null ? newProperties.entrySet().stream().filter(entry -> !oldProperties.containsKey(entry.getKey()))
410 .collect(Collectors.toMap(Entry::getKey, Entry::getValue)) : null;
417 private JanusGraphOperationStatus updateOldProperty(PropertyDefinition newPropDef, PropertyDefinition oldPropDef) {
418 if (!isUpdateAllowed(newPropDef, oldPropDef)) {
419 return JanusGraphOperationStatus.MATCH_NOT_FOUND;
421 if (isUpdateRequired(newPropDef, oldPropDef)) {
422 modifyOldPropByNewOne(newPropDef, oldPropDef);
423 List<PropertyConstraint> constraints = oldPropDef.getConstraints();
424 PropertyData node = new PropertyData(oldPropDef, convertConstraintsToString(constraints));
425 Either<PropertyData, JanusGraphOperationStatus> updateResult = janusGraphGenericDao.updateNode(node, PropertyData.class);
426 if (updateResult.isRight()) {
427 return updateResult.right().value();
430 return JanusGraphOperationStatus.OK;
437 private boolean isUpdateAllowed(PropertyDefinition newPropDef, PropertyDefinition oldPropDef) {
438 if (newPropDef == null) {
439 log.error("#mergePropertiesAssociatedToNode - Failed due attempt to delete the property with id {}", oldPropDef.getUniqueId());
442 // If the property type is missing it's something that we could want to fix
443 if (oldPropDef.getType() != null && !oldPropDef.getType().equals(newPropDef.getType())) {
444 log.error("#mergePropertiesAssociatedToNode - Failed due attempt to change type of the property with id {}", oldPropDef.getUniqueId());
451 * Update only fields which modification is permitted.
456 private void modifyOldPropByNewOne(PropertyDefinition newPropDef, PropertyDefinition oldPropDef) {
457 oldPropDef.setDefaultValue(newPropDef.getDefaultValue());
458 oldPropDef.setDescription(newPropDef.getDescription());
459 oldPropDef.setRequired(newPropDef.isRequired());
460 // Type is updated to fix possible null type issue in janusGraph DB
461 oldPropDef.setType(newPropDef.getType());
464 private boolean isUpdateRequired(PropertyDefinition newPropDef, PropertyDefinition oldPropDef) {
465 return !StringUtils.equals(oldPropDef.getDefaultValue(), newPropDef.getDefaultValue()) || !StringUtils
466 .equals(oldPropDef.getDescription(), newPropDef.getDescription()) || oldPropDef.isRequired() != newPropDef.isRequired();
470 * Adds newProperties and returns in case of success (left part of Either) map of all properties i. e. added ones and contained in
475 * @param newProperties
476 * @param unchangedPropsData
479 private Either<Map<String, PropertyData>, JanusGraphOperationStatus> addPropertiesToElementType(NodeTypeEnum nodeType, String uniqueId,
480 Map<String, PropertyDefinition> newProperties,
481 Map<String, PropertyData> unchangedPropsData) {
482 return addPropertiesToElementType(uniqueId, nodeType, newProperties).left().map(m -> {
483 m.putAll(unchangedPropsData);
488 public Either<Map<String, PropertyDefinition>, StorageOperationStatus> deleteAllPropertiesAssociatedToNode(NodeTypeEnum nodeType,
490 Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> propertiesOfNodeRes = findPropertiesOfNode(nodeType, uniqueId);
491 if (propertiesOfNodeRes.isRight()) {
492 JanusGraphOperationStatus status = propertiesOfNodeRes.right().value();
493 if (status == JanusGraphOperationStatus.NOT_FOUND) {
494 return Either.right(StorageOperationStatus.OK);
496 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
498 Map<String, PropertyDefinition> value = propertiesOfNodeRes.left().value();
499 for (PropertyDefinition propertyDefinition : value.values()) {
500 String propertyUid = propertyDefinition.getUniqueId();
501 Either<PropertyData, JanusGraphOperationStatus> deletePropertyRes = deletePropertyFromGraph(propertyUid);
502 if (deletePropertyRes.isRight()) {
503 log.error("Failed to delete property with id {}", propertyUid);
504 JanusGraphOperationStatus status = deletePropertyRes.right().value();
505 if (status == JanusGraphOperationStatus.NOT_FOUND) {
506 status = JanusGraphOperationStatus.INVALID_ID;
508 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
511 log.debug("The properties deleted from node {} are {}", uniqueId, value);
512 return Either.left(value);
516 * Checks existence of a property with the same name belonging to the same resource or existence of property with the same name and different type
517 * (including derived from hierarchy)
521 * @param propertyName
522 * @param propertyType
525 public boolean isPropertyExist(List<PropertyDefinition> properties, String resourceUid, String propertyName, String propertyType) {
526 boolean result = false;
527 if (!CollectionUtils.isEmpty(properties)) {
528 for (PropertyDefinition propertyDefinition : properties) {
529 if (propertyDefinition.getName().equals(propertyName) && (propertyDefinition.getParentUniqueId().equals(resourceUid)
530 || !propertyDefinition.getType().equals(propertyType))) {
539 public ImmutablePair<String, Boolean> validateAndUpdateRules(String propertyType, List<PropertyRule> rules, String innerType,
540 Map<String, DataTypeDefinition> dataTypes, boolean isValidate) {
541 if (rules == null || rules.isEmpty()) {
542 return new ImmutablePair<>(null, true);
544 for (PropertyRule rule : rules) {
545 String value = rule.getValue();
546 Either<Object, Boolean> updateResult = validateAndUpdatePropertyValue(propertyType, value, isValidate, innerType, dataTypes);
547 if (updateResult.isRight()) {
548 Boolean status = updateResult.right().value();
550 return new ImmutablePair<>(value, status);
553 String newValue = null;
554 Object object = updateResult.left().value();
555 if (object != null) {
556 newValue = object.toString();
558 rule.setValue(newValue);
561 return new ImmutablePair<>(null, true);
564 public void addRulesToNewPropertyValue(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty,
565 String resourceInstanceId) {
566 List<PropertyRule> rules = resourceInstanceProperty.getRules();
568 PropertyRule propertyRule = buildRuleFromPath(propertyValueData, resourceInstanceProperty, resourceInstanceId);
569 rules = new ArrayList<>();
570 rules.add(propertyRule);
572 rules = sortRules(rules);
574 propertyValueData.setRules(rules);
577 private PropertyRule buildRuleFromPath(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty,
578 String resourceInstanceId) {
579 List<String> path = resourceInstanceProperty.getPath();
580 // FOR BC. Since old Property values on VFC/VF does not have rules on
584 // Update could be done on one level only, thus we can use this
586 // operation to avoid migration.
587 if (path == null || path.isEmpty()) {
588 path = new ArrayList<>();
589 path.add(resourceInstanceId);
591 PropertyRule propertyRule = new PropertyRule();
592 propertyRule.setRule(path);
593 propertyRule.setValue(propertyValueData.getValue());
597 private List<PropertyRule> sortRules(List<PropertyRule> rules) {
598 // TODO: sort the rules by size and binary representation.
600 // (x, y, .+) --> 110 6 priority 1
602 // (x, .+, z) --> 101 5 priority 2
606 public ImmutablePair<JanusGraphOperationStatus, String> findPropertyValue(String resourceInstanceId, String propertyId) {
607 log.debug("Going to check whether the property {} already added to resource instance {}", propertyId, resourceInstanceId);
608 Either<List<ComponentInstanceProperty>, JanusGraphOperationStatus> getAllRes = this
609 .getAllPropertiesOfResourceInstanceOnlyPropertyDefId(resourceInstanceId);
610 if (getAllRes.isRight()) {
611 JanusGraphOperationStatus status = getAllRes.right().value();
612 log.trace("After fetching all properties of resource instance {}. Status is {}", resourceInstanceId, status);
613 return new ImmutablePair<>(status, null);
615 List<ComponentInstanceProperty> list = getAllRes.left().value();
617 for (ComponentInstanceProperty instanceProperty : list) {
618 String propertyUniqueId = instanceProperty.getUniqueId();
619 String valueUniqueUid = instanceProperty.getValueUniqueUid();
620 log.trace("Go over property {} under resource instance {}. valueUniqueId = {}", propertyUniqueId, resourceInstanceId, valueUniqueUid);
621 if (propertyId.equals(propertyUniqueId) && valueUniqueUid != null) {
622 log.debug("The property {} already created under resource instance {}", propertyId, resourceInstanceId);
623 return new ImmutablePair<>(JanusGraphOperationStatus.ALREADY_EXIST, valueUniqueUid);
627 return new ImmutablePair<>(JanusGraphOperationStatus.NOT_FOUND, null);
630 public void updateRulesInPropertyValue(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty,
631 String resourceInstanceId) {
632 List<PropertyRule> currentRules = propertyValueData.getRules();
633 List<PropertyRule> rules = resourceInstanceProperty.getRules();
634 // if rules are not supported.
636 PropertyRule propertyRule = buildRuleFromPath(propertyValueData, resourceInstanceProperty, resourceInstanceId);
637 rules = new ArrayList<>();
638 rules.add(propertyRule);
639 if (currentRules != null) {
640 rules = mergeRules(currentRules, rules);
643 // Full mode. all rules are sent in update operation.
644 rules = sortRules(rules);
646 propertyValueData.setRules(rules);
649 private List<PropertyRule> mergeRules(List<PropertyRule> currentRules, List<PropertyRule> newRules) {
650 List<PropertyRule> mergedRules = new ArrayList<>();
651 if (newRules == null || newRules.isEmpty()) {
654 for (PropertyRule rule : currentRules) {
655 PropertyRule propertyRule = new PropertyRule(rule.getRule(), rule.getValue());
656 mergedRules.add(propertyRule);
658 for (PropertyRule rule : newRules) {
659 PropertyRule foundRule = findRuleInList(rule, mergedRules);
660 if (foundRule != null) {
661 foundRule.setValue(rule.getValue());
663 mergedRules.add(rule);
669 private PropertyRule findRuleInList(PropertyRule rule, List<PropertyRule> rules) {
670 if (rules == null || rules.isEmpty() || rule.getRule() == null || rule.getRule().isEmpty()) {
673 PropertyRule foundRule = null;
674 for (PropertyRule propertyRule : rules) {
675 if (rule.getRuleSize() != propertyRule.getRuleSize()) {
678 boolean equals = propertyRule.compareRule(rule);
680 foundRule = propertyRule;
688 * return all properties associated to resource instance. The result does contains the property unique id but not its type, default value...
690 * @param resourceInstanceUid
693 public Either<List<ComponentInstanceProperty>, JanusGraphOperationStatus> getAllPropertiesOfResourceInstanceOnlyPropertyDefId(
694 String resourceInstanceUid) {
695 return getAllPropertiesOfResourceInstanceOnlyPropertyDefId(resourceInstanceUid, NodeTypeEnum.ResourceInstance);
698 public Either<PropertyValueData, JanusGraphOperationStatus> removePropertyOfResourceInstance(String propertyValueUid, String resourceInstanceId) {
699 Either<ComponentInstanceData, JanusGraphOperationStatus> findResInstanceRes = janusGraphGenericDao
700 .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, ComponentInstanceData.class);
701 if (findResInstanceRes.isRight()) {
702 JanusGraphOperationStatus status = findResInstanceRes.right().value();
703 if (status == JanusGraphOperationStatus.NOT_FOUND) {
704 status = JanusGraphOperationStatus.INVALID_ID;
706 return Either.right(status);
708 Either<PropertyValueData, JanusGraphOperationStatus> findPropertyDefRes = janusGraphGenericDao
709 .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.PropertyValue), propertyValueUid, PropertyValueData.class);
710 if (findPropertyDefRes.isRight()) {
711 JanusGraphOperationStatus status = findPropertyDefRes.right().value();
712 if (status == JanusGraphOperationStatus.NOT_FOUND) {
713 status = JanusGraphOperationStatus.INVALID_ID;
715 return Either.right(status);
717 Either<GraphRelation, JanusGraphOperationStatus> relation = janusGraphGenericDao
718 .getRelation(findResInstanceRes.left().value(), findPropertyDefRes.left().value(), GraphEdgeLabels.PROPERTY_VALUE);
719 if (relation.isRight()) {
720 // TODO: add error in case of error
721 JanusGraphOperationStatus status = relation.right().value();
722 if (status == JanusGraphOperationStatus.NOT_FOUND) {
723 status = JanusGraphOperationStatus.INVALID_ID;
725 return Either.right(status);
727 Either<PropertyValueData, JanusGraphOperationStatus> deleteNode = janusGraphGenericDao
728 .deleteNode(findPropertyDefRes.left().value(), PropertyValueData.class);
729 if (deleteNode.isRight()) {
730 return Either.right(deleteNode.right().value());
732 PropertyValueData value = deleteNode.left().value();
733 return Either.left(value);
736 public Either<ComponentInstanceProperty, StorageOperationStatus> removePropertyValueFromResourceInstance(String propertyValueUid,
737 String resourceInstanceId,
738 boolean inTransaction) {
739 Either<ComponentInstanceProperty, StorageOperationStatus> result = null;
741 Either<PropertyValueData, JanusGraphOperationStatus> eitherStatus = this
742 .removePropertyOfResourceInstance(propertyValueUid, resourceInstanceId);
743 if (eitherStatus.isRight()) {
744 log.error("Failed to remove property value {} from resource instance {} in Graph. status is {}", propertyValueUid, resourceInstanceId,
745 eitherStatus.right().value().name());
746 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(eitherStatus.right().value()));
749 PropertyValueData propertyValueData = eitherStatus.left().value();
750 ComponentInstanceProperty propertyValueResult = new ComponentInstanceProperty();
751 propertyValueResult.setUniqueId(resourceInstanceId);
752 propertyValueResult.setValue(propertyValueData.getValue());
753 log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult);
754 result = Either.left(propertyValueResult);
758 if (!inTransaction) {
759 if (result == null || result.isRight()) {
760 log.error(GOING_TO_EXECUTE_ROLLBACK_ON_GRAPH);
761 janusGraphGenericDao.rollback();
763 log.debug(GOING_TO_EXECUTE_COMMIT_ON_GRAPH);
764 janusGraphGenericDao.commit();
770 public ComponentInstanceProperty buildResourceInstanceProperty(PropertyValueData propertyValueData,
771 ComponentInstanceProperty resourceInstanceProperty) {
772 String value = propertyValueData.getValue();
773 String uid = propertyValueData.getUniqueId();
774 ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty(resourceInstanceProperty, value, uid);
775 instanceProperty.setPath(resourceInstanceProperty.getPath());
776 return instanceProperty;
780 public boolean isPropertyDefaultValueValid(IComplexDefaultValue propertyDefinition, Map<String, DataTypeDefinition> dataTypes) {
781 if (propertyDefinition == null) {
784 String innerType = null;
785 String propertyType = propertyDefinition.getType();
786 ToscaPropertyType type = getType(propertyType);
787 if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
788 SchemaDefinition def = propertyDefinition.getSchema();
792 PropertyDataDefinition propDef = def.getProperty();
793 if (propDef == null) {
796 innerType = propDef.getType();
798 String value = propertyDefinition.getDefaultValue();
800 return isValidValue(type, value, innerType, dataTypes);
802 log.trace("The given type {} is not a pre defined one.", propertyType);
803 DataTypeDefinition foundDt = dataTypes.get(propertyType);
804 if (foundDt != null) {
805 return isValidComplexValue(foundDt, value, dataTypes);
812 public boolean isPropertyTypeValid(IComplexDefaultValue property) {
813 if (property == null) {
816 if (ToscaPropertyType.isValidType(property.getType()) == null) {
817 Either<Boolean, JanusGraphOperationStatus> definedInDataTypes = isDefinedInDataTypes(property.getType());
818 if (definedInDataTypes.isRight()) {
821 Boolean isExist = definedInDataTypes.left().value();
822 return isExist.booleanValue();
829 public ImmutablePair<String, Boolean> isPropertyInnerTypeValid(IComplexDefaultValue property, Map<String, DataTypeDefinition> dataTypes) {
830 if (property == null) {
831 return new ImmutablePair<>(null, false);
833 SchemaDefinition schema;
834 PropertyDataDefinition innerProp;
835 String innerType = null;
836 if ((schema = property.getSchema()) != null) {
837 if ((innerProp = schema.getProperty()) != null) {
838 innerType = innerProp.getType();
841 ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType);
842 if (innerToscaType == null) {
843 DataTypeDefinition dataTypeDefinition = dataTypes.get(innerType);
844 if (dataTypeDefinition == null) {
845 log.debug("The inner type {} is not a data type.", innerType);
846 return new ImmutablePair<>(innerType, false);
848 log.debug("The inner type {} is a data type. Data type definition is {}", innerType, dataTypeDefinition);
851 return new ImmutablePair<>(innerType, true);
854 private boolean isValidComplexValue(DataTypeDefinition foundDt, String value, Map<String, DataTypeDefinition> dataTypes) {
855 ImmutablePair<JsonElement, Boolean> validateAndUpdate = dataTypeValidatorConverter.validateAndUpdate(value, foundDt, dataTypes);
856 log.trace("The result after validating complex value of type {} is {}", foundDt.getName(), validateAndUpdate);
857 return validateAndUpdate.right.booleanValue();
860 public Either<List<ComponentInstanceProperty>, JanusGraphOperationStatus> getAllPropertiesOfResourceInstanceOnlyPropertyDefId(
861 String resourceInstanceUid, NodeTypeEnum instanceNodeType) {
862 Either<JanusGraphVertex, JanusGraphOperationStatus> findResInstanceRes = janusGraphGenericDao
863 .getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(instanceNodeType), resourceInstanceUid);
864 if (findResInstanceRes.isRight()) {
865 JanusGraphOperationStatus status = findResInstanceRes.right().value();
866 if (status == JanusGraphOperationStatus.NOT_FOUND) {
867 status = JanusGraphOperationStatus.INVALID_ID;
869 return Either.right(status);
871 Either<List<ImmutablePair<JanusGraphVertex, Edge>>, JanusGraphOperationStatus> propertyImplNodes = janusGraphGenericDao
872 .getChildrenVertecies(UniqueIdBuilder.getKeyByNodeType(instanceNodeType), resourceInstanceUid, GraphEdgeLabels.PROPERTY_VALUE);
873 if (propertyImplNodes.isRight()) {
874 JanusGraphOperationStatus status = propertyImplNodes.right().value();
875 return Either.right(status);
877 List<ImmutablePair<JanusGraphVertex, Edge>> list = propertyImplNodes.left().value();
878 if (list == null || list.isEmpty()) {
879 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
881 List<ComponentInstanceProperty> result = new ArrayList<>();
882 for (ImmutablePair<JanusGraphVertex, Edge> propertyValue : list) {
883 JanusGraphVertex propertyValueDataVertex = propertyValue.getLeft();
884 String propertyValueUid = (String) janusGraphGenericDao
885 .getProperty(propertyValueDataVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty());
886 String value = (String) janusGraphGenericDao.getProperty(propertyValueDataVertex, GraphPropertiesDictionary.VALUE.getProperty());
887 ImmutablePair<JanusGraphVertex, Edge> propertyDefPair = janusGraphGenericDao
888 .getChildVertex(propertyValueDataVertex, GraphEdgeLabels.PROPERTY_IMPL);
889 if (propertyDefPair == null) {
890 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
892 Map<String, Object> properties = janusGraphGenericDao.getProperties(propertyValueDataVertex);
893 PropertyValueData propertyValueData = GraphElementFactory
894 .createElement(NodeTypeEnum.PropertyValue.getName(), GraphElementTypeEnum.Node, properties, PropertyValueData.class);
895 String propertyUniqueId = (String) janusGraphGenericDao
896 .getProperty(propertyDefPair.left, GraphPropertiesDictionary.UNIQUE_ID.getProperty());
897 ComponentInstanceProperty resourceInstanceProperty = new ComponentInstanceProperty();
898 // set property original unique id
899 resourceInstanceProperty.setUniqueId(propertyUniqueId);
902 // TODO: esofer add resource id
903 resourceInstanceProperty.setParentUniqueId(null);
905 resourceInstanceProperty.setValue(value);
906 // set property value unique id
907 resourceInstanceProperty.setValueUniqueUid(propertyValueUid);
909 resourceInstanceProperty.setRules(propertyValueData.getRules());
910 result.add(resourceInstanceProperty);
912 return Either.left(result);
916 * Find the default value from the list of component instances. Start the search from the second component instance
918 * @param pathOfComponentInstances
919 * @param propertyUniqueId
920 * @param defaultValue
923 public Either<String, JanusGraphOperationStatus> findDefaultValueFromSecondPosition(List<String> pathOfComponentInstances,
924 String propertyUniqueId, String defaultValue) {
925 log.trace("In find default value: path= {} propertyUniqId={} defaultValue= {}", pathOfComponentInstances, propertyUniqueId, defaultValue);
926 if (pathOfComponentInstances == null || pathOfComponentInstances.size() < 2) {
927 return Either.left(defaultValue);
929 String result = defaultValue;
930 for (int i = 1; i < pathOfComponentInstances.size(); i++) {
931 String compInstanceId = pathOfComponentInstances.get(i);
932 Either<List<ComponentInstanceProperty>, JanusGraphOperationStatus> propertyValuesResult = this
933 .getAllPropertiesOfResourceInstanceOnlyPropertyDefId(compInstanceId, NodeTypeEnum.ResourceInstance);
934 log.trace("After fetching properties values of component instance {}. {}", compInstanceId, propertyValuesResult);
935 if (propertyValuesResult.isRight()) {
936 JanusGraphOperationStatus status = propertyValuesResult.right().value();
937 if (status != JanusGraphOperationStatus.NOT_FOUND) {
938 return Either.right(status);
943 ComponentInstanceProperty foundCompInstanceProperty = fetchByPropertyUid(propertyValuesResult.left().value(), propertyUniqueId);
944 log.trace("After finding the component instance property on{} . {}", compInstanceId, foundCompInstanceProperty);
945 if (foundCompInstanceProperty == null) {
948 List<PropertyRule> rules = getOrBuildRulesIfNotExists(pathOfComponentInstances.size() - i, pathOfComponentInstances.get(i),
949 foundCompInstanceProperty.getRules(), foundCompInstanceProperty.getValue());
950 log.trace("Rules of property {} on component instance {} are {}", propertyUniqueId, compInstanceId, rules);
951 PropertyRule matchedRule = findMatchRule(pathOfComponentInstances, i, rules);
952 log.trace("Match rule is {}", matchedRule);
953 if (matchedRule != null) {
954 result = matchedRule.getValue();
958 return Either.left(result);
961 private ComponentInstanceProperty fetchByPropertyUid(List<ComponentInstanceProperty> list, String propertyUniqueId) {
962 ComponentInstanceProperty result = null;
966 for (ComponentInstanceProperty instProperty : list) {
967 if (instProperty.getUniqueId().equals(propertyUniqueId)) {
968 result = instProperty;
975 private List<PropertyRule> getOrBuildRulesIfNotExists(int ruleSize, String compInstanceId, List<PropertyRule> rules, String value) {
979 rules = buildDefaultRule(compInstanceId, ruleSize, value);
983 private List<PropertyRule> getRulesOfPropertyValue(int size, String instanceId, ComponentInstanceProperty componentInstanceProperty) {
984 List<PropertyRule> rules = componentInstanceProperty.getRules();
986 rules = buildDefaultRule(instanceId, size, componentInstanceProperty.getValue());
991 private List<PropertyRule> buildDefaultRule(String componentInstanceId, int size, String value) {
992 List<PropertyRule> rules = new ArrayList<>();
993 List<String> rule = new ArrayList<>();
994 rule.add(componentInstanceId);
995 for (int i = 0; i < size - 1; i++) {
996 rule.add(PropertyRule.getRuleAnyMatch());
998 PropertyRule propertyRule = new PropertyRule(rule, value);
999 rules.add(propertyRule);
1003 private PropertyRule findMatchRule(List<String> pathOfInstances, int level, List<PropertyRule> rules) {
1004 PropertyRule propertyRule = null;
1005 String stringForMatch = buildStringForMatch(pathOfInstances, level);
1006 String firstCompInstance = pathOfInstances.get(level);
1007 if (rules != null) {
1008 for (PropertyRule rule : rules) {
1009 int ruleSize = rule.getRule().size();
1010 // check the length of the rule equals to the length of the
1013 if (ruleSize != pathOfInstances.size() - level) {
1016 // check that the rule starts with correct component instance id
1017 if (!checkFirstItem(firstCompInstance, rule.getFirstToken())) {
1020 String secondToken = rule.getToken(2);
1021 if (secondToken != null && (secondToken.equals(PropertyRule.getForceAll()) || secondToken.equals(PropertyRule.getALL()))) {
1022 propertyRule = rule;
1025 String patternStr = buildStringForMatch(rule.getRule(), 0);
1026 Pattern pattern = Pattern.compile(patternStr);
1027 Matcher matcher = pattern.matcher(stringForMatch);
1028 if (matcher.matches()) {
1029 if (log.isTraceEnabled()) {
1030 log.trace("{} matches the rule {}", stringForMatch, patternStr);
1032 propertyRule = rule;
1037 return propertyRule;
1040 private boolean checkFirstItem(String left, String right) {
1041 if (left != null && left.equals(right)) {
1047 private String buildStringForMatch(List<String> pathOfInstances, int level) {
1048 StringBuilder builder = new StringBuilder();
1049 for (int i = level; i < pathOfInstances.size(); i++) {
1050 builder.append(pathOfInstances.get(i));
1051 if (i < pathOfInstances.size() - 1) {
1052 builder.append("#");
1055 return builder.toString();
1058 public void updatePropertyByBestMatch(String propertyUniqueId, ComponentInstanceProperty instanceProperty,
1059 Map<String, ComponentInstanceProperty> instanceIdToValue) {
1060 List<String> pathOfInstances = instanceProperty.getPath();
1062 int size = pathOfInstances.size();
1063 int numberOfMatches = 0;
1064 for (String instanceId : pathOfInstances) {
1065 ComponentInstanceProperty componentInstanceProperty = instanceIdToValue.get(instanceId);
1066 if (componentInstanceProperty != null) {
1067 List<PropertyRule> rules = getRulesOfPropertyValue(size - level, instanceId, componentInstanceProperty);
1068 // If it is the first level instance, then update valueUniuqeId
1070 // parameter in order to know on update that
1072 // we should update and not create new node on graph.
1074 instanceProperty.setValueUniqueUid(componentInstanceProperty.getValueUniqueUid());
1075 instanceProperty.setRules(rules);
1077 PropertyRule rule = findMatchRule(pathOfInstances, level, rules);
1080 String value = rule.getValue();
1081 if (numberOfMatches == 1) {
1082 instanceProperty.setValue(value);
1083 if (log.isDebugEnabled()) {
1084 log.debug("Set the value of property {} {} on path {} to be {}", propertyUniqueId, instanceProperty.getName(),
1085 pathOfInstances, value);
1087 } else if (numberOfMatches == 2) {
1088 // In case of another property value match, then use the
1090 // value to be the default value of the property.
1091 instanceProperty.setDefaultValue(value);
1092 if (log.isDebugEnabled()) {
1093 log.debug("Set the default value of property {} {} on path {} to be {}", propertyUniqueId, instanceProperty.getName(),
1094 pathOfInstances, value);
1105 * Add data type to graph.
1107 * 1. Add data type node
1109 * 2. Add edge between the former node to its parent(if exists)
1111 * 3. Add property node and associate it to the node created at #1. (per property & if exists)
1113 * @param dataTypeDefinition
1116 private Either<DataTypeData, JanusGraphOperationStatus> addDataTypeToGraph(DataTypeDefinition dataTypeDefinition) {
1117 log.debug("Got data type {}", dataTypeDefinition);
1118 String dtUniqueId = UniqueIdBuilder.buildDataTypeUid(dataTypeDefinition.getName());
1119 DataTypeData dataTypeData = buildDataTypeData(dataTypeDefinition, dtUniqueId);
1120 log.debug("Before adding data type to graph. dataTypeData = {}", dataTypeData);
1121 Either<DataTypeData, JanusGraphOperationStatus> createDataTypeResult = janusGraphGenericDao.createNode(dataTypeData, DataTypeData.class);
1122 log.debug("After adding data type to graph. status is = {}", createDataTypeResult);
1123 if (createDataTypeResult.isRight()) {
1124 JanusGraphOperationStatus operationStatus = createDataTypeResult.right().value();
1125 log.debug("Failed to data type {} to graph. status is {}", dataTypeDefinition.getName(), operationStatus);
1126 BeEcompErrorManager.getInstance().logBeFailedAddingNodeTypeError("AddDataType", NodeTypeEnum.DataType.getName());
1127 return Either.right(operationStatus);
1129 DataTypeData resultCTD = createDataTypeResult.left().value();
1130 List<PropertyDefinition> properties = dataTypeDefinition.getProperties();
1131 Either<Map<String, PropertyData>, JanusGraphOperationStatus> addPropertiesToDataType = addPropertiesToDataType(resultCTD.getUniqueId(),
1133 if (addPropertiesToDataType.isRight()) {
1134 log.debug("Failed add properties {} to data type {}", properties, dataTypeDefinition.getName());
1135 return Either.right(addPropertiesToDataType.right().value());
1137 String derivedFrom = dataTypeDefinition.getDerivedFromName();
1138 if (derivedFrom != null) {
1139 log.debug("Before creating relation between data type {} to its parent {}", dtUniqueId, derivedFrom);
1140 UniqueIdData from = new UniqueIdData(NodeTypeEnum.DataType, dtUniqueId);
1141 String deriveFromUid = UniqueIdBuilder.buildDataTypeUid(derivedFrom);
1142 UniqueIdData to = new UniqueIdData(NodeTypeEnum.DataType, deriveFromUid);
1143 Either<GraphRelation, JanusGraphOperationStatus> createRelation = janusGraphGenericDao
1144 .createRelation(from, to, GraphEdgeLabels.DERIVED_FROM, null);
1145 log.debug("After create relation between capability type {} to its parent {}. status is {}", dtUniqueId, derivedFrom, createRelation);
1146 if (createRelation.isRight()) {
1147 return Either.right(createRelation.right().value());
1150 return Either.left(createDataTypeResult.left().value());
1153 private DataTypeData buildDataTypeData(DataTypeDefinition dataTypeDefinition, String ctUniqueId) {
1154 DataTypeData dataTypeData = new DataTypeData(dataTypeDefinition);
1155 dataTypeData.getDataTypeDataDefinition().setUniqueId(ctUniqueId);
1156 Long creationDate = dataTypeData.getDataTypeDataDefinition().getCreationTime();
1157 if (creationDate == null) {
1158 creationDate = System.currentTimeMillis();
1160 dataTypeData.getDataTypeDataDefinition().setCreationTime(creationDate);
1161 dataTypeData.getDataTypeDataDefinition().setModificationTime(creationDate);
1162 return dataTypeData;
1166 * add properties to capability type.
1168 * Per property, add a property node and associate it to the capability type
1174 private Either<Map<String, PropertyData>, JanusGraphOperationStatus> addPropertiesToDataType(String uniqueId,
1175 List<PropertyDefinition> properties) {
1176 Map<String, PropertyData> propertiesData = new HashMap<>();
1177 if (properties != null && !properties.isEmpty()) {
1178 for (PropertyDefinition propertyDefinition : properties) {
1179 String propertyName = propertyDefinition.getName();
1180 String propertyType = propertyDefinition.getType();
1181 Either<Boolean, JanusGraphOperationStatus> validPropertyType = isValidPropertyType(propertyType);
1182 if (validPropertyType.isRight()) {
1183 log.debug("Data type {} contains invalid property type {}", uniqueId, propertyType);
1184 return Either.right(validPropertyType.right().value());
1186 Boolean isValid = validPropertyType.left().value();
1187 if (isValid == null || !isValid.booleanValue()) {
1188 log.debug("Data type {} contains invalid property type {}", uniqueId, propertyType);
1189 return Either.right(JanusGraphOperationStatus.INVALID_TYPE);
1191 Either<PropertyData, JanusGraphOperationStatus> addPropertyToNodeType = this
1192 .addPropertyToNodeType(propertyName, propertyDefinition, NodeTypeEnum.DataType, uniqueId);
1193 if (addPropertyToNodeType.isRight()) {
1194 JanusGraphOperationStatus operationStatus = addPropertyToNodeType.right().value();
1195 log.debug("Failed to associate data type {} to property {} in graph. status is {}", uniqueId, propertyName, operationStatus);
1196 BeEcompErrorManager.getInstance()
1197 .logInternalFlowError("AddPropertyToDataType", "Failed to associate property to data type. Status is " + operationStatus,
1198 ErrorSeverity.ERROR);
1199 return Either.right(operationStatus);
1201 propertiesData.put(propertyName, addPropertyToNodeType.left().value());
1203 DataTypeData dataTypeData = new DataTypeData();
1204 dataTypeData.getDataTypeDataDefinition().setUniqueId(uniqueId);
1205 long modificationTime = System.currentTimeMillis();
1206 dataTypeData.getDataTypeDataDefinition().setModificationTime(modificationTime);
1207 Either<DataTypeData, JanusGraphOperationStatus> updateNode = janusGraphGenericDao.updateNode(dataTypeData, DataTypeData.class);
1208 if (updateNode.isRight()) {
1209 JanusGraphOperationStatus operationStatus = updateNode.right().value();
1210 log.debug("Failed to update modification time data type {} from graph. status is {}", uniqueId, operationStatus);
1211 BeEcompErrorManager.getInstance()
1212 .logInternalFlowError("AddPropertyToDataType", "Failed to fetch data type. Status is " + operationStatus, ErrorSeverity.ERROR);
1213 return Either.right(operationStatus);
1215 log.debug("Update data type uid {}. Set modification time to {}", uniqueId, modificationTime);
1218 return Either.left(propertiesData);
1222 * Build Data type object from graph by unique id
1227 public Either<DataTypeDefinition, JanusGraphOperationStatus> getDataTypeByUid(String uniqueId) {
1228 Either<DataTypeDefinition, JanusGraphOperationStatus> result = null;
1229 Either<DataTypeData, JanusGraphOperationStatus> dataTypesRes = janusGraphGenericDao
1230 .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, DataTypeData.class);
1231 if (dataTypesRes.isRight()) {
1232 JanusGraphOperationStatus status = dataTypesRes.right().value();
1233 log.debug(DATA_TYPE_CANNOT_BE_FOUND_IN_GRAPH_STATUS_IS, uniqueId, status);
1234 return Either.right(status);
1236 DataTypeData ctData = dataTypesRes.left().value();
1237 DataTypeDefinition dataTypeDefinition = new DataTypeDefinition(ctData.getDataTypeDataDefinition());
1238 JanusGraphOperationStatus propertiesStatus = fillProperties(uniqueId, dataTypeDefinition);
1239 if (propertiesStatus != JanusGraphOperationStatus.OK) {
1240 log.error(FAILED_TO_FETCH_PROPERTIES_OF_DATA_TYPE, uniqueId);
1241 return Either.right(propertiesStatus);
1243 Either<ImmutablePair<DataTypeData, GraphEdge>, JanusGraphOperationStatus> parentNode = janusGraphGenericDao
1244 .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.DataType,
1245 DataTypeData.class);
1246 log.debug("After retrieving DERIVED_FROM node of {}. status is {}", uniqueId, parentNode);
1247 if (parentNode.isRight()) {
1248 JanusGraphOperationStatus janusGraphOperationStatus = parentNode.right().value();
1249 if (janusGraphOperationStatus != JanusGraphOperationStatus.NOT_FOUND) {
1250 log.error("Failed to find the parent data type of data type {}. status is {}", uniqueId, janusGraphOperationStatus);
1251 result = Either.right(janusGraphOperationStatus);
1255 // derived from node was found
1256 ImmutablePair<DataTypeData, GraphEdge> immutablePair = parentNode.left().value();
1257 DataTypeData parentCT = immutablePair.getKey();
1258 String parentUniqueId = parentCT.getUniqueId();
1259 Either<DataTypeDefinition, JanusGraphOperationStatus> dataTypeByUid = getDataTypeByUid(parentUniqueId);
1260 if (dataTypeByUid.isRight()) {
1261 return Either.right(dataTypeByUid.right().value());
1263 DataTypeDefinition parentDataTypeDefinition = dataTypeByUid.left().value();
1264 dataTypeDefinition.setDerivedFrom(parentDataTypeDefinition);
1266 result = Either.left(dataTypeDefinition);
1270 private JanusGraphOperationStatus fillProperties(String uniqueId, DataTypeDefinition dataTypeDefinition) {
1271 Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> findPropertiesOfNode = this
1272 .findPropertiesOfNode(NodeTypeEnum.DataType, uniqueId);
1273 if (findPropertiesOfNode.isRight()) {
1274 JanusGraphOperationStatus janusGraphOperationStatus = findPropertiesOfNode.right().value();
1275 log.debug("After looking for properties of vertex {}. status is {}", uniqueId, janusGraphOperationStatus);
1276 if (JanusGraphOperationStatus.NOT_FOUND.equals(janusGraphOperationStatus)) {
1277 return JanusGraphOperationStatus.OK;
1279 return janusGraphOperationStatus;
1282 Map<String, PropertyDefinition> properties = findPropertiesOfNode.left().value();
1283 if (properties != null && !properties.isEmpty()) {
1284 List<PropertyDefinition> listOfProps = new ArrayList<>();
1285 for (Entry<String, PropertyDefinition> entry : properties.entrySet()) {
1286 String propName = entry.getKey();
1287 PropertyDefinition propertyDefinition = entry.getValue();
1288 PropertyDefinition newPropertyDefinition = new PropertyDefinition(propertyDefinition);
1289 newPropertyDefinition.setName(propName);
1290 listOfProps.add(newPropertyDefinition);
1292 dataTypeDefinition.setProperties(listOfProps);
1294 return JanusGraphOperationStatus.OK;
1298 private Either<DataTypeDefinition, StorageOperationStatus> addDataType(DataTypeDefinition dataTypeDefinition, boolean inTransaction) {
1299 Either<DataTypeDefinition, StorageOperationStatus> result = null;
1301 Either<DataTypeData, JanusGraphOperationStatus> eitherStatus = addDataTypeToGraph(dataTypeDefinition);
1302 if (eitherStatus.isRight()) {
1303 log.debug("Failed to add data type {} to Graph. status is {}", dataTypeDefinition, eitherStatus.right().value().name());
1304 BeEcompErrorManager.getInstance().logBeFailedAddingNodeTypeError("AddDataType", "DataType");
1305 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(eitherStatus.right().value()));
1308 DataTypeData capabilityTypeData = eitherStatus.left().value();
1309 DataTypeDefinition dataTypeDefResult = convertDTDataToDTDefinition(capabilityTypeData);
1310 log.debug("The returned CapabilityTypeDefinition is {}", dataTypeDefResult);
1311 result = Either.left(dataTypeDefResult);
1315 if (!inTransaction) {
1316 if (result == null || result.isRight()) {
1317 log.error(GOING_TO_EXECUTE_ROLLBACK_ON_GRAPH);
1318 janusGraphGenericDao.rollback();
1320 log.debug(GOING_TO_EXECUTE_COMMIT_ON_GRAPH);
1321 janusGraphGenericDao.commit();
1328 public Either<DataTypeDefinition, StorageOperationStatus> addDataType(DataTypeDefinition dataTypeDefinition) {
1329 return addDataType(dataTypeDefinition, true);
1333 public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByName(String name, boolean inTransaction) {
1334 Either<DataTypeDefinition, StorageOperationStatus> result = null;
1336 String dtUid = UniqueIdBuilder.buildDataTypeUid(name);
1337 Either<DataTypeDefinition, JanusGraphOperationStatus> ctResult = this.getDataTypeByUid(dtUid);
1338 if (ctResult.isRight()) {
1339 JanusGraphOperationStatus status = ctResult.right().value();
1340 if (status != JanusGraphOperationStatus.NOT_FOUND) {
1341 log.error("Failed to retrieve information on capability type {} status is {}", name, status);
1343 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(ctResult.right().value()));
1346 result = Either.left(ctResult.left().value());
1349 if (!inTransaction) {
1350 if (result == null || result.isRight()) {
1351 log.error(GOING_TO_EXECUTE_ROLLBACK_ON_GRAPH);
1352 janusGraphGenericDao.rollback();
1354 log.debug(GOING_TO_EXECUTE_COMMIT_ON_GRAPH);
1355 janusGraphGenericDao.commit();
1362 public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByName(String name) {
1363 return getDataTypeByName(name, true);
1367 public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByNameWithoutDerived(String name) {
1368 return getDataTypeByNameWithoutDerived(name, true);
1371 private Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByNameWithoutDerived(String name, boolean inTransaction) {
1372 Either<DataTypeDefinition, StorageOperationStatus> result = null;
1374 String uid = UniqueIdBuilder.buildDataTypeUid(name);
1375 Either<DataTypeDefinition, JanusGraphOperationStatus> ctResult = this.getDataTypeByUidWithoutDerivedDataTypes(uid);
1376 if (ctResult.isRight()) {
1377 JanusGraphOperationStatus status = ctResult.right().value();
1378 if (status != JanusGraphOperationStatus.NOT_FOUND) {
1379 log.error("Failed to retrieve information on capability type {} status is {}", name, status);
1381 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(ctResult.right().value()));
1384 result = Either.left(ctResult.left().value());
1387 if (!inTransaction) {
1388 if (result == null || result.isRight()) {
1389 log.error(GOING_TO_EXECUTE_ROLLBACK_ON_GRAPH);
1390 janusGraphGenericDao.rollback();
1392 log.debug(GOING_TO_EXECUTE_COMMIT_ON_GRAPH);
1393 janusGraphGenericDao.commit();
1399 public Either<DataTypeDefinition, JanusGraphOperationStatus> getDataTypeByUidWithoutDerivedDataTypes(String uniqueId) {
1400 Either<DataTypeData, JanusGraphOperationStatus> dataTypesRes = janusGraphGenericDao
1401 .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, DataTypeData.class);
1402 if (dataTypesRes.isRight()) {
1403 JanusGraphOperationStatus status = dataTypesRes.right().value();
1404 log.debug(DATA_TYPE_CANNOT_BE_FOUND_IN_GRAPH_STATUS_IS, uniqueId, status);
1405 return Either.right(status);
1407 DataTypeData ctData = dataTypesRes.left().value();
1408 DataTypeDefinition dataTypeDefinition = new DataTypeDefinition(ctData.getDataTypeDataDefinition());
1409 JanusGraphOperationStatus propertiesStatus = fillProperties(uniqueId, dataTypeDefinition);
1410 if (propertiesStatus != JanusGraphOperationStatus.OK) {
1411 log.error(FAILED_TO_FETCH_PROPERTIES_OF_DATA_TYPE, uniqueId);
1412 return Either.right(propertiesStatus);
1414 return Either.left(dataTypeDefinition);
1418 * convert between graph Node object to Java object
1420 * @param dataTypeData
1423 protected DataTypeDefinition convertDTDataToDTDefinition(DataTypeData dataTypeData) {
1424 log.debug("The object returned after create data type is {}", dataTypeData);
1425 return new DataTypeDefinition(dataTypeData.getDataTypeDataDefinition());
1428 private Either<Boolean, JanusGraphOperationStatus> isValidPropertyType(String propertyType) {
1429 if (propertyType == null || propertyType.isEmpty()) {
1430 return Either.left(false);
1432 ToscaPropertyType toscaPropertyType = ToscaPropertyType.isValidType(propertyType);
1433 if (toscaPropertyType == null) {
1434 return isDefinedInDataTypes(propertyType);
1436 return Either.left(true);
1440 public Either<Boolean, JanusGraphOperationStatus> isDefinedInDataTypes(String propertyType) {
1441 String dataTypeUid = UniqueIdBuilder.buildDataTypeUid(propertyType);
1442 Either<DataTypeDefinition, JanusGraphOperationStatus> dataTypeByUid = getDataTypeByUid(dataTypeUid);
1443 if (dataTypeByUid.isRight()) {
1444 JanusGraphOperationStatus status = dataTypeByUid.right().value();
1445 if (status == JanusGraphOperationStatus.NOT_FOUND) {
1446 return Either.left(false);
1448 return Either.right(status);
1450 return Either.left(true);
1453 public Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> getAllDataTypes() {
1454 Map<String, DataTypeDefinition> dataTypes = new HashMap<>();
1455 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> result = Either.left(dataTypes);
1456 Either<List<DataTypeData>, JanusGraphOperationStatus> getAllDataTypes = janusGraphGenericDao
1457 .getByCriteria(NodeTypeEnum.DataType, null, DataTypeData.class);
1458 if (getAllDataTypes.isRight()) {
1459 JanusGraphOperationStatus status = getAllDataTypes.right().value();
1460 if (status != JanusGraphOperationStatus.NOT_FOUND) {
1461 return Either.right(status);
1466 List<DataTypeData> list = getAllDataTypes.left().value();
1468 log.trace("Number of data types to load is {}", list.size());
1469 List<String> collect = list.stream().map(p -> p.getDataTypeDataDefinition().getName()).collect(Collectors.toList());
1470 log.trace("The data types to load are {}", collect);
1471 for (DataTypeData dataTypeData : list) {
1472 log.trace("Going to fetch data type {}. uid is {}", dataTypeData.getDataTypeDataDefinition().getName(), dataTypeData.getUniqueId());
1473 Either<DataTypeDefinition, JanusGraphOperationStatus> dataTypeByUid = this
1474 .getAndAddDataTypeByUid(dataTypeData.getUniqueId(), dataTypes);
1475 if (dataTypeByUid.isRight()) {
1476 JanusGraphOperationStatus status = dataTypeByUid.right().value();
1477 if (status == JanusGraphOperationStatus.NOT_FOUND) {
1478 status = JanusGraphOperationStatus.INVALID_ID;
1480 return Either.right(status);
1484 if (log.isTraceEnabled()) {
1485 if (result.isRight()) {
1486 log.trace("After fetching all data types {}", result);
1488 Map<String, DataTypeDefinition> map = result.left().value();
1490 String types = map.keySet().stream().collect(Collectors.joining(",", "[", "]"));
1491 log.trace("After fetching all data types {} ", types);
1499 * Build Data type object from graph by unique id
1504 private Either<DataTypeDefinition, JanusGraphOperationStatus> getAndAddDataTypeByUid(String uniqueId,
1505 Map<String, DataTypeDefinition> allDataTypes) {
1506 Either<DataTypeDefinition, JanusGraphOperationStatus> result = null;
1507 if (allDataTypes.containsKey(uniqueId)) {
1508 return Either.left(allDataTypes.get(uniqueId));
1510 Either<DataTypeData, JanusGraphOperationStatus> dataTypesRes = janusGraphGenericDao
1511 .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, DataTypeData.class);
1512 if (dataTypesRes.isRight()) {
1513 JanusGraphOperationStatus status = dataTypesRes.right().value();
1514 log.debug(DATA_TYPE_CANNOT_BE_FOUND_IN_GRAPH_STATUS_IS, uniqueId, status);
1515 return Either.right(status);
1517 DataTypeData ctData = dataTypesRes.left().value();
1518 DataTypeDefinition dataTypeDefinition = new DataTypeDefinition(ctData.getDataTypeDataDefinition());
1519 JanusGraphOperationStatus propertiesStatus = fillProperties(uniqueId, dataTypeDefinition);
1520 if (propertiesStatus != JanusGraphOperationStatus.OK) {
1521 log.error(FAILED_TO_FETCH_PROPERTIES_OF_DATA_TYPE, uniqueId);
1522 return Either.right(propertiesStatus);
1524 allDataTypes.put(dataTypeDefinition.getName(), dataTypeDefinition);
1525 String derivedFrom = dataTypeDefinition.getDerivedFromName();
1526 if (allDataTypes.containsKey(derivedFrom)) {
1527 DataTypeDefinition parentDataTypeDefinition = allDataTypes.get(derivedFrom);
1528 dataTypeDefinition.setDerivedFrom(parentDataTypeDefinition);
1529 return Either.left(dataTypeDefinition);
1531 Either<ImmutablePair<DataTypeData, GraphEdge>, JanusGraphOperationStatus> parentNode = janusGraphGenericDao
1532 .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.DataType,
1533 DataTypeData.class);
1534 log.debug("After retrieving DERIVED_FROM node of {}. status is {}", uniqueId, parentNode);
1535 if (parentNode.isRight()) {
1536 JanusGraphOperationStatus janusGraphOperationStatus = parentNode.right().value();
1537 if (janusGraphOperationStatus != JanusGraphOperationStatus.NOT_FOUND) {
1538 log.error("Failed to find the parent data type of data type {}. status is {}", uniqueId, janusGraphOperationStatus);
1539 result = Either.right(janusGraphOperationStatus);
1543 // derived from node was found
1544 ImmutablePair<DataTypeData, GraphEdge> immutablePair = parentNode.left().value();
1545 DataTypeData parentCT = immutablePair.getKey();
1546 String parentUniqueId = parentCT.getUniqueId();
1547 Either<DataTypeDefinition, JanusGraphOperationStatus> dataTypeByUid = getDataTypeByUid(parentUniqueId);
1548 if (dataTypeByUid.isRight()) {
1549 return Either.right(dataTypeByUid.right().value());
1551 DataTypeDefinition parentDataTypeDefinition = dataTypeByUid.left().value();
1552 dataTypeDefinition.setDerivedFrom(parentDataTypeDefinition);
1554 result = Either.left(dataTypeDefinition);
1558 public Either<String, JanusGraphOperationStatus> checkInnerType(PropertyDataDefinition propDataDef) {
1559 String propertyType = propDataDef.getType();
1560 ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
1561 return getInnerType(type, propDataDef::getSchema);
1564 public Either<List<DataTypeData>, JanusGraphOperationStatus> getAllDataTypeNodes() {
1565 Either<List<DataTypeData>, JanusGraphOperationStatus> getAllDataTypes = janusGraphGenericDao
1566 .getByCriteria(NodeTypeEnum.DataType, null, DataTypeData.class);
1567 if (getAllDataTypes.isRight()) {
1568 JanusGraphOperationStatus status = getAllDataTypes.right().value();
1569 if (status == JanusGraphOperationStatus.NOT_FOUND) {
1570 status = JanusGraphOperationStatus.OK;
1571 return Either.right(status);
1574 return getAllDataTypes;
1577 public Either<Object, Boolean> validateAndUpdatePropertyValue(String propertyType, String value, boolean isValidate, String innerType,
1578 Map<String, DataTypeDefinition> dataTypes) {
1579 log.trace("Going to validate property value and its type. type = {}, value = {}", propertyType, value);
1580 ToscaPropertyType type = getType(propertyType);
1583 DataTypeDefinition dataTypeDefinition = dataTypes.get(propertyType);
1584 ImmutablePair<JsonElement, Boolean> validateResult = dataTypeValidatorConverter
1585 .validateAndUpdate(value, dataTypeDefinition, dataTypes);
1586 if (Boolean.FALSE.equals(validateResult.right)) {
1587 log.debug(THE_VALUE_OF_PROPERTY_FROM_TYPE_IS_INVALID, value, propertyType);
1588 return Either.right(false);
1590 JsonElement jsonElement = validateResult.left;
1591 String valueFromJsonElement = getValueFromJsonElement(jsonElement);
1592 return Either.left(valueFromJsonElement);
1594 log.trace("before validating property type {}", propertyType);
1595 boolean isValidProperty = isValidValue(type, value, innerType, dataTypes);
1596 if (!isValidProperty) {
1597 log.debug(THE_VALUE_OF_PROPERTY_FROM_TYPE_IS_INVALID, value, type);
1598 return Either.right(false);
1601 Object convertedValue = value;
1602 if (!isEmptyValue(value) && isValidate) {
1603 PropertyValueConverter converter = type.getConverter();
1604 convertedValue = converter.convert(value, innerType, dataTypes);
1606 return Either.left(convertedValue);
1609 public Either<Object, Boolean> validateAndUpdatePropertyValue(String propertyType, String value, String innerType,
1610 Map<String, DataTypeDefinition> dataTypes) {
1611 return validateAndUpdatePropertyValue(propertyType, value, true, innerType, dataTypes);
1614 public <T extends GraphNode> Either<List<PropertyDefinition>, StorageOperationStatus> getAllPropertiesRec(String uniqueId, NodeTypeEnum nodeType,
1616 return this.findPropertiesOfNode(nodeType, uniqueId).right().bind(this::handleNotFoundProperties).left()
1617 .bind(props -> getAllDerivedFromChainProperties(uniqueId, nodeType, clazz, props.values()));
1620 private Either<Map<String, PropertyDefinition>, StorageOperationStatus> handleNotFoundProperties(
1621 JanusGraphOperationStatus janusGraphOperationStatus) {
1622 if (janusGraphOperationStatus == JanusGraphOperationStatus.NOT_FOUND) {
1623 return Either.left(new HashMap<>());
1625 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(janusGraphOperationStatus));
1628 private <T extends GraphNode> Either<List<PropertyDefinition>, StorageOperationStatus> getAllDerivedFromChainProperties(String uniqueId,
1629 NodeTypeEnum nodeType,
1631 Collection<PropertyDefinition> nodeProps) {
1632 List<PropertyDefinition> accumulatedProps = new ArrayList<>(nodeProps);
1633 String currentNodeUid = uniqueId;
1634 Either<T, StorageOperationStatus> derivedFrom;
1635 while ((derivedFrom = derivedFromOperation.getDerivedFromChild(currentNodeUid, nodeType, clazz)).isLeft()) {
1636 currentNodeUid = derivedFrom.left().value().getUniqueId();
1637 JanusGraphOperationStatus janusGraphOperationStatus = fillPropertiesList(currentNodeUid, nodeType, accumulatedProps::addAll);
1638 if (janusGraphOperationStatus != JanusGraphOperationStatus.OK) {
1639 log.debug("failed to fetch properties for type {} with id {}", nodeType, currentNodeUid);
1640 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(janusGraphOperationStatus));
1643 StorageOperationStatus getDerivedResult = derivedFrom.right().value();
1644 return isReachedEndOfDerivedFromChain(getDerivedResult) ? Either.left(accumulatedProps) : Either.right(getDerivedResult);
1647 private boolean isReachedEndOfDerivedFromChain(StorageOperationStatus getDerivedResult) {
1648 return getDerivedResult == StorageOperationStatus.NOT_FOUND;
1652 * @Override public PropertyOperation getPropertyOperation() { return this; }
1654 public JanusGraphOperationStatus fillPropertiesList(String uniqueId, NodeTypeEnum nodeType, Consumer<List<PropertyDefinition>> propertySetter) {
1655 Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> findPropertiesRes = findPropertiesifExist(uniqueId, nodeType);
1656 if (findPropertiesRes.isRight()) {
1657 return findPropertiesRes.right().value();
1659 Map<String, PropertyDefinition> properties = findPropertiesRes.left().value();
1660 if (properties != null) {
1661 List<PropertyDefinition> propertiesAsList = properties.entrySet().stream().map(Entry::getValue).collect(Collectors.toList());
1662 propertySetter.accept(propertiesAsList);
1664 return JanusGraphOperationStatus.OK;
1667 Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> findPropertiesifExist(String uniqueId, NodeTypeEnum nodeType) {
1668 Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> findPropertiesOfNode = this.findPropertiesOfNode(nodeType, uniqueId);
1669 if (findPropertiesOfNode.isRight()) {
1670 log.debug("After looking for properties of vertex {}. status is {}", uniqueId, findPropertiesOfNode.right().value());
1671 if (findPropertiesOfNode.right().value() == JanusGraphOperationStatus.NOT_FOUND) {
1672 return Either.left(Maps.newHashMap());
1674 return findPropertiesOfNode;
1676 return findPropertiesOfNode;
1680 * add properties to element type.
1682 * Per property, add a property node and associate it to the element type
1685 * @param propertiesMap
1688 protected Either<Map<String, PropertyData>, JanusGraphOperationStatus> addPropertiesToElementType(String uniqueId, NodeTypeEnum nodeType,
1689 Map<String, PropertyDefinition> propertiesMap) {
1690 Map<String, PropertyData> propertiesData = new HashMap<>();
1691 if (propertiesMap != null) {
1692 for (Entry<String, PropertyDefinition> propertyDefinitionEntry : propertiesMap.entrySet()) {
1693 String propertyName = propertyDefinitionEntry.getKey();
1694 Either<PropertyData, JanusGraphOperationStatus> addPropertyToNodeType = this
1695 .addPropertyToNodeType(propertyName, propertyDefinitionEntry.getValue(), nodeType, uniqueId);
1696 if (addPropertyToNodeType.isRight()) {
1697 JanusGraphOperationStatus operationStatus = addPropertyToNodeType.right().value();
1698 log.error("Failed to associate {} {} to property {} in graph. status is {}", nodeType.getName(), uniqueId, propertyName,
1700 return Either.right(operationStatus);
1702 propertiesData.put(propertyName, addPropertyToNodeType.left().value());
1705 return Either.left(propertiesData);
1708 public Either<Map<String, PropertyData>, JanusGraphOperationStatus> addPropertiesToElementType(String uniqueId, NodeTypeEnum elementType,
1709 List<PropertyDefinition> properties) {
1710 Map<String, PropertyDefinition> propMap;
1711 if (properties == null) {
1714 propMap = properties.stream().collect(Collectors.toMap(PropertyDataDefinition::getName, propDef -> propDef));
1716 return addPropertiesToElementType(uniqueId, elementType, propMap);
1720 public Either<DataTypeDefinition, StorageOperationStatus> updateDataType(DataTypeDefinition newDataTypeDefinition,
1721 DataTypeDefinition oldDataTypeDefinition) {
1722 return updateDataType(newDataTypeDefinition, oldDataTypeDefinition, true);
1725 private Either<DataTypeDefinition, StorageOperationStatus> updateDataType(DataTypeDefinition newDataTypeDefinition,
1726 DataTypeDefinition oldDataTypeDefinition, boolean inTransaction) {
1727 Either<DataTypeDefinition, StorageOperationStatus> result = null;
1729 List<PropertyDefinition> newProperties = newDataTypeDefinition.getProperties();
1730 List<PropertyDefinition> oldProperties = oldDataTypeDefinition.getProperties();
1731 String newDerivedFromName = newDataTypeDefinition.getDerivedFromName();
1732 String oldDerivedFromName = oldDataTypeDefinition.getDerivedFromName();
1733 String dataTypeName = newDataTypeDefinition.getName();
1734 List<PropertyDefinition> propertiesToAdd = new ArrayList<>();
1735 if (isPropertyOmitted(newProperties, oldProperties, dataTypeName) || isPropertyTypeChanged(dataTypeName, newProperties, oldProperties,
1736 propertiesToAdd) || isDerivedFromNameChanged(dataTypeName, newDerivedFromName, oldDerivedFromName)) {
1737 log.debug("The new data type {} is invalid.", dataTypeName);
1738 result = Either.right(StorageOperationStatus.CANNOT_UPDATE_EXISTING_ENTITY);
1741 if (propertiesToAdd == null || propertiesToAdd.isEmpty()) {
1742 log.debug("No new properties has been defined in the new data type {}", newDataTypeDefinition);
1743 result = Either.right(StorageOperationStatus.OK);
1746 Map<String, String> newDescriptions = getPropertyDescriptionsToUpdate(oldProperties, newProperties);
1747 if (MapUtils.isNotEmpty(newDescriptions)) {
1748 JanusGraphOperationStatus updatePropertiesStatus = updateDataTypePropertyDescriptions(oldDataTypeDefinition.getUniqueId(),
1750 if (updatePropertiesStatus != JanusGraphOperationStatus.OK) {
1751 log.debug("#updateDataType - Failed to update the descriptions of the properties of the data type {}. Status is {}",
1752 oldDataTypeDefinition, updatePropertiesStatus);
1753 BeEcompErrorManager.getInstance().logBeFailedAddingNodeTypeError(UPDATE_DATA_TYPE, PROPERTY);
1754 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(updatePropertiesStatus));
1758 Either<Map<String, PropertyData>, JanusGraphOperationStatus> addPropertiesToDataType = addPropertiesToDataType(
1759 oldDataTypeDefinition.getUniqueId(), propertiesToAdd);
1760 if (addPropertiesToDataType.isRight()) {
1761 log.debug("Failed to update data type {} to Graph. Status is {}", oldDataTypeDefinition,
1762 addPropertiesToDataType.right().value().name());
1763 BeEcompErrorManager.getInstance().logBeFailedAddingNodeTypeError(UPDATE_DATA_TYPE, PROPERTY);
1764 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(addPropertiesToDataType.right().value()));
1767 Either<DataTypeDefinition, JanusGraphOperationStatus> dataTypeByUid = this.getDataTypeByUid(oldDataTypeDefinition.getUniqueId());
1768 if (dataTypeByUid.isRight()) {
1769 JanusGraphOperationStatus status = addPropertiesToDataType.right().value();
1770 log.debug("Failed to get data type {} after update. Status is {}", oldDataTypeDefinition.getUniqueId(), status.name());
1771 BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError(UPDATE_DATA_TYPE, PROPERTY, status.name());
1772 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
1774 result = Either.left(dataTypeByUid.left().value());
1779 if (!inTransaction) {
1780 if (result == null || result.isRight()) {
1781 log.error(GOING_TO_EXECUTE_ROLLBACK_ON_GRAPH);
1782 janusGraphGenericDao.rollback();
1784 log.debug(GOING_TO_EXECUTE_COMMIT_ON_GRAPH);
1785 janusGraphGenericDao.commit();
1791 private boolean isPropertyTypeChanged(String dataTypeName, List<PropertyDefinition> newProperties, List<PropertyDefinition> oldProperties,
1792 List<PropertyDefinition> outputPropertiesToAdd) {
1793 if (newProperties != null && oldProperties != null) {
1794 Map<String, PropertyDefinition> newPropsMapper = newProperties.stream()
1795 .collect(Collectors.toMap(PropertyDataDefinition::getName, p -> p));
1796 Map<String, PropertyDefinition> oldPropsMapper = oldProperties.stream()
1797 .collect(Collectors.toMap(PropertyDataDefinition::getName, p -> p));
1798 for (Entry<String, PropertyDefinition> newPropertyEntry : newPropsMapper.entrySet()) {
1799 String propName = newPropertyEntry.getKey();
1800 PropertyDefinition propDef = newPropertyEntry.getValue();
1801 PropertyDefinition oldPropertyDefinition = oldPropsMapper.get(propName);
1802 if (oldPropertyDefinition == null) {
1803 log.debug("New property {} received in the data type {}", propName, dataTypeName);
1804 outputPropertiesToAdd.add(propDef);
1807 String oldType = oldPropertyDefinition.getType();
1808 String oldEntryType = getEntryType(oldPropertyDefinition);
1809 String newType = propDef.getType();
1810 String newEntryType = getEntryType(propDef);
1811 if (!oldType.equals(newType)) {
1812 log.debug("Existing property {} in data type {} has a differnet type {} than the new one {}", propName, dataTypeName, oldType,
1816 if (!equalsEntryTypes(oldEntryType, newEntryType)) {
1817 log.debug("Existing property {} in data type {} has a differnet entry type {} than the new one {}", propName, dataTypeName,
1818 oldEntryType, newEntryType);
1826 private boolean equalsEntryTypes(String oldEntryType, String newEntryType) {
1827 if (oldEntryType == null && newEntryType == null) {
1829 } else if (oldEntryType != null && newEntryType != null) {
1830 return oldEntryType.equals(newEntryType);
1836 private String getEntryType(PropertyDefinition oldPropertyDefinition) {
1837 String entryType = null;
1838 SchemaDefinition schema = oldPropertyDefinition.getSchema();
1839 if (schema != null) {
1840 PropertyDataDefinition schemaProperty = schema.getProperty();
1841 if (schemaProperty != null) {
1842 entryType = schemaProperty.getType();
1848 private boolean isPropertyOmitted(List<PropertyDefinition> newProperties, List<PropertyDefinition> oldProperties, String dataTypeName) {
1849 boolean isValid = validateChangeInCaseOfEmptyProperties(newProperties, oldProperties, dataTypeName);
1851 log.debug("At least one property is missing in the new data type {}", dataTypeName);
1854 if (newProperties != null && oldProperties != null) {
1855 List<String> newProps = newProperties.stream().map(PropertyDataDefinition::getName).collect(Collectors.toList());
1856 List<String> oldProps = oldProperties.stream().map(PropertyDataDefinition::getName).collect(Collectors.toList());
1857 if (!newProps.containsAll(oldProps)) {
1858 StringJoiner joiner = new StringJoiner(",", "[", "]");
1859 newProps.forEach(joiner::add);
1860 log.debug("Properties {} in data type {} are missing, but they already defined in the existing data type", joiner.toString(),
1868 private boolean validateChangeInCaseOfEmptyProperties(List<PropertyDefinition> newProperties, List<PropertyDefinition> oldProperties,
1869 String dataTypeName) {
1870 if (newProperties != null) {
1871 if (newProperties.isEmpty()) {
1872 newProperties = null;
1875 if (oldProperties != null) {
1876 if (oldProperties.isEmpty()) {
1877 oldProperties = null;
1880 if ((newProperties == null && oldProperties == null) || (newProperties != null && oldProperties != null)) {
1886 private boolean isDerivedFromNameChanged(String dataTypeName, String newDerivedFromName, String oldDerivedFromName) {
1887 if (newDerivedFromName != null) {
1888 boolean isEqual = newDerivedFromName.equals(oldDerivedFromName);
1890 log.debug("The new datatype {} derived from another data type {} than the existing one {}", dataTypeName, newDerivedFromName,
1891 oldDerivedFromName);
1894 } else if (oldDerivedFromName == null) {
1896 } else {// new=null, old != null
1897 log.debug("The new datatype {} derived from another data type {} than the existing one {}", dataTypeName, newDerivedFromName,
1898 oldDerivedFromName);
1908 public Either<Integer, StorageOperationStatus> increaseAndGetObjInstancePropertyCounter(String instanceId, NodeTypeEnum nodeType) {
1909 Either<JanusGraph, JanusGraphOperationStatus> graphResult = janusGraphGenericDao.getGraph();
1910 if (graphResult.isRight()) {
1911 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(graphResult.right().value()));
1913 Either<JanusGraphVertex, JanusGraphOperationStatus> vertexService = janusGraphGenericDao
1914 .getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(nodeType), instanceId);
1915 if (vertexService.isRight()) {
1916 log.debug("failed to fetch vertex of resource instance for id = {}", instanceId);
1917 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(vertexService.right().value()));
1919 Vertex vertex = vertexService.left().value();
1920 VertexProperty<Object> vertexProperty = vertex.property(GraphPropertiesDictionary.PROPERTY_COUNTER.getProperty());
1921 Integer counter = 0;
1922 if (vertexProperty.isPresent() && vertexProperty.value() != null) {
1923 counter = (Integer) vertexProperty.value();
1926 vertex.property(GraphPropertiesDictionary.PROPERTY_COUNTER.getProperty(), counter);
1927 return Either.left(counter);
1930 public Either<List<PropertyDefinition>, JanusGraphOperationStatus> validatePropertiesUniqueness(
1931 Map<String, PropertyDefinition> inheritedProperties, List<PropertyDefinition> properties) {
1932 Either<List<PropertyDefinition>, JanusGraphOperationStatus> result = Either.left(properties);
1933 for (PropertyDefinition property : properties) {
1934 JanusGraphOperationStatus status = validatePropertyUniqueness(inheritedProperties, property);
1935 if (status != JanusGraphOperationStatus.OK) {
1936 result = Either.right(status);
1944 * Validates uniqueness of examined property by comparing it with properties in propertiesOfType and updates if need type and inner type of the
1947 private JanusGraphOperationStatus validatePropertyUniqueness(Map<String, PropertyDefinition> inheritedProperties, PropertyDefinition property) {
1948 String propertyName = property.getName();
1949 String propertyType = property.getType();
1950 JanusGraphOperationStatus result = JanusGraphOperationStatus.OK;
1951 if (inheritedProperties.containsKey(propertyName)) {
1952 PropertyDefinition defaultProperty = inheritedProperties.get(propertyName);
1953 if (typesMismatch(propertyType, defaultProperty.getType())) {
1954 log.error("#validatePropertyUniqueness - Property with name {} and different type already exists.", propertyName);
1955 result = JanusGraphOperationStatus.PROPERTY_NAME_ALREADY_EXISTS;
1957 property.setType(defaultProperty.getType());
1958 String innerType = defaultProperty.getSchemaType();
1959 PropertyDataDefinition schemaProperty = property.getSchemaProperty();
1960 if (schemaProperty != null) {
1961 schemaProperty.setType(innerType);
1968 private boolean typesMismatch(String type1, String type2) {
1969 return type1 != null && type2 != null && !type2.equals(type1);
1972 public <T extends GraphNode> Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> getAllTypePropertiesFromAllDerivedFrom(
1973 String nextParentUid, NodeTypeEnum nodeType, Class<T> clazz) {
1974 Map<String, PropertyDefinition> allProperies = new HashMap<>();
1975 return getTypePropertiesFromDerivedFromRecursively(nextParentUid, allProperies, nodeType, clazz);
1978 private <T extends GraphNode> Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> getTypePropertiesFromDerivedFromRecursively(
1979 String nextParentUid, Map<String, PropertyDefinition> allProperies, NodeTypeEnum nodeType, Class<T> clazz) {
1980 JanusGraphOperationStatus error;
1981 Either<List<ImmutablePair<T, GraphEdge>>, JanusGraphOperationStatus> childrenNodes = janusGraphGenericDao
1982 .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), nextParentUid, GraphEdgeLabels.DERIVED_FROM, nodeType, clazz);
1983 if (childrenNodes.isRight()) {
1984 if (childrenNodes.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
1985 error = childrenNodes.right().value();
1986 log.debug("#getTypePropertiesFromDerivedFromRecursively - Couldn't fetch derived from node with UID {}, error: {}", nextParentUid,
1988 return Either.right(error);
1990 log.debug("#getTypePropertiesFromDerivedFromRecursively - Derived from node is not found with UID {} - this is OK for root.",
1992 return Either.left(allProperies);
1995 Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> allPropertiesOfTypeRes = findPropertiesOfNode(nodeType, nextParentUid);
1996 if (allPropertiesOfTypeRes.isRight() && !allPropertiesOfTypeRes.right().value().equals(JanusGraphOperationStatus.NOT_FOUND)) {
1997 error = allPropertiesOfTypeRes.right().value();
1999 "#getTypePropertiesFromDerivedFromRecursively - Failed to retrieve properties for node with UID {} from graph. status is {}",
2000 nextParentUid, error);
2001 return Either.right(error);
2002 } else if (allPropertiesOfTypeRes.isLeft()) {
2003 if (allProperies.isEmpty()) {
2004 allProperies.putAll(allPropertiesOfTypeRes.left().value());
2006 allProperies.putAll(allPropertiesOfTypeRes.left().value().entrySet().stream().filter(e -> !allProperies.containsKey(e.getKey()))
2007 .collect(Collectors.toMap(Entry::getKey, Entry::getValue)));
2010 return getTypePropertiesFromDerivedFromRecursively(childrenNodes.left().value().get(0).getLeft().getUniqueId(), allProperies, nodeType,
2015 private JanusGraphOperationStatus updateDataTypePropertyDescriptions(String uniqueId, Map<String, String> newDescriptions) {
2016 if (MapUtils.isNotEmpty(newDescriptions)) {
2017 Either<List<ImmutablePair<JanusGraphVertex, Edge>>, JanusGraphOperationStatus> getDataTypePropertiesRes = janusGraphGenericDao
2018 .getChildrenVertecies(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), uniqueId, GraphEdgeLabels.PROPERTY);
2019 if (getDataTypePropertiesRes.isRight()) {
2020 log.debug("#updateDataTypePropertiesDescriptions - Failed to fetch the property verticies of the Data type {} ", uniqueId);
2021 return getDataTypePropertiesRes.right().value();
2023 getDataTypePropertiesRes.left().value().stream().filter(pair -> newDescriptions.containsKey(getPropertyNameFromEdge(pair)))
2024 .forEach(pair -> setNewDescriptionToVertex(newDescriptions.get(getPropertyNameFromEdge(pair)), pair));
2026 return JanusGraphOperationStatus.OK;
2029 private JanusGraphVertexProperty<String> setNewDescriptionToVertex(String newDescription, ImmutablePair<JanusGraphVertex, Edge> pair) {
2030 return pair.getLeft().property(GraphPropertiesDictionary.DESCRIPTION.getProperty(), newDescription);
2033 private String getPropertyNameFromEdge(ImmutablePair<JanusGraphVertex, Edge> pair) {
2034 return (String) pair.getRight().property(GraphPropertiesDictionary.NAME.getProperty()).value();
2037 private Map<String, String> getPropertyDescriptionsToUpdate(List<PropertyDefinition> oldProperties, List<PropertyDefinition> newProperties) {
2038 Map<String, PropertyDefinition> newPropertiesMap = newProperties.stream().collect(Collectors.toMap(PropertyDefinition::getName, p -> p));
2039 return oldProperties.stream()
2040 .filter(p -> newPropertiesMap.containsKey(p.getName()) && !descriptionsEqual(p, newPropertiesMap.get(p.getName())))
2041 .collect(Collectors.toMap(PropertyDefinition::getName, p -> newPropertiesMap.get(p.getName()).getDescription()));
2044 private boolean descriptionsEqual(PropertyDefinition property, PropertyDefinition otherProperty) {
2045 if (StringUtils.isEmpty(property.getDescription()) && StringUtils.isEmpty(otherProperty.getDescription())) {
2048 if (StringUtils.isNotEmpty(property.getDescription()) && StringUtils.isEmpty(otherProperty.getDescription())) {
2051 if (StringUtils.isEmpty(property.getDescription()) && StringUtils.isNotEmpty(otherProperty.getDescription())) {
2054 return property.getDescription().equals(otherProperty.getDescription());
2057 public static class PropertyConstraintSerialiser implements JsonSerializer<PropertyConstraint> {
2060 public JsonElement serialize(PropertyConstraint src, Type typeOfSrc, JsonSerializationContext context) {
2061 JsonParser parser = new JsonParser();
2062 JsonObject result = new JsonObject();
2063 JsonArray jsonArray = new JsonArray();
2064 if (src instanceof InRangeConstraint) {
2065 InRangeConstraint rangeConstraint = (InRangeConstraint) src;
2066 jsonArray.add(parser.parse(rangeConstraint.getRangeMinValue()));
2067 jsonArray.add(parser.parse(rangeConstraint.getRangeMaxValue()));
2068 result.add("inRange", jsonArray);
2069 } else if (src instanceof GreaterThanConstraint) {
2070 GreaterThanConstraint greaterThanConstraint = (GreaterThanConstraint) src;
2071 jsonArray.add(parser.parse(greaterThanConstraint.getGreaterThan()));
2072 result.add("greaterThan", jsonArray);
2073 } else if (src instanceof LessOrEqualConstraint) {
2074 LessOrEqualConstraint lessOrEqualConstraint = (LessOrEqualConstraint) src;
2075 jsonArray.add(parser.parse(lessOrEqualConstraint.getLessOrEqual()));
2076 result.add("lessOrEqual", jsonArray);
2078 log.warn("PropertyConstraint {} is not supported. Ignored.", src.getClass().getName());
2084 public static class PropertyConstraintDeserialiser implements JsonDeserializer<PropertyConstraint> {
2086 private static final String THE_VALUE_OF_GREATER_THAN_CONSTRAINT_IS_NULL = "The value of GreaterThanConstraint is null";
2089 public PropertyConstraint deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
2090 PropertyConstraint propertyConstraint = null;
2091 Set<Entry<String, JsonElement>> set = json.getAsJsonObject().entrySet();
2092 if (set.size() == 1) {
2093 Entry<String, JsonElement> element = set.iterator().next();
2094 String key = element.getKey();
2095 JsonElement value = element.getValue();
2096 ConstraintType constraintType = ConstraintType.getByType(key);
2097 if (constraintType == null) {
2098 log.warn("ConstraintType was not found for constraint name:{}", key);
2100 switch (constraintType) {
2102 if (value != null) {
2103 if (value instanceof JsonArray) {
2104 JsonArray rangeArray = (JsonArray) value;
2105 if (rangeArray.size() != 2) {
2106 log.error("The range constraint content is invalid. value = {}", value);
2108 InRangeConstraint rangeConstraint = new InRangeConstraint();
2109 String minValue = rangeArray.get(0).getAsString();
2111 JsonElement maxElement = rangeArray.get(1);
2112 if (maxElement.isJsonNull()) {
2113 maxValue = String.valueOf(maxElement.getAsJsonNull());
2115 maxValue = maxElement.getAsString();
2117 rangeConstraint.setRangeMinValue(minValue);
2118 rangeConstraint.setRangeMaxValue(maxValue);
2119 propertyConstraint = rangeConstraint;
2123 log.warn(THE_VALUE_OF_GREATER_THAN_CONSTRAINT_IS_NULL);
2127 if (value != null) {
2128 String asString = value.getAsString();
2129 log.debug("Before adding value to GreaterThanConstraint object. value = {}", asString);
2130 propertyConstraint = new GreaterThanConstraint(asString);
2133 log.warn(THE_VALUE_OF_GREATER_THAN_CONSTRAINT_IS_NULL);
2137 if (value != null) {
2138 String asString = value.getAsString();
2139 log.debug("Before adding value to LessThanConstraint object. value = {}", asString);
2140 propertyConstraint = new LessThanConstraint(asString);
2143 log.warn("The value of LessThanConstraint is null");
2146 case GREATER_OR_EQUAL:
2147 if (value != null) {
2148 String asString = value.getAsString();
2149 log.debug("Before adding value to GreaterThanConstraint object. value = {}", asString);
2150 propertyConstraint = new GreaterOrEqualConstraint(asString);
2153 log.warn("The value of GreaterOrEqualConstraint is null");
2157 if (value != null) {
2158 String asString = value.getAsString();
2159 log.debug("Before adding value to LessOrEqualConstraint object. value = {}", asString);
2160 propertyConstraint = new LessOrEqualConstraint(asString);
2162 log.warn(THE_VALUE_OF_GREATER_THAN_CONSTRAINT_IS_NULL);
2166 if (value != null) {
2167 JsonArray rangeArray = (JsonArray) value;
2168 if (rangeArray.size() == 0) {
2169 log.error("The valid values constraint content is invalid. value = {}", value);
2171 ValidValuesConstraint vvConstraint = new ValidValuesConstraint();
2172 List<String> validValues = new ArrayList<>();
2173 for (JsonElement jsonElement : rangeArray) {
2174 String item = jsonElement.getAsString();
2175 validValues.add(item);
2177 vvConstraint.setValidValues(validValues);
2178 propertyConstraint = vvConstraint;
2183 if (value != null) {
2184 int asInt = value.getAsInt();
2185 log.debug("Before adding value to Min Length object. value = {}", asInt);
2186 propertyConstraint = new MinLengthConstraint(asInt);
2189 log.warn("The value of MinLengthConstraint is null");
2193 log.warn("Key {} is not supported. Ignored.", key);
2197 return propertyConstraint;
2201 public static class PropertyConstraintJacksonDeserializer extends com.fasterxml.jackson.databind.JsonDeserializer<PropertyConstraint> {
2204 public PropertyConstraint deserialize(com.fasterxml.jackson.core.JsonParser json, DeserializationContext context) throws IOException {
2205 ObjectCodec oc = json.getCodec();
2206 JsonNode node = oc.readTree(json);