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 fj.data.Either;
23 import java.util.ArrayList;
24 import java.util.HashMap;
25 import java.util.Iterator;
26 import java.util.List;
28 import java.util.UUID;
29 import java.util.function.Supplier;
30 import java.util.stream.Collectors;
31 import org.apache.commons.collections.MapUtils;
32 import org.apache.commons.lang3.tuple.ImmutablePair;
33 import org.apache.tinkerpop.gremlin.structure.Vertex;
34 import org.janusgraph.core.JanusGraph;
35 import org.janusgraph.core.JanusGraphVertex;
36 import org.openecomp.sdc.be.config.BeEcompErrorManager;
37 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
38 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
39 import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
40 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
41 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
42 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
43 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
44 import org.openecomp.sdc.be.datatypes.elements.GroupInstanceDataDefinition;
45 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
46 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
47 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
48 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
49 import org.openecomp.sdc.be.model.DataTypeDefinition;
50 import org.openecomp.sdc.be.model.GroupDefinition;
51 import org.openecomp.sdc.be.model.GroupInstance;
52 import org.openecomp.sdc.be.model.GroupInstanceProperty;
53 import org.openecomp.sdc.be.model.GroupProperty;
54 import org.openecomp.sdc.be.model.IComponentInstanceConnectedElement;
55 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
56 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
57 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
58 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
59 import org.openecomp.sdc.be.model.validation.ToscaFunctionValidator;
60 import org.openecomp.sdc.be.resources.data.ArtifactData;
61 import org.openecomp.sdc.be.resources.data.GroupInstanceData;
62 import org.openecomp.sdc.be.resources.data.PropertyData;
63 import org.openecomp.sdc.be.resources.data.PropertyValueData;
64 import org.openecomp.sdc.be.resources.data.UniqueIdData;
65 import org.openecomp.sdc.common.datastructure.Wrapper;
66 import org.openecomp.sdc.common.log.wrappers.Logger;
67 import org.springframework.beans.factory.annotation.Autowired;
69 @org.springframework.stereotype.Component("group-instance-operation")
70 public class GroupInstanceOperation extends AbstractOperation implements IGroupInstanceOperation {
72 private static final String UPDATE_PROPERTY_VALUE_ON_COMPONENT_INSTANCE = "UpdatePropertyValueOnComponentInstance";
73 private static final String FAILED_TO_UPDATE_PROPERTY_VALUE_ON_INSTANCE_STATUS_IS = "Failed to update property value on instance. Status is ";
74 private static final Logger log = Logger.getLogger(GroupInstanceOperation.class.getName());
75 private final GroupOperation groupOperation;
76 private final PropertyOperation propertyOperation;
77 private final ToscaFunctionValidator toscaFunctionValidator;
78 private final ApplicationDataTypeCache applicationDataTypeCache;
81 public GroupInstanceOperation(final GroupOperation groupOperation, final PropertyOperation propertyOperation,
82 final ToscaFunctionValidator toscaFunctionValidator,
83 final ApplicationDataTypeCache applicationDataTypeCache) {
84 this.groupOperation = groupOperation;
85 this.propertyOperation = propertyOperation;
86 this.toscaFunctionValidator = toscaFunctionValidator;
87 this.applicationDataTypeCache = applicationDataTypeCache;
90 public Either<List<GroupInstance>, StorageOperationStatus> getAllGroupInstances(String parentId, NodeTypeEnum parentType) {
91 Either<List<GroupInstance>, StorageOperationStatus> result = null;
92 List<GroupInstance> groupInstanceRes = new ArrayList<>();
93 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphGenericDao.getGraph();
94 if (graph.isRight()) {
95 log.debug("Failed to work with graph {}", graph.right().value());
96 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(graph.right().value()));
98 JanusGraph tGraph = graph.left().value();
99 @SuppressWarnings("unchecked") Iterable<JanusGraphVertex> vertices = tGraph.query()
100 .has(UniqueIdBuilder.getKeyByNodeType(parentType), parentId).vertices();
101 if (vertices == null || vertices.iterator() == null || !vertices.iterator().hasNext()) {
102 log.debug("No nodes for type {} for id = {}", parentType, parentId);
103 result = Either.right(StorageOperationStatus.NOT_FOUND);
106 Iterator<JanusGraphVertex> iterator = vertices.iterator();
107 Vertex vertex = iterator.next();
108 Map<String, Object> edgeProperties = null;
109 Either<List<ImmutablePair<GroupInstanceData, GraphEdge>>, JanusGraphOperationStatus> childrenByEdgeCriteria = janusGraphGenericDao
110 .getChildrenByEdgeCriteria(vertex, parentId, GraphEdgeLabels.GROUP_INST, NodeTypeEnum.GroupInstance, GroupInstanceData.class,
112 if (childrenByEdgeCriteria.isRight()) {
113 JanusGraphOperationStatus status = childrenByEdgeCriteria.right().value();
114 log.debug("Failed to find group instance {} on graph", childrenByEdgeCriteria.right().value());
115 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
117 List<ImmutablePair<GroupInstanceData, GraphEdge>> list = childrenByEdgeCriteria.left().value();
118 for (ImmutablePair<GroupInstanceData, GraphEdge> pair : list) {
119 GroupInstanceData groupInstData = pair.getLeft();
120 GroupInstance groupInstance = new GroupInstance(groupInstData.getGroupDataDefinition());
121 String instOriginGroupId = groupInstance.getGroupUid();
122 Either<GroupDefinition, StorageOperationStatus> groupRes = groupOperation.getGroupFromGraph(instOriginGroupId, false, true, false);
123 if (groupRes.isRight()) {
124 return Either.right(groupRes.right().value());
126 GroupDefinition groupDefinition = groupRes.left().value();
127 Either<Map<String, PropertyValueData>, JanusGraphOperationStatus> groupInstancePropertyValuesRes = getAllGroupInstancePropertyValuesData(
129 if (groupInstancePropertyValuesRes.isRight()) {
130 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(groupInstancePropertyValuesRes.right().value()));
132 buildGroupInstanceFromGroup(groupInstance, groupDefinition, groupInstancePropertyValuesRes.left().value());
133 Either<List<ImmutablePair<String, String>>, JanusGraphOperationStatus> artifactsRes = getGroupArtifactsPairs(groupInstance.getUniqueId());
134 if (artifactsRes.isRight()) {
135 JanusGraphOperationStatus status = artifactsRes.right().value();
136 if (status != JanusGraphOperationStatus.OK) {
137 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
141 List<String> artifactsUid = new ArrayList<>();
142 List<String> artifactsUUID = new ArrayList<>();
143 List<ImmutablePair<String, String>> list1 = artifactsRes.left().value();
145 for (ImmutablePair<String, String> pair1 : list1) {
146 String uid = pair1.left;
147 String UUID = pair1.right;
148 artifactsUid.add(uid);
149 artifactsUUID.add(UUID);
151 groupInstance.setGroupInstanceArtifacts(artifactsUid);
152 groupInstance.setGroupInstanceArtifactsUuid(artifactsUUID);
155 groupInstanceRes.add(groupInstance);
156 log.debug("GroupInstance {} was added to list ", groupInstance.getUniqueId());
158 result = Either.left(groupInstanceRes);
162 public Either<Integer, StorageOperationStatus> increaseAndGetGroupInstancePropertyCounter(String instanceId) {
163 return propertyOperation.increaseAndGetObjInstancePropertyCounter(instanceId, NodeTypeEnum.GroupInstance);
166 public Either<ComponentInstanceProperty, StorageOperationStatus> addPropertyValueToGroupInstance(ComponentInstanceProperty groupInstanceProperty,
167 String groupInstanceId, Integer index,
168 boolean inTransaction) {
171 /// Ignore rules received from client till support
172 groupInstanceProperty.setRules(null);
176 Either<ComponentInstanceProperty, StorageOperationStatus> result = null;
178 Either<PropertyValueData, JanusGraphOperationStatus> eitherStatus = addPropertyToGroupInstance(groupInstanceProperty, groupInstanceId,
180 if (eitherStatus.isRight()) {
181 log.error("Failed to add property value {} to resource instance {} in Graph. status is {}", groupInstanceProperty, groupInstanceId,
182 eitherStatus.right().value().name());
183 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(eitherStatus.right().value()));
186 PropertyValueData propertyValueData = eitherStatus.left().value();
187 ComponentInstanceProperty propertyValueResult = propertyOperation
188 .buildResourceInstanceProperty(propertyValueData, groupInstanceProperty);
189 log.debug("The returned GroupInstanceProperty is {}", propertyValueResult);
190 Either<String, JanusGraphOperationStatus> findDefaultValue = propertyOperation
191 .findDefaultValueFromSecondPosition(groupInstanceProperty.getPath(), groupInstanceProperty.getUniqueId(),
192 groupInstanceProperty.getDefaultValue());
193 if (findDefaultValue.isRight()) {
194 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(findDefaultValue.right().value()));
197 String defaultValue = findDefaultValue.left().value();
198 propertyValueResult.setDefaultValue(defaultValue);
199 log.debug("The returned default value in ResourceInstanceProperty is {}", defaultValue);
200 result = Either.left(propertyValueResult);
204 if (!inTransaction) {
205 if (result == null || result.isRight()) {
206 log.error("Going to execute rollback on graph.");
207 janusGraphGenericDao.rollback();
209 log.debug("Going to execute commit on graph.");
210 janusGraphGenericDao.commit();
216 public Either<ComponentInstanceProperty, StorageOperationStatus> updatePropertyValueInGroupInstance(
217 ComponentInstanceProperty gropuInstanceProperty, String groupInstanceId, boolean inTransaction) {
218 // TODO Auto-generated method stub
220 // change Propety class
224 public void generateCustomizationUUID(GroupInstance groupInstance) {
225 UUID uuid = UUID.randomUUID();
226 groupInstance.setCustomizationUUID(uuid.toString());
230 * add property to resource instance
235 public Either<PropertyValueData, JanusGraphOperationStatus> addPropertyToGroupInstance(ComponentInstanceProperty groupInstanceProperty,
236 String groupInstanceId, Integer index) {
237 Either<GroupInstanceData, JanusGraphOperationStatus> findResInstanceRes = janusGraphGenericDao
238 .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.GroupInstance), groupInstanceId, GroupInstanceData.class);
239 if (findResInstanceRes.isRight()) {
240 JanusGraphOperationStatus status = findResInstanceRes.right().value();
241 if (status == JanusGraphOperationStatus.NOT_FOUND) {
242 status = JanusGraphOperationStatus.INVALID_ID;
244 return Either.right(status);
246 String propertyId = groupInstanceProperty.getUniqueId();
247 Either<PropertyData, JanusGraphOperationStatus> findPropertyDefRes = janusGraphGenericDao
248 .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class);
249 if (findPropertyDefRes.isRight()) {
250 JanusGraphOperationStatus status = findPropertyDefRes.right().value();
251 if (status == JanusGraphOperationStatus.NOT_FOUND) {
252 status = JanusGraphOperationStatus.INVALID_ID;
254 return Either.right(status);
256 String valueUniqueUid = groupInstanceProperty.getValueUniqueUid();
257 if (valueUniqueUid == null) {
258 PropertyData propertyData = findPropertyDefRes.left().value();
259 GroupInstanceData resourceInstanceData = findResInstanceRes.left().value();
260 ImmutablePair<JanusGraphOperationStatus, String> isPropertyValueExists = propertyOperation.findPropertyValue(groupInstanceId, propertyId);
261 if (isPropertyValueExists.getLeft() == JanusGraphOperationStatus.ALREADY_EXIST) {
262 log.debug("The property {} already added to the resource instance {}", propertyId, groupInstanceId);
263 groupInstanceProperty.setValueUniqueUid(isPropertyValueExists.getRight());
264 Either<PropertyValueData, JanusGraphOperationStatus> updatePropertyOfResourceInstance = updatePropertyOfGroupInstance(
265 groupInstanceProperty, groupInstanceId);
266 if (updatePropertyOfResourceInstance.isRight()) {
267 BeEcompErrorManager.getInstance().logInternalFlowError(UPDATE_PROPERTY_VALUE_ON_COMPONENT_INSTANCE,
268 FAILED_TO_UPDATE_PROPERTY_VALUE_ON_INSTANCE_STATUS_IS + updatePropertyOfResourceInstance.right().value(),
269 ErrorSeverity.ERROR);
270 return Either.right(updatePropertyOfResourceInstance.right().value());
272 return Either.left(updatePropertyOfResourceInstance.left().value());
274 if (isPropertyValueExists.getLeft() != JanusGraphOperationStatus.NOT_FOUND) {
275 log.debug("After finding property value of {} on componenet instance {}", propertyId, groupInstanceId);
276 return Either.right(isPropertyValueExists.getLeft());
278 String innerType = null;
279 PropertyDataDefinition propDataDef = propertyData.getPropertyDataDefinition();
280 String propertyType = propDataDef.getType();
281 String value = groupInstanceProperty.getValue();
282 ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
283 if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
284 SchemaDefinition def = propDataDef.getSchema();
286 log.debug("Schema doesn't exists for property of type {}", type);
287 return Either.right(JanusGraphOperationStatus.ILLEGAL_ARGUMENT);
289 PropertyDataDefinition propDef = def.getProperty();
290 if (propDef == null) {
291 log.debug("Property in Schema Definition inside property of type {} doesn't exist", type);
292 return Either.right(JanusGraphOperationStatus.ILLEGAL_ARGUMENT);
294 innerType = propDef.getType();
296 log.debug("Before validateAndUpdatePropertyValue");
297 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypes =
298 applicationDataTypeCache.getAll(groupInstanceProperty.getModel());
299 if (allDataTypes.isRight()) {
300 JanusGraphOperationStatus status = allDataTypes.right().value();
301 BeEcompErrorManager.getInstance()
302 .logInternalFlowError(UPDATE_PROPERTY_VALUE_ON_COMPONENT_INSTANCE, FAILED_TO_UPDATE_PROPERTY_VALUE_ON_INSTANCE_STATUS_IS + status,
303 ErrorSeverity.ERROR);
304 return Either.right(status);
306 Either<Object, Boolean> isValid = propertyOperation
307 .validateAndUpdatePropertyValue(propertyType, value, innerType, allDataTypes.left().value());
308 log.debug("After validateAndUpdatePropertyValue. isValid = {}", isValid);
309 String newValue = value;
310 if (isValid.isRight()) {
311 Boolean res = isValid.right().value();
313 return Either.right(JanusGraphOperationStatus.ILLEGAL_ARGUMENT);
316 Object object = isValid.left().value();
317 if (object != null) {
318 newValue = object.toString();
321 String uniqueId = UniqueIdBuilder.buildResourceInstancePropertyValueUid(resourceInstanceData.getUniqueId(), index);
322 PropertyValueData propertyValueData = new PropertyValueData();
323 propertyValueData.setUniqueId(uniqueId);
324 propertyValueData.setValue(newValue);
325 log.debug("Before validateAndUpdateRules");
326 ImmutablePair<String, Boolean> pair = propertyOperation
327 .validateAndUpdateRules(propertyType, groupInstanceProperty.getRules(), innerType, allDataTypes.left().value(), false);
328 log.debug("After validateAndUpdateRules. pair = {}", pair);
329 if (pair.getRight() != null && !pair.getRight()) {
330 BeEcompErrorManager.getInstance()
331 .logBeInvalidValueError("Add property value", pair.getLeft(), groupInstanceProperty.getName(), propertyType);
332 return Either.right(JanusGraphOperationStatus.ILLEGAL_ARGUMENT);
334 propertyOperation.addRulesToNewPropertyValue(propertyValueData, groupInstanceProperty, groupInstanceId);
335 log.debug("Before adding property value to graph {}", propertyValueData);
336 Either<PropertyValueData, JanusGraphOperationStatus> createNodeResult = janusGraphGenericDao
337 .createNode(propertyValueData, PropertyValueData.class);
338 log.debug("After adding property value to graph {}", propertyValueData);
339 if (createNodeResult.isRight()) {
340 JanusGraphOperationStatus operationStatus = createNodeResult.right().value();
341 return Either.right(operationStatus);
343 propertyValueData = createNodeResult.left().value();
344 Either<GraphRelation, JanusGraphOperationStatus> createRelResult = janusGraphGenericDao
345 .createRelation(propertyValueData, propertyData, GraphEdgeLabels.PROPERTY_IMPL, null);
346 if (createRelResult.isRight()) {
347 JanusGraphOperationStatus operationStatus = createRelResult.right().value();
348 log.error("Failed to associate property value {} to property {} in graph. status is {}", uniqueId, propertyId, operationStatus);
349 return Either.right(operationStatus);
351 createRelResult = janusGraphGenericDao.createRelation(resourceInstanceData, propertyValueData, GraphEdgeLabels.PROPERTY_VALUE, null);
352 if (createRelResult.isRight()) {
353 JanusGraphOperationStatus operationStatus = createRelResult.right().value();
354 log.error("Failed to associate resource instance {} property value {} in graph. status is {}", groupInstanceId, uniqueId,
356 return Either.right(operationStatus);
358 return Either.left(propertyValueData);
360 log.error("property value already exists.");
361 return Either.right(JanusGraphOperationStatus.ALREADY_EXIST);
366 * update value of attribute on resource instance
370 public Either<PropertyValueData, JanusGraphOperationStatus> updatePropertyOfGroupInstance(ComponentInstanceProperty groupInstanceProperty,
371 String groupInstanceId) {
372 Wrapper<JanusGraphOperationStatus> errorWrapper = new Wrapper<>();
373 UpdateDataContainer<PropertyData, PropertyValueData> updateDataContainer = new UpdateDataContainer<>(GraphEdgeLabels.PROPERTY_IMPL,
374 (() -> PropertyData.class), (() -> PropertyValueData.class), NodeTypeEnum.Property, NodeTypeEnum.PropertyValue);
375 preUpdateElementOfResourceInstanceValidations(updateDataContainer, groupInstanceProperty, groupInstanceId, errorWrapper);
376 if (!errorWrapper.isEmpty()) {
377 return Either.right(errorWrapper.getInnerElement());
380 String value = groupInstanceProperty.getValue();
381 // Specific Validation Logic
382 PropertyData propertyData = updateDataContainer.getDataWrapper().getInnerElement();
383 PropertyDataDefinition propDataDef = propertyData.getPropertyDataDefinition();
384 String propertyType = propDataDef.getType();
385 final ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
386 log.debug("The type of the property {} is {}", propertyData.getUniqueId(), propertyType);
387 final Either<String, JanusGraphOperationStatus> innerTypeEither = propertyOperation.getInnerType(type, propDataDef::getSchema);
388 if (innerTypeEither.isRight()) {
389 return Either.right(innerTypeEither.right().value());
391 // Specific Update Logic
392 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypes =
393 applicationDataTypeCache.getAll(groupInstanceProperty.getModel());
394 if (allDataTypes.isRight()) {
395 JanusGraphOperationStatus status = allDataTypes.right().value();
396 BeEcompErrorManager.getInstance()
397 .logInternalFlowError(UPDATE_PROPERTY_VALUE_ON_COMPONENT_INSTANCE, FAILED_TO_UPDATE_PROPERTY_VALUE_ON_INSTANCE_STATUS_IS + status,
398 ErrorSeverity.ERROR);
399 return Either.right(status);
401 PropertyValueData propertyValueData = updateDataContainer.getValueDataWrapper().getInnerElement();
402 if (propDataDef.isToscaFunction()) {
403 Either<GroupInstanceData, JanusGraphOperationStatus> findResInstanceRes = janusGraphGenericDao
404 .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.GroupInstance), groupInstanceId, GroupInstanceData.class);
405 final GroupInstanceData groupInstanceData = findResInstanceRes.left().value();
407 toscaFunctionValidator.validate(propDataDef, null);
408 propertyValueData.setValue(propDataDef.getToscaFunction().getValue());
410 final String innerType = innerTypeEither.left().value();
411 Either<Object, Boolean> isValid = propertyOperation
412 .validateAndUpdatePropertyValue(propertyType, value, innerType, allDataTypes.left().value());
413 String newValue = value;
414 if (isValid.isRight()) {
415 Boolean res = isValid.right().value();
417 return Either.right(JanusGraphOperationStatus.ILLEGAL_ARGUMENT);
420 Object object = isValid.left().value();
421 if (object != null) {
422 newValue = object.toString();
425 log.debug("Going to update property value from {} to {}", propertyValueData.getValue(), newValue);
426 propertyValueData.setValue(newValue);
427 ImmutablePair<String, Boolean> pair = propertyOperation
428 .validateAndUpdateRules(propertyType, groupInstanceProperty.getRules(), innerType, allDataTypes.left().value(), true);
429 if (pair.getRight() != null && !pair.getRight()) {
430 BeEcompErrorManager.getInstance()
431 .logBeInvalidValueError("Add property value", pair.getLeft(), groupInstanceProperty.getName(), propertyType);
432 return Either.right(JanusGraphOperationStatus.ILLEGAL_ARGUMENT);
436 propertyOperation.updateRulesInPropertyValue(propertyValueData, groupInstanceProperty, groupInstanceId);
437 Either<PropertyValueData, JanusGraphOperationStatus> updateRes = janusGraphGenericDao
438 .updateNode(propertyValueData, PropertyValueData.class);
439 if (updateRes.isRight()) {
440 JanusGraphOperationStatus status = updateRes.right().value();
441 return Either.right(status);
443 return Either.left(updateRes.left().value());
447 private <SomeData extends GraphNode, SomeValueData extends GraphNode> void preUpdateElementOfResourceInstanceValidations(
448 UpdateDataContainer<SomeData, SomeValueData> updateDataContainer, IComponentInstanceConnectedElement resourceInstanceProerty,
449 String resourceInstanceId, Wrapper<JanusGraphOperationStatus> errorWrapper) {
450 if (errorWrapper.isEmpty()) {
451 // Verify VFC instance Exist
452 validateGIExist(resourceInstanceId, errorWrapper);
454 if (errorWrapper.isEmpty()) {
455 // Example: Verify Property connected to VFC exist
456 validateElementConnectedToComponentExist(updateDataContainer, resourceInstanceProerty, errorWrapper);
458 if (errorWrapper.isEmpty()) {
459 // Example: Verify PropertyValue connected to VFC Instance exist
460 validateElementConnectedToComponentInstanceExist(updateDataContainer, resourceInstanceProerty, errorWrapper);
462 if (errorWrapper.isEmpty()) {
463 // Example: Verify PropertyValue connected Property
464 validateElementConnectedToInstance(updateDataContainer, resourceInstanceProerty, errorWrapper);
468 private <SomeData extends GraphNode, SomeValueData extends GraphNode> void validateElementConnectedToInstance(
469 UpdateDataContainer<SomeData, SomeValueData> updateDataContainer, IComponentInstanceConnectedElement resourceInstanceProerty,
470 Wrapper<JanusGraphOperationStatus> errorWrapper) {
471 Either<ImmutablePair<SomeData, GraphEdge>, JanusGraphOperationStatus> child = janusGraphGenericDao
472 .getChild(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeTypeValue()), resourceInstanceProerty.getValueUniqueUid(),
473 updateDataContainer.getGraphEdge(), updateDataContainer.getNodeType(), updateDataContainer.getSomeDataClassGen().get());
474 if (child.isRight()) {
475 JanusGraphOperationStatus status = child.right().value();
476 if (status == JanusGraphOperationStatus.NOT_FOUND) {
477 status = JanusGraphOperationStatus.INVALID_ID;
479 errorWrapper.setInnerElement(status);
481 updateDataContainer.getDataWrapper().setInnerElement(child.left().value().left);
485 private <SomeValueData extends GraphNode, SomeData extends GraphNode> void validateElementConnectedToComponentInstanceExist(
486 UpdateDataContainer<SomeData, SomeValueData> updateDataContainer, IComponentInstanceConnectedElement resourceInstanceProerty,
487 Wrapper<JanusGraphOperationStatus> errorWrapper) {
488 String valueUniqueUid = resourceInstanceProerty.getValueUniqueUid();
489 if (valueUniqueUid == null) {
490 errorWrapper.setInnerElement(JanusGraphOperationStatus.INVALID_ID);
492 Either<SomeValueData, JanusGraphOperationStatus> findPropertyValueRes = janusGraphGenericDao
493 .getNode(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeTypeValue()), valueUniqueUid,
494 updateDataContainer.getSomeValueDataClassGen().get());
495 if (findPropertyValueRes.isRight()) {
496 JanusGraphOperationStatus status = findPropertyValueRes.right().value();
497 if (status == JanusGraphOperationStatus.NOT_FOUND) {
498 status = JanusGraphOperationStatus.INVALID_ID;
500 errorWrapper.setInnerElement(status);
502 updateDataContainer.getValueDataWrapper().setInnerElement(findPropertyValueRes.left().value());
507 private <SomeData extends GraphNode, SomeValueData extends GraphNode> void validateElementConnectedToComponentExist(
508 UpdateDataContainer<SomeData, SomeValueData> updateDataContainer, IComponentInstanceConnectedElement resourceInstanceElementConnected,
509 Wrapper<JanusGraphOperationStatus> errorWrapper) {
510 String uniqueId = resourceInstanceElementConnected.getUniqueId();
511 Either<SomeData, JanusGraphOperationStatus> findPropertyDefRes = janusGraphGenericDao
512 .getNode(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeType()), uniqueId, updateDataContainer.getSomeDataClassGen().get());
513 if (findPropertyDefRes.isRight()) {
514 JanusGraphOperationStatus status = findPropertyDefRes.right().value();
515 errorWrapper.setInnerElement(status);
519 private void validateGIExist(String resourceInstanceId, Wrapper<JanusGraphOperationStatus> errorWrapper) {
520 validateGIExist(resourceInstanceId, null, errorWrapper);
523 private void validateGIExist(String resourceInstanceId, Wrapper<GroupInstanceData> compInsDataWrapper,
524 Wrapper<JanusGraphOperationStatus> errorWrapper) {
525 validateElementExistInGraph(resourceInstanceId, NodeTypeEnum.GroupInstance, () -> GroupInstanceData.class, compInsDataWrapper, errorWrapper);
528 public <ElementData extends GraphNode> void validateElementExistInGraph(String elementUniqueId, NodeTypeEnum elementNodeType,
529 Supplier<Class<ElementData>> elementClassGen,
530 Wrapper<ElementData> elementDataWrapper,
531 Wrapper<JanusGraphOperationStatus> errorWrapper) {
532 Either<ElementData, JanusGraphOperationStatus> findResInstanceRes = janusGraphGenericDao
533 .getNode(UniqueIdBuilder.getKeyByNodeType(elementNodeType), elementUniqueId, elementClassGen.get());
534 if (findResInstanceRes.isRight()) {
535 JanusGraphOperationStatus status = findResInstanceRes.right().value();
536 if (status == JanusGraphOperationStatus.NOT_FOUND) {
537 status = JanusGraphOperationStatus.INVALID_ID;
539 errorWrapper.setInnerElement(status);
541 if (elementDataWrapper != null) {
542 elementDataWrapper.setInnerElement(findResInstanceRes.left().value());
547 private void buildGroupInstanceFromGroup(GroupInstance groupInstance, GroupDefinition groupDefinition,
548 Map<String, PropertyValueData> groupInstancePropertyValues) {
549 groupInstance.setGroupName(groupDefinition.getName());
550 groupInstance.setInvariantUUID(groupDefinition.getInvariantUUID());
551 groupInstance.setDescription(groupDefinition.getDescription());
552 groupInstance.setVersion(groupDefinition.getVersion());
553 groupInstance.setArtifacts(groupDefinition.getArtifacts());
554 groupInstance.setArtifactsUuid(groupDefinition.getArtifactsUuid());
555 groupInstance.setType(groupDefinition.getType());
556 groupInstance.setGroupUUID(groupDefinition.getGroupUUID());
557 List<GroupInstanceProperty> groupInstanceProperties = groupDefinition.convertToGroupProperties()
558 //converts List of GroupProperties to List of GroupInstanceProperties and updates it with group instance property data
559 .stream().map(p -> getUpdatedConvertedProperty(p, groupInstancePropertyValues)).collect(Collectors.toList());
560 groupInstance.convertFromGroupInstancesProperties(groupInstanceProperties);
563 private GroupInstanceProperty getUpdatedConvertedProperty(GroupProperty groupProperty,
564 Map<String, PropertyValueData> groupInstancePropertyValues) {
565 GroupInstanceProperty updatedProperty = new GroupInstanceProperty(groupProperty, groupProperty.getValue());
566 if (!MapUtils.isEmpty(groupInstancePropertyValues) && groupInstancePropertyValues.containsKey(groupProperty.getName())) {
567 PropertyValueData groupInstancePropertyValue = groupInstancePropertyValues.get(groupProperty.getName());
568 updatedProperty.setValue(groupInstancePropertyValue.getValue());
569 updatedProperty.setValueUniqueUid(groupInstancePropertyValue.getUniqueId());
571 return updatedProperty;
574 private Either<List<ImmutablePair<String, String>>, JanusGraphOperationStatus> getGroupArtifactsPairs(String groupUniqueId) {
575 Either<List<ImmutablePair<String, String>>, JanusGraphOperationStatus> result = null;
576 Either<List<ImmutablePair<ArtifactData, GraphEdge>>, JanusGraphOperationStatus> childrenNodes = janusGraphGenericDao
577 .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.GroupInstance), groupUniqueId, GraphEdgeLabels.GROUP_ARTIFACT_REF,
578 NodeTypeEnum.ArtifactRef, ArtifactData.class);
579 if (childrenNodes.isRight()) {
580 JanusGraphOperationStatus status = childrenNodes.right().value();
581 if (status == JanusGraphOperationStatus.NOT_FOUND) {
582 status = JanusGraphOperationStatus.OK;
584 result = Either.right(status);
586 List<ImmutablePair<String, String>> artifactsList = new ArrayList<>();
587 List<ImmutablePair<ArtifactData, GraphEdge>> list = childrenNodes.left().value();
589 for (ImmutablePair<ArtifactData, GraphEdge> pair : list) {
590 ArtifactData artifactData = pair.getKey();
591 String uniqueId = artifactData.getArtifactDataDefinition().getUniqueId();
592 String UUID = artifactData.getArtifactDataDefinition().getArtifactUUID();
593 ImmutablePair<String, String> artifact = new ImmutablePair<>(uniqueId, UUID);
594 artifactsList.add(artifact);
597 log.debug("The artifacts list related to group {} is {}", groupUniqueId, artifactsList);
598 result = Either.left(artifactsList);
603 public StorageOperationStatus dissociateAndAssociateGroupsInstanceFromArtifact(String componentId, NodeTypeEnum componentTypeEnum,
604 String oldArtifactId, ArtifactData newArtifact) {
605 return this.dissociateAndAssociateGroupsInstanceFromArtifactOnGraph(componentId, componentTypeEnum, oldArtifactId, newArtifact);
608 private StorageOperationStatus dissociateAndAssociateGroupsInstanceFromArtifactOnGraph(String componentId, NodeTypeEnum componentTypeEnum,
609 String oldArtifactId, ArtifactData newArtifact) {
610 Either<List<GroupInstance>, StorageOperationStatus> allGroupsFromGraph = getAllGroupInstances(componentId, componentTypeEnum);
611 if (allGroupsFromGraph.isRight()) {
612 return allGroupsFromGraph.right().value();
614 List<GroupInstance> allGroups = allGroupsFromGraph.left().value();
615 if (allGroups == null || allGroups.isEmpty()) {
616 return StorageOperationStatus.OK;
618 // Find all groups which contains this artifact id
619 List<GroupInstance> associatedGroups = allGroups.stream()
620 .filter(p -> p.getGroupInstanceArtifacts() != null && p.getGroupInstanceArtifacts().contains(oldArtifactId)).collect(Collectors.toList());
621 if (associatedGroups != null && !associatedGroups.isEmpty()) {
622 log.debug("The groups {} contains the artifact {}",
623 associatedGroups.stream().map(GroupInstanceDataDefinition::getName).collect(Collectors.toList()), oldArtifactId);
624 UniqueIdData oldArtifactData = new UniqueIdData(NodeTypeEnum.ArtifactRef, oldArtifactId);
625 UniqueIdData newArtifactData = new UniqueIdData(NodeTypeEnum.ArtifactRef, newArtifact.getArtifactDataDefinition().getUniqueId());
626 Map<String, Object> props = new HashMap<>();
627 props.put(GraphPropertiesDictionary.NAME.getProperty(), newArtifactData.getLabel());
628 for (GroupInstance groupDefinition : associatedGroups) {
629 UniqueIdData groupData = new UniqueIdData(NodeTypeEnum.GroupInstance, groupDefinition.getUniqueId());
630 Either<GraphRelation, JanusGraphOperationStatus> deleteRelation = janusGraphGenericDao
631 .deleteRelation(groupData, oldArtifactData, GraphEdgeLabels.GROUP_ARTIFACT_REF);
632 log.trace("After dissociate group {} from artifact {}", groupDefinition.getName(), oldArtifactId);
633 if (deleteRelation.isRight()) {
634 JanusGraphOperationStatus status = deleteRelation.right().value();
635 if (status == JanusGraphOperationStatus.NOT_FOUND) {
636 status = JanusGraphOperationStatus.INVALID_ID;
638 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
640 Either<GraphRelation, JanusGraphOperationStatus> createRelation = janusGraphGenericDao
641 .createRelation(groupData, newArtifactData, GraphEdgeLabels.GROUP_ARTIFACT_REF, props);
642 log.trace("After associate group {} to artifact {}", groupDefinition.getName(), newArtifact.getUniqueIdKey());
643 if (createRelation.isRight()) {
644 JanusGraphOperationStatus status = createRelation.right().value();
645 if (status == JanusGraphOperationStatus.NOT_FOUND) {
646 status = JanusGraphOperationStatus.INVALID_ID;
648 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
652 return StorageOperationStatus.OK;
655 private Either<Map<String, PropertyValueData>, JanusGraphOperationStatus> getAllGroupInstancePropertyValuesData(GroupInstanceData groupInstData) {
656 Either<Map<String, PropertyValueData>, JanusGraphOperationStatus> result = null;
658 Either<List<ImmutablePair<PropertyValueData, GraphEdge>>, JanusGraphOperationStatus> getPropertyValueChildrenRes = janusGraphGenericDao
659 .getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), groupInstData.getUniqueId(), GraphEdgeLabels.PROPERTY_VALUE,
660 NodeTypeEnum.PropertyValue, PropertyValueData.class, true);
661 if (getPropertyValueChildrenRes.isRight()) {
662 JanusGraphOperationStatus status = getPropertyValueChildrenRes.right().value();
663 log.debug("Failed to fetch property value nodes for group instance {}. Status is {}. ", groupInstData.getName(), status);
664 if (status == JanusGraphOperationStatus.NOT_FOUND) {
665 result = Either.left(null);
667 result = Either.right(status);
670 result = Either.left(getPropertyValueChildrenRes.left().value().stream().collect(Collectors
671 .toMap(pair -> (String) (pair.getRight().getProperties().get(GraphPropertiesDictionary.PROPERTY_NAME.getProperty())),
672 ImmutablePair::getLeft)));
674 } catch (Exception e) {
675 log.debug("The Exception occured during fetch group instance () property values. The message is {}. ", groupInstData.getName(),
677 if (result == null) {
678 result = Either.right(JanusGraphOperationStatus.GENERAL_ERROR);
684 private static final class UpdateDataContainer<SomeData, SomeValueData> {
686 final Wrapper<SomeValueData> valueDataWrapper;
687 final Wrapper<SomeData> dataWrapper;
688 final GraphEdgeLabels graphEdge;
689 final Supplier<Class<SomeData>> someDataClassGen;
690 final Supplier<Class<SomeValueData>> someValueDataClassGen;
691 final NodeTypeEnum nodeType;
692 final NodeTypeEnum nodeTypeValue;
694 private UpdateDataContainer(GraphEdgeLabels graphEdge, Supplier<Class<SomeData>> someDataClassGen,
695 Supplier<Class<SomeValueData>> someValueDataClassGen, NodeTypeEnum nodeType, NodeTypeEnum nodeTypeValue) {
697 this.valueDataWrapper = new Wrapper<>();
698 this.dataWrapper = new Wrapper<>();
699 this.graphEdge = graphEdge;
700 this.someDataClassGen = someDataClassGen;
701 this.someValueDataClassGen = someValueDataClassGen;
702 this.nodeType = nodeType;
703 this.nodeTypeValue = nodeTypeValue;
706 public Wrapper<SomeValueData> getValueDataWrapper() {
707 return valueDataWrapper;
710 public Wrapper<SomeData> getDataWrapper() {
714 public GraphEdgeLabels getGraphEdge() {
718 public Supplier<Class<SomeData>> getSomeDataClassGen() {
719 return someDataClassGen;
722 public Supplier<Class<SomeValueData>> getSomeValueDataClassGen() {
723 return someValueDataClassGen;
726 public NodeTypeEnum getNodeType() {
730 public NodeTypeEnum getNodeTypeValue() {
731 return nodeTypeValue;