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.StringEscapeUtils;
33 import org.apache.commons.lang3.tuple.ImmutablePair;
34 import org.apache.tinkerpop.gremlin.structure.Vertex;
35 import org.janusgraph.core.JanusGraph;
36 import org.janusgraph.core.JanusGraphVertex;
37 import org.openecomp.sdc.be.config.BeEcompErrorManager;
38 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
39 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
40 import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
41 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
42 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
43 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
44 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
45 import org.openecomp.sdc.be.datatypes.elements.GroupInstanceDataDefinition;
46 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
47 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
48 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
49 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
50 import org.openecomp.sdc.be.model.DataTypeDefinition;
51 import org.openecomp.sdc.be.model.GroupDefinition;
52 import org.openecomp.sdc.be.model.GroupInstance;
53 import org.openecomp.sdc.be.model.GroupInstanceProperty;
54 import org.openecomp.sdc.be.model.GroupProperty;
55 import org.openecomp.sdc.be.model.IComponentInstanceConnectedElement;
56 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
57 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
58 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
59 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
60 import org.openecomp.sdc.be.model.validation.ToscaFunctionValidator;
61 import org.openecomp.sdc.be.resources.data.ArtifactData;
62 import org.openecomp.sdc.be.resources.data.GroupInstanceData;
63 import org.openecomp.sdc.be.resources.data.PropertyData;
64 import org.openecomp.sdc.be.resources.data.PropertyValueData;
65 import org.openecomp.sdc.be.resources.data.UniqueIdData;
66 import org.openecomp.sdc.common.datastructure.Wrapper;
67 import org.openecomp.sdc.common.log.wrappers.Logger;
68 import org.springframework.beans.factory.annotation.Autowired;
70 @org.springframework.stereotype.Component("group-instance-operation")
71 public class GroupInstanceOperation extends AbstractOperation implements IGroupInstanceOperation {
73 private static final String UPDATE_PROPERTY_VALUE_ON_COMPONENT_INSTANCE = "UpdatePropertyValueOnComponentInstance";
74 private static final String FAILED_TO_UPDATE_PROPERTY_VALUE_ON_INSTANCE_STATUS_IS = "Failed to update property value on instance. Status is ";
75 private static final Logger log = Logger.getLogger(GroupInstanceOperation.class.getName());
76 private final GroupOperation groupOperation;
77 private final PropertyOperation propertyOperation;
78 private final ToscaFunctionValidator toscaFunctionValidator;
79 private final ApplicationDataTypeCache applicationDataTypeCache;
82 public GroupInstanceOperation(final GroupOperation groupOperation, final PropertyOperation propertyOperation,
83 final ToscaFunctionValidator toscaFunctionValidator,
84 final ApplicationDataTypeCache applicationDataTypeCache) {
85 this.groupOperation = groupOperation;
86 this.propertyOperation = propertyOperation;
87 this.toscaFunctionValidator = toscaFunctionValidator;
88 this.applicationDataTypeCache = applicationDataTypeCache;
91 public Either<List<GroupInstance>, StorageOperationStatus> getAllGroupInstances(String parentId, NodeTypeEnum parentType) {
92 Either<List<GroupInstance>, StorageOperationStatus> result = null;
93 List<GroupInstance> groupInstanceRes = new ArrayList<>();
94 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphGenericDao.getGraph();
95 if (graph.isRight()) {
96 log.debug("Failed to work with graph {}", graph.right().value());
97 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(graph.right().value()));
99 JanusGraph tGraph = graph.left().value();
100 @SuppressWarnings("unchecked") Iterable<JanusGraphVertex> vertices = tGraph.query()
101 .has(UniqueIdBuilder.getKeyByNodeType(parentType), parentId).vertices();
102 if (vertices == null || vertices.iterator() == null || !vertices.iterator().hasNext()) {
103 log.debug("No nodes for type {} for id = {}", parentType, parentId);
104 result = Either.right(StorageOperationStatus.NOT_FOUND);
107 Iterator<JanusGraphVertex> iterator = vertices.iterator();
108 Vertex vertex = iterator.next();
109 Map<String, Object> edgeProperties = null;
110 Either<List<ImmutablePair<GroupInstanceData, GraphEdge>>, JanusGraphOperationStatus> childrenByEdgeCriteria = janusGraphGenericDao
111 .getChildrenByEdgeCriteria(vertex, parentId, GraphEdgeLabels.GROUP_INST, NodeTypeEnum.GroupInstance, GroupInstanceData.class,
113 if (childrenByEdgeCriteria.isRight()) {
114 JanusGraphOperationStatus status = childrenByEdgeCriteria.right().value();
115 log.debug("Failed to find group instance {} on graph", childrenByEdgeCriteria.right().value());
116 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
118 List<ImmutablePair<GroupInstanceData, GraphEdge>> list = childrenByEdgeCriteria.left().value();
119 for (ImmutablePair<GroupInstanceData, GraphEdge> pair : list) {
120 GroupInstanceData groupInstData = pair.getLeft();
121 GroupInstance groupInstance = new GroupInstance(groupInstData.getGroupDataDefinition());
122 String instOriginGroupId = groupInstance.getGroupUid();
123 Either<GroupDefinition, StorageOperationStatus> groupRes = groupOperation.getGroupFromGraph(instOriginGroupId, false, true, false);
124 if (groupRes.isRight()) {
125 return Either.right(groupRes.right().value());
127 GroupDefinition groupDefinition = groupRes.left().value();
128 Either<Map<String, PropertyValueData>, JanusGraphOperationStatus> groupInstancePropertyValuesRes = getAllGroupInstancePropertyValuesData(
130 if (groupInstancePropertyValuesRes.isRight()) {
131 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(groupInstancePropertyValuesRes.right().value()));
133 buildGroupInstanceFromGroup(groupInstance, groupDefinition, groupInstancePropertyValuesRes.left().value());
134 Either<List<ImmutablePair<String, String>>, JanusGraphOperationStatus> artifactsRes = getGroupArtifactsPairs(groupInstance.getUniqueId());
135 if (artifactsRes.isRight()) {
136 JanusGraphOperationStatus status = artifactsRes.right().value();
137 if (status != JanusGraphOperationStatus.OK) {
138 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
142 List<String> artifactsUid = new ArrayList<>();
143 List<String> artifactsUUID = new ArrayList<>();
144 List<ImmutablePair<String, String>> list1 = artifactsRes.left().value();
146 for (ImmutablePair<String, String> pair1 : list1) {
147 String uid = pair1.left;
148 String UUID = pair1.right;
149 artifactsUid.add(uid);
150 artifactsUUID.add(UUID);
152 groupInstance.setGroupInstanceArtifacts(artifactsUid);
153 groupInstance.setGroupInstanceArtifactsUuid(artifactsUUID);
156 groupInstanceRes.add(groupInstance);
157 log.debug("GroupInstance {} was added to list ", groupInstance.getUniqueId());
159 result = Either.left(groupInstanceRes);
163 public Either<Integer, StorageOperationStatus> increaseAndGetGroupInstancePropertyCounter(String instanceId) {
164 return propertyOperation.increaseAndGetObjInstancePropertyCounter(instanceId, NodeTypeEnum.GroupInstance);
167 public Either<ComponentInstanceProperty, StorageOperationStatus> addPropertyValueToGroupInstance(ComponentInstanceProperty groupInstanceProperty,
168 String groupInstanceId, Integer index,
169 boolean inTransaction) {
172 /// Ignore rules received from client till support
173 groupInstanceProperty.setRules(null);
177 Either<ComponentInstanceProperty, StorageOperationStatus> result = null;
179 Either<PropertyValueData, JanusGraphOperationStatus> eitherStatus = addPropertyToGroupInstance(groupInstanceProperty, groupInstanceId,
181 if (eitherStatus.isRight()) {
182 log.error("Failed to add property value {} to resource instance {} in Graph. status is {}", groupInstanceProperty, groupInstanceId,
183 eitherStatus.right().value().name());
184 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(eitherStatus.right().value()));
187 PropertyValueData propertyValueData = eitherStatus.left().value();
188 ComponentInstanceProperty propertyValueResult = propertyOperation
189 .buildResourceInstanceProperty(propertyValueData, groupInstanceProperty);
190 log.debug("The returned GroupInstanceProperty is {}", propertyValueResult);
191 Either<String, JanusGraphOperationStatus> findDefaultValue = propertyOperation
192 .findDefaultValueFromSecondPosition(groupInstanceProperty.getPath(), groupInstanceProperty.getUniqueId(),
193 groupInstanceProperty.getDefaultValue());
194 if (findDefaultValue.isRight()) {
195 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(findDefaultValue.right().value()));
198 String defaultValue = findDefaultValue.left().value();
199 propertyValueResult.setDefaultValue(defaultValue);
200 log.debug("The returned default value in ResourceInstanceProperty is {}", defaultValue);
201 result = Either.left(propertyValueResult);
205 if (!inTransaction) {
206 if (result == null || result.isRight()) {
207 log.error("Going to execute rollback on graph.");
208 janusGraphGenericDao.rollback();
210 log.debug("Going to execute commit on graph.");
211 janusGraphGenericDao.commit();
217 public Either<ComponentInstanceProperty, StorageOperationStatus> updatePropertyValueInGroupInstance(
218 ComponentInstanceProperty gropuInstanceProperty, String groupInstanceId, boolean inTransaction) {
219 // TODO Auto-generated method stub
221 // change Propety class
225 public void generateCustomizationUUID(GroupInstance groupInstance) {
226 UUID uuid = UUID.randomUUID();
227 groupInstance.setCustomizationUUID(uuid.toString());
231 * add property to resource instance
236 public Either<PropertyValueData, JanusGraphOperationStatus> addPropertyToGroupInstance(ComponentInstanceProperty groupInstanceProperty,
237 String groupInstanceId, Integer index) {
238 Either<GroupInstanceData, JanusGraphOperationStatus> findResInstanceRes = janusGraphGenericDao
239 .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.GroupInstance), groupInstanceId, GroupInstanceData.class);
240 if (findResInstanceRes.isRight()) {
241 JanusGraphOperationStatus status = findResInstanceRes.right().value();
242 if (status == JanusGraphOperationStatus.NOT_FOUND) {
243 status = JanusGraphOperationStatus.INVALID_ID;
245 return Either.right(status);
247 String propertyId = groupInstanceProperty.getUniqueId();
248 Either<PropertyData, JanusGraphOperationStatus> findPropertyDefRes = janusGraphGenericDao
249 .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class);
250 if (findPropertyDefRes.isRight()) {
251 JanusGraphOperationStatus status = findPropertyDefRes.right().value();
252 if (status == JanusGraphOperationStatus.NOT_FOUND) {
253 status = JanusGraphOperationStatus.INVALID_ID;
255 return Either.right(status);
257 String valueUniqueUid = groupInstanceProperty.getValueUniqueUid();
258 if (valueUniqueUid == null) {
259 PropertyData propertyData = findPropertyDefRes.left().value();
260 GroupInstanceData resourceInstanceData = findResInstanceRes.left().value();
261 ImmutablePair<JanusGraphOperationStatus, String> isPropertyValueExists = propertyOperation.findPropertyValue(groupInstanceId, propertyId);
262 if (isPropertyValueExists.getLeft() == JanusGraphOperationStatus.ALREADY_EXIST) {
263 log.debug("The property {} already added to the resource instance {}", propertyId, groupInstanceId);
264 groupInstanceProperty.setValueUniqueUid(isPropertyValueExists.getRight());
265 Either<PropertyValueData, JanusGraphOperationStatus> updatePropertyOfResourceInstance = updatePropertyOfGroupInstance(
266 groupInstanceProperty, groupInstanceId);
267 if (updatePropertyOfResourceInstance.isRight()) {
268 BeEcompErrorManager.getInstance().logInternalFlowError(UPDATE_PROPERTY_VALUE_ON_COMPONENT_INSTANCE,
269 FAILED_TO_UPDATE_PROPERTY_VALUE_ON_INSTANCE_STATUS_IS + updatePropertyOfResourceInstance.right().value(),
270 ErrorSeverity.ERROR);
271 return Either.right(updatePropertyOfResourceInstance.right().value());
273 return Either.left(updatePropertyOfResourceInstance.left().value());
275 if (isPropertyValueExists.getLeft() != JanusGraphOperationStatus.NOT_FOUND) {
276 log.debug("After finding property value of {} on componenet instance {}", propertyId, groupInstanceId);
277 return Either.right(isPropertyValueExists.getLeft());
279 String innerType = null;
280 PropertyDataDefinition propDataDef = propertyData.getPropertyDataDefinition();
281 String propertyType = propDataDef.getType();
282 String value = groupInstanceProperty.getValue();
283 ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
284 if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
285 SchemaDefinition def = propDataDef.getSchema();
287 log.debug("Schema doesn't exists for property of type {}", type);
288 return Either.right(JanusGraphOperationStatus.ILLEGAL_ARGUMENT);
290 PropertyDataDefinition propDef = def.getProperty();
291 if (propDef == null) {
292 log.debug("Property in Schema Definition inside property of type {} doesn't exist", type);
293 return Either.right(JanusGraphOperationStatus.ILLEGAL_ARGUMENT);
295 innerType = propDef.getType();
297 log.debug("Before validateAndUpdatePropertyValue");
298 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypes =
299 applicationDataTypeCache.getAll(groupInstanceProperty.getModel());
300 if (allDataTypes.isRight()) {
301 JanusGraphOperationStatus status = allDataTypes.right().value();
302 BeEcompErrorManager.getInstance()
303 .logInternalFlowError(UPDATE_PROPERTY_VALUE_ON_COMPONENT_INSTANCE, FAILED_TO_UPDATE_PROPERTY_VALUE_ON_INSTANCE_STATUS_IS + status,
304 ErrorSeverity.ERROR);
305 return Either.right(status);
307 Either<Object, Boolean> isValid = propertyOperation
308 .validateAndUpdatePropertyValue(propertyType, value, innerType, allDataTypes.left().value());
309 log.debug("After validateAndUpdatePropertyValue. isValid = {}", isValid);
310 String newValue = value;
311 if (isValid.isRight()) {
312 Boolean res = isValid.right().value();
314 return Either.right(JanusGraphOperationStatus.ILLEGAL_ARGUMENT);
317 Object object = isValid.left().value();
318 if (object != null) {
319 newValue = object.toString();
322 String uniqueId = UniqueIdBuilder.buildResourceInstancePropertyValueUid(resourceInstanceData.getUniqueId(), index);
323 PropertyValueData propertyValueData = new PropertyValueData();
324 propertyValueData.setUniqueId(uniqueId);
325 propertyValueData.setValue(newValue);
326 log.debug("Before validateAndUpdateRules");
327 ImmutablePair<String, Boolean> pair = propertyOperation
328 .validateAndUpdateRules(propertyType, groupInstanceProperty.getRules(), innerType, allDataTypes.left().value(), false);
329 log.debug("After validateAndUpdateRules. pair = {}", pair);
330 if (pair.getRight() != null && !pair.getRight()) {
331 BeEcompErrorManager.getInstance()
332 .logBeInvalidValueError("Add property value", pair.getLeft(), groupInstanceProperty.getName(), propertyType);
333 return Either.right(JanusGraphOperationStatus.ILLEGAL_ARGUMENT);
335 propertyOperation.addRulesToNewPropertyValue(propertyValueData, groupInstanceProperty, groupInstanceId);
336 log.debug("Before adding property value to graph {}", propertyValueData);
337 Either<PropertyValueData, JanusGraphOperationStatus> createNodeResult = janusGraphGenericDao
338 .createNode(propertyValueData, PropertyValueData.class);
339 log.debug("After adding property value to graph {}", propertyValueData);
340 if (createNodeResult.isRight()) {
341 JanusGraphOperationStatus operationStatus = createNodeResult.right().value();
342 return Either.right(operationStatus);
344 propertyValueData = createNodeResult.left().value();
345 Either<GraphRelation, JanusGraphOperationStatus> createRelResult = janusGraphGenericDao
346 .createRelation(propertyValueData, propertyData, GraphEdgeLabels.PROPERTY_IMPL, null);
347 if (createRelResult.isRight()) {
348 JanusGraphOperationStatus operationStatus = createRelResult.right().value();
349 log.error("Failed to associate property value {} to property {} in graph. status is {}", uniqueId, propertyId, operationStatus);
350 return Either.right(operationStatus);
352 createRelResult = janusGraphGenericDao.createRelation(resourceInstanceData, propertyValueData, GraphEdgeLabels.PROPERTY_VALUE, null);
353 if (createRelResult.isRight()) {
354 JanusGraphOperationStatus operationStatus = createRelResult.right().value();
355 log.error("Failed to associate resource instance {} property value {} in graph. status is {}", groupInstanceId, uniqueId,
357 return Either.right(operationStatus);
359 return Either.left(propertyValueData);
361 log.error("property value already exists.");
362 return Either.right(JanusGraphOperationStatus.ALREADY_EXIST);
367 * update value of attribute on resource instance
371 public Either<PropertyValueData, JanusGraphOperationStatus> updatePropertyOfGroupInstance(ComponentInstanceProperty groupInstanceProperty,
372 String groupInstanceId) {
373 Wrapper<JanusGraphOperationStatus> errorWrapper = new Wrapper<>();
374 UpdateDataContainer<PropertyData, PropertyValueData> updateDataContainer = new UpdateDataContainer<>(GraphEdgeLabels.PROPERTY_IMPL,
375 (() -> PropertyData.class), (() -> PropertyValueData.class), NodeTypeEnum.Property, NodeTypeEnum.PropertyValue);
376 preUpdateElementOfResourceInstanceValidations(updateDataContainer, groupInstanceProperty, groupInstanceId, errorWrapper);
377 if (!errorWrapper.isEmpty()) {
378 return Either.right(errorWrapper.getInnerElement());
381 String value = groupInstanceProperty.getValue();
382 // Specific Validation Logic
383 PropertyData propertyData = updateDataContainer.getDataWrapper().getInnerElement();
384 PropertyDataDefinition propDataDef = propertyData.getPropertyDataDefinition();
385 String propertyType = propDataDef.getType();
386 final ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
387 log.debug("The type of the property {} is {}", propertyData.getUniqueId(), propertyType);
388 final Either<String, JanusGraphOperationStatus> innerTypeEither = propertyOperation.getInnerType(type, propDataDef::getSchema);
389 if (innerTypeEither.isRight()) {
390 return Either.right(innerTypeEither.right().value());
392 // Specific Update Logic
393 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypes =
394 applicationDataTypeCache.getAll(groupInstanceProperty.getModel());
395 if (allDataTypes.isRight()) {
396 JanusGraphOperationStatus status = allDataTypes.right().value();
397 BeEcompErrorManager.getInstance()
398 .logInternalFlowError(UPDATE_PROPERTY_VALUE_ON_COMPONENT_INSTANCE, FAILED_TO_UPDATE_PROPERTY_VALUE_ON_INSTANCE_STATUS_IS + status,
399 ErrorSeverity.ERROR);
400 return Either.right(status);
402 PropertyValueData propertyValueData = updateDataContainer.getValueDataWrapper().getInnerElement();
403 if (propDataDef.isToscaFunction()) {
404 Either<GroupInstanceData, JanusGraphOperationStatus> findResInstanceRes = janusGraphGenericDao
405 .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.GroupInstance), groupInstanceId, GroupInstanceData.class);
406 final GroupInstanceData groupInstanceData = findResInstanceRes.left().value();
408 toscaFunctionValidator.validate(propDataDef, null);
409 propertyValueData.setValue(StringEscapeUtils.unescapeJava(propDataDef.getToscaFunction().getValue()));
411 final String innerType = innerTypeEither.left().value();
412 Either<Object, Boolean> isValid = propertyOperation
413 .validateAndUpdatePropertyValue(propertyType, value, innerType, allDataTypes.left().value());
414 String newValue = value;
415 if (isValid.isRight()) {
416 Boolean res = isValid.right().value();
418 return Either.right(JanusGraphOperationStatus.ILLEGAL_ARGUMENT);
421 Object object = isValid.left().value();
422 if (object != null) {
423 newValue = object.toString();
426 log.debug("Going to update property value from {} to {}", propertyValueData.getValue(), newValue);
427 propertyValueData.setValue(newValue);
428 ImmutablePair<String, Boolean> pair = propertyOperation
429 .validateAndUpdateRules(propertyType, groupInstanceProperty.getRules(), innerType, allDataTypes.left().value(), true);
430 if (pair.getRight() != null && !pair.getRight()) {
431 BeEcompErrorManager.getInstance()
432 .logBeInvalidValueError("Add property value", pair.getLeft(), groupInstanceProperty.getName(), propertyType);
433 return Either.right(JanusGraphOperationStatus.ILLEGAL_ARGUMENT);
437 propertyOperation.updateRulesInPropertyValue(propertyValueData, groupInstanceProperty, groupInstanceId);
438 Either<PropertyValueData, JanusGraphOperationStatus> updateRes = janusGraphGenericDao
439 .updateNode(propertyValueData, PropertyValueData.class);
440 if (updateRes.isRight()) {
441 JanusGraphOperationStatus status = updateRes.right().value();
442 return Either.right(status);
444 return Either.left(updateRes.left().value());
448 private <SomeData extends GraphNode, SomeValueData extends GraphNode> void preUpdateElementOfResourceInstanceValidations(
449 UpdateDataContainer<SomeData, SomeValueData> updateDataContainer, IComponentInstanceConnectedElement resourceInstanceProerty,
450 String resourceInstanceId, Wrapper<JanusGraphOperationStatus> errorWrapper) {
451 if (errorWrapper.isEmpty()) {
452 // Verify VFC instance Exist
453 validateGIExist(resourceInstanceId, errorWrapper);
455 if (errorWrapper.isEmpty()) {
456 // Example: Verify Property connected to VFC exist
457 validateElementConnectedToComponentExist(updateDataContainer, resourceInstanceProerty, errorWrapper);
459 if (errorWrapper.isEmpty()) {
460 // Example: Verify PropertyValue connected to VFC Instance exist
461 validateElementConnectedToComponentInstanceExist(updateDataContainer, resourceInstanceProerty, errorWrapper);
463 if (errorWrapper.isEmpty()) {
464 // Example: Verify PropertyValue connected Property
465 validateElementConnectedToInstance(updateDataContainer, resourceInstanceProerty, errorWrapper);
469 private <SomeData extends GraphNode, SomeValueData extends GraphNode> void validateElementConnectedToInstance(
470 UpdateDataContainer<SomeData, SomeValueData> updateDataContainer, IComponentInstanceConnectedElement resourceInstanceProerty,
471 Wrapper<JanusGraphOperationStatus> errorWrapper) {
472 Either<ImmutablePair<SomeData, GraphEdge>, JanusGraphOperationStatus> child = janusGraphGenericDao
473 .getChild(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeTypeValue()), resourceInstanceProerty.getValueUniqueUid(),
474 updateDataContainer.getGraphEdge(), updateDataContainer.getNodeType(), updateDataContainer.getSomeDataClassGen().get());
475 if (child.isRight()) {
476 JanusGraphOperationStatus status = child.right().value();
477 if (status == JanusGraphOperationStatus.NOT_FOUND) {
478 status = JanusGraphOperationStatus.INVALID_ID;
480 errorWrapper.setInnerElement(status);
482 updateDataContainer.getDataWrapper().setInnerElement(child.left().value().left);
486 private <SomeValueData extends GraphNode, SomeData extends GraphNode> void validateElementConnectedToComponentInstanceExist(
487 UpdateDataContainer<SomeData, SomeValueData> updateDataContainer, IComponentInstanceConnectedElement resourceInstanceProerty,
488 Wrapper<JanusGraphOperationStatus> errorWrapper) {
489 String valueUniqueUid = resourceInstanceProerty.getValueUniqueUid();
490 if (valueUniqueUid == null) {
491 errorWrapper.setInnerElement(JanusGraphOperationStatus.INVALID_ID);
493 Either<SomeValueData, JanusGraphOperationStatus> findPropertyValueRes = janusGraphGenericDao
494 .getNode(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeTypeValue()), valueUniqueUid,
495 updateDataContainer.getSomeValueDataClassGen().get());
496 if (findPropertyValueRes.isRight()) {
497 JanusGraphOperationStatus status = findPropertyValueRes.right().value();
498 if (status == JanusGraphOperationStatus.NOT_FOUND) {
499 status = JanusGraphOperationStatus.INVALID_ID;
501 errorWrapper.setInnerElement(status);
503 updateDataContainer.getValueDataWrapper().setInnerElement(findPropertyValueRes.left().value());
508 private <SomeData extends GraphNode, SomeValueData extends GraphNode> void validateElementConnectedToComponentExist(
509 UpdateDataContainer<SomeData, SomeValueData> updateDataContainer, IComponentInstanceConnectedElement resourceInstanceElementConnected,
510 Wrapper<JanusGraphOperationStatus> errorWrapper) {
511 String uniqueId = resourceInstanceElementConnected.getUniqueId();
512 Either<SomeData, JanusGraphOperationStatus> findPropertyDefRes = janusGraphGenericDao
513 .getNode(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeType()), uniqueId, updateDataContainer.getSomeDataClassGen().get());
514 if (findPropertyDefRes.isRight()) {
515 JanusGraphOperationStatus status = findPropertyDefRes.right().value();
516 errorWrapper.setInnerElement(status);
520 private void validateGIExist(String resourceInstanceId, Wrapper<JanusGraphOperationStatus> errorWrapper) {
521 validateGIExist(resourceInstanceId, null, errorWrapper);
524 private void validateGIExist(String resourceInstanceId, Wrapper<GroupInstanceData> compInsDataWrapper,
525 Wrapper<JanusGraphOperationStatus> errorWrapper) {
526 validateElementExistInGraph(resourceInstanceId, NodeTypeEnum.GroupInstance, () -> GroupInstanceData.class, compInsDataWrapper, errorWrapper);
529 public <ElementData extends GraphNode> void validateElementExistInGraph(String elementUniqueId, NodeTypeEnum elementNodeType,
530 Supplier<Class<ElementData>> elementClassGen,
531 Wrapper<ElementData> elementDataWrapper,
532 Wrapper<JanusGraphOperationStatus> errorWrapper) {
533 Either<ElementData, JanusGraphOperationStatus> findResInstanceRes = janusGraphGenericDao
534 .getNode(UniqueIdBuilder.getKeyByNodeType(elementNodeType), elementUniqueId, elementClassGen.get());
535 if (findResInstanceRes.isRight()) {
536 JanusGraphOperationStatus status = findResInstanceRes.right().value();
537 if (status == JanusGraphOperationStatus.NOT_FOUND) {
538 status = JanusGraphOperationStatus.INVALID_ID;
540 errorWrapper.setInnerElement(status);
542 if (elementDataWrapper != null) {
543 elementDataWrapper.setInnerElement(findResInstanceRes.left().value());
548 private void buildGroupInstanceFromGroup(GroupInstance groupInstance, GroupDefinition groupDefinition,
549 Map<String, PropertyValueData> groupInstancePropertyValues) {
550 groupInstance.setGroupName(groupDefinition.getName());
551 groupInstance.setInvariantUUID(groupDefinition.getInvariantUUID());
552 groupInstance.setDescription(groupDefinition.getDescription());
553 groupInstance.setVersion(groupDefinition.getVersion());
554 groupInstance.setArtifacts(groupDefinition.getArtifacts());
555 groupInstance.setArtifactsUuid(groupDefinition.getArtifactsUuid());
556 groupInstance.setType(groupDefinition.getType());
557 groupInstance.setGroupUUID(groupDefinition.getGroupUUID());
558 List<GroupInstanceProperty> groupInstanceProperties = groupDefinition.convertToGroupProperties()
559 //converts List of GroupProperties to List of GroupInstanceProperties and updates it with group instance property data
560 .stream().map(p -> getUpdatedConvertedProperty(p, groupInstancePropertyValues)).collect(Collectors.toList());
561 groupInstance.convertFromGroupInstancesProperties(groupInstanceProperties);
564 private GroupInstanceProperty getUpdatedConvertedProperty(GroupProperty groupProperty,
565 Map<String, PropertyValueData> groupInstancePropertyValues) {
566 GroupInstanceProperty updatedProperty = new GroupInstanceProperty(groupProperty, groupProperty.getValue());
567 if (!MapUtils.isEmpty(groupInstancePropertyValues) && groupInstancePropertyValues.containsKey(groupProperty.getName())) {
568 PropertyValueData groupInstancePropertyValue = groupInstancePropertyValues.get(groupProperty.getName());
569 updatedProperty.setValue(groupInstancePropertyValue.getValue());
570 updatedProperty.setValueUniqueUid(groupInstancePropertyValue.getUniqueId());
572 return updatedProperty;
575 private Either<List<ImmutablePair<String, String>>, JanusGraphOperationStatus> getGroupArtifactsPairs(String groupUniqueId) {
576 Either<List<ImmutablePair<String, String>>, JanusGraphOperationStatus> result = null;
577 Either<List<ImmutablePair<ArtifactData, GraphEdge>>, JanusGraphOperationStatus> childrenNodes = janusGraphGenericDao
578 .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.GroupInstance), groupUniqueId, GraphEdgeLabels.GROUP_ARTIFACT_REF,
579 NodeTypeEnum.ArtifactRef, ArtifactData.class);
580 if (childrenNodes.isRight()) {
581 JanusGraphOperationStatus status = childrenNodes.right().value();
582 if (status == JanusGraphOperationStatus.NOT_FOUND) {
583 status = JanusGraphOperationStatus.OK;
585 result = Either.right(status);
587 List<ImmutablePair<String, String>> artifactsList = new ArrayList<>();
588 List<ImmutablePair<ArtifactData, GraphEdge>> list = childrenNodes.left().value();
590 for (ImmutablePair<ArtifactData, GraphEdge> pair : list) {
591 ArtifactData artifactData = pair.getKey();
592 String uniqueId = artifactData.getArtifactDataDefinition().getUniqueId();
593 String UUID = artifactData.getArtifactDataDefinition().getArtifactUUID();
594 ImmutablePair<String, String> artifact = new ImmutablePair<>(uniqueId, UUID);
595 artifactsList.add(artifact);
598 log.debug("The artifacts list related to group {} is {}", groupUniqueId, artifactsList);
599 result = Either.left(artifactsList);
604 public StorageOperationStatus dissociateAndAssociateGroupsInstanceFromArtifact(String componentId, NodeTypeEnum componentTypeEnum,
605 String oldArtifactId, ArtifactData newArtifact) {
606 return this.dissociateAndAssociateGroupsInstanceFromArtifactOnGraph(componentId, componentTypeEnum, oldArtifactId, newArtifact);
609 private StorageOperationStatus dissociateAndAssociateGroupsInstanceFromArtifactOnGraph(String componentId, NodeTypeEnum componentTypeEnum,
610 String oldArtifactId, ArtifactData newArtifact) {
611 Either<List<GroupInstance>, StorageOperationStatus> allGroupsFromGraph = getAllGroupInstances(componentId, componentTypeEnum);
612 if (allGroupsFromGraph.isRight()) {
613 return allGroupsFromGraph.right().value();
615 List<GroupInstance> allGroups = allGroupsFromGraph.left().value();
616 if (allGroups == null || allGroups.isEmpty()) {
617 return StorageOperationStatus.OK;
619 // Find all groups which contains this artifact id
620 List<GroupInstance> associatedGroups = allGroups.stream()
621 .filter(p -> p.getGroupInstanceArtifacts() != null && p.getGroupInstanceArtifacts().contains(oldArtifactId)).collect(Collectors.toList());
622 if (associatedGroups != null && !associatedGroups.isEmpty()) {
623 log.debug("The groups {} contains the artifact {}",
624 associatedGroups.stream().map(GroupInstanceDataDefinition::getName).collect(Collectors.toList()), oldArtifactId);
625 UniqueIdData oldArtifactData = new UniqueIdData(NodeTypeEnum.ArtifactRef, oldArtifactId);
626 UniqueIdData newArtifactData = new UniqueIdData(NodeTypeEnum.ArtifactRef, newArtifact.getArtifactDataDefinition().getUniqueId());
627 Map<String, Object> props = new HashMap<>();
628 props.put(GraphPropertiesDictionary.NAME.getProperty(), newArtifactData.getLabel());
629 for (GroupInstance groupDefinition : associatedGroups) {
630 UniqueIdData groupData = new UniqueIdData(NodeTypeEnum.GroupInstance, groupDefinition.getUniqueId());
631 Either<GraphRelation, JanusGraphOperationStatus> deleteRelation = janusGraphGenericDao
632 .deleteRelation(groupData, oldArtifactData, GraphEdgeLabels.GROUP_ARTIFACT_REF);
633 log.trace("After dissociate group {} from artifact {}", groupDefinition.getName(), oldArtifactId);
634 if (deleteRelation.isRight()) {
635 JanusGraphOperationStatus status = deleteRelation.right().value();
636 if (status == JanusGraphOperationStatus.NOT_FOUND) {
637 status = JanusGraphOperationStatus.INVALID_ID;
639 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
641 Either<GraphRelation, JanusGraphOperationStatus> createRelation = janusGraphGenericDao
642 .createRelation(groupData, newArtifactData, GraphEdgeLabels.GROUP_ARTIFACT_REF, props);
643 log.trace("After associate group {} to artifact {}", groupDefinition.getName(), newArtifact.getUniqueIdKey());
644 if (createRelation.isRight()) {
645 JanusGraphOperationStatus status = createRelation.right().value();
646 if (status == JanusGraphOperationStatus.NOT_FOUND) {
647 status = JanusGraphOperationStatus.INVALID_ID;
649 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
653 return StorageOperationStatus.OK;
656 private Either<Map<String, PropertyValueData>, JanusGraphOperationStatus> getAllGroupInstancePropertyValuesData(GroupInstanceData groupInstData) {
657 Either<Map<String, PropertyValueData>, JanusGraphOperationStatus> result = null;
659 Either<List<ImmutablePair<PropertyValueData, GraphEdge>>, JanusGraphOperationStatus> getPropertyValueChildrenRes = janusGraphGenericDao
660 .getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), groupInstData.getUniqueId(), GraphEdgeLabels.PROPERTY_VALUE,
661 NodeTypeEnum.PropertyValue, PropertyValueData.class, true);
662 if (getPropertyValueChildrenRes.isRight()) {
663 JanusGraphOperationStatus status = getPropertyValueChildrenRes.right().value();
664 log.debug("Failed to fetch property value nodes for group instance {}. Status is {}. ", groupInstData.getName(), status);
665 if (status == JanusGraphOperationStatus.NOT_FOUND) {
666 result = Either.left(null);
668 result = Either.right(status);
671 result = Either.left(getPropertyValueChildrenRes.left().value().stream().collect(Collectors
672 .toMap(pair -> (String) (pair.getRight().getProperties().get(GraphPropertiesDictionary.PROPERTY_NAME.getProperty())),
673 ImmutablePair::getLeft)));
675 } catch (Exception e) {
676 log.debug("The Exception occured during fetch group instance () property values. The message is {}. ", groupInstData.getName(),
678 if (result == null) {
679 result = Either.right(JanusGraphOperationStatus.GENERAL_ERROR);
685 private static final class UpdateDataContainer<SomeData, SomeValueData> {
687 final Wrapper<SomeValueData> valueDataWrapper;
688 final Wrapper<SomeData> dataWrapper;
689 final GraphEdgeLabels graphEdge;
690 final Supplier<Class<SomeData>> someDataClassGen;
691 final Supplier<Class<SomeValueData>> someValueDataClassGen;
692 final NodeTypeEnum nodeType;
693 final NodeTypeEnum nodeTypeValue;
695 private UpdateDataContainer(GraphEdgeLabels graphEdge, Supplier<Class<SomeData>> someDataClassGen,
696 Supplier<Class<SomeValueData>> someValueDataClassGen, NodeTypeEnum nodeType, NodeTypeEnum nodeTypeValue) {
698 this.valueDataWrapper = new Wrapper<>();
699 this.dataWrapper = new Wrapper<>();
700 this.graphEdge = graphEdge;
701 this.someDataClassGen = someDataClassGen;
702 this.someValueDataClassGen = someValueDataClassGen;
703 this.nodeType = nodeType;
704 this.nodeTypeValue = nodeTypeValue;
707 public Wrapper<SomeValueData> getValueDataWrapper() {
708 return valueDataWrapper;
711 public Wrapper<SomeData> getDataWrapper() {
715 public GraphEdgeLabels getGraphEdge() {
719 public Supplier<Class<SomeData>> getSomeDataClassGen() {
720 return someDataClassGen;
723 public Supplier<Class<SomeValueData>> getSomeValueDataClassGen() {
724 return someValueDataClassGen;
727 public NodeTypeEnum getNodeType() {
731 public NodeTypeEnum getNodeTypeValue() {
732 return nodeTypeValue;