0ed0a7b79d72874670edbe6c31d184e4b6c09efa
[sdc.git] / catalog-model / src / main / java / org / openecomp / sdc / be / model / jsonjanusgraph / operations / ToscaOperationFacade.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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=========================================================
19  */
20 package org.openecomp.sdc.be.model.jsonjanusgraph.operations;
21
22 import com.vdurmont.semver4j.Semver;
23 import com.vdurmont.semver4j.Semver.SemverType;
24 import fj.data.Either;
25 import org.apache.commons.collections.CollectionUtils;
26 import org.apache.commons.collections.MapUtils;
27 import org.apache.commons.lang3.StringUtils;
28 import org.apache.commons.lang3.tuple.ImmutablePair;
29 import org.apache.tinkerpop.gremlin.structure.Direction;
30 import org.apache.tinkerpop.gremlin.structure.Edge;
31 import org.janusgraph.graphdb.query.JanusGraphPredicate;
32 import org.openecomp.sdc.be.config.Configuration;
33 import org.openecomp.sdc.be.config.ConfigurationManager;
34 import org.openecomp.sdc.be.dao.api.exception.JanusGraphException;
35 import org.openecomp.sdc.be.dao.janusgraph.HealingJanusGraphDao;
36 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
37 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
38 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
39 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
40 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
41 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
42 import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition;
43 import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
44 import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
45 import org.openecomp.sdc.be.datatypes.elements.DataTypeDataDefinition;
46 import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
47 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
48 import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition;
49 import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition;
50 import org.openecomp.sdc.be.datatypes.elements.MapArtifactDataDefinition;
51 import org.openecomp.sdc.be.datatypes.elements.MapAttributesDataDefinition;
52 import org.openecomp.sdc.be.datatypes.elements.MapCapabilityProperty;
53 import org.openecomp.sdc.be.datatypes.elements.MapInterfaceDataDefinition;
54 import org.openecomp.sdc.be.datatypes.elements.MapListCapabilityDataDefinition;
55 import org.openecomp.sdc.be.datatypes.elements.MapListRequirementDataDefinition;
56 import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
57 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
58 import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition;
59 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
60 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
61 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
62 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
63 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
64 import org.openecomp.sdc.be.datatypes.enums.PromoteVersionEnum;
65 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
66 import org.openecomp.sdc.be.model.ArtifactDefinition;
67 import org.openecomp.sdc.be.model.AttributeDefinition;
68 import org.openecomp.sdc.be.model.CapabilityDefinition;
69 import org.openecomp.sdc.be.model.CatalogUpdateTimestamp;
70 import org.openecomp.sdc.be.model.Component;
71 import org.openecomp.sdc.be.model.ComponentInstance;
72 import org.openecomp.sdc.be.model.ComponentInstanceAttribute;
73 import org.openecomp.sdc.be.model.ComponentInstanceInput;
74 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
75 import org.openecomp.sdc.be.model.ComponentInstanceOutput;
76 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
77 import org.openecomp.sdc.be.model.ComponentParametersView;
78 import org.openecomp.sdc.be.model.DataTypeDefinition;
79 import org.openecomp.sdc.be.model.DistributionStatusEnum;
80 import org.openecomp.sdc.be.model.GroupDefinition;
81 import org.openecomp.sdc.be.model.GroupInstance;
82 import org.openecomp.sdc.be.model.InputDefinition;
83 import org.openecomp.sdc.be.model.InterfaceDefinition;
84 import org.openecomp.sdc.be.model.LifecycleStateEnum;
85 import org.openecomp.sdc.be.model.OutputDefinition;
86 import org.openecomp.sdc.be.model.PolicyDefinition;
87 import org.openecomp.sdc.be.model.PropertyDefinition;
88 import org.openecomp.sdc.be.model.RelationshipInfo;
89 import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
90 import org.openecomp.sdc.be.model.RequirementDefinition;
91 import org.openecomp.sdc.be.model.Resource;
92 import org.openecomp.sdc.be.model.Service;
93 import org.openecomp.sdc.be.model.User;
94 import org.openecomp.sdc.be.model.catalog.CatalogComponent;
95 import org.openecomp.sdc.be.model.jsonjanusgraph.config.ContainerInstanceTypesData;
96 import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.TopologyTemplate;
97 import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.ToscaElement;
98 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.exception.ToscaOperationExceptionSupplier;
99 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
100 import org.openecomp.sdc.be.model.operations.StorageException;
101 import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation;
102 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
103 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
104 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
105 import org.openecomp.sdc.be.model.utils.GroupUtils;
106 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
107 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
108 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
109 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
110 import org.openecomp.sdc.common.log.wrappers.Logger;
111 import org.openecomp.sdc.common.util.ValidationUtils;
112 import org.springframework.beans.factory.annotation.Autowired;
113
114 import java.util.ArrayList;
115 import java.util.Arrays;
116 import java.util.Collection;
117 import java.util.Collections;
118 import java.util.Comparator;
119 import java.util.EnumMap;
120 import java.util.HashMap;
121 import java.util.HashSet;
122 import java.util.Iterator;
123 import java.util.LinkedList;
124 import java.util.List;
125 import java.util.Map;
126 import java.util.Map.Entry;
127 import java.util.Objects;
128 import java.util.Optional;
129 import java.util.Set;
130 import java.util.TreeSet;
131 import java.util.function.BiPredicate;
132 import java.util.stream.Collectors;
133
134 import static java.util.Objects.requireNonNull;
135 import static org.apache.commons.collections.CollectionUtils.isEmpty;
136 import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
137 import static org.janusgraph.core.attribute.Text.REGEX;
138 import static org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum.TOPOLOGY_TEMPLATE;
139
140 @org.springframework.stereotype.Component("tosca-operation-facade")
141 public class ToscaOperationFacade {
142
143     // region - ToscaElement - GetById
144     public static final String PROXY_SUFFIX = "_proxy";
145     // region - Fields
146     private static final String COULDNT_FETCH_A_COMPONENT_WITH_AND_UNIQUE_ID_ERROR = "Couldn't fetch a component with and UniqueId {}, error: {}";
147     private static final String FAILED_TO_FIND_RECENTLY_ADDED_PROPERTY_ON_THE_RESOURCE_STATUS_IS = "Failed to find recently added property {} on the resource {}. Status is {}. ";
148     private static final String FAILED_TO_GET_UPDATED_RESOURCE_STATUS_IS = "Failed to get updated resource {}. Status is {}. ";
149     private static final String FAILED_TO_ADD_THE_PROPERTY_TO_THE_RESOURCE_STATUS_IS = "Failed to add the property {} to the resource {}. Status is {}. ";
150     private static final String SERVICE = "service";
151     private static final String VF = "VF";
152     private static final String NOT_SUPPORTED_COMPONENT_TYPE = "Not supported component type {}";
153     private static final String COMPONENT_CREATED_SUCCESSFULLY = "Component created successfully!!!";
154     private static final String INPUTS_ASSOCIATED_TO_COMPONENT_SUCCESSFULLY = "Inputs associated to component successfully!";
155     private static final String OUTPUTS_ASSOCIATED_TO_COMPONENT_SUCCESSFULLY = "Outputs associated to component successfully!";
156     private static final String COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR = "Couldn't fetch component with and unique id {}, error: {}";
157     private static final Logger log = Logger.getLogger(ToscaOperationFacade.class.getName());
158     @Autowired
159     private IGraphLockOperation graphLockOperation;
160     @Autowired
161     private NodeTypeOperation nodeTypeOperation;
162     @Autowired
163     private TopologyTemplateOperation topologyTemplateOperation;
164     @Autowired
165     private NodeTemplateOperation nodeTemplateOperation;
166     @Autowired
167     private GroupsOperation groupsOperation;
168     @Autowired
169     private HealingJanusGraphDao janusGraphDao;
170     // endregion
171     @Autowired
172     private ContainerInstanceTypesData containerInstanceTypesData;
173
174     private static Optional<CapabilityDefinition> getPropertyCapability(String propertyParentUniqueId, Component containerComponent) {
175         Map<String, List<CapabilityDefinition>> componentCapabilities = containerComponent.getCapabilities();
176         if (MapUtils.isEmpty(componentCapabilities)) {
177             return Optional.empty();
178         }
179         List<CapabilityDefinition> capabilityDefinitionList = componentCapabilities.values().stream().flatMap(Collection::stream)
180             .collect(Collectors.toList());
181         if (CollectionUtils.isEmpty(capabilityDefinitionList)) {
182             return Optional.empty();
183         }
184         return capabilityDefinitionList.stream().filter(capabilityDefinition -> capabilityDefinition.getUniqueId().equals(propertyParentUniqueId))
185             .findAny();
186     }
187
188     public <T extends Component> Either<T, StorageOperationStatus> getToscaFullElement(String componentId) {
189         ComponentParametersView filters = new ComponentParametersView();
190         filters.setIgnoreCapabiltyProperties(false);
191         filters.setIgnoreServicePath(false);
192         return getToscaElement(componentId, filters);
193     }
194
195     public <T extends Component> Either<T, StorageOperationStatus> getToscaElement(String componentId) {
196         return getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
197     }
198
199     public <T extends Component> Either<T, StorageOperationStatus> getToscaElement(String componentId, ComponentParametersView filters) {
200         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao.getVertexById(componentId, filters.detectParseFlag());
201         if (getVertexEither.isRight()) {
202             log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
203             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value()));
204         }
205         return getToscaElementByOperation(getVertexEither.left().value(), filters);
206     }
207
208     public <T extends Component> Either<T, StorageOperationStatus> getToscaElement(String componentId, JsonParseFlagEnum parseFlag) {
209         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao.getVertexById(componentId, parseFlag);
210         if (getVertexEither.isRight()) {
211             log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
212             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value()));
213         }
214         return getToscaElementByOperation(getVertexEither.left().value());
215     }
216
217     public <T extends Component> Either<T, StorageOperationStatus> getToscaElement(GraphVertex componentVertex) {
218         return getToscaElementByOperation(componentVertex);
219     }
220
221     public Either<Boolean, StorageOperationStatus> validateComponentExists(String componentId) {
222         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
223         if (getVertexEither.isRight()) {
224             JanusGraphOperationStatus status = getVertexEither.right().value();
225             if (status == JanusGraphOperationStatus.NOT_FOUND) {
226                 return Either.left(false);
227             } else {
228                 log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
229                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value()));
230             }
231         }
232         return Either.left(true);
233     }
234     // endregion
235
236     public <T extends Component> Either<T, StorageOperationStatus> findLastCertifiedToscaElementByUUID(T component) {
237         Map<GraphPropertyEnum, Object> props = new EnumMap<>(GraphPropertyEnum.class);
238         props.put(GraphPropertyEnum.UUID, component.getUUID());
239         props.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
240         props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
241         Either<List<GraphVertex>, JanusGraphOperationStatus> getVertexEither = janusGraphDao
242             .getByCriteria(ModelConverter.getVertexType(component), props);
243         if (getVertexEither.isRight()) {
244             log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, component.getUniqueId(), getVertexEither.right().value());
245             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value()));
246         }
247         return getToscaElementByOperation(getVertexEither.left().value().get(0));
248     }
249
250     // region - ToscaElement - GetByOperation
251     private <T extends Component> Either<T, StorageOperationStatus> getToscaElementByOperation(GraphVertex componentV) {
252         return getToscaElementByOperation(componentV, new ComponentParametersView());
253     }
254
255     private <T extends Component> Either<T, StorageOperationStatus> getToscaElementByOperation(GraphVertex componentV,
256                                                                                                ComponentParametersView filters) {
257         if (componentV == null) {
258             log.debug("Unexpected null value for `componentV`");
259             return Either.right(StorageOperationStatus.GENERAL_ERROR);
260         } else {
261             VertexTypeEnum label = componentV.getLabel();
262             ToscaElementOperation toscaOperation = getToscaElementOperation(componentV);
263             if (toscaOperation != null) {
264                 log.debug("getToscaElementByOperation: toscaOperation={}", toscaOperation.getClass());
265             }
266             Either<ToscaElement, StorageOperationStatus> toscaElement;
267             String componentId = componentV.getUniqueId();
268             if (toscaOperation != null) {
269                 log.debug("Need to fetch tosca element for id {}", componentId);
270                 toscaElement = toscaOperation.getToscaElement(componentV, filters);
271             } else {
272                 log.debug("not supported tosca type {} for id {}", label, componentId);
273                 toscaElement = Either.right(StorageOperationStatus.BAD_REQUEST);
274             }
275             return toscaElement.left().map(ModelConverter::convertFromToscaElement);
276         }
277     }
278
279     // endregion
280     private ToscaElementOperation getToscaElementOperation(GraphVertex componentV) {
281         VertexTypeEnum label = componentV.getLabel();
282         switch (label) {
283             case NODE_TYPE:
284                 return nodeTypeOperation;
285             case TOPOLOGY_TEMPLATE:
286                 return topologyTemplateOperation;
287             default:
288                 return null;
289         }
290     }
291
292     public <T extends Component> Either<T, StorageOperationStatus> createToscaComponent(T resource) {
293         ToscaElement toscaElement = ModelConverter.convertToToscaElement(resource);
294         ToscaElementOperation toscaElementOperation = getToscaElementOperation(resource);
295         Either<ToscaElement, StorageOperationStatus> createToscaElement = toscaElementOperation.createToscaElement(toscaElement);
296         if (createToscaElement.isLeft()) {
297             log.debug(COMPONENT_CREATED_SUCCESSFULLY);
298             T dataModel = ModelConverter.convertFromToscaElement(createToscaElement.left().value());
299             return Either.left(dataModel);
300         }
301         return Either.right(createToscaElement.right().value());
302     }
303
304     // region - ToscaElement Delete
305     public StorageOperationStatus markComponentToDelete(Component componentToDelete) {
306         if (Boolean.TRUE.equals(componentToDelete.getIsDeleted()) && Boolean.FALSE.equals(componentToDelete.isHighestVersion())) {
307             // component already marked for delete
308             return StorageOperationStatus.OK;
309         } else {
310             Either<GraphVertex, JanusGraphOperationStatus> getResponse = janusGraphDao
311                 .getVertexById(componentToDelete.getUniqueId(), JsonParseFlagEnum.ParseAll);
312             if (getResponse.isRight()) {
313                 log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentToDelete.getUniqueId(), getResponse.right().value());
314                 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getResponse.right().value());
315             }
316             GraphVertex componentV = getResponse.left().value();
317             // same operation for node type and topology template operations
318             Either<GraphVertex, StorageOperationStatus> result = nodeTypeOperation.markComponentToDelete(componentV);
319             if (result.isRight()) {
320                 return result.right().value();
321             }
322             return StorageOperationStatus.OK;
323         }
324     }
325
326     public <T extends Component> Either<T, StorageOperationStatus> deleteToscaComponent(String componentId) {
327         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
328         if (getVertexEither.isRight()) {
329             log.debug("Couldn't fetch component vertex with and unique id {}, error: {}", componentId, getVertexEither.right().value());
330             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value()));
331         }
332         Either<ToscaElement, StorageOperationStatus> deleteElement = deleteToscaElement(getVertexEither.left().value());
333         if (deleteElement.isRight()) {
334             log.debug("Failed to delete component with and unique id {}, error: {}", componentId, deleteElement.right().value());
335             return Either.right(deleteElement.right().value());
336         }
337         T dataModel = ModelConverter.convertFromToscaElement(deleteElement.left().value());
338         return Either.left(dataModel);
339     }
340
341     private Either<ToscaElement, StorageOperationStatus> deleteToscaElement(GraphVertex componentV) {
342         VertexTypeEnum label = componentV.getLabel();
343         Either<ToscaElement, StorageOperationStatus> toscaElement;
344         Object componentId = componentV.getUniqueId();
345         switch (label) {
346             case NODE_TYPE:
347                 log.debug("Need to fetch node type for id {}", componentId);
348                 toscaElement = nodeTypeOperation.deleteToscaElement(componentV);
349                 break;
350             case TOPOLOGY_TEMPLATE:
351                 log.debug("Need to fetch topology template for id {}", componentId);
352                 toscaElement = topologyTemplateOperation.deleteToscaElement(componentV);
353                 break;
354             default:
355                 log.debug("not supported tosca type {} for id {}", label, componentId);
356                 toscaElement = Either.right(StorageOperationStatus.BAD_REQUEST);
357                 break;
358         }
359         return toscaElement;
360     }
361
362     // endregion
363     private ToscaElementOperation getToscaElementOperation(Component component) {
364         return ModelConverter.isAtomicComponent(component) ? nodeTypeOperation : topologyTemplateOperation;
365     }
366
367     public <T extends Component> Either<T, StorageOperationStatus> getLatestByToscaResourceNameAndModel(final String toscaResourceName,
368                                                                                                         final String model) {
369         return getLatestByNameAndModel(toscaResourceName, JsonParseFlagEnum.ParseMetadata, new ComponentParametersView(), model);
370     }
371
372     private <T extends Component> Either<T, StorageOperationStatus> getLatestByNameAndModel(final String nodeName,
373                                                                                             final JsonParseFlagEnum parseFlag,
374                                                                                             final ComponentParametersView filter,
375                                                                                             final String model) {
376         Either<T, StorageOperationStatus> result;
377         final Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
378         final Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
379         propertiesToMatch.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, nodeName);
380         propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
381         propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
382         final Either<List<GraphVertex>, JanusGraphOperationStatus> highestResources = janusGraphDao
383             .getByCriteria(null, propertiesToMatch, propertiesNotToMatch, parseFlag, model);
384         if (highestResources.isRight()) {
385             final JanusGraphOperationStatus status = highestResources.right().value();
386             log.debug("failed to find resource with name {}. status={} ", nodeName, status);
387             result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
388             return result;
389         }
390         final List<GraphVertex> resources = highestResources.left().value();
391         double version = 0.0;
392         GraphVertex highestResource = null;
393         for (final GraphVertex vertex : resources) {
394             final Object versionObj = vertex.getMetadataProperty(GraphPropertyEnum.VERSION);
395             double resourceVersion = Double.parseDouble((String) versionObj);
396             if (resourceVersion > version) {
397                 version = resourceVersion;
398                 highestResource = vertex;
399             }
400         }
401         return getToscaElementByOperation(highestResource, filter);
402     }
403
404     public <T extends Component> Either<T, StorageOperationStatus> getLatestByToscaResourceName(String toscaResourceName, String modelName) {
405         return getLatestByName(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaResourceName, modelName);
406     }
407
408     public <T extends Component> Either<T, StorageOperationStatus> getFullLatestComponentByToscaResourceName(String toscaResourceName) {
409         ComponentParametersView fetchAllFilter = new ComponentParametersView();
410         fetchAllFilter.setIgnoreServicePath(true);
411         fetchAllFilter.setIgnoreCapabiltyProperties(false);
412         return getLatestByName(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaResourceName, JsonParseFlagEnum.ParseAll, fetchAllFilter, null);
413     }
414
415     public <T extends Component> Either<T, StorageOperationStatus> getLatestByName(String resourceName, String modelName) {
416         return getLatestByName(GraphPropertyEnum.NAME, resourceName, modelName);
417     }
418
419     public StorageOperationStatus validateCsarUuidUniqueness(String csarUUID) {
420         Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
421         properties.put(GraphPropertyEnum.CSAR_UUID, csarUUID);
422         Either<List<GraphVertex>, JanusGraphOperationStatus> resources = janusGraphDao
423             .getByCriteria(null, properties, JsonParseFlagEnum.ParseMetadata);
424         if (resources.isRight()) {
425             if (resources.right().value() == JanusGraphOperationStatus.NOT_FOUND) {
426                 return StorageOperationStatus.OK;
427             } else {
428                 log.debug("failed to get resources from graph with property name: {}", csarUUID);
429                 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(resources.right().value());
430             }
431         }
432         return StorageOperationStatus.ENTITY_ALREADY_EXISTS;
433     }
434
435     public <T extends Component> Either<Set<T>, StorageOperationStatus> getFollowed(String userId, Set<LifecycleStateEnum> lifecycleStates,
436                                                                                     Set<LifecycleStateEnum> lastStateStates,
437                                                                                     ComponentTypeEnum componentType) {
438         Either<List<ToscaElement>, StorageOperationStatus> followedResources;
439         if (componentType == ComponentTypeEnum.RESOURCE) {
440             followedResources = nodeTypeOperation.getFollowedComponent(userId, lifecycleStates, lastStateStates, componentType);
441         } else {
442             followedResources = topologyTemplateOperation.getFollowedComponent(userId, lifecycleStates, lastStateStates, componentType);
443         }
444         Set<T> components = new HashSet<>();
445         if (followedResources.isRight() && followedResources.right().value() != StorageOperationStatus.NOT_FOUND) {
446             return Either.right(followedResources.right().value());
447         }
448         if (followedResources.isLeft()) {
449             List<ToscaElement> toscaElements = followedResources.left().value();
450             toscaElements.forEach(te -> {
451                 T component = ModelConverter.convertFromToscaElement(te);
452                 components.add(component);
453             });
454         }
455         return Either.left(components);
456     }
457
458     public Either<Resource, StorageOperationStatus> getLatestCertifiedNodeTypeByToscaResourceName(String toscaResourceName) {
459         return getLatestCertifiedByToscaResourceName(toscaResourceName, VertexTypeEnum.NODE_TYPE, JsonParseFlagEnum.ParseMetadata);
460     }
461
462     public Either<Resource, StorageOperationStatus> getByToscaResourceNameMatchingVendorRelease(final String toscaResourceName,
463                                                                                                 final String vendorVersion) {
464         return getByToscaResourceNameMatchingVendorRelease(toscaResourceName, VertexTypeEnum.NODE_TYPE, JsonParseFlagEnum.ParseMetadata,
465             vendorVersion);
466     }
467
468     public Either<Resource, StorageOperationStatus> getByToscaResourceNameMatchingVendorRelease(String toscaResourceName, VertexTypeEnum vertexType,
469                                                                                                 JsonParseFlagEnum parseFlag, String vendorRelease) {
470         Map<GraphPropertyEnum, Object> props = new EnumMap<>(GraphPropertyEnum.class);
471         props.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaResourceName);
472         props.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
473         Map<String, Entry<JanusGraphPredicate, Object>> predicateCriteria = getVendorVersionPredicate(vendorRelease);
474         Either<List<GraphVertex>, JanusGraphOperationStatus> getLatestRes = janusGraphDao
475             .getByCriteria(vertexType, props, null, predicateCriteria, parseFlag, null);
476         if (getLatestRes.isRight() || CollectionUtils.isEmpty(getLatestRes.left().value())) {
477             getLatestRes = janusGraphDao.getByCriteria(vertexType, props, parseFlag);
478         }
479         return getLatestRes.right().map(status -> {
480             CommonUtility
481                 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch {} with name {}. status={} ", vertexType, toscaResourceName, status);
482             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
483         }).left().bind(resources -> {
484             double version = 0.0;
485             GraphVertex highestResource = null;
486             for (GraphVertex resource : resources) {
487                 double resourceVersion = Double.parseDouble((String) resource.getJsonMetadataField(JsonPresentationFields.VERSION));
488                 if (resourceVersion > version && isValidForVendorRelease(resource, vendorRelease)) {
489                     version = resourceVersion;
490                     highestResource = resource;
491                 }
492             }
493             if (highestResource != null) {
494                 return getToscaFullElement(highestResource.getUniqueId());
495             } else {
496                 log.debug("The vertex with the highest version could not be found for {}", toscaResourceName);
497                 return Either.right(StorageOperationStatus.GENERAL_ERROR);
498             }
499         });
500     }
501
502     public <T extends Component> Either<T, StorageOperationStatus> getByToscaResourceNameAndVersion(final String toscaResourceName,
503                                                                                                     final String version, final String model) {
504         Either<T, StorageOperationStatus> result;
505
506         Map<GraphPropertyEnum, Object> hasProperties = new EnumMap<>(GraphPropertyEnum.class);
507         Map<GraphPropertyEnum, Object> hasNotProperties = new EnumMap<>(GraphPropertyEnum.class);
508
509         hasProperties.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaResourceName);
510         hasProperties.put(GraphPropertyEnum.VERSION, version);
511         hasNotProperties.put(GraphPropertyEnum.IS_DELETED, true);
512
513         Either<List<GraphVertex>, JanusGraphOperationStatus> getResourceRes = janusGraphDao
514             .getByCriteria(VertexTypeEnum.NODE_TYPE, hasProperties, hasNotProperties, JsonParseFlagEnum.ParseAll, model);
515         if (getResourceRes.isRight()) {
516             JanusGraphOperationStatus status = getResourceRes.right().value();
517             log.debug("failed to find resource with toscaResourceName {}, version {}. Status is {} ", toscaResourceName, version, status);
518             result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
519             return result;
520         }
521         return getToscaElementByOperation(getResourceRes.left().value().get(0));
522     }
523
524     private Map<String, Entry<JanusGraphPredicate, Object>> getVendorVersionPredicate(final String vendorRelease) {
525         Map<String, Entry<JanusGraphPredicate, Object>> predicateCriteria = new HashMap<>();
526         if (!"1.0".equals(vendorRelease)) {
527             String[] vendorReleaseElements = vendorRelease.split("\\.");
528             if (vendorReleaseElements.length > 0) {
529                 String regex = ".*\"vendorRelease\":\"";
530                 for (int i = 0; i < vendorReleaseElements.length; i++) {
531                     regex += vendorReleaseElements[i];
532                     regex += i < vendorReleaseElements.length - 1 ? "\\." : "\".*";
533                 }
534                 predicateCriteria.put("metadata", new HashMap.SimpleEntry<>(REGEX, regex));
535             }
536         }
537         return predicateCriteria;
538     }
539
540     public boolean isNodeAssociatedToModel(final String model, final Resource resource) {
541         final List<GraphVertex> modelElementVertices = getResourceModelElementVertices(resource);
542         if (model == null) {
543             return modelElementVertices.isEmpty();
544         }
545         return modelElementVertices.stream().anyMatch(graphVertex -> graphVertex.getMetadataProperty(GraphPropertyEnum.NAME).equals(model));
546     }
547
548     public List<GraphVertex> getResourceModelElementVertices(final Resource resource) {
549         final Either<GraphVertex, JanusGraphOperationStatus> vertex =
550             janusGraphDao.getVertexById(resource.getUniqueId(), JsonParseFlagEnum.NoParse);
551         if (vertex.isRight() || Objects.isNull(vertex.left().value())) {
552             return Collections.emptyList();
553         }
554         final Either<List<GraphVertex>, JanusGraphOperationStatus> nodeModelVertices =
555             janusGraphDao.getParentVertices(vertex.left().value(), EdgeLabelEnum.MODEL_ELEMENT, JsonParseFlagEnum.NoParse);
556         if (nodeModelVertices.isRight() || nodeModelVertices.left().value() == null) {
557             return Collections.emptyList();
558         }
559         return nodeModelVertices.left().value();
560     }
561
562     private boolean isValidForVendorRelease(final GraphVertex resource, final String vendorRelease) {
563         if (!vendorRelease.equals("1.0")) {
564             try {
565                 Semver resourceSemVer = new Semver((String) resource.getJsonMetadataField(JsonPresentationFields.VENDOR_RELEASE), SemverType.NPM);
566                 Semver packageSemVer = new Semver(vendorRelease, SemverType.NPM);
567                 return !resourceSemVer.isGreaterThan(packageSemVer);
568             } catch (Exception exception) {
569                 log.debug("Error in comparing vendor release", exception);
570                 return true;
571             }
572         }
573         return true;
574     }
575
576     public Either<Resource, StorageOperationStatus> getLatestCertifiedByToscaResourceName(String toscaResourceName, VertexTypeEnum vertexType,
577                                                                                           JsonParseFlagEnum parseFlag) {
578         Map<GraphPropertyEnum, Object> props = new EnumMap<>(GraphPropertyEnum.class);
579         props.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaResourceName);
580         props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
581         props.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
582         Either<List<GraphVertex>, JanusGraphOperationStatus> getLatestRes = janusGraphDao.getByCriteria(vertexType, props, parseFlag);
583         return getLatestRes.right().map(status -> {
584             CommonUtility
585                 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch {} with name {}. status={} ", vertexType, toscaResourceName, status);
586             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
587         }).left().bind(resources -> {
588             double version = 0.0;
589             GraphVertex highestResource = null;
590             for (GraphVertex resource : resources) {
591                 double resourceVersion = Double.parseDouble((String) resource.getJsonMetadataField(JsonPresentationFields.VERSION));
592                 if (resourceVersion > version) {
593                     version = resourceVersion;
594                     highestResource = resource;
595                 }
596             }
597             if (highestResource != null) {
598                 return getToscaFullElement(highestResource.getUniqueId());
599             } else {
600                 log.debug("The vertex with the highest version could not be found for {}", toscaResourceName);
601                 return Either.right(StorageOperationStatus.GENERAL_ERROR);
602             }
603         });
604     }
605
606     public Either<Resource, StorageOperationStatus> getLatestResourceByToscaResourceName(String toscaResourceName) {
607         if (toscaResourceName != null && toscaResourceName.contains("org.openecomp.resource.vf")) {
608             return getLatestResourceByToscaResourceName(toscaResourceName, TOPOLOGY_TEMPLATE, JsonParseFlagEnum.ParseMetadata);
609         } else {
610             return getLatestResourceByToscaResourceName(toscaResourceName, VertexTypeEnum.NODE_TYPE, JsonParseFlagEnum.ParseMetadata);
611         }
612     }
613
614     public Either<Resource, StorageOperationStatus> getLatestResourceByToscaResourceName(String toscaResourceName, VertexTypeEnum vertexType,
615                                                                                          JsonParseFlagEnum parseFlag) {
616         Either<Resource, StorageOperationStatus> result = null;
617         Map<GraphPropertyEnum, Object> props = new EnumMap<>(GraphPropertyEnum.class);
618         props.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaResourceName);
619         props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
620         if (!toscaResourceName.contains("org.openecomp.resource.vf")) {
621             props.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
622         }
623         Either<List<GraphVertex>, JanusGraphOperationStatus> getLatestRes = janusGraphDao.getByCriteria(vertexType, props, parseFlag);
624         if (getLatestRes.isRight()) {
625             JanusGraphOperationStatus status = getLatestRes.right().value();
626             CommonUtility
627                 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch {} with name {}. status={} ", vertexType, toscaResourceName, status);
628             result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
629         }
630         if (result == null) {
631             List<GraphVertex> resources = getLatestRes.left().value();
632             double version = 0.0;
633             GraphVertex highestResource = null;
634             for (GraphVertex resource : resources) {
635                 double resourceVersion = Double.parseDouble((String) resource.getJsonMetadataField(JsonPresentationFields.VERSION));
636                 if (resourceVersion > version) {
637                     version = resourceVersion;
638                     highestResource = resource;
639                 }
640             }
641             if (highestResource != null) {
642                 result = getToscaFullElement(highestResource.getUniqueId());
643             } else {
644                 log.debug("The vertex with the highest version could not be found for {}", toscaResourceName);
645                 result = Either.right(StorageOperationStatus.GENERAL_ERROR);
646             }
647         }
648         return result;
649     }
650
651     public Either<Boolean, StorageOperationStatus> validateToscaResourceNameExists(String templateName) {
652         Either<Boolean, StorageOperationStatus> validateUniquenessRes = validateToscaResourceNameUniqueness(templateName);
653         if (validateUniquenessRes.isLeft()) {
654             return Either.left(!validateUniquenessRes.left().value());
655         }
656         return validateUniquenessRes;
657     }
658
659     public Either<RequirementCapabilityRelDef, StorageOperationStatus> dissociateResourceInstances(String componentId,
660                                                                                                    RequirementCapabilityRelDef requirementDef) {
661         return nodeTemplateOperation.dissociateResourceInstances(componentId, requirementDef);
662     }
663
664     /**
665      * Allows to get fulfilled requirement by relation and received predicate
666      */
667     public Either<RequirementDataDefinition, StorageOperationStatus> getFulfilledRequirementByRelation(String componentId, String instanceId,
668                                                                                                        RequirementCapabilityRelDef relation,
669                                                                                                        BiPredicate<RelationshipInfo, RequirementDataDefinition> predicate) {
670         return nodeTemplateOperation.getFulfilledRequirementByRelation(componentId, instanceId, relation, predicate);
671     }
672
673     /**
674      * Allows to get fulfilled capability by relation and received predicate
675      */
676     public Either<CapabilityDataDefinition, StorageOperationStatus> getFulfilledCapabilityByRelation(String componentId, String instanceId,
677                                                                                                      RequirementCapabilityRelDef relation,
678                                                                                                      BiPredicate<RelationshipInfo, CapabilityDataDefinition> predicate) {
679         return nodeTemplateOperation.getFulfilledCapabilityByRelation(componentId, instanceId, relation, predicate);
680     }
681
682     public Either<List<RequirementCapabilityRelDef>, StorageOperationStatus> associateResourceInstances(Component component, String componentId,
683                                                                                                         List<RequirementCapabilityRelDef> relations) {
684         Either<List<RequirementCapabilityRelDef>, StorageOperationStatus> reqAndCapListEither = nodeTemplateOperation
685             .associateResourceInstances(componentId, relations);
686         if (component != null) {
687             updateInstancesCapAndReqOnComponentFromDB(component);
688         }
689         return reqAndCapListEither;
690     }
691
692     protected Either<Boolean, StorageOperationStatus> validateToscaResourceNameUniqueness(String name) {
693         Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
694         properties.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, name);
695         Either<List<GraphVertex>, JanusGraphOperationStatus> resources = janusGraphDao
696             .getByCriteria(null, properties, JsonParseFlagEnum.ParseMetadata);
697         if (resources.isRight() && resources.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
698             log.debug("failed to get resources from graph with property name: {}", name);
699             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(resources.right().value()));
700         }
701         List<GraphVertex> resourceList = (resources.isLeft() ? resources.left().value() : null);
702         if (isNotEmpty(resourceList)) {
703             if (log.isDebugEnabled()) {
704                 StringBuilder builder = new StringBuilder();
705                 for (GraphVertex resourceData : resourceList) {
706                     builder.append(resourceData.getUniqueId() + "|");
707                 }
708                 log.debug("resources  with property name:{} exists in graph. found {}", name, builder);
709             }
710             return Either.left(false);
711         } else {
712             log.debug("resources  with property name:{} does not exists in graph", name);
713             return Either.left(true);
714         }
715     }
716
717     // region - Component Update
718     public Either<Resource, StorageOperationStatus> overrideComponent(Resource newComponent, Resource oldComponent) {
719         copyArtifactsToNewComponent(newComponent, oldComponent);
720         Either<GraphVertex, JanusGraphOperationStatus> componentVEither = janusGraphDao
721             .getVertexById(oldComponent.getUniqueId(), JsonParseFlagEnum.NoParse);
722         if (componentVEither.isRight()) {
723             log.debug("Failed to fetch component {} error {}", oldComponent.getUniqueId(), componentVEither.right().value());
724             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(componentVEither.right().value()));
725         }
726         GraphVertex componentv = componentVEither.left().value();
727         Either<GraphVertex, JanusGraphOperationStatus> parentVertexEither = janusGraphDao
728             .getParentVertex(componentv, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
729         if (parentVertexEither.isRight() && parentVertexEither.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
730             log.debug("Failed to fetch parent version for component {} error {}", oldComponent.getUniqueId(), parentVertexEither.right().value());
731             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(parentVertexEither.right().value()));
732         }
733         Either<ToscaElement, StorageOperationStatus> deleteToscaComponent = deleteToscaElement(componentv);
734         if (deleteToscaComponent.isRight()) {
735             log.debug("Failed to remove old component {} error {}", oldComponent.getUniqueId(), deleteToscaComponent.right().value());
736             return Either.right(deleteToscaComponent.right().value());
737         }
738         Either<Resource, StorageOperationStatus> createToscaComponent = createToscaComponent(newComponent);
739         if (createToscaComponent.isRight()) {
740             log.debug("Failed to create tosca element component {} error {}", newComponent.getUniqueId(), createToscaComponent.right().value());
741             return Either.right(createToscaComponent.right().value());
742         }
743         Resource newElement = createToscaComponent.left().value();
744         Either<GraphVertex, JanusGraphOperationStatus> newVersionEither = janusGraphDao
745             .getVertexById(newElement.getUniqueId(), JsonParseFlagEnum.NoParse);
746         if (newVersionEither.isRight()) {
747             log.debug("Failed to fetch new tosca element component {} error {}", newComponent.getUniqueId(), newVersionEither.right().value());
748             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(newVersionEither.right().value()));
749         }
750         if (parentVertexEither.isLeft()) {
751             GraphVertex previousVersionV = parentVertexEither.left().value();
752             JanusGraphOperationStatus createEdge = janusGraphDao
753                 .createEdge(previousVersionV, newVersionEither.left().value(), EdgeLabelEnum.VERSION, null);
754             if (createEdge != JanusGraphOperationStatus.OK) {
755                 log.debug("Failed to associate to previous version {} new version {} error {}", previousVersionV.getUniqueId(),
756                     newVersionEither.right().value(), createEdge);
757                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(createEdge));
758             }
759         }
760         return Either.left(newElement);
761     }
762
763     void copyArtifactsToNewComponent(Resource newComponent, Resource oldComponent) {
764         // TODO - check if required
765         Map<String, ArtifactDefinition> toscaArtifacts = oldComponent.getToscaArtifacts();
766         if (toscaArtifacts != null && !toscaArtifacts.isEmpty()) {
767             toscaArtifacts.values().stream().forEach(a -> a.setDuplicated(Boolean.TRUE));
768         }
769         newComponent.setToscaArtifacts(toscaArtifacts);
770         Map<String, ArtifactDefinition> artifacts = oldComponent.getArtifacts();
771         if (artifacts != null && !artifacts.isEmpty()) {
772             artifacts.values().stream().forEach(a -> a.setDuplicated(Boolean.TRUE));
773         }
774         newComponent.setArtifacts(artifacts);
775         Map<String, ArtifactDefinition> depArtifacts = oldComponent.getDeploymentArtifacts();
776         if (depArtifacts != null && !depArtifacts.isEmpty()) {
777             depArtifacts.values().stream().forEach(a -> a.setDuplicated(Boolean.TRUE));
778         }
779         newComponent.setDeploymentArtifacts(depArtifacts);
780         newComponent.setLastUpdateDate(null);
781         newComponent.setHighestVersion(true);
782     }
783
784     public <T extends Component> Either<T, StorageOperationStatus> updateToscaElement(T componentToUpdate) {
785         return updateToscaElement(componentToUpdate, new ComponentParametersView());
786     }
787
788     public <T extends Component> Either<T, StorageOperationStatus> updateToscaElement(T componentToUpdate, ComponentParametersView filterResult) {
789         String componentId = componentToUpdate.getUniqueId();
790         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
791         if (getVertexEither.isRight()) {
792             log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
793             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value()));
794         }
795         GraphVertex elementV = getVertexEither.left().value();
796         ToscaElementOperation toscaElementOperation = getToscaElementOperation(elementV);
797         ToscaElement toscaElementToUpdate = ModelConverter.convertToToscaElement(componentToUpdate);
798         Either<ToscaElement, StorageOperationStatus> updateToscaElement = null;
799         if (toscaElementOperation != null) {
800             updateToscaElement = toscaElementOperation.updateToscaElement(toscaElementToUpdate, elementV, filterResult);
801         } else {
802             log.debug("Null value returned by `getToscaElementOperation` with value {}", elementV);
803             updateToscaElement = Either.right(StorageOperationStatus.GENERAL_ERROR);
804         }
805         return updateToscaElement.bimap(ModelConverter::convertFromToscaElement, status -> {
806             log.debug("Failed to update tosca element {} error {}", componentId, status);
807             return status;
808         });
809     }
810
811     private <T extends Component> Either<T, StorageOperationStatus> getLatestByName(GraphPropertyEnum property, String nodeName,
812                                                                                     JsonParseFlagEnum parseFlag, String modelName) {
813         return getLatestByName(property, nodeName, parseFlag, new ComponentParametersView(), modelName);
814     }
815
816     private <T extends Component> Either<T, StorageOperationStatus> getLatestByName(GraphPropertyEnum property, String nodeName,
817                                                                                     JsonParseFlagEnum parseFlag, ComponentParametersView filter,
818                                                                                     String model) {
819         Either<T, StorageOperationStatus> result;
820         Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
821         Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
822         propertiesToMatch.put(property, nodeName);
823         propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
824         propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
825         Either<List<GraphVertex>, JanusGraphOperationStatus> highestResources = janusGraphDao
826             .getByCriteria(null, propertiesToMatch, propertiesNotToMatch, parseFlag, model);
827         if (highestResources.isRight()) {
828             JanusGraphOperationStatus status = highestResources.right().value();
829             log.debug("failed to find resource with name {}. status={} ", nodeName, status);
830             result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
831             return result;
832         }
833         List<GraphVertex> resources = highestResources.left().value();
834         double version = 0.0;
835         GraphVertex highestResource = null;
836         for (GraphVertex vertex : resources) {
837             Object versionObj = vertex.getMetadataProperty(GraphPropertyEnum.VERSION);
838             double resourceVersion = Double.parseDouble((String) versionObj);
839             if (resourceVersion > version) {
840                 version = resourceVersion;
841                 highestResource = vertex;
842             }
843         }
844         return getToscaElementByOperation(highestResource, filter);
845     }
846
847     // region - Component Get By ..
848     private <T extends Component> Either<T, StorageOperationStatus> getLatestByName(GraphPropertyEnum property, String nodeName, String modelName) {
849         return getLatestByName(property, nodeName, JsonParseFlagEnum.ParseMetadata, modelName);
850     }
851
852     public <T extends Component> Either<T, StorageOperationStatus> getBySystemNameAndVersion(final ComponentTypeEnum componentType,
853                                                                                              final String systemName,
854                                                                                              final String version) {
855         final Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
856         final Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
857         propertiesToMatch.put(GraphPropertyEnum.SYSTEM_NAME, systemName);
858         propertiesToMatch.put(GraphPropertyEnum.VERSION, version);
859         if (componentType != null) {
860             propertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
861         }
862         propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
863
864         final Either<List<GraphVertex>, JanusGraphOperationStatus> getResourceResult
865             = janusGraphDao.getByCriteria(null, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseAll);
866         if (getResourceResult.isRight()) {
867             final JanusGraphOperationStatus status = getResourceResult.right().value();
868             log.debug("Failed to find resource with systemName {}, version {}. Status is {} ", systemName, version, status);
869             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
870         }
871         return getToscaElementByOperation(getResourceResult.left().value().get(0));
872     }
873
874     public <T extends Component> Either<T, StorageOperationStatus> getComponentByNameAndVersion(ComponentTypeEnum componentType, String name,
875                                                                                                 String version) {
876         return getComponentByNameAndVersion(componentType, name, version, JsonParseFlagEnum.ParseAll);
877     }
878
879     public <T extends Component> Either<T, StorageOperationStatus> getComponentByNameAndVersion(ComponentTypeEnum componentType, String name,
880                                                                                                 String version, JsonParseFlagEnum parseFlag) {
881         Map<GraphPropertyEnum, Object> hasProperties = new EnumMap<>(GraphPropertyEnum.class);
882         Map<GraphPropertyEnum, Object> hasNotProperties = new EnumMap<>(GraphPropertyEnum.class);
883         hasProperties.put(GraphPropertyEnum.NAME, name);
884         hasProperties.put(GraphPropertyEnum.VERSION, version);
885         hasNotProperties.put(GraphPropertyEnum.IS_DELETED, true);
886         if (componentType != null) {
887             hasProperties.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
888         }
889         Either<List<GraphVertex>, JanusGraphOperationStatus> getResourceRes = janusGraphDao
890             .getByCriteria(null, hasProperties, hasNotProperties, parseFlag);
891         if (getResourceRes.isRight()) {
892             JanusGraphOperationStatus status = getResourceRes.right().value();
893             log.debug("failed to find resource with name {}, version {}. Status is {} ", name, version, status);
894             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
895         }
896         return getToscaElementByOperation(getResourceRes.left().value().get(0));
897     }
898
899     public <T extends Component> Either<T, StorageOperationStatus> getComponentByNameAndVendorRelease(final ComponentTypeEnum componentType,
900                                                                                                       final String name, final String vendorRelease,
901                                                                                                       final JsonParseFlagEnum parseFlag,
902                                                                                                       final String modelName) {
903         Map<GraphPropertyEnum, Object> hasProperties = new EnumMap<>(GraphPropertyEnum.class);
904         Map<GraphPropertyEnum, Object> hasNotProperties = new EnumMap<>(GraphPropertyEnum.class);
905         hasProperties.put(GraphPropertyEnum.NAME, name);
906         hasNotProperties.put(GraphPropertyEnum.IS_DELETED, true);
907         if (componentType != null) {
908             hasProperties.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
909         }
910         Map<String, Entry<JanusGraphPredicate, Object>> predicateCriteria = getVendorVersionPredicate(vendorRelease);
911         Either<List<GraphVertex>, JanusGraphOperationStatus> getResourceRes = janusGraphDao.getByCriteria(null, hasProperties, hasNotProperties,
912             predicateCriteria, parseFlag, modelName);
913         if (getResourceRes.isRight()) {
914             JanusGraphOperationStatus status = getResourceRes.right().value();
915             log.debug("failed to find resource with name {}, version {}. Status is {} ", name, predicateCriteria, status);
916             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
917         }
918         return getToscaElementByOperation(getResourceRes.left().value().get(0));
919     }
920
921     public Either<List<CatalogComponent>, StorageOperationStatus> getCatalogOrArchiveComponents(boolean isCatalog,
922                                                                                                 List<OriginTypeEnum> excludeTypes) {
923         List<ResourceTypeEnum> excludedResourceTypes = Optional.ofNullable(excludeTypes).orElse(Collections.emptyList()).stream()
924             .filter(type -> !type.equals(OriginTypeEnum.SERVICE)).map(type -> ResourceTypeEnum.getTypeByName(type.name()))
925             .collect(Collectors.toList());
926         return topologyTemplateOperation.getElementCatalogData(isCatalog, excludedResourceTypes);
927     }
928
929     // endregion
930     public <T extends Component> Either<List<T>, StorageOperationStatus> getCatalogComponents(ComponentTypeEnum componentType,
931                                                                                               List<OriginTypeEnum> excludeTypes,
932                                                                                               boolean isHighestVersions) {
933         List<T> components = new ArrayList<>();
934         Either<List<ToscaElement>, StorageOperationStatus> catalogDataResult;
935         List<ToscaElement> toscaElements = new ArrayList<>();
936         List<ResourceTypeEnum> excludedResourceTypes = Optional.ofNullable(excludeTypes).orElse(Collections.emptyList()).stream()
937             .filter(type -> !type.equals(OriginTypeEnum.SERVICE)).map(type -> ResourceTypeEnum.getTypeByName(type.name()))
938             .collect(Collectors.toList());
939         switch (componentType) {
940             case RESOURCE:
941                 catalogDataResult = nodeTypeOperation.getElementCatalogData(ComponentTypeEnum.RESOURCE, excludedResourceTypes, isHighestVersions);
942                 if (catalogDataResult.isRight()) {
943                     return Either.right(catalogDataResult.right().value());
944                 }
945                 toscaElements = catalogDataResult.left().value();
946                 break;
947             case SERVICE:
948                 if (excludeTypes != null && excludeTypes.contains(OriginTypeEnum.SERVICE)) {
949                     break;
950                 }
951                 catalogDataResult = topologyTemplateOperation.getElementCatalogData(ComponentTypeEnum.SERVICE, null, isHighestVersions);
952                 if (catalogDataResult.isRight()) {
953                     return Either.right(catalogDataResult.right().value());
954                 }
955                 toscaElements = catalogDataResult.left().value();
956                 break;
957             default:
958                 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, componentType);
959                 return Either.right(StorageOperationStatus.BAD_REQUEST);
960         }
961         toscaElements.forEach(te -> {
962             T component = ModelConverter.convertFromToscaElement(te);
963             components.add(component);
964         });
965         return Either.left(components);
966     }
967
968     public Either<List<String>, StorageOperationStatus> deleteMarkedElements(ComponentTypeEnum componentType) {
969         Either<List<GraphVertex>, StorageOperationStatus> allComponentsMarkedForDeletion;
970         switch (componentType) {
971             case RESOURCE:
972                 allComponentsMarkedForDeletion = nodeTypeOperation.getAllComponentsMarkedForDeletion(componentType);
973                 break;
974             case SERVICE:
975             case PRODUCT:
976                 allComponentsMarkedForDeletion = topologyTemplateOperation.getAllComponentsMarkedForDeletion(componentType);
977                 break;
978             default:
979                 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, componentType);
980                 return Either.right(StorageOperationStatus.BAD_REQUEST);
981         }
982         if (allComponentsMarkedForDeletion.isRight()) {
983             return Either.right(allComponentsMarkedForDeletion.right().value());
984         }
985         List<GraphVertex> allMarked = allComponentsMarkedForDeletion.left().value();
986         return Either.left(checkIfInUseAndDelete(allMarked));
987     }
988
989     public List<String> deleteService(String invariantUUID, final boolean inTransaction) {
990         return deleteComponent(invariantUUID, NodeTypeEnum.Service, inTransaction);
991     }
992
993     public List<String> deleteComponent(String invariantUUID, NodeTypeEnum componentType, final boolean inTransaction) {
994         final List<GraphVertex> allServiceVerticesToDelete = findVertexListByInvariantUuid(invariantUUID);
995         List<String> affectedComponentIds = new ArrayList<>();
996         try {
997             checkNotUsed(allServiceVerticesToDelete);
998             lockAllVerticesByNodeType(allServiceVerticesToDelete, componentType);
999             for (GraphVertex elementV : allServiceVerticesToDelete) {
1000                 Either<ToscaElement, StorageOperationStatus> deleteToscaElement = deleteToscaElement(elementV);
1001                 if (deleteToscaElement.isRight()) {
1002                     log.debug("Failed to delete element UniqueID {}, Name {}, error {}", elementV.getUniqueId(),
1003                         elementV.getMetadataProperties().get(GraphPropertyEnum.NAME), deleteToscaElement.right().value());
1004                     throwStorageException(deleteToscaElement.right().value());
1005                 }
1006                 affectedComponentIds.add(elementV.getUniqueId());
1007             }
1008             if (!inTransaction) {
1009                 janusGraphDao.commit();
1010             }
1011         } catch (Exception exception) {
1012             if (!inTransaction) {
1013                 janusGraphDao.rollback();
1014             }
1015             throw exception;
1016         } finally {
1017             unlockAllVerticesByNodeType(allServiceVerticesToDelete, componentType);
1018         }
1019         return affectedComponentIds;
1020     }
1021
1022     private void checkNotUsed(List<GraphVertex> vertices) {
1023         boolean isInUse = isAnyComponentInUse(vertices);
1024         if (isInUse) {
1025             Set<GraphVertex> listOfVertices = getComponentsUsingComponents(vertices);
1026             List<String> listOfStringComponents = new ArrayList<>();
1027             for (GraphVertex componentVertex : listOfVertices) {
1028                 listOfStringComponents.add(
1029                     componentVertex.getMetadataJson().get(GraphPropertyEnum.COMPONENT_TYPE.getProperty()) + " "
1030                         + componentVertex.getMetadataJson().get(GraphPropertyEnum.NAME.getProperty())
1031                 );
1032             }
1033             String stringOfComponents = String.join(", ", listOfStringComponents);
1034             throw ToscaOperationExceptionSupplier.componentInUse(stringOfComponents).get();
1035         }
1036     }
1037
1038     public List<GraphVertex> findVertexListByInvariantUuid(final String invariantUuid) {
1039         try {
1040             return janusGraphDao.findAllVertexByInvariantUuid(invariantUuid, Collections.emptyMap());
1041         } catch (final JanusGraphException e) {
1042             log.error(EcompLoggerErrorCode.DATA_ERROR, this.getClass().getName(), e.getMessage());
1043             throw new StorageException(e.getStatus());
1044         }
1045     }
1046
1047     public void commitAndCheck(String componentId) {
1048         JanusGraphOperationStatus status = janusGraphDao.commit();
1049         if (!status.equals(JanusGraphOperationStatus.OK)) {
1050             log.debug("error occurred when trying to DELETE {}. Return code is: {}", componentId, status);
1051             throwStorageException(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
1052         }
1053     }
1054
1055     private Set<GraphVertex> getComponentsUsingComponents(List<GraphVertex> componentVertices) {
1056         Set<GraphVertex> inUseBy = new TreeSet<>(Comparator.comparing(GraphVertex::getUniqueId));
1057         for (final GraphVertex elementV : componentVertices) {
1058             List<GraphVertex> inUseByVertex = isInUse(elementV);
1059             if (!inUseByVertex.isEmpty()) {
1060                 inUseBy.addAll(inUseByVertex);
1061             }
1062         }
1063         return inUseBy;
1064     }
1065
1066     private boolean isAnyComponentInUse(List<GraphVertex> componentVertices) {
1067         boolean isComponentInUse = false;
1068         if (log.isDebugEnabled()) {
1069             for (final GraphVertex graphVertex : componentVertices) {
1070                 if (!isInUse(graphVertex).isEmpty()) {
1071                     isComponentInUse = true;
1072                 }
1073             }
1074         } else {
1075             isComponentInUse = componentVertices.stream().anyMatch(vertex -> !isInUse(vertex).isEmpty());
1076         }
1077         return isComponentInUse;
1078     }
1079
1080     private List<GraphVertex> isInUse(GraphVertex elementV) {
1081         final List<EdgeLabelEnum> forbiddenEdgeLabelEnums = Arrays
1082             .asList(EdgeLabelEnum.INSTANCE_OF, EdgeLabelEnum.PROXY_OF, EdgeLabelEnum.ALLOTTED_OF);
1083         for (EdgeLabelEnum edgeLabelEnum : forbiddenEdgeLabelEnums) {
1084             Either<List<GraphVertex>, JanusGraphOperationStatus> inUseBy =
1085                 janusGraphDao.getParentVertices(elementV, edgeLabelEnum, JsonParseFlagEnum.ParseAll);
1086             if (inUseBy.isLeft()) {
1087                 if (log.isDebugEnabled()) {
1088                     log.debug("Element {} in use.", elementV.getUniqueId());
1089                 }
1090                 return inUseBy.left().value();
1091             }
1092         }
1093         return Collections.emptyList();
1094     }
1095
1096     private List<String> checkIfInUseAndDelete(List<GraphVertex> allMarked) {
1097         List<String> deleted = new ArrayList<>();
1098         for (GraphVertex elementV : allMarked) {
1099             boolean isAllowedToDelete = !isInUse(elementV).isEmpty();
1100             if (isAllowedToDelete) {
1101                 Either<ToscaElement, StorageOperationStatus> deleteToscaElement = deleteToscaElement(elementV);
1102                 if (deleteToscaElement.isRight()) {
1103                     log.debug("Failed to delete marked element UniqueID {}, Name {}, error {}", elementV.getUniqueId(),
1104                         elementV.getMetadataProperties().get(GraphPropertyEnum.NAME), deleteToscaElement.right().value());
1105                     continue;
1106                 }
1107                 deleted.add(elementV.getUniqueId());
1108             }
1109         }
1110         return deleted;
1111     }
1112
1113     private void lockAllVerticesByNodeType(List<GraphVertex> allVerticesToLock, NodeTypeEnum nodeType) {
1114         for (GraphVertex graphVertex : allVerticesToLock) {
1115             StorageOperationStatus storageOperationStatus = graphLockOperation.lockComponent(graphVertex.getUniqueId(), nodeType);
1116             if (!storageOperationStatus.equals(StorageOperationStatus.OK)) {
1117                 throwStorageException(storageOperationStatus);
1118             }
1119         }
1120     }
1121
1122     private void unlockAllVerticesByNodeType(List<GraphVertex> allVerticesToUnlock, NodeTypeEnum nodeType) {
1123         for (GraphVertex graphVertex : allVerticesToUnlock) {
1124             graphLockOperation.unlockComponent(graphVertex.getUniqueId(), nodeType);
1125         }
1126     }
1127
1128     public Either<List<String>, StorageOperationStatus> getAllComponentsMarkedForDeletion(ComponentTypeEnum componentType) {
1129         Either<List<GraphVertex>, StorageOperationStatus> allComponentsMarkedForDeletion;
1130         switch (componentType) {
1131             case RESOURCE:
1132                 allComponentsMarkedForDeletion = nodeTypeOperation.getAllComponentsMarkedForDeletion(componentType);
1133                 break;
1134             case SERVICE:
1135             case PRODUCT:
1136                 allComponentsMarkedForDeletion = topologyTemplateOperation.getAllComponentsMarkedForDeletion(componentType);
1137                 break;
1138             default:
1139                 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, componentType);
1140                 return Either.right(StorageOperationStatus.BAD_REQUEST);
1141         }
1142         if (allComponentsMarkedForDeletion.isRight()) {
1143             return Either.right(allComponentsMarkedForDeletion.right().value());
1144         }
1145         return Either.left(allComponentsMarkedForDeletion.left().value().stream().map(GraphVertex::getUniqueId).collect(Collectors.toList()));
1146     }
1147
1148     // region - Component Update
1149     public Either<ImmutablePair<Component, String>, StorageOperationStatus> addComponentInstanceToTopologyTemplate(Component containerComponent,
1150                                                                                                                    Component origComponent,
1151                                                                                                                    ComponentInstance componentInstance,
1152                                                                                                                    boolean allowDeleted, User user) {
1153         Either<ImmutablePair<Component, String>, StorageOperationStatus> result = null;
1154         Either<ToscaElement, StorageOperationStatus> updateContainerComponentRes = null;
1155         if (StringUtils.isEmpty(componentInstance.getIcon())) {
1156             componentInstance.setIcon(origComponent.getIcon());
1157         }
1158         String nameToFindForCounter;
1159         switch (componentInstance.getOriginType()) {
1160             case ServiceProxy:
1161                 nameToFindForCounter = ValidationUtils.normaliseComponentName(componentInstance.getSourceModelName()) + PROXY_SUFFIX;
1162                 break;
1163             case ServiceSubstitution:
1164                 nameToFindForCounter = ValidationUtils.normaliseComponentName(componentInstance.getSourceModelName());
1165                 break;
1166             default:
1167                 nameToFindForCounter = origComponent.getName();
1168         }
1169         String nextComponentInstanceCounter = getNextComponentInstanceCounter(containerComponent, nameToFindForCounter);
1170         Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> addResult = nodeTemplateOperation
1171             .addComponentInstanceToTopologyTemplate(ModelConverter.convertToToscaElement(containerComponent),
1172                 ModelConverter.convertToToscaElement(origComponent), nextComponentInstanceCounter, componentInstance, allowDeleted, user);
1173         if (addResult.isRight()) {
1174             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add the component instance {} to container component {}. ",
1175                 componentInstance.getName(), containerComponent.getName());
1176             result = Either.right(addResult.right().value());
1177         }
1178         if (result == null) {
1179             updateContainerComponentRes = topologyTemplateOperation.getToscaElement(containerComponent.getUniqueId());
1180             if (updateContainerComponentRes.isRight()) {
1181                 CommonUtility
1182                     .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch updated topology template {} with updated component instance {}. ",
1183                         containerComponent.getName(), componentInstance.getName());
1184                 result = Either.right(updateContainerComponentRes.right().value());
1185             }
1186         }
1187         if (result == null) {
1188             Component updatedComponent = ModelConverter.convertFromToscaElement(updateContainerComponentRes.left().value());
1189             String createdInstanceId = addResult.left().value().getRight();
1190             CommonUtility
1191                 .addRecordToLog(log, LogLevelEnum.TRACE, "The component instance {} has been added to container component {}. ", createdInstanceId,
1192                     updatedComponent.getName());
1193             result = Either.left(new ImmutablePair<>(updatedComponent, createdInstanceId));
1194         }
1195         return result;
1196     }
1197
1198     public void associateComponentInstancesToComponent(Component containerComponent, Map<ComponentInstance, Resource> resourcesInstancesMap,
1199                                                        boolean allowDeleted, boolean isUpdateCsar) {
1200         CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Going to add component instances to component {}", containerComponent.getUniqueId());
1201         Either<GraphVertex, JanusGraphOperationStatus> metadataVertex = janusGraphDao
1202             .getVertexById(containerComponent.getUniqueId(), JsonParseFlagEnum.ParseAll);
1203         if (metadataVertex.isRight()) {
1204             JanusGraphOperationStatus status = metadataVertex.right().value();
1205             if (status == JanusGraphOperationStatus.NOT_FOUND) {
1206                 status = JanusGraphOperationStatus.INVALID_ID;
1207             }
1208             throw new StorageException(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
1209         }
1210         Map<String, ComponentInstanceDataDefinition> compnentInstancesMap = nodeTemplateOperation
1211             .associateComponentInstancesToComponent(containerComponent, resourcesInstancesMap, metadataVertex.left().value(), allowDeleted,
1212                 isUpdateCsar);
1213         containerComponent.setComponentInstances(ModelConverter.getComponentInstancesFromMapObject(compnentInstancesMap, containerComponent));
1214     }
1215
1216     public Either<ImmutablePair<Component, String>, StorageOperationStatus> updateComponentInstanceMetadataOfTopologyTemplate(
1217         Component containerComponent, Component origComponent, ComponentInstance componentInstance) {
1218         Either<ImmutablePair<Component, String>, StorageOperationStatus> result = null;
1219         CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE,
1220             "Going to update the metadata of the component instance {} belonging to container component {}. ", componentInstance.getName(),
1221             containerComponent.getName());
1222         componentInstance.setIcon(origComponent.getIcon());
1223         Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> updateResult = nodeTemplateOperation
1224             .updateComponentInstanceMetadataOfTopologyTemplate(ModelConverter.convertToToscaElement(containerComponent),
1225                 ModelConverter.convertToToscaElement(origComponent), componentInstance);
1226         if (updateResult.isRight()) {
1227             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
1228                 "Failed to update the metadata of the component instance {} belonging to container component {}. ", componentInstance.getName(),
1229                 containerComponent.getName());
1230             result = Either.right(updateResult.right().value());
1231         }
1232         if (result == null) {
1233             Component updatedComponent = ModelConverter.convertFromToscaElement(updateResult.left().value().getLeft());
1234             String createdInstanceId = updateResult.left().value().getRight();
1235             CommonUtility
1236                 .addRecordToLog(log, LogLevelEnum.TRACE, "The metadata of the component instance {} has been updated to container component {}. ",
1237                     createdInstanceId, updatedComponent.getName());
1238             result = Either.left(new ImmutablePair<>(updatedComponent, createdInstanceId));
1239         }
1240         return result;
1241     }
1242
1243     public Either<Component, StorageOperationStatus> updateComponentInstanceMetadataOfTopologyTemplate(Component containerComponent) {
1244         return updateComponentInstanceMetadataOfTopologyTemplate(containerComponent, new ComponentParametersView());
1245     }
1246
1247     public Either<Component, StorageOperationStatus> updateComponentInstanceMetadataOfTopologyTemplate(Component containerComponent,
1248                                                                                                        ComponentParametersView filter) {
1249         Either<Component, StorageOperationStatus> result = null;
1250         CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "Going to update the metadata  belonging to container component {}. ",
1251             containerComponent.getName());
1252         Either<TopologyTemplate, StorageOperationStatus> updateResult = nodeTemplateOperation
1253             .updateComponentInstanceMetadataOfTopologyTemplate(ModelConverter.convertToToscaElement(containerComponent), filter);
1254         if (updateResult.isRight()) {
1255             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update the metadata  belonging to container component {}. ",
1256                 containerComponent.getName());
1257             result = Either.right(updateResult.right().value());
1258         }
1259         if (result == null) {
1260             Component updatedComponent = ModelConverter.convertFromToscaElement(updateResult.left().value());
1261             CommonUtility
1262                 .addRecordToLog(log, LogLevelEnum.TRACE, "The metadata has been updated to container component {}. ", updatedComponent.getName());
1263             result = Either.left(updatedComponent);
1264         }
1265         return result;
1266     }
1267
1268     // endregion
1269     public Either<ImmutablePair<Component, String>, StorageOperationStatus> deleteComponentInstanceFromTopologyTemplate(Component containerComponent,
1270                                                                                                                         String resourceInstanceId) {
1271         Either<ImmutablePair<Component, String>, StorageOperationStatus> result = null;
1272         CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "Going to delete the component instance {} belonging to container component {}. ",
1273             resourceInstanceId, containerComponent.getName());
1274         Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> updateResult = nodeTemplateOperation
1275             .deleteComponentInstanceFromTopologyTemplate(ModelConverter.convertToToscaElement(containerComponent), resourceInstanceId);
1276         if (updateResult.isRight()) {
1277             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete the component instance {} belonging to container component {}. ",
1278                 resourceInstanceId, containerComponent.getName());
1279             result = Either.right(updateResult.right().value());
1280         }
1281         if (result == null) {
1282             Component updatedComponent = ModelConverter.convertFromToscaElement(updateResult.left().value().getLeft());
1283             String deletedInstanceId = updateResult.left().value().getRight();
1284             CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "The component instance {} has been deleted from container component {}. ",
1285                 deletedInstanceId, updatedComponent.getName());
1286             result = Either.left(new ImmutablePair<>(updatedComponent, deletedInstanceId));
1287         }
1288         return result;
1289     }
1290
1291     private String getNextComponentInstanceCounter(Component containerComponent, String originResourceName) {
1292         Integer nextCounter = 0;
1293         if (CollectionUtils.isNotEmpty(containerComponent.getComponentInstances())) {
1294             String normalizedName = ValidationUtils.normalizeComponentInstanceName(originResourceName);
1295             Integer maxCounter = getMaxCounterFromNamesAndIds(containerComponent, normalizedName);
1296             if (maxCounter != null) {
1297                 nextCounter = maxCounter + 1;
1298             }
1299         }
1300         return nextCounter.toString();
1301     }
1302
1303     /**
1304      * @return max counter of component instance Id's, null if not found
1305      */
1306     private Integer getMaxCounterFromNamesAndIds(Component containerComponent, String normalizedName) {
1307         List<String> countersInNames = containerComponent.getComponentInstances().stream()
1308             .filter(ci -> ci.getNormalizedName() != null && ci.getNormalizedName().startsWith(normalizedName))
1309             .map(ci -> ci.getNormalizedName().split(normalizedName)[1].replaceAll("\\D", "")).collect(Collectors.toList());
1310         List<String> countersInIds = containerComponent.getComponentInstances().stream()
1311             .filter(ci -> ci.getUniqueId() != null && ci.getUniqueId().contains(normalizedName))
1312             .map(ci -> ci.getUniqueId().split(normalizedName)[1].replaceAll("\\D", "")).collect(Collectors.toList());
1313         List<String> namesAndIdsList = new ArrayList<>(countersInNames);
1314         namesAndIdsList.addAll(countersInIds);
1315         return getMaxInteger(namesAndIdsList);
1316     }
1317
1318     private Integer getMaxInteger(List<String> counters) {
1319         Integer maxCounter = 0;
1320         Integer currCounter = null;
1321         for (String counter : counters) {
1322             try {
1323                 currCounter = Integer.parseInt(counter);
1324                 if (maxCounter < currCounter) {
1325                     maxCounter = currCounter;
1326                 }
1327             } catch (NumberFormatException e) {
1328             }
1329         }
1330         return currCounter == null ? null : maxCounter;
1331     }
1332
1333     public Either<RequirementCapabilityRelDef, StorageOperationStatus> associateResourceInstances(Component component, String componentId,
1334                                                                                                   RequirementCapabilityRelDef requirementDef) {
1335         return nodeTemplateOperation.associateResourceInstances(componentId, requirementDef);
1336     }
1337
1338     public Either<List<InputDefinition>, StorageOperationStatus> createAndAssociateInputs(Map<String, InputDefinition> inputs, String componentId) {
1339         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
1340         if (getVertexEither.isRight()) {
1341             log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
1342             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value()));
1343         }
1344         GraphVertex vertex = getVertexEither.left().value();
1345         Map<String, PropertyDataDefinition> inputsMap = inputs.entrySet().stream()
1346             .collect(Collectors.toMap(Map.Entry::getKey, e -> new PropertyDataDefinition(e.getValue())));
1347         StorageOperationStatus status = topologyTemplateOperation.associateInputsToComponent(vertex, inputsMap, componentId);
1348         if (StorageOperationStatus.OK == status) {
1349             log.debug(INPUTS_ASSOCIATED_TO_COMPONENT_SUCCESSFULLY);
1350             List<InputDefinition> inputsResList = null;
1351             if (inputsMap != null && !inputsMap.isEmpty()) {
1352                 inputsResList = inputsMap.values().stream().map(InputDefinition::new).collect(Collectors.toList());
1353             }
1354             return Either.left(inputsResList);
1355         }
1356         return Either.right(status);
1357     }
1358
1359     public Either<List<OutputDefinition>, StorageOperationStatus> createAndAssociateOutputs(final Map<String, OutputDefinition> outputs,
1360                                                                                             final String componentId) {
1361         final Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
1362         if (getVertexEither.isRight()) {
1363             log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
1364             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value()));
1365         }
1366         final GraphVertex vertex = getVertexEither.left().value();
1367         final Map<String, OutputDefinition> outputsMap = outputs.entrySet().stream()
1368             .collect(Collectors.toMap(Map.Entry::getKey, e -> new OutputDefinition(e.getValue())));
1369         final StorageOperationStatus status = topologyTemplateOperation.associateOutputsToComponent(vertex, outputsMap, componentId);
1370         if (StorageOperationStatus.OK == status) {
1371             log.debug(OUTPUTS_ASSOCIATED_TO_COMPONENT_SUCCESSFULLY);
1372             List<OutputDefinition> outputsResList = null;
1373             if (MapUtils.isNotEmpty(outputsMap)) {
1374                 outputsResList = outputsMap.values().stream().map(OutputDefinition::new).collect(Collectors.toList());
1375             }
1376             return Either.left(outputsResList);
1377         }
1378         return Either.right(status);
1379     }
1380
1381     public Either<List<InputDefinition>, StorageOperationStatus> addInputsToComponent(Map<String, InputDefinition> inputs, String componentId) {
1382         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
1383         if (getVertexEither.isRight()) {
1384             log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
1385             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value()));
1386         }
1387         GraphVertex vertex = getVertexEither.left().value();
1388         Map<String, PropertyDefinition> inputsMap = inputs.entrySet().stream()
1389             .collect(Collectors.toMap(Map.Entry::getKey, e -> new PropertyDefinition(e.getValue())));
1390         StorageOperationStatus status = topologyTemplateOperation
1391             .addToscaDataToToscaElement(vertex, EdgeLabelEnum.INPUTS, VertexTypeEnum.INPUTS, inputsMap, JsonPresentationFields.NAME);
1392         if (StorageOperationStatus.OK == status) {
1393             log.debug(COMPONENT_CREATED_SUCCESSFULLY);
1394             List<InputDefinition> inputsResList = null;
1395             if (inputsMap != null && !inputsMap.isEmpty()) {
1396                 inputsResList = inputsMap.values().stream().map(InputDefinition::new).collect(Collectors.toList());
1397             }
1398             return Either.left(inputsResList);
1399         }
1400         return Either.right(status);
1401     }
1402
1403     public Either<List<OutputDefinition>, StorageOperationStatus> addOutputsToComponent(Map<String, OutputDefinition> outputs, String componentId) {
1404         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
1405         if (getVertexEither.isRight()) {
1406             log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
1407             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value()));
1408         }
1409         GraphVertex vertex = getVertexEither.left().value();
1410         Map<String, AttributeDefinition> outputsMap = outputs.entrySet().stream()
1411             .collect(Collectors.toMap(Map.Entry::getKey, e -> new AttributeDefinition(e.getValue())));
1412         StorageOperationStatus status = topologyTemplateOperation
1413             .addToscaDataToToscaElement(vertex, EdgeLabelEnum.OUTPUTS, VertexTypeEnum.OUTPUTS, outputsMap, JsonPresentationFields.NAME);
1414         if (StorageOperationStatus.OK == status) {
1415             log.debug(COMPONENT_CREATED_SUCCESSFULLY);
1416             List<OutputDefinition> outputsResList = null;
1417             if (outputsMap != null && !outputsMap.isEmpty()) {
1418                 outputsResList = outputsMap.values().stream().map(OutputDefinition::new).collect(Collectors.toList());
1419             }
1420             return Either.left(outputsResList);
1421         }
1422         return Either.right(status);
1423     }
1424
1425     /**
1426      * Add data types into a Component.
1427      *
1428      * @param dataTypes   datatypes to be added. the key should be each name of data type.
1429      * @param componentId unique ID of Component.
1430      * @return list of data types.
1431      */
1432     public Either<List<DataTypeDefinition>, StorageOperationStatus> addDataTypesToComponent(Map<String, DataTypeDefinition> dataTypes,
1433                                                                                             String componentId) {
1434         log.trace("#addDataTypesToComponent - enter, componentId={}", componentId);
1435         /* get component vertex */
1436         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao
1437             .getVertexById(componentId, JsonParseFlagEnum.NoParse);
1438         if (getVertexEither.isRight()) {
1439             /* not found / error */
1440             log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
1441             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value()));
1442         }
1443         GraphVertex vertex = getVertexEither.left().value();
1444         log.trace("#addDataTypesToComponent - get vertex ok");
1445         // convert DataTypeDefinition to DataTypeDataDefinition
1446         Map<String, DataTypeDataDefinition> dataTypeDataMap = dataTypes.entrySet().stream()
1447             .collect(Collectors.toMap(Map.Entry::getKey, e -> convertDataTypeToDataTypeData(e.getValue())));
1448         // add datatype(s) to the Component.
1449
1450         // if child vertex does not exist, it will be created.
1451         StorageOperationStatus status = topologyTemplateOperation
1452             .addToscaDataToToscaElement(vertex, EdgeLabelEnum.DATA_TYPES, VertexTypeEnum.DATA_TYPES, dataTypeDataMap, JsonPresentationFields.NAME);
1453         if (StorageOperationStatus.OK == status) {
1454             log.debug(COMPONENT_CREATED_SUCCESSFULLY);
1455             List<DataTypeDefinition> inputsResList = null;
1456             if (!dataTypes.isEmpty()) {
1457                 inputsResList = new ArrayList<>(dataTypes.values());
1458             }
1459             return Either.left(inputsResList);
1460         }
1461         log.trace("#addDataTypesToComponent - leave");
1462         return Either.right(status);
1463     }
1464
1465     private DataTypeDataDefinition convertDataTypeToDataTypeData(DataTypeDefinition dataType) {
1466         DataTypeDataDefinition dataTypeData = new DataTypeDataDefinition(dataType);
1467         if (CollectionUtils.isNotEmpty(dataType.getProperties())) {
1468             List<PropertyDataDefinition> propertyDataList = dataType.getProperties().stream().map(PropertyDataDefinition::new)
1469                 .collect(Collectors.toList());
1470             dataTypeData.setPropertiesData(propertyDataList);
1471         }
1472         // if "derivedFrom" data_type exists, copy the name to "derivedFromName"
1473         if (dataType.getDerivedFrom() != null && StringUtils.isNotEmpty(dataType.getDerivedFrom().getName())) {
1474             // if names are different, log it
1475             if (!StringUtils.equals(dataTypeData.getDerivedFromName(), dataType.getDerivedFrom().getName())) {
1476                 log.debug("#convertDataTypeToDataTypeData - derivedFromName(={}) overwritten by derivedFrom.name(={})", dataType.getDerivedFromName(),
1477                     dataType.getDerivedFrom().getName());
1478             }
1479             dataTypeData.setDerivedFromName(dataType.getDerivedFrom().getName());
1480         }
1481         // supply "name" field to toscaPresentationValue in each datatype object for DAO operations
1482         dataTypeData.setToscaPresentationValue(JsonPresentationFields.NAME, dataType.getName());
1483         return dataTypeData;
1484     }
1485
1486     public Either<List<InputDefinition>, StorageOperationStatus> getComponentInputs(String componentId) {
1487         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
1488         if (getVertexEither.isRight()) {
1489             log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
1490             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value()));
1491         }
1492         Either<ToscaElement, StorageOperationStatus> toscaElement = topologyTemplateOperation.getToscaElement(componentId);
1493         if (toscaElement.isRight()) {
1494             return Either.right(toscaElement.right().value());
1495         }
1496         TopologyTemplate topologyTemplate = (TopologyTemplate) toscaElement.left().value();
1497         Map<String, PropertyDataDefinition> inputsMap = topologyTemplate.getInputs();
1498         List<InputDefinition> inputs = new ArrayList<>();
1499         if (MapUtils.isNotEmpty(inputsMap)) {
1500             inputs = inputsMap.values().stream().map(p -> new InputDefinition(p)).collect(Collectors.toList());
1501         }
1502         return Either.left(inputs);
1503     }
1504
1505     public Either<List<InputDefinition>, StorageOperationStatus> updateInputsToComponent(List<InputDefinition> inputs, String componentId) {
1506         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
1507         if (getVertexEither.isRight()) {
1508             log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
1509             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value()));
1510         }
1511         GraphVertex vertex = getVertexEither.left().value();
1512         List<PropertyDataDefinition> inputsAsDataDef = inputs.stream().map(PropertyDataDefinition::new).collect(Collectors.toList());
1513         StorageOperationStatus status = topologyTemplateOperation
1514             .updateToscaDataOfToscaElement(vertex, EdgeLabelEnum.INPUTS, VertexTypeEnum.INPUTS, inputsAsDataDef, JsonPresentationFields.NAME);
1515         if (StorageOperationStatus.OK == status) {
1516             log.debug(COMPONENT_CREATED_SUCCESSFULLY);
1517             List<InputDefinition> inputsResList = null;
1518             if (CollectionUtils.isNotEmpty(inputsAsDataDef)) {
1519                 inputsResList = inputsAsDataDef.stream().map(InputDefinition::new).collect(Collectors.toList());
1520             }
1521             return Either.left(inputsResList);
1522         }
1523         return Either.right(status);
1524     }
1525
1526     public Either<List<OutputDefinition>, StorageOperationStatus> updateOutputsToComponent(List<OutputDefinition> outputs, String componentId) {
1527         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
1528         if (getVertexEither.isRight()) {
1529             log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
1530             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value()));
1531         }
1532         GraphVertex vertex = getVertexEither.left().value();
1533         List<AttributeDataDefinition> outputsAsDataDef = outputs.stream().map(AttributeDataDefinition::new).collect(Collectors.toList());
1534         StorageOperationStatus status = topologyTemplateOperation
1535             .updateToscaDataOfToscaElement(vertex, EdgeLabelEnum.OUTPUTS, VertexTypeEnum.OUTPUTS, outputsAsDataDef, JsonPresentationFields.NAME);
1536         if (StorageOperationStatus.OK == status) {
1537             log.debug(COMPONENT_CREATED_SUCCESSFULLY);
1538             List<OutputDefinition> outputsResList = null;
1539             if (!outputsAsDataDef.isEmpty()) {
1540                 outputsResList = outputsAsDataDef.stream().map(OutputDefinition::new).collect(Collectors.toList());
1541             }
1542             return Either.left(outputsResList);
1543         }
1544         return Either.right(status);
1545     }
1546
1547     // region - ComponentInstance
1548     public Either<Map<String, List<ComponentInstanceProperty>>, StorageOperationStatus> associateComponentInstancePropertiesToComponent(
1549         Map<String, List<ComponentInstanceProperty>> instProperties, String componentId) {
1550         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
1551         if (getVertexEither.isRight()) {
1552             log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
1553             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value()));
1554         }
1555         GraphVertex vertex = getVertexEither.left().value();
1556         Map<String, MapPropertiesDataDefinition> instPropsMap = new HashMap<>();
1557         if (instProperties != null) {
1558             MapPropertiesDataDefinition propertiesMap;
1559             for (Entry<String, List<ComponentInstanceProperty>> entry : instProperties.entrySet()) {
1560                 propertiesMap = new MapPropertiesDataDefinition();
1561                 propertiesMap.setMapToscaDataDefinition(
1562                     entry.getValue().stream().map(PropertyDataDefinition::new).collect(Collectors.toMap(PropertyDataDefinition::getName, e -> e)));
1563                 instPropsMap.put(entry.getKey(), propertiesMap);
1564             }
1565         }
1566         StorageOperationStatus status = topologyTemplateOperation.associateInstPropertiesToComponent(vertex, instPropsMap);
1567         if (StorageOperationStatus.OK == status) {
1568             log.debug(COMPONENT_CREATED_SUCCESSFULLY);
1569             return Either.left(instProperties);
1570         }
1571         return Either.right(status);
1572     }
1573
1574     /**
1575      * saves the instInputs as the updated instance inputs of the component container in DB
1576      */
1577     public Either<Map<String, List<ComponentInstanceInput>>, StorageOperationStatus> updateComponentInstanceInputsToComponent(
1578         Map<String, List<ComponentInstanceInput>> instInputs, String componentId) {
1579         if (instInputs == null || instInputs.isEmpty()) {
1580             return Either.left(instInputs);
1581         }
1582         StorageOperationStatus status;
1583         for (Entry<String, List<ComponentInstanceInput>> inputsPerIntance : instInputs.entrySet()) {
1584             List<ComponentInstanceInput> toscaDataListPerInst = inputsPerIntance.getValue();
1585             List<String> pathKeysPerInst = new ArrayList<>();
1586             pathKeysPerInst.add(inputsPerIntance.getKey());
1587             status = topologyTemplateOperation
1588                 .updateToscaDataDeepElementsOfToscaElement(componentId, EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, toscaDataListPerInst,
1589                     pathKeysPerInst, JsonPresentationFields.NAME);
1590             if (status != StorageOperationStatus.OK) {
1591                 log.debug("Failed to update component instance inputs for instance {} in component {} edge type {} error {}",
1592                     inputsPerIntance.getKey(), componentId, EdgeLabelEnum.INST_INPUTS, status);
1593                 return Either.right(status);
1594             }
1595         }
1596         return Either.left(instInputs);
1597     }
1598
1599     /**
1600      * saves the instProps as the updated instance properties of the component container in DB
1601      */
1602     public Either<Map<String, List<ComponentInstanceProperty>>, StorageOperationStatus> updateComponentInstancePropsToComponent(
1603         Map<String, List<ComponentInstanceProperty>> instProps, String componentId) {
1604         if (instProps == null || instProps.isEmpty()) {
1605             return Either.left(instProps);
1606         }
1607         StorageOperationStatus status;
1608         for (Entry<String, List<ComponentInstanceProperty>> propsPerIntance : instProps.entrySet()) {
1609             List<ComponentInstanceProperty> toscaDataListPerInst = propsPerIntance.getValue();
1610             List<String> pathKeysPerInst = new ArrayList<>();
1611             pathKeysPerInst.add(propsPerIntance.getKey());
1612             status = topologyTemplateOperation
1613                 .updateToscaDataDeepElementsOfToscaElement(componentId, EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES,
1614                     toscaDataListPerInst, pathKeysPerInst, JsonPresentationFields.NAME);
1615             if (status != StorageOperationStatus.OK) {
1616                 log.debug("Failed to update component instance inputs for instance {} in component {} edge type {} error {}",
1617                     propsPerIntance.getKey(), componentId, EdgeLabelEnum.INST_PROPERTIES, status);
1618                 return Either.right(status);
1619             }
1620         }
1621         return Either.left(instProps);
1622     }
1623
1624     public Either<Map<String, List<ComponentInstanceInput>>, StorageOperationStatus> associateComponentInstanceInputsToComponent(
1625         Map<String, List<ComponentInstanceInput>> instInputs, String componentId) {
1626         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
1627         if (getVertexEither.isRight()) {
1628             log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
1629             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value()));
1630         }
1631         GraphVertex vertex = getVertexEither.left().value();
1632         Map<String, MapPropertiesDataDefinition> instPropsMap = new HashMap<>();
1633         if (instInputs != null) {
1634             MapPropertiesDataDefinition propertiesMap;
1635             for (Entry<String, List<ComponentInstanceInput>> entry : instInputs.entrySet()) {
1636                 propertiesMap = new MapPropertiesDataDefinition();
1637                 propertiesMap.setMapToscaDataDefinition(
1638                     entry.getValue().stream().map(PropertyDataDefinition::new).collect(Collectors.toMap(PropertyDataDefinition::getName, e -> e)));
1639                 instPropsMap.put(entry.getKey(), propertiesMap);
1640             }
1641         }
1642         StorageOperationStatus status = topologyTemplateOperation.associateInstInputsToComponent(vertex, instPropsMap);
1643         if (StorageOperationStatus.OK == status) {
1644             log.debug(COMPONENT_CREATED_SUCCESSFULLY);
1645             return Either.left(instInputs);
1646         }
1647         return Either.right(status);
1648     }
1649
1650     public Either<Map<String, MapInterfaceDataDefinition>, StorageOperationStatus> associateComponentInstanceInterfacesToComponent(
1651         Map<String, Map<String, InterfaceDefinition>> instInterfaces,
1652         String componentId
1653     ) {
1654         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao.getVertexById(
1655             componentId,
1656             JsonParseFlagEnum.NoParse
1657         );
1658         if (getVertexEither.isRight()) {
1659             log.debug(
1660                 COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR,
1661                 componentId,
1662                 getVertexEither.right().value()
1663             );
1664             return Either.right(
1665                 DaoStatusConverter.convertJanusGraphStatusToStorageStatus(
1666                     getVertexEither.right().value()
1667                 )
1668             );
1669         }
1670         GraphVertex vertex = getVertexEither.left().value();
1671         Map<String, MapInterfaceDataDefinition> instInterfacesMap = new HashMap<>();
1672         if (instInterfaces != null) {
1673
1674             for (Map.Entry<String, Map<String, InterfaceDefinition>> entryInstances : instInterfaces.entrySet()) {
1675                 Map<String, InterfaceDataDefinition> incomingInterfacesMap = entryInstances.getValue().entrySet().stream()
1676                     .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()));
1677                 MapInterfaceDataDefinition interfacesMap = new MapInterfaceDataDefinition();
1678                 interfacesMap.setMapToscaDataDefinition(incomingInterfacesMap);
1679                 instInterfacesMap.put(entryInstances.getKey(), interfacesMap);
1680             }
1681         }
1682         StorageOperationStatus status = topologyTemplateOperation.associateInstInterfacesToComponent(
1683             vertex,
1684             instInterfacesMap
1685         );
1686         if (StorageOperationStatus.OK == status) {
1687             log.debug(COMPONENT_CREATED_SUCCESSFULLY);
1688             return Either.left(instInterfacesMap);
1689         }
1690         return Either.right(status);
1691     }
1692
1693     public Either<Map<String, List<ComponentInstanceInput>>, StorageOperationStatus> addComponentInstanceInputsToComponent(
1694         Component containerComponent, Map<String, List<ComponentInstanceInput>> instProperties) {
1695         requireNonNull(instProperties);
1696         StorageOperationStatus status;
1697         for (Entry<String, List<ComponentInstanceInput>> entry : instProperties.entrySet()) {
1698             List<ComponentInstanceInput> props = entry.getValue();
1699             String componentInstanceId = entry.getKey();
1700             if (!isEmpty(props)) {
1701                 for (ComponentInstanceInput property : props) {
1702                     List<ComponentInstanceInput> componentInstancesInputs = containerComponent.getComponentInstancesInputs().get(componentInstanceId);
1703                     Optional<ComponentInstanceInput> instanceProperty = componentInstancesInputs.stream()
1704                         .filter(p -> p.getName().equals(property.getName())).findAny();
1705                     if (instanceProperty.isPresent()) {
1706                         status = updateComponentInstanceInput(containerComponent, componentInstanceId, property);
1707                     } else {
1708                         status = addComponentInstanceInput(containerComponent, componentInstanceId, property);
1709                     }
1710                     if (status != StorageOperationStatus.OK) {
1711                         log.debug("Failed to update instance input {} for instance {} error {} ", property, componentInstanceId, status);
1712                         return Either.right(status);
1713                     } else {
1714                         log.trace("instance input {} for instance {} updated", property, componentInstanceId);
1715                     }
1716                 }
1717             }
1718         }
1719         return Either.left(instProperties);
1720     }
1721
1722     public Either<Map<String, List<ComponentInstanceOutput>>, StorageOperationStatus> addComponentInstanceOutputsToComponent(
1723         Component containerComponent, Map<String, List<ComponentInstanceOutput>> instOutputs) {
1724         requireNonNull(instOutputs);
1725         StorageOperationStatus status;
1726         for (final Entry<String, List<ComponentInstanceOutput>> entry : instOutputs.entrySet()) {
1727             final List<ComponentInstanceOutput> outputs = entry.getValue();
1728             final String componentInstanceId = entry.getKey();
1729             if (!isEmpty(outputs)) {
1730                 for (final ComponentInstanceOutput output : outputs) {
1731                     final List<ComponentInstanceOutput> componentInstanceOutputs = containerComponent.getComponentInstancesOutputs()
1732                         .get(componentInstanceId);
1733                     final Optional<ComponentInstanceOutput> componentInstanceOutput = componentInstanceOutputs.stream()
1734                         .filter(p -> p.getName().equals(output.getName())).findAny();
1735                     if (componentInstanceOutput.isPresent()) {
1736                         status = updateComponentInstanceOutput(containerComponent, componentInstanceId, output);
1737                     } else {
1738                         status = addComponentInstanceOutput(containerComponent, componentInstanceId, output);
1739                     }
1740                     if (status != StorageOperationStatus.OK) {
1741                         log.debug("Failed to update instance output {} for instance {} error {} ", output, componentInstanceId, status);
1742                         return Either.right(status);
1743                     } else {
1744                         log.trace("instance output {} for instance {} updated", output, componentInstanceId);
1745                     }
1746                 }
1747             }
1748         }
1749         return Either.left(instOutputs);
1750     }
1751
1752     public Either<Map<String, List<ComponentInstanceProperty>>, StorageOperationStatus> addComponentInstancePropertiesToComponent(
1753         Component containerComponent, Map<String, List<ComponentInstanceProperty>> instProperties) {
1754         requireNonNull(instProperties);
1755         for (Entry<String, List<ComponentInstanceProperty>> entry : instProperties.entrySet()) {
1756             List<ComponentInstanceProperty> props = entry.getValue();
1757             String componentInstanceId = entry.getKey();
1758             List<ComponentInstanceProperty> originalComponentInstProps = containerComponent.getComponentInstancesProperties()
1759                 .get(componentInstanceId);
1760             Map<String, List<CapabilityDefinition>> containerComponentCapabilities = containerComponent.getCapabilities();
1761             if (isEmpty(props)) {
1762                 continue;
1763             }
1764             for (ComponentInstanceProperty property : props) {
1765                 StorageOperationStatus status = null;
1766                 String propertyParentUniqueId = property.getParentUniqueId();
1767                 Optional<CapabilityDefinition> capPropDefinition = getPropertyCapability(propertyParentUniqueId, containerComponent);
1768                 if (capPropDefinition.isPresent() && MapUtils.isNotEmpty(containerComponentCapabilities)) {
1769                     status = populateAndUpdateInstanceCapProperty(containerComponent, componentInstanceId, containerComponentCapabilities, property,
1770                         capPropDefinition.get());
1771                 }
1772                 if (status == null) {
1773                     status = updateOrAddComponentInstanceProperty(containerComponent, componentInstanceId, originalComponentInstProps, property);
1774                 }
1775                 if (status != StorageOperationStatus.OK) {
1776                     return Either.right(status);
1777                 }
1778             }
1779         }
1780         return Either.left(instProperties);
1781     }
1782
1783     public Either<Map<String, List<ComponentInstanceAttribute>>, StorageOperationStatus> addComponentInstanceAttributesToComponent(
1784         final Component containerComponent, final Map<String, List<ComponentInstanceAttribute>> instProperties) {
1785         requireNonNull(instProperties);
1786         for (final Entry<String, List<ComponentInstanceAttribute>> entry : instProperties.entrySet()) {
1787             final List<ComponentInstanceAttribute> props = entry.getValue();
1788             if (isEmpty(props)) {
1789                 continue;
1790             }
1791             final String componentInstanceId = entry.getKey();
1792             final List<ComponentInstanceAttribute> originalComponentInstProps = containerComponent.getComponentInstancesAttributes()
1793                 .get(componentInstanceId);
1794             for (final ComponentInstanceAttribute property : props) {
1795                 final StorageOperationStatus status = updateOrAddComponentInstanceAttribute(containerComponent, componentInstanceId,
1796                     originalComponentInstProps, property);
1797                 if (status != StorageOperationStatus.OK) {
1798                     return Either.right(status);
1799                 }
1800             }
1801         }
1802         return Either.left(instProperties);
1803     }
1804
1805     private StorageOperationStatus populateAndUpdateInstanceCapProperty(Component containerComponent, String componentInstanceId,
1806                                                                         Map<String, List<CapabilityDefinition>> containerComponentCapabilities,
1807                                                                         ComponentInstanceProperty property,
1808                                                                         CapabilityDefinition capabilityDefinition) {
1809         List<CapabilityDefinition> capabilityDefinitions = containerComponentCapabilities.get(capabilityDefinition.getType());
1810         if (CollectionUtils.isEmpty(capabilityDefinitions)) {
1811             return null;
1812         }
1813         Optional<CapabilityDefinition> capDefToGetProp = capabilityDefinitions.stream()
1814             .filter(cap -> cap.getUniqueId().equals(capabilityDefinition.getUniqueId()) && cap.getPath().size() == 1).findAny();
1815         if (capDefToGetProp.isPresent()) {
1816             return updateInstanceCapabilityProperty(containerComponent, componentInstanceId, property, capDefToGetProp.get());
1817         }
1818         return null;
1819     }
1820
1821     private StorageOperationStatus updateOrAddComponentInstanceProperty(Component containerComponent, String componentInstanceId,
1822                                                                         List<ComponentInstanceProperty> originalComponentInstProps,
1823                                                                         ComponentInstanceProperty property) {
1824         StorageOperationStatus status;
1825         // check if the property already exists or not
1826         Optional<ComponentInstanceProperty> instanceProperty = originalComponentInstProps.stream()
1827             .filter(p -> p.getUniqueId().equals(property.getUniqueId())).findAny();
1828         if (instanceProperty.isPresent()) {
1829             status = updateComponentInstanceProperty(containerComponent, componentInstanceId, property);
1830         } else {
1831             status = addComponentInstanceProperty(containerComponent, componentInstanceId, property);
1832         }
1833         if (status != StorageOperationStatus.OK) {
1834             log.debug("Failed to update instance property {} for instance {} error {} ", property, componentInstanceId, status);
1835         }
1836         return status;
1837     }
1838
1839     private StorageOperationStatus updateOrAddComponentInstanceAttribute(Component containerComponent, String componentInstanceId,
1840                                                                          List<ComponentInstanceAttribute> originalComponentInstProps,
1841                                                                          ComponentInstanceAttribute property) {
1842         StorageOperationStatus status;
1843         // check if the property already exists or not
1844         Optional<ComponentInstanceAttribute> instanceProperty = originalComponentInstProps.stream()
1845             .filter(p -> p.getUniqueId().equals(property.getUniqueId())).findAny();
1846         if (instanceProperty.isPresent()) {
1847             status = updateComponentInstanceAttribute(containerComponent, componentInstanceId, property);
1848         } else {
1849             status = addComponentInstanceAttribute(containerComponent, componentInstanceId, property);
1850         }
1851         if (status != StorageOperationStatus.OK) {
1852             log.debug("Failed to update instance property {} for instance {} error {} ", property, componentInstanceId, status);
1853         }
1854         return status;
1855     }
1856
1857     public StorageOperationStatus updateInstanceCapabilityProperty(Component containerComponent, String componentInstanceId,
1858                                                                    ComponentInstanceProperty property, CapabilityDefinition capabilityDefinition) {
1859         Optional<ComponentInstance> fetchedCIOptional = containerComponent.getComponentInstanceById(componentInstanceId);
1860         if (!fetchedCIOptional.isPresent()) {
1861             return StorageOperationStatus.GENERAL_ERROR;
1862         }
1863         Either<Component, StorageOperationStatus> getComponentRes = getToscaFullElement(fetchedCIOptional.get().getComponentUid());
1864         if (getComponentRes.isRight()) {
1865             return StorageOperationStatus.GENERAL_ERROR;
1866         }
1867         Optional<Component> componentOptional = isNodeServiceProxy(getComponentRes.left().value());
1868         String propOwner;
1869         if (!componentOptional.isPresent()) {
1870             propOwner = componentInstanceId;
1871         } else {
1872             propOwner = fetchedCIOptional.get().getSourceModelUid();
1873         }
1874         StorageOperationStatus status;
1875         StringBuilder sb = new StringBuilder(componentInstanceId);
1876         sb.append(ModelConverter.CAP_PROP_DELIM).append(propOwner).append(ModelConverter.CAP_PROP_DELIM).append(capabilityDefinition.getType())
1877             .append(ModelConverter.CAP_PROP_DELIM).append(capabilityDefinition.getName());
1878         String capKey = sb.toString();
1879         status = updateComponentInstanceCapabiltyProperty(containerComponent, componentInstanceId, capKey, property);
1880         if (status != StorageOperationStatus.OK) {
1881             log.debug("Failed to update instance capability property {} for instance {} error {} ", property, componentInstanceId, status);
1882             return status;
1883         }
1884         return StorageOperationStatus.OK;
1885     }
1886
1887     private Optional<Component> isNodeServiceProxy(Component component) {
1888         if (component.getComponentType().equals(ComponentTypeEnum.SERVICE)) {
1889             return Optional.empty();
1890         }
1891         Resource resource = (Resource) component;
1892         ResourceTypeEnum resType = resource.getResourceType();
1893         if (resType.equals(ResourceTypeEnum.ServiceProxy)) {
1894             return Optional.of(component);
1895         }
1896         return Optional.empty();
1897     }
1898
1899     public StorageOperationStatus associateCapabilitiesToService(Map<String, ListCapabilityDataDefinition> capabilities, String componentId) {
1900         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
1901         if (getVertexEither.isRight()) {
1902             log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
1903             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value());
1904         }
1905         GraphVertex vertex = getVertexEither.left().value();
1906         if (MapUtils.isNotEmpty(capabilities)) {
1907             Either<GraphVertex, StorageOperationStatus> associateElementToData = topologyTemplateOperation
1908                 .associateElementToData(vertex, VertexTypeEnum.CAPABILITIES, EdgeLabelEnum.CAPABILITIES, capabilities);
1909             if (associateElementToData.isRight()) {
1910                 return associateElementToData.right().value();
1911             }
1912         }
1913         return StorageOperationStatus.OK;
1914     }
1915
1916     public StorageOperationStatus associateRequirementsToService(Map<String, ListRequirementDataDefinition> requirements, String componentId) {
1917         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
1918         if (getVertexEither.isRight()) {
1919             log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
1920             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value());
1921         }
1922         GraphVertex vertex = getVertexEither.left().value();
1923         if (MapUtils.isNotEmpty(requirements)) {
1924             Either<GraphVertex, StorageOperationStatus> associateElementToData = topologyTemplateOperation
1925                 .associateElementToData(vertex, VertexTypeEnum.REQUIREMENTS, EdgeLabelEnum.REQUIREMENTS, requirements);
1926             if (associateElementToData.isRight()) {
1927                 return associateElementToData.right().value();
1928             }
1929         }
1930         return StorageOperationStatus.OK;
1931     }
1932
1933     public StorageOperationStatus associateDeploymentArtifactsToInstances(Map<String, Map<String, ArtifactDefinition>> instDeploymentArtifacts,
1934                                                                           Component component, User user) {
1935         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao
1936             .getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
1937         if (getVertexEither.isRight()) {
1938             log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, component.getUniqueId(), getVertexEither.right().value());
1939             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value());
1940         }
1941         GraphVertex vertex = getVertexEither.left().value();
1942         Map<String, MapArtifactDataDefinition> instArtMap = new HashMap<>();
1943         if (instDeploymentArtifacts != null) {
1944             MapArtifactDataDefinition artifactsMap;
1945             for (Entry<String, Map<String, ArtifactDefinition>> entry : instDeploymentArtifacts.entrySet()) {
1946                 Map<String, ArtifactDefinition> artList = entry.getValue();
1947                 Map<String, ArtifactDataDefinition> artifacts = artList.entrySet().stream()
1948                     .collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDataDefinition(e.getValue())));
1949                 artifactsMap = nodeTemplateOperation
1950                     .prepareInstDeploymentArtifactPerInstance(artifacts, entry.getKey(), user, NodeTemplateOperation.HEAT_VF_ENV_NAME);
1951                 instArtMap.put(entry.getKey(), artifactsMap);
1952             }
1953         }
1954         ModelConverter.setComponentInstancesDeploymentArtifactsToComponent(instArtMap, component);
1955         return topologyTemplateOperation.associateInstDeploymentArtifactsToComponent(vertex, instArtMap);
1956     }
1957
1958     public StorageOperationStatus associateArtifactsToInstances(Map<String, Map<String, ArtifactDefinition>> instArtifacts, Component component) {
1959         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao
1960             .getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
1961         if (getVertexEither.isRight()) {
1962             log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, component.getUniqueId(), getVertexEither.right().value());
1963             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value());
1964         }
1965         GraphVertex vertex = getVertexEither.left().value();
1966         Map<String, MapArtifactDataDefinition> instArtMap = new HashMap<>();
1967         if (instArtifacts != null) {
1968             MapArtifactDataDefinition artifactsMap;
1969             for (Entry<String, Map<String, ArtifactDefinition>> entry : instArtifacts.entrySet()) {
1970                 Map<String, ArtifactDefinition> artList = entry.getValue();
1971                 Map<String, ArtifactDataDefinition> artifacts = artList.entrySet().stream()
1972                     .collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDataDefinition(e.getValue())));
1973                 artifactsMap = new MapArtifactDataDefinition(artifacts);
1974                 instArtMap.put(entry.getKey(), artifactsMap);
1975             }
1976         }
1977         ModelConverter.setComponentInstancesInformationalArtifactsToComponent(instArtMap, component);
1978         return topologyTemplateOperation.associateInstArtifactsToComponent(vertex, instArtMap);
1979     }
1980
1981     public StorageOperationStatus associateInstAttributeToComponentToInstances(Map<String, List<AttributeDefinition>> instArttributes,
1982                                                                                Component component) {
1983         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao
1984             .getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
1985         if (getVertexEither.isRight()) {
1986             log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, component.getUniqueId(), getVertexEither.right().value());
1987             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value());
1988         }
1989         GraphVertex vertex = getVertexEither.left().value();
1990         Map<String, MapAttributesDataDefinition> instAttr = new HashMap<>();
1991         if (instArttributes != null) {
1992             MapAttributesDataDefinition attributesMap;
1993             for (Entry<String, List<AttributeDefinition>> entry : instArttributes.entrySet()) {
1994                 final List<AttributeDefinition> value = entry.getValue();
1995                 attributesMap = new MapAttributesDataDefinition();
1996                 attributesMap.setMapToscaDataDefinition(
1997                     value.stream().map(AttributeDefinition::new).collect(Collectors.toMap(AttributeDefinition::getName, e -> e)));
1998                 instAttr.put(entry.getKey(), attributesMap);
1999             }
2000         }
2001         setComponentInstanceAttributesOnComponent(component, instAttr);
2002         return topologyTemplateOperation.associateInstAttributeToComponent(vertex, instAttr);
2003     }
2004
2005     // endregion
2006     private void setComponentInstanceAttributesOnComponent(Component resource, Map<String, MapAttributesDataDefinition> instAttr) {
2007         Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes = resource.getComponentInstancesAttributes();
2008         if (componentInstancesAttributes == null) {
2009             componentInstancesAttributes = new HashMap<>();
2010         }
2011         componentInstancesAttributes.putAll(ModelConverter.getComponentInstancesAttributes(instAttr));
2012         resource.setComponentInstancesAttributes(componentInstancesAttributes);
2013     }
2014
2015     public StorageOperationStatus associateOrAddCalculatedCapReq(Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilties,
2016                                                                  Map<ComponentInstance, Map<String, List<RequirementDefinition>>> instReg,
2017                                                                  Component component) {
2018         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao
2019             .getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
2020         if (getVertexEither.isRight()) {
2021             log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, component.getUniqueId(), getVertexEither.right().value());
2022             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value());
2023         }
2024         GraphVertex vertex = getVertexEither.left().value();
2025         Map<String, MapListRequirementDataDefinition> calcRequirements = new HashMap<>();
2026         Map<String, MapListCapabilityDataDefinition> calcCapabilty = new HashMap<>();
2027         Map<String, MapCapabilityProperty> calculatedCapabilitiesProperties = new HashMap<>();
2028         if (instCapabilties != null) {
2029             for (Entry<ComponentInstance, Map<String, List<CapabilityDefinition>>> entry : instCapabilties.entrySet()) {
2030                 Map<String, List<CapabilityDefinition>> caps = entry.getValue();
2031                 Map<String, ListCapabilityDataDefinition> mapToscaDataDefinition = new HashMap<>();
2032                 for (Entry<String, List<CapabilityDefinition>> instCapability : caps.entrySet()) {
2033                     mapToscaDataDefinition.put(instCapability.getKey(), new ListCapabilityDataDefinition(
2034                         instCapability.getValue().stream().map(CapabilityDataDefinition::new).collect(Collectors.toList())));
2035                 }
2036                 ComponentInstanceDataDefinition componentInstance = new ComponentInstanceDataDefinition(entry.getKey());
2037                 MapListCapabilityDataDefinition capMap = nodeTemplateOperation
2038                     .prepareCalculatedCapabiltyForNodeType(mapToscaDataDefinition, componentInstance);
2039                 MapCapabilityProperty mapCapabilityProperty = ModelConverter
2040                     .convertToMapOfMapCapabiltyProperties(caps, componentInstance.getUniqueId(), true);
2041                 calcCapabilty.put(entry.getKey().getUniqueId(), capMap);
2042                 calculatedCapabilitiesProperties.put(entry.getKey().getUniqueId(), mapCapabilityProperty);
2043             }
2044         }
2045         if (instReg != null) {
2046             for (Entry<ComponentInstance, Map<String, List<RequirementDefinition>>> entry : instReg.entrySet()) {
2047                 Map<String, List<RequirementDefinition>> req = entry.getValue();
2048                 Map<String, ListRequirementDataDefinition> mapToscaDataDefinition = new HashMap<>();
2049                 for (Entry<String, List<RequirementDefinition>> instReq : req.entrySet()) {
2050                     mapToscaDataDefinition.put(instReq.getKey(), new ListRequirementDataDefinition(
2051                         instReq.getValue().stream().map(RequirementDataDefinition::new).collect(Collectors.toList())));
2052                 }
2053                 MapListRequirementDataDefinition reqMap = nodeTemplateOperation
2054                     .prepareCalculatedRequirementForNodeType(mapToscaDataDefinition, new ComponentInstanceDataDefinition(entry.getKey()));
2055                 String componentInstanceId = entry.getKey().getUniqueId();
2056                 calcRequirements.put(componentInstanceId, reqMap);
2057             }
2058         }
2059         StorageOperationStatus storageOperationStatus = topologyTemplateOperation
2060             .associateOrAddCalcCapReqToComponent(vertex, calcRequirements, calcCapabilty, calculatedCapabilitiesProperties);
2061         updateInstancesCapAndReqOnComponentFromDB(component);
2062         return storageOperationStatus;
2063     }
2064
2065     public StorageOperationStatus updateCalculatedCapabilitiesRequirements(
2066         final Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilties,
2067         final Map<ComponentInstance, Map<String, List<RequirementDefinition>>> instReg,
2068         final Component component) {
2069         StorageOperationStatus storageOperationStatus = StorageOperationStatus.OK;
2070         if (instCapabilties != null) {
2071             for (Entry<ComponentInstance, Map<String, List<CapabilityDefinition>>> entry : instCapabilties.entrySet()) {
2072                 final Map<String, List<CapabilityDefinition>> cap = entry.getValue();
2073                 for (List<CapabilityDefinition> capabilityList : cap.values()) {
2074                     for (CapabilityDefinition capability : capabilityList) {
2075                         nodeTemplateOperation.updateComponentInstanceCapabilities(component.getUniqueId(), entry.getKey().getUniqueId(), capability);
2076                     }
2077                 }
2078             }
2079         }
2080         if (instReg != null) {
2081             for (Entry<ComponentInstance, Map<String, List<RequirementDefinition>>> entry : instReg.entrySet()) {
2082                 final Map<String, List<RequirementDefinition>> req = entry.getValue();
2083                 for (List<RequirementDefinition> requirementList : req.values()) {
2084                     for (RequirementDefinition requirement : requirementList) {
2085                         storageOperationStatus = nodeTemplateOperation.updateComponentInstanceRequirement(component.getUniqueId(),
2086                             entry.getKey().getUniqueId(), requirement);
2087                         if (storageOperationStatus != StorageOperationStatus.OK) {
2088                             return storageOperationStatus;
2089                         }
2090                     }
2091                 }
2092             }
2093         }
2094         return storageOperationStatus;
2095     }
2096
2097     private void updateInstancesCapAndReqOnComponentFromDB(Component component) {
2098         ComponentParametersView componentParametersView = new ComponentParametersView(true);
2099         componentParametersView.setIgnoreCapabilities(false);
2100         componentParametersView.setIgnoreRequirements(false);
2101         componentParametersView.setIgnoreCapabiltyProperties(false);
2102         componentParametersView.setIgnoreComponentInstances(false);
2103         Either<Component, StorageOperationStatus> componentEither = getToscaElement(component.getUniqueId(), componentParametersView);
2104         if (componentEither.isRight()) {
2105             throw new StorageException(StorageOperationStatus.NOT_FOUND);
2106         }
2107         Component updatedComponent = componentEither.left().value();
2108         component.setCapabilities(updatedComponent.getCapabilities());
2109         component.setRequirements(updatedComponent.getRequirements());
2110         component.setComponentInstancesRelations(updatedComponent.getComponentInstancesRelations());
2111         component.setComponentInstances(updatedComponent.getComponentInstances());
2112     }
2113
2114     private Either<List<Service>, StorageOperationStatus> getLatestVersionNonCheckoutServicesMetadataOnly(Map<GraphPropertyEnum, Object> hasProps,
2115                                                                                                           Map<GraphPropertyEnum, Object> hasNotProps,
2116                                                                                                           String modelName) {
2117         List<Service> services = new ArrayList<>();
2118         List<LifecycleStateEnum> states = new ArrayList<>();
2119         // include props
2120         hasProps.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.SERVICE.name());
2121         hasProps.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
2122         if (modelName != null) {
2123             hasProps.put(GraphPropertyEnum.MODEL, modelName);
2124         }
2125         // exclude props
2126         states.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
2127         hasNotProps.put(GraphPropertyEnum.STATE, states);
2128         hasNotProps.put(GraphPropertyEnum.IS_DELETED, true);
2129         hasNotProps.put(GraphPropertyEnum.IS_ARCHIVED, true);
2130         return fetchServicesByCriteria(services, hasProps, hasNotProps, modelName);
2131     }
2132
2133     private Either<List<Component>, StorageOperationStatus> getLatestVersionNotAbstractToscaElementsMetadataOnly(final boolean isAbstract,
2134                                                                                                                  final ComponentTypeEnum componentTypeEnum,
2135                                                                                                                  final String internalComponentType,
2136                                                                                                                  final VertexTypeEnum vertexType,
2137                                                                                                                  final String modelName,
2138                                                                                                                  final boolean includeNormativeExtensionModels) {
2139         List<Service> services = null;
2140         Map<GraphPropertyEnum, Object> hasProps = new EnumMap<>(GraphPropertyEnum.class);
2141         Map<GraphPropertyEnum, Object> hasNotProps = new EnumMap<>(GraphPropertyEnum.class);
2142         fillPropsMap(hasProps, hasNotProps, internalComponentType, componentTypeEnum, isAbstract, vertexType, modelName);
2143         Either<List<GraphVertex>, JanusGraphOperationStatus> getRes = janusGraphDao
2144             .getByCriteria(vertexType, hasProps, hasNotProps, JsonParseFlagEnum.ParseMetadata, modelName, includeNormativeExtensionModels);
2145         if (getRes.isRight() && !JanusGraphOperationStatus.NOT_FOUND.equals(getRes.right().value())) {
2146             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getRes.right().value()));
2147         }
2148         // region -> Fetch non checked-out services
2149         if (internalComponentType != null && internalComponentType.toLowerCase().trim().equals(SERVICE) && VertexTypeEnum.NODE_TYPE == vertexType) {
2150             Either<List<Service>, StorageOperationStatus> result = getLatestVersionNonCheckoutServicesMetadataOnly(
2151                 new EnumMap<>(GraphPropertyEnum.class), new EnumMap<>(GraphPropertyEnum.class), modelName);
2152             if (result.isRight()) {
2153                 log.debug("Failed to fetch services for");
2154                 return Either.right(result.right().value());
2155             }
2156             services = result.left().value();
2157             if (log.isTraceEnabled() && isEmpty(services)) {
2158                 log.trace("No relevant services available");
2159             }
2160         }
2161         // endregion
2162         List<Component> nonAbstractLatestComponents = new ArrayList<>();
2163         ComponentParametersView params = new ComponentParametersView(true);
2164         params.setIgnoreAllVersions(false);
2165         if (getRes.isLeft()) {
2166             for (GraphVertex vertexComponent : getRes.left().value()) {
2167                 Either<ToscaElement, StorageOperationStatus> componentRes = topologyTemplateOperation
2168                     .getLightComponent(vertexComponent, componentTypeEnum, params);
2169                 if (componentRes.isRight()) {
2170                     log.debug("Failed to fetch light element for {} error {}", vertexComponent.getUniqueId(), componentRes.right().value());
2171                     return Either.right(componentRes.right().value());
2172                 } else {
2173                     Component component = ModelConverter.convertFromToscaElement(componentRes.left().value());
2174                     nonAbstractLatestComponents.add(component);
2175                 }
2176             }
2177         }
2178         if (CollectionUtils.isNotEmpty(services)) {
2179             nonAbstractLatestComponents.addAll(services);
2180         }
2181         return Either.left(nonAbstractLatestComponents);
2182     }
2183
2184     public Either<ComponentMetadataData, StorageOperationStatus> getLatestComponentMetadataByUuid(String componentUuid, JsonParseFlagEnum parseFlag,
2185                                                                                                   Boolean isHighest) {
2186         Either<ComponentMetadataData, StorageOperationStatus> result;
2187         Map<GraphPropertyEnum, Object> hasProperties = new EnumMap<>(GraphPropertyEnum.class);
2188         hasProperties.put(GraphPropertyEnum.UUID, componentUuid);
2189         if (isHighest != null) {
2190             hasProperties.put(GraphPropertyEnum.IS_HIGHEST_VERSION, isHighest);
2191         }
2192         Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
2193         propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
2194         propertiesNotToMatch.put(GraphPropertyEnum.IS_ARCHIVED, true); //US382674, US382683
2195         Either<List<GraphVertex>, JanusGraphOperationStatus> getRes = janusGraphDao
2196             .getByCriteria(null, hasProperties, propertiesNotToMatch, parseFlag);
2197         if (getRes.isRight()) {
2198             result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getRes.right().value()));
2199         } else {
2200             List<ComponentMetadataData> latestVersionList = getRes.left().value().stream().map(ModelConverter::convertToComponentMetadata)
2201                 .collect(Collectors.toList());
2202             ComponentMetadataData latestVersion = latestVersionList.size() == 1 ? latestVersionList.get(0) : latestVersionList.stream().max(
2203                 (c1, c2) -> Double.compare(Double.parseDouble(c1.getMetadataDataDefinition().getVersion()),
2204                     Double.parseDouble(c2.getMetadataDataDefinition().getVersion()))).get();
2205             result = Either.left(latestVersion);
2206         }
2207         return result;
2208     }
2209
2210     public Either<ComponentMetadataData, StorageOperationStatus> getComponentMetadata(String componentId) {
2211         Either<ComponentMetadataData, StorageOperationStatus> result;
2212         Either<GraphVertex, JanusGraphOperationStatus> getRes = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata);
2213         if (getRes.isRight()) {
2214             result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getRes.right().value()));
2215         } else {
2216             ComponentMetadataData componentMetadata = ModelConverter.convertToComponentMetadata(getRes.left().value());
2217             result = Either.left(componentMetadata);
2218         }
2219         return result;
2220     }
2221
2222     public Either<List<Component>, StorageOperationStatus> getLatestVersionNotAbstractComponents(boolean isAbstract,
2223                                                                                                  ComponentTypeEnum componentTypeEnum,
2224                                                                                                  String internalComponentType,
2225                                                                                                  List<String> componentUids) {
2226         List<Component> components = new ArrayList<>();
2227         if (componentUids == null) {
2228             Either<List<String>, StorageOperationStatus> componentUidsRes = getComponentUids(isAbstract, componentTypeEnum, internalComponentType);
2229             if (componentUidsRes.isRight()) {
2230                 return Either.right(componentUidsRes.right().value());
2231             }
2232             componentUids = componentUidsRes.left().value();
2233         }
2234         if (!isEmpty(componentUids)) {
2235             for (String componentUid : componentUids) {
2236                 ComponentParametersView componentParametersView = buildComponentViewForNotAbstract();
2237                 if ("vl".equalsIgnoreCase(internalComponentType)) {
2238                     componentParametersView.setIgnoreCapabilities(false);
2239                     componentParametersView.setIgnoreRequirements(false);
2240                 }
2241                 Either<ToscaElement, StorageOperationStatus> getToscaElementRes = nodeTemplateOperation.getToscaElementOperation(componentTypeEnum)
2242                     .getLightComponent(componentUid, componentTypeEnum, componentParametersView);
2243                 if (getToscaElementRes.isRight()) {
2244                     log.debug("Failed to fetch resource for error is {}", getToscaElementRes.right().value());
2245                     return Either.right(getToscaElementRes.right().value());
2246                 }
2247                 Component component = ModelConverter.convertFromToscaElement(getToscaElementRes.left().value());
2248                 nullifySomeComponentProperties(component);
2249                 components.add(component);
2250             }
2251         }
2252         return Either.left(components);
2253     }
2254
2255     public void nullifySomeComponentProperties(Component component) {
2256         component.setContactId(null);
2257         component.setCreationDate(null);
2258         component.setCreatorUserId(null);
2259         component.setCreatorFullName(null);
2260         component.setLastUpdateDate(null);
2261         component.setLastUpdaterUserId(null);
2262         component.setLastUpdaterFullName(null);
2263         component.setNormalizedName(null);
2264     }
2265
2266     private Either<List<String>, StorageOperationStatus> getComponentUids(boolean isAbstract, ComponentTypeEnum componentTypeEnum,
2267                                                                           String internalComponentType) {
2268         Either<List<Component>, StorageOperationStatus> getToscaElementsRes = getLatestVersionNotAbstractMetadataOnly(isAbstract, componentTypeEnum,
2269             internalComponentType, null, false);
2270         if (getToscaElementsRes.isRight()) {
2271             return Either.right(getToscaElementsRes.right().value());
2272         }
2273         List<Component> collection = getToscaElementsRes.left().value();
2274         List<String> componentUids;
2275         if (collection == null) {
2276             componentUids = new ArrayList<>();
2277         } else {
2278             componentUids = collection.stream().map(Component::getUniqueId).collect(Collectors.toList());
2279         }
2280         return Either.left(componentUids);
2281     }
2282
2283     private ComponentParametersView buildComponentViewForNotAbstract() {
2284         ComponentParametersView componentParametersView = new ComponentParametersView();
2285         componentParametersView.disableAll();
2286         componentParametersView.setIgnoreCategories(false);
2287         componentParametersView.setIgnoreAllVersions(false);
2288         return componentParametersView;
2289     }
2290
2291     public Either<Boolean, StorageOperationStatus> validateComponentNameExists(String name, ResourceTypeEnum resourceType,
2292                                                                                ComponentTypeEnum componentType) {
2293         Either<Boolean, StorageOperationStatus> result = validateComponentNameUniqueness(name, resourceType, componentType);
2294         if (result.isLeft()) {
2295             result = Either.left(!result.left().value());
2296         }
2297         return result;
2298     }
2299
2300     public Either<Boolean, StorageOperationStatus> validateComponentNameUniqueness(String name, ResourceTypeEnum resourceType,
2301                                                                                    ComponentTypeEnum componentType) {
2302         String normalizedName = ValidationUtils.normaliseComponentName(name);
2303         Either<List<GraphVertex>, JanusGraphOperationStatus> vertexEither = janusGraphDao
2304             .getByCriteria(getVertexTypeEnum(resourceType), propertiesToMatch(normalizedName, componentType), JsonParseFlagEnum.NoParse);
2305         if (vertexEither.isRight() && vertexEither.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
2306             log.debug("failed to get vertex from graph with property normalizedName: {}", normalizedName);
2307             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(vertexEither.right().value()));
2308         }
2309         return Either.left(CollectionUtils.isEmpty(vertexEither.isLeft() ? vertexEither.left().value() : null));
2310     }
2311
2312     public Either<Boolean, StorageOperationStatus> validateComponentNameAndModelExists(final String resourceName, final String model,
2313                                                                                        final ResourceTypeEnum resourceType,
2314                                                                                        final ComponentTypeEnum componentType) {
2315         Either<Boolean, StorageOperationStatus> result = validateComponentNameAndModelUniqueness(resourceName, model, resourceType, componentType);
2316         if (result.isLeft()) {
2317             result = Either.left(!result.left().value());
2318         }
2319         return result;
2320     }
2321
2322     private Either<Boolean, StorageOperationStatus> validateComponentNameAndModelUniqueness(final String resourceName, final String modelName,
2323                                                                                             final ResourceTypeEnum resourceType,
2324                                                                                             final ComponentTypeEnum componentType) {
2325         final String normalizedName = ValidationUtils.normaliseComponentName(resourceName);
2326         final Either<List<GraphVertex>, JanusGraphOperationStatus> vertexEither = janusGraphDao
2327             .getByCriteria(getVertexTypeEnum(resourceType), propertiesToMatch(normalizedName, componentType), null, null, JsonParseFlagEnum.NoParse,
2328                 modelName);
2329         if (vertexEither.isRight() && vertexEither.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
2330             log.debug("failed to get vertex from graph with property normalizedName: {} and model: {}", normalizedName, modelName);
2331             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(vertexEither.right().value()));
2332         }
2333         return Either.left(CollectionUtils.isEmpty(vertexEither.isLeft() ? vertexEither.left().value().stream()
2334             .collect(Collectors.toList()) : null));
2335     }
2336
2337     private VertexTypeEnum getVertexTypeEnum(final ResourceTypeEnum resourceType) {
2338         return ModelConverter.isAtomicComponent(resourceType) ? VertexTypeEnum.NODE_TYPE : TOPOLOGY_TEMPLATE;
2339     }
2340
2341     private Map<GraphPropertyEnum, Object> propertiesToMatch(final String normalizedName, final ComponentTypeEnum componentType) {
2342         final Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
2343         properties.put(GraphPropertyEnum.NORMALIZED_NAME, normalizedName);
2344         properties.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
2345         return properties;
2346     }
2347
2348     private void fillNodeTypePropsMap(final Map<GraphPropertyEnum, Object> hasProps, final Map<GraphPropertyEnum, Object> hasNotProps,
2349                                       final String internalComponentType, String modelName) {
2350         final Configuration configuration = ConfigurationManager.getConfigurationManager().getConfiguration();
2351         final List<String> allowedTypes;
2352         if (ComponentTypeEnum.SERVICE.getValue().equalsIgnoreCase(internalComponentType)) {
2353             allowedTypes = containerInstanceTypesData.getServiceAllowedList(modelName);
2354         } else {
2355             final ResourceTypeEnum resourceType = ResourceTypeEnum.getTypeIgnoreCase(internalComponentType);
2356             allowedTypes = containerInstanceTypesData.getComponentAllowedList(ComponentTypeEnum.RESOURCE, resourceType);
2357         }
2358         final List<String> allResourceTypes = configuration.getResourceTypes();
2359         if (allowedTypes == null) {
2360             hasNotProps.put(GraphPropertyEnum.RESOURCE_TYPE, allResourceTypes);
2361             return;
2362         }
2363         if (ResourceTypeEnum.VL.getValue().equalsIgnoreCase(internalComponentType)) {
2364             hasProps.put(GraphPropertyEnum.RESOURCE_TYPE, allowedTypes);
2365         } else {
2366             final List<String> notAllowedTypes = allResourceTypes.stream().filter(s -> !allowedTypes.contains(s)).collect(Collectors.toList());
2367             hasNotProps.put(GraphPropertyEnum.RESOURCE_TYPE, notAllowedTypes);
2368         }
2369     }
2370
2371     private void fillTopologyTemplatePropsMap(Map<GraphPropertyEnum, Object> hasProps, Map<GraphPropertyEnum, Object> hasNotProps,
2372                                               ComponentTypeEnum componentTypeEnum) {
2373         switch (componentTypeEnum) {
2374             case RESOURCE:
2375                 hasProps.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.RESOURCE.name());
2376                 break;
2377             case SERVICE:
2378                 hasProps.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.SERVICE.name());
2379                 break;
2380             default:
2381                 break;
2382         }
2383         hasNotProps.put(GraphPropertyEnum.RESOURCE_TYPE, ResourceTypeEnum.CVFC.name());
2384     }
2385
2386     private void fillPropsMap(Map<GraphPropertyEnum, Object> hasProps, Map<GraphPropertyEnum, Object> hasNotProps, String internalComponentType,
2387                               ComponentTypeEnum componentTypeEnum, boolean isAbstract, VertexTypeEnum internalVertexType, String modelName) {
2388         hasNotProps.put(GraphPropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name());
2389         hasNotProps.put(GraphPropertyEnum.IS_DELETED, true);
2390         hasNotProps.put(GraphPropertyEnum.IS_ARCHIVED, true);
2391         hasProps.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
2392
2393         if (VertexTypeEnum.NODE_TYPE == internalVertexType) {
2394             hasProps.put(GraphPropertyEnum.IS_ABSTRACT, isAbstract);
2395             if (internalComponentType != null) {
2396                 fillNodeTypePropsMap(hasProps, hasNotProps, internalComponentType, modelName);
2397             }
2398         } else {
2399             fillTopologyTemplatePropsMap(hasProps, hasNotProps, componentTypeEnum);
2400         }
2401     }
2402
2403     private List<VertexTypeEnum> getInternalVertexTypes(ComponentTypeEnum componentTypeEnum, String internalComponentType) {
2404         List<VertexTypeEnum> internalVertexTypes = new ArrayList<>();
2405         if (ComponentTypeEnum.RESOURCE == componentTypeEnum) {
2406             internalVertexTypes.add(VertexTypeEnum.NODE_TYPE);
2407         }
2408         if (ComponentTypeEnum.SERVICE == componentTypeEnum || SERVICE.equalsIgnoreCase(internalComponentType) || VF.equalsIgnoreCase(
2409             internalComponentType)) {
2410             internalVertexTypes.add(TOPOLOGY_TEMPLATE);
2411         }
2412         return internalVertexTypes;
2413     }
2414
2415     public Either<List<Component>, StorageOperationStatus> getLatestVersionNotAbstractMetadataOnly(boolean isAbstract,
2416                                                                                                    final ComponentTypeEnum componentTypeEnum,
2417                                                                                                    final String internalComponentType,
2418                                                                                                    final String modelName,
2419                                                                                                    final boolean includeNormativeExtensionModels) {
2420         List<VertexTypeEnum> internalVertexTypes = getInternalVertexTypes(componentTypeEnum, internalComponentType);
2421         List<Component> result = new ArrayList<>();
2422         for (VertexTypeEnum vertexType : internalVertexTypes) {
2423             Either<List<Component>, StorageOperationStatus> listByVertexType = getLatestVersionNotAbstractToscaElementsMetadataOnly(isAbstract,
2424                 componentTypeEnum, internalComponentType, vertexType, modelName, includeNormativeExtensionModels);
2425             if (listByVertexType.isRight()) {
2426                 return listByVertexType;
2427             }
2428             result.addAll(listByVertexType.left().value());
2429         }
2430         return Either.left(result);
2431     }
2432
2433     private Either<List<Component>, StorageOperationStatus> getLatestComponentListByUuid(String componentUuid,
2434                                                                                          Map<GraphPropertyEnum, Object> additionalPropertiesToMatch) {
2435         Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
2436         if (additionalPropertiesToMatch != null) {
2437             propertiesToMatch.putAll(additionalPropertiesToMatch);
2438         }
2439         propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
2440         return getComponentListByUuid(componentUuid, propertiesToMatch);
2441     }
2442
2443     public Either<Component, StorageOperationStatus> getComponentByUuidAndVersion(String componentUuid, String version) {
2444         Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
2445         propertiesToMatch.put(GraphPropertyEnum.UUID, componentUuid);
2446         propertiesToMatch.put(GraphPropertyEnum.VERSION, version);
2447         Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
2448         propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
2449         Either<List<GraphVertex>, JanusGraphOperationStatus> vertexEither = janusGraphDao
2450             .getByCriteria(null, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseAll);
2451         if (vertexEither.isRight()) {
2452             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(vertexEither.right().value()));
2453         }
2454         List<GraphVertex> vertexList = vertexEither.isLeft() ? vertexEither.left().value() : null;
2455         if (vertexList == null || vertexList.isEmpty() || vertexList.size() > 1) {
2456             return Either.right(StorageOperationStatus.NOT_FOUND);
2457         }
2458         return getToscaElementByOperation(vertexList.get(0));
2459     }
2460
2461     public Either<List<Component>, StorageOperationStatus> getComponentListByUuid(String componentUuid,
2462                                                                                   Map<GraphPropertyEnum, Object> additionalPropertiesToMatch) {
2463         Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
2464         if (additionalPropertiesToMatch != null) {
2465             propertiesToMatch.putAll(additionalPropertiesToMatch);
2466         }
2467         propertiesToMatch.put(GraphPropertyEnum.UUID, componentUuid);
2468         Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
2469         propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
2470         propertiesNotToMatch.put(GraphPropertyEnum.IS_ARCHIVED, true); //US382674, US382683
2471         Either<List<GraphVertex>, JanusGraphOperationStatus> vertexEither = janusGraphDao
2472             .getByCriteria(null, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseAll);
2473         if (vertexEither.isRight()) {
2474             log.debug("Couldn't fetch metadata for component with uuid {}, error: {}", componentUuid, vertexEither.right().value());
2475             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(vertexEither.right().value()));
2476         }
2477         List<GraphVertex> vertexList = vertexEither.isLeft() ? vertexEither.left().value() : null;
2478         if (vertexList == null || vertexList.isEmpty()) {
2479             log.debug("Component with uuid {} was not found", componentUuid);
2480             return Either.right(StorageOperationStatus.NOT_FOUND);
2481         }
2482         ArrayList<Component> latestComponents = new ArrayList<>();
2483         for (GraphVertex vertex : vertexList) {
2484             Either<Component, StorageOperationStatus> toscaElementByOperation = getToscaElementByOperation(vertex);
2485             if (toscaElementByOperation.isRight()) {
2486                 log.debug("Could not fetch the following Component by UUID {}", vertex.getUniqueId());
2487                 return Either.right(toscaElementByOperation.right().value());
2488             }
2489             latestComponents.add(toscaElementByOperation.left().value());
2490         }
2491         if (latestComponents.size() > 1) {
2492             for (Component component : latestComponents) {
2493                 if (Boolean.TRUE.equals(component.isHighestVersion())) {
2494                     LinkedList<Component> highestComponent = new LinkedList<>();
2495                     highestComponent.add(component);
2496                     return Either.left(highestComponent);
2497                 }
2498             }
2499         }
2500         return Either.left(latestComponents);
2501     }
2502
2503     public Either<Component, StorageOperationStatus> getLatestServiceByUuid(String serviceUuid) {
2504         Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
2505         propertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.SERVICE.name());
2506         return getLatestComponentByUuid(serviceUuid, propertiesToMatch);
2507     }
2508
2509     public Either<Component, StorageOperationStatus> getLatestComponentByUuid(String componentUuid) {
2510         return getLatestComponentByUuid(componentUuid, null);
2511     }
2512
2513     public Either<Component, StorageOperationStatus> getLatestComponentByUuid(String componentUuid,
2514                                                                               Map<GraphPropertyEnum, Object> propertiesToMatch) {
2515         Either<List<Component>, StorageOperationStatus> latestVersionListEither = getLatestComponentListByUuid(componentUuid, propertiesToMatch);
2516         if (latestVersionListEither.isRight()) {
2517             return Either.right(latestVersionListEither.right().value());
2518         }
2519         List<Component> latestVersionList = latestVersionListEither.left().value();
2520         if (latestVersionList.isEmpty()) {
2521             return Either.right(StorageOperationStatus.NOT_FOUND);
2522         }
2523         Component component = latestVersionList.size() == 1 ? latestVersionList.get(0)
2524             : latestVersionList.stream().max((c1, c2) -> Double.compare(Double.parseDouble(c1.getVersion()), Double.parseDouble(c2.getVersion())))
2525                 .get();
2526         return Either.left(component);
2527     }
2528
2529     public Either<List<Resource>, StorageOperationStatus> getAllCertifiedResources(boolean isAbstract, Boolean isHighest) {
2530         List<Resource> resources = new ArrayList<>();
2531         Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
2532         Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
2533         propertiesToMatch.put(GraphPropertyEnum.IS_ABSTRACT, isAbstract);
2534         if (isHighest != null) {
2535             propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, isHighest);
2536         }
2537         propertiesToMatch.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
2538         propertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.RESOURCE.name());
2539         propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
2540         Either<List<GraphVertex>, JanusGraphOperationStatus> getResourcesRes = janusGraphDao
2541             .getByCriteria(null, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseAll);
2542         if (getResourcesRes.isRight()) {
2543             log.debug("Failed to fetch all certified resources. Status is {}", getResourcesRes.right().value());
2544             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getResourcesRes.right().value()));
2545         }
2546         List<GraphVertex> resourceVerticies = getResourcesRes.left().value();
2547         for (GraphVertex resourceV : resourceVerticies) {
2548             Either<Resource, StorageOperationStatus> getResourceRes = getToscaElement(resourceV);
2549             if (getResourceRes.isRight()) {
2550                 return Either.right(getResourceRes.right().value());
2551             }
2552             resources.add(getResourceRes.left().value());
2553         }
2554         return Either.left(resources);
2555     }
2556
2557     public <T extends Component> Either<T, StorageOperationStatus> getLatestByNameAndVersion(String name, String version,
2558                                                                                              JsonParseFlagEnum parseFlag, String model) {
2559         Either<T, StorageOperationStatus> result;
2560         Map<GraphPropertyEnum, Object> hasProperties = new EnumMap<>(GraphPropertyEnum.class);
2561         Map<GraphPropertyEnum, Object> hasNotProperties = new EnumMap<>(GraphPropertyEnum.class);
2562         hasProperties.put(GraphPropertyEnum.NAME, name);
2563         hasProperties.put(GraphPropertyEnum.VERSION, version);
2564         hasProperties.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
2565         hasNotProperties.put(GraphPropertyEnum.IS_DELETED, true);
2566         Either<List<GraphVertex>, JanusGraphOperationStatus> getResourceRes = janusGraphDao
2567             .getByCriteria(null, hasProperties, hasNotProperties, parseFlag, model);
2568         if (getResourceRes.isRight()) {
2569             JanusGraphOperationStatus status = getResourceRes.right().value();
2570             log.debug("failed to find resource with name {}, version {}. Status is {} ", name, version, status);
2571             result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
2572             return result;
2573         }
2574         return getToscaElementByOperation(getResourceRes.left().value().get(0));
2575     }
2576
2577     public Either<Resource, StorageOperationStatus> getLatestComponentByCsarOrName(ComponentTypeEnum componentType, String csarUUID,
2578                                                                                    String systemName) {
2579         return getLatestComponentByCsarOrName(componentType, csarUUID, systemName, JsonParseFlagEnum.ParseAll);
2580     }
2581
2582     public Either<Resource, StorageOperationStatus> getLatestComponentByCsarOrName(ComponentTypeEnum componentType, String csarUUID,
2583                                                                                    String systemName, JsonParseFlagEnum parseFlag) {
2584         Map<GraphPropertyEnum, Object> props = new EnumMap<>(GraphPropertyEnum.class);
2585         Map<GraphPropertyEnum, Object> propsHasNot = new EnumMap<>(GraphPropertyEnum.class);
2586         props.put(GraphPropertyEnum.CSAR_UUID, csarUUID);
2587         props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
2588         if (componentType != null) {
2589             props.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
2590         }
2591         propsHasNot.put(GraphPropertyEnum.IS_DELETED, true);
2592         GraphVertex resourceMetadataData = null;
2593         List<GraphVertex> resourceMetadataDataList = null;
2594         Either<List<GraphVertex>, JanusGraphOperationStatus> byCsar = janusGraphDao
2595             .getByCriteria(null, props, propsHasNot, JsonParseFlagEnum.ParseMetadata);
2596         if (byCsar.isRight()) {
2597             if (JanusGraphOperationStatus.NOT_FOUND == byCsar.right().value()) {
2598                 // Fix Defect DE256036
2599                 if (StringUtils.isEmpty(systemName)) {
2600                     return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.NOT_FOUND));
2601                 }
2602                 props.clear();
2603                 props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
2604                 props.put(GraphPropertyEnum.SYSTEM_NAME, systemName);
2605                 Either<List<GraphVertex>, JanusGraphOperationStatus> bySystemname = janusGraphDao
2606                     .getByCriteria(null, props, JsonParseFlagEnum.ParseMetadata);
2607                 if (bySystemname.isRight()) {
2608                     log.debug("getLatestResourceByCsarOrName - Failed to find by system name {}  error {} ", systemName,
2609                         bySystemname.right().value());
2610                     return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(bySystemname.right().value()));
2611                 }
2612                 if (bySystemname.left().value().size() > 2) {
2613                     log.debug(
2614                         "getLatestResourceByCsarOrName - getByCriteria(by system name) must return only 2 latest version, but was returned - {}",
2615                         bySystemname.left().value().size());
2616                     return Either.right(StorageOperationStatus.GENERAL_ERROR);
2617                 }
2618                 resourceMetadataDataList = bySystemname.left().value();
2619                 if (resourceMetadataDataList.size() == 1) {
2620                     resourceMetadataData = resourceMetadataDataList.get(0);
2621                 } else {
2622                     for (GraphVertex curResource : resourceMetadataDataList) {
2623                         if (!((String) curResource.getJsonMetadataField(JsonPresentationFields.LIFECYCLE_STATE)).equals("CERTIFIED")) {
2624                             resourceMetadataData = curResource;
2625                             break;
2626                         }
2627                     }
2628                 }
2629                 if (resourceMetadataData == null) {
2630                     log.debug("getLatestResourceByCsarOrName - getByCriteria(by system name) returned 2 latest CERTIFIED versions");
2631                     return Either.right(StorageOperationStatus.GENERAL_ERROR);
2632                 }
2633                 final Object csarUuid = resourceMetadataData.getJsonMetadataField(JsonPresentationFields.CSAR_UUID);
2634                 if (csarUuid != null && !csarUuid.equals(csarUUID)) {
2635                     log.debug("getLatestResourceByCsarOrName - same system name {} but different csarUUID. exist {} and new {} ", systemName,
2636                         csarUuid, csarUUID);
2637                     // correct error will be returned from create flow. with all
2638
2639                     // correct audit records!!!!!
2640                     return Either.right(StorageOperationStatus.NOT_FOUND);
2641                 }
2642                 return getToscaElement(resourceMetadataData.getUniqueId());
2643             }
2644         } else {
2645             resourceMetadataDataList = byCsar.left().value();
2646             if (resourceMetadataDataList.size() > 2) {
2647                 log.debug("getLatestResourceByCsarOrName - getByCriteria(by csar) must return only 2 latest version, but was returned - {}",
2648                     byCsar.left().value().size());
2649                 return Either.right(StorageOperationStatus.GENERAL_ERROR);
2650             }
2651             if (resourceMetadataDataList.size() == 1) {
2652                 resourceMetadataData = resourceMetadataDataList.get(0);
2653             } else {
2654                 for (GraphVertex curResource : resourceMetadataDataList) {
2655                     if (!((String) curResource.getJsonMetadataField(JsonPresentationFields.LIFECYCLE_STATE)).equals("CERTIFIED")) {
2656                         resourceMetadataData = curResource;
2657                         break;
2658                     }
2659                 }
2660             }
2661             if (resourceMetadataData == null) {
2662                 log.debug("getLatestResourceByCsarOrName - getByCriteria(by csar) returned 2 latest CERTIFIED versions");
2663                 return Either.right(StorageOperationStatus.GENERAL_ERROR);
2664             }
2665             return getToscaElement((String) resourceMetadataData.getJsonMetadataField(JsonPresentationFields.UNIQUE_ID), parseFlag);
2666         }
2667         return null;
2668     }
2669
2670     public Either<Boolean, StorageOperationStatus> validateToscaResourceNameExtends(String templateNameCurrent, String templateNameExtends,
2671                                                                                     String model) {
2672         String currentTemplateNameChecked = templateNameExtends;
2673         while (currentTemplateNameChecked != null && !currentTemplateNameChecked.equalsIgnoreCase(templateNameCurrent)) {
2674             Either<Resource, StorageOperationStatus> latestByToscaResourceName = getLatestByToscaResourceName(currentTemplateNameChecked, model);
2675             if (latestByToscaResourceName.isRight()) {
2676                 return latestByToscaResourceName.right().value() == StorageOperationStatus.NOT_FOUND ? Either.left(false)
2677                     : Either.right(latestByToscaResourceName.right().value());
2678             }
2679             Resource value = latestByToscaResourceName.left().value();
2680             if (value.getDerivedFrom() != null) {
2681                 currentTemplateNameChecked = value.getDerivedFrom().get(0);
2682             } else {
2683                 currentTemplateNameChecked = null;
2684             }
2685         }
2686         return (currentTemplateNameChecked != null && currentTemplateNameChecked.equalsIgnoreCase(templateNameCurrent)) ? Either.left(true)
2687             : Either.left(false);
2688     }
2689
2690     public Either<List<Component>, StorageOperationStatus> fetchMetaDataByResourceType(String resourceType, ComponentParametersView filterBy) {
2691         Map<GraphPropertyEnum, Object> props = new EnumMap<>(GraphPropertyEnum.class);
2692         props.put(GraphPropertyEnum.RESOURCE_TYPE, resourceType);
2693         props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
2694         Map<GraphPropertyEnum, Object> propsHasNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
2695         propsHasNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
2696         Either<List<GraphVertex>, JanusGraphOperationStatus> resourcesByTypeEither = janusGraphDao
2697             .getByCriteria(null, props, propsHasNotToMatch, JsonParseFlagEnum.ParseMetadata);
2698         if (resourcesByTypeEither.isRight()) {
2699             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(resourcesByTypeEither.right().value()));
2700         }
2701         List<GraphVertex> vertexList = resourcesByTypeEither.left().value();
2702         List<Component> components = new ArrayList<>();
2703         for (GraphVertex vertex : vertexList) {
2704             components.add(getToscaElementByOperation(vertex, filterBy).left().value());
2705         }
2706         return Either.left(components);
2707     }
2708
2709     public void commit() {
2710         janusGraphDao.commit();
2711     }
2712
2713     public Either<Service, StorageOperationStatus> updateDistributionStatus(Service service, User user, DistributionStatusEnum distributionStatus) {
2714         Either<GraphVertex, StorageOperationStatus> updateDistributionStatus = topologyTemplateOperation
2715             .updateDistributionStatus(service.getUniqueId(), user, distributionStatus);
2716         if (updateDistributionStatus.isRight()) {
2717             return Either.right(updateDistributionStatus.right().value());
2718         }
2719         GraphVertex serviceV = updateDistributionStatus.left().value();
2720         service.setDistributionStatus(distributionStatus);
2721         service.setLastUpdateDate((Long) serviceV.getJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE));
2722         return Either.left(service);
2723     }
2724
2725     public Either<ComponentMetadataData, StorageOperationStatus> updateComponentLastUpdateDateOnGraph(Component component) {
2726         Either<ComponentMetadataData, StorageOperationStatus> result = null;
2727         GraphVertex serviceVertex;
2728         Either<GraphVertex, JanusGraphOperationStatus> updateRes = null;
2729         Either<GraphVertex, JanusGraphOperationStatus> getRes = janusGraphDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.ParseMetadata);
2730         if (getRes.isRight()) {
2731             JanusGraphOperationStatus status = getRes.right().value();
2732             log.error("Failed to fetch component {}. status is {}", component.getUniqueId(), status);
2733             result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
2734         }
2735         if (result == null) {
2736             serviceVertex = getRes.left().value();
2737             long lastUpdateDate = System.currentTimeMillis();
2738             serviceVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, lastUpdateDate);
2739             component.setLastUpdateDate(lastUpdateDate);
2740             updateRes = janusGraphDao.updateVertex(serviceVertex);
2741             if (updateRes.isRight()) {
2742                 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(updateRes.right().value()));
2743             }
2744         }
2745         if (result == null) {
2746             result = Either.left(ModelConverter.convertToComponentMetadata(updateRes.left().value()));
2747         }
2748         return result;
2749     }
2750
2751     public HealingJanusGraphDao getJanusGraphDao() {
2752         return janusGraphDao;
2753     }
2754
2755     public Either<List<Service>, StorageOperationStatus> getCertifiedServicesWithDistStatus(Set<DistributionStatusEnum> distStatus) {
2756         Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
2757         propertiesToMatch.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
2758         return getServicesWithDistStatus(distStatus, propertiesToMatch);
2759     }
2760
2761     public Either<List<Service>, StorageOperationStatus> getServicesWithDistStatus(Set<DistributionStatusEnum> distStatus,
2762                                                                                    Map<GraphPropertyEnum, Object> additionalPropertiesToMatch) {
2763         List<Service> servicesAll = new ArrayList<>();
2764         Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
2765         Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
2766         if (additionalPropertiesToMatch != null && !additionalPropertiesToMatch.isEmpty()) {
2767             propertiesToMatch.putAll(additionalPropertiesToMatch);
2768         }
2769         propertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.SERVICE.name());
2770         propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
2771         if (CollectionUtils.isNotEmpty(distStatus)) {
2772             for (DistributionStatusEnum state : distStatus) {
2773                 propertiesToMatch.put(GraphPropertyEnum.DISTRIBUTION_STATUS, state.name());
2774                 Either<List<Service>, StorageOperationStatus> fetchServicesByCriteria = fetchServicesByCriteria(servicesAll, propertiesToMatch,
2775                     propertiesNotToMatch, null);
2776                 if (fetchServicesByCriteria.isRight()) {
2777                     return fetchServicesByCriteria;
2778                 } else {
2779                     servicesAll = fetchServicesByCriteria.left().value();
2780                 }
2781             }
2782             return Either.left(servicesAll);
2783         } else {
2784             return fetchServicesByCriteria(servicesAll, propertiesToMatch, propertiesNotToMatch, null);
2785         }
2786     }
2787
2788     private Either<List<Service>, StorageOperationStatus> fetchServicesByCriteria(List<Service> servicesAll,
2789                                                                                   Map<GraphPropertyEnum, Object> propertiesToMatch,
2790                                                                                   Map<GraphPropertyEnum, Object> propertiesNotToMatch,
2791                                                                                   String modelName) {
2792         Either<List<GraphVertex>, JanusGraphOperationStatus> getRes;
2793         if (StringUtils.isEmpty(modelName)) {
2794             getRes = janusGraphDao.getByCriteria(TOPOLOGY_TEMPLATE, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseAll);
2795         } else {
2796             getRes = janusGraphDao.getByCriteria(TOPOLOGY_TEMPLATE, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseAll, modelName);
2797         }
2798         if (getRes.isRight()) {
2799             if (getRes.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
2800                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
2801                     "Failed to fetch certified services by match properties {} not match properties {} . Status is {}. ", propertiesToMatch,
2802                     propertiesNotToMatch, getRes.right().value());
2803                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getRes.right().value()));
2804             }
2805         } else {
2806             for (final GraphVertex vertex : getRes.left().value()) {
2807                 Either<ToscaElement, StorageOperationStatus> getServiceRes = topologyTemplateOperation
2808                     .getLightComponent(vertex, ComponentTypeEnum.SERVICE, new ComponentParametersView(true));
2809                 if (getServiceRes.isRight()) {
2810                     CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch certified service {}. Status is {}. ",
2811                         vertex.getJsonMetadataField(JsonPresentationFields.NAME), getServiceRes.right().value());
2812                     return Either.right(getServiceRes.right().value());
2813                 } else {
2814                     servicesAll.add(ModelConverter.convertFromToscaElement(getServiceRes.left().value()));
2815                 }
2816             }
2817         }
2818         return Either.left(servicesAll);
2819     }
2820
2821     public void rollback() {
2822         janusGraphDao.rollback();
2823     }
2824
2825     public StorageOperationStatus addDeploymentArtifactsToInstance(String componentId, ComponentInstance componentInstance,
2826                                                                    Map<String, ArtifactDefinition> finalDeploymentArtifacts) {
2827         Map<String, ArtifactDataDefinition> instDeplArtifacts = finalDeploymentArtifacts.entrySet().stream()
2828             .collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDataDefinition(e.getValue())));
2829         return nodeTemplateOperation.addDeploymentArtifactsToInstance(componentId, componentInstance.getUniqueId(), instDeplArtifacts);
2830     }
2831
2832     public StorageOperationStatus addInformationalArtifactsToInstance(String componentId, ComponentInstance componentInstance,
2833                                                                       Map<String, ArtifactDefinition> artifacts) {
2834         StorageOperationStatus status = StorageOperationStatus.OK;
2835         if (MapUtils.isNotEmpty(artifacts)) {
2836             Map<String, ArtifactDataDefinition> instDeplArtifacts = artifacts.entrySet().stream()
2837                 .collect(Collectors.toMap(Map.Entry::getKey, e -> new ArtifactDataDefinition(e.getValue())));
2838             status = nodeTemplateOperation.addInformationalArtifactsToInstance(componentId, componentInstance.getUniqueId(), instDeplArtifacts);
2839         }
2840         return status;
2841     }
2842
2843     public StorageOperationStatus generateCustomizationUUIDOnInstance(String componentId, String instanceId) {
2844         return nodeTemplateOperation.generateCustomizationUUIDOnInstance(componentId, instanceId);
2845     }
2846
2847     public StorageOperationStatus generateCustomizationUUIDOnInstanceGroup(String componentId, String instanceId, List<String> groupInstances) {
2848         return nodeTemplateOperation.generateCustomizationUUIDOnInstanceGroup(componentId, instanceId, groupInstances);
2849     }
2850
2851     public Either<PropertyDefinition, StorageOperationStatus> addPropertyToComponent(PropertyDefinition newPropertyDefinition,
2852                                                                                      Component component) {
2853         final String propertyName = newPropertyDefinition.getName();
2854         StorageOperationStatus status = getToscaElementOperation(component)
2855             .addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, newPropertyDefinition,
2856                 JsonPresentationFields.NAME);
2857         if (status != StorageOperationStatus.OK) {
2858             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add the property {} to the component {}. Status is {}. ", propertyName,
2859                 component.getName(), status);
2860             return Either.right(status);
2861         }
2862         ComponentParametersView filter = new ComponentParametersView(true);
2863         filter.setIgnoreProperties(false);
2864         filter.setIgnoreInputs(false);
2865         Either<Component, StorageOperationStatus> getUpdatedComponentRes = getToscaElement(component.getUniqueId(), filter);
2866         if (getUpdatedComponentRes.isRight()) {
2867             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to get updated component {}. Status is {}. ", component.getUniqueId(),
2868                 getUpdatedComponentRes.right().value());
2869             return Either.right(status);
2870         }
2871         PropertyDefinition newProperty = null;
2872         List<PropertyDefinition> properties = (getUpdatedComponentRes.left().value()).getProperties();
2873         if (CollectionUtils.isNotEmpty(properties)) {
2874             Optional<PropertyDefinition> propertyOptional = properties.stream().filter(propertyEntry -> propertyEntry.getName().equals(propertyName))
2875                 .findAny();
2876             if (propertyOptional.isPresent()) {
2877                 newProperty = propertyOptional.get();
2878             }
2879         }
2880         if (newProperty == null) {
2881             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find recently added property {} on the component {}. Status is {}. ",
2882                 propertyName, component.getUniqueId(), StorageOperationStatus.NOT_FOUND);
2883             return Either.right(StorageOperationStatus.NOT_FOUND);
2884         }
2885         return Either.left(newProperty);
2886     }
2887
2888     public Either<InputDefinition, StorageOperationStatus> addInputToComponent(String inputName, InputDefinition newInputDefinition,
2889                                                                                Component component) {
2890         newInputDefinition.setName(inputName);
2891         StorageOperationStatus status = getToscaElementOperation(component)
2892             .addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.INPUTS, VertexTypeEnum.INPUTS, newInputDefinition,
2893                 JsonPresentationFields.NAME);
2894         if (status != StorageOperationStatus.OK) {
2895             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add the input {} to the component {}. Status is {}. ", inputName,
2896                 component.getName(), status);
2897             return Either.right(status);
2898         }
2899         ComponentParametersView filter = new ComponentParametersView(true);
2900         filter.setIgnoreProperties(false);
2901         filter.setIgnoreInputs(false);
2902         Either<Component, StorageOperationStatus> getUpdatedComponentRes = getToscaElement(component.getUniqueId(), filter);
2903         if (getUpdatedComponentRes.isRight()) {
2904             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to get updated component {}. Status is {}. ", component.getUniqueId(),
2905                 getUpdatedComponentRes.right().value());
2906             return Either.right(status);
2907         }
2908         InputDefinition newInput = null;
2909         List<InputDefinition> inputs = (getUpdatedComponentRes.left().value()).getInputs();
2910         if (CollectionUtils.isNotEmpty(inputs)) {
2911             Optional<InputDefinition> inputOptional = inputs.stream().filter(inputEntry -> inputEntry.getName().equals(inputName)).findAny();
2912             if (inputOptional.isPresent()) {
2913                 newInput = inputOptional.get();
2914             }
2915         }
2916         if (newInput == null) {
2917             CommonUtility
2918                 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find recently added input {} " + "on the component {}. Status is {}. ", inputs,
2919                     component.getUniqueId(), StorageOperationStatus.NOT_FOUND);
2920             return Either.right(StorageOperationStatus.NOT_FOUND);
2921         }
2922         return Either.left(newInput);
2923     }
2924
2925     public StorageOperationStatus deletePropertyOfComponent(Component component, String propertyName) {
2926         return getToscaElementOperation(component)
2927             .deleteToscaDataElement(component.getUniqueId(), EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, propertyName,
2928                 JsonPresentationFields.NAME);
2929     }
2930
2931     public StorageOperationStatus deleteAttributeOfResource(Component component, String attributeName) {
2932         return getToscaElementOperation(component)
2933             .deleteToscaDataElement(component.getUniqueId(), EdgeLabelEnum.ATTRIBUTES, VertexTypeEnum.ATTRIBUTES, attributeName,
2934                 JsonPresentationFields.NAME);
2935     }
2936
2937     public StorageOperationStatus deleteInputOfResource(Component resource, String inputName) {
2938         return getToscaElementOperation(resource)
2939             .deleteToscaDataElement(resource.getUniqueId(), EdgeLabelEnum.INPUTS, VertexTypeEnum.INPUTS, inputName, JsonPresentationFields.NAME);
2940     }
2941
2942     public StorageOperationStatus deleteOutputOfResource(final Component resource, final String outputName) {
2943         return getToscaElementOperation(resource)
2944             .deleteToscaDataElement(resource.getUniqueId(), EdgeLabelEnum.OUTPUTS, VertexTypeEnum.OUTPUTS, outputName, JsonPresentationFields.NAME);
2945     }
2946
2947     /**
2948      * Deletes a data type from a component.
2949      *
2950      * @param component    the container which has the data type
2951      * @param dataTypeName the data type name to be deleted
2952      * @return Operation result.
2953      */
2954     public StorageOperationStatus deleteDataTypeOfComponent(Component component, String dataTypeName) {
2955         return getToscaElementOperation(component)
2956             .deleteToscaDataElement(component.getUniqueId(), EdgeLabelEnum.DATA_TYPES, VertexTypeEnum.DATA_TYPES, dataTypeName,
2957                 JsonPresentationFields.NAME);
2958     }
2959
2960     public Either<PropertyDefinition, StorageOperationStatus> updatePropertyOfComponent(Component component,
2961                                                                                         PropertyDefinition newPropertyDefinition) {
2962         Either<Component, StorageOperationStatus> getUpdatedComponentRes = null;
2963         Either<PropertyDefinition, StorageOperationStatus> result = null;
2964         StorageOperationStatus status = getToscaElementOperation(component)
2965             .updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, newPropertyDefinition,
2966                 JsonPresentationFields.NAME);
2967         if (status != StorageOperationStatus.OK) {
2968             CommonUtility
2969                 .addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_ADD_THE_PROPERTY_TO_THE_RESOURCE_STATUS_IS, newPropertyDefinition.getName(),
2970                     component.getName(), status);
2971             result = Either.right(status);
2972         }
2973         if (result == null) {
2974             ComponentParametersView filter = new ComponentParametersView(true);
2975             filter.setIgnoreProperties(false);
2976             getUpdatedComponentRes = getToscaElement(component.getUniqueId(), filter);
2977             if (getUpdatedComponentRes.isRight()) {
2978                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_UPDATED_RESOURCE_STATUS_IS, component.getUniqueId(),
2979                     getUpdatedComponentRes.right().value());
2980                 result = Either.right(status);
2981             }
2982         }
2983         if (result == null) {
2984             Optional<PropertyDefinition> newProperty = (getUpdatedComponentRes.left().value()).getProperties().stream()
2985                 .filter(p -> p.getName().equals(newPropertyDefinition.getName())).findAny();
2986             if (newProperty.isPresent()) {
2987                 result = Either.left(newProperty.get());
2988             } else {
2989                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FIND_RECENTLY_ADDED_PROPERTY_ON_THE_RESOURCE_STATUS_IS,
2990                     newPropertyDefinition.getName(), component.getUniqueId(), StorageOperationStatus.NOT_FOUND);
2991                 result = Either.right(StorageOperationStatus.NOT_FOUND);
2992             }
2993         }
2994         return result;
2995     }
2996
2997     public Either<AttributeDefinition, StorageOperationStatus> updateAttributeOfComponent(Component component,
2998                                                                                           AttributeDefinition newPropertyDefinition) {
2999         Either<Component, StorageOperationStatus> getUpdatedComponentRes = null;
3000         Either<AttributeDefinition, StorageOperationStatus> result = null;
3001         StorageOperationStatus status = getToscaElementOperation(component)
3002             .updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.ATTRIBUTES, VertexTypeEnum.ATTRIBUTES, newPropertyDefinition,
3003                 JsonPresentationFields.NAME);
3004         if (status != StorageOperationStatus.OK) {
3005             CommonUtility
3006                 .addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_ADD_THE_PROPERTY_TO_THE_RESOURCE_STATUS_IS, newPropertyDefinition.getName(),
3007                     component.getName(), status);
3008             result = Either.right(status);
3009         }
3010         if (result == null) {
3011             ComponentParametersView filter = new ComponentParametersView(true);
3012             filter.setIgnoreProperties(false);
3013             getUpdatedComponentRes = getToscaElement(component.getUniqueId(), filter);
3014             if (getUpdatedComponentRes.isRight()) {
3015                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_UPDATED_RESOURCE_STATUS_IS, component.getUniqueId(),
3016                     getUpdatedComponentRes.right().value());
3017                 result = Either.right(status);
3018             }
3019         }
3020         if (result == null) {
3021             Optional<AttributeDefinition> newProperty = (getUpdatedComponentRes.left().value()).getAttributes().stream()
3022                 .filter(p -> p.getName().equals(newPropertyDefinition.getName())).findAny();
3023             if (newProperty.isPresent()) {
3024                 result = Either.left(newProperty.get());
3025             } else {
3026                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FIND_RECENTLY_ADDED_PROPERTY_ON_THE_RESOURCE_STATUS_IS,
3027                     newPropertyDefinition.getName(), component.getUniqueId(), StorageOperationStatus.NOT_FOUND);
3028                 result = Either.right(StorageOperationStatus.NOT_FOUND);
3029             }
3030         }
3031         return result;
3032     }
3033
3034     public Either<AttributeDefinition, StorageOperationStatus> addAttributeOfResource(Component component, AttributeDefinition newAttributeDef) {
3035         Either<Component, StorageOperationStatus> getUpdatedComponentRes = null;
3036         Either<AttributeDefinition, StorageOperationStatus> result = null;
3037         if (newAttributeDef.getUniqueId() == null || newAttributeDef.getUniqueId().isEmpty()) {
3038             String attUniqueId = UniqueIdBuilder.buildAttributeUid(component.getUniqueId(), newAttributeDef.getName());
3039             newAttributeDef.setUniqueId(attUniqueId);
3040             newAttributeDef.setOwnerId(component.getUniqueId());
3041         }
3042         StorageOperationStatus status = getToscaElementOperation(component)
3043             .addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.ATTRIBUTES, VertexTypeEnum.ATTRIBUTES, newAttributeDef,
3044                 JsonPresentationFields.NAME);
3045         if (status != StorageOperationStatus.OK) {
3046             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_ADD_THE_PROPERTY_TO_THE_RESOURCE_STATUS_IS, newAttributeDef.getName(),
3047                 component.getName(), status);
3048             result = Either.right(status);
3049         }
3050         if (result == null) {
3051             ComponentParametersView filter = new ComponentParametersView(true);
3052             filter.setIgnoreAttributes(false);
3053             getUpdatedComponentRes = getToscaElement(component.getUniqueId(), filter);
3054             if (getUpdatedComponentRes.isRight()) {
3055                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_UPDATED_RESOURCE_STATUS_IS, component.getUniqueId(),
3056                     getUpdatedComponentRes.right().value());
3057                 result = Either.right(status);
3058             }
3059         }
3060         if (result == null) {
3061             Optional<AttributeDefinition> newAttribute = ((Resource) getUpdatedComponentRes.left().value()).getAttributes().stream()
3062                 .filter(p -> p.getName().equals(newAttributeDef.getName())).findAny();
3063             if (newAttribute.isPresent()) {
3064                 result = Either.left(newAttribute.get());
3065             } else {
3066                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FIND_RECENTLY_ADDED_PROPERTY_ON_THE_RESOURCE_STATUS_IS,
3067                     newAttributeDef.getName(), component.getUniqueId(), StorageOperationStatus.NOT_FOUND);
3068                 result = Either.right(StorageOperationStatus.NOT_FOUND);
3069             }
3070         }
3071         return result;
3072     }
3073
3074     public Either<AttributeDefinition, StorageOperationStatus> updateAttributeOfResource(Component component, AttributeDefinition newAttributeDef) {
3075         Either<Component, StorageOperationStatus> getUpdatedComponentRes = null;
3076         Either<AttributeDefinition, StorageOperationStatus> result = null;
3077         StorageOperationStatus status = getToscaElementOperation(component)
3078             .updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.ATTRIBUTES, VertexTypeEnum.ATTRIBUTES, newAttributeDef,
3079                 JsonPresentationFields.NAME);
3080         if (status != StorageOperationStatus.OK) {
3081             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_ADD_THE_PROPERTY_TO_THE_RESOURCE_STATUS_IS, newAttributeDef.getName(),
3082                 component.getName(), status);
3083             result = Either.right(status);
3084         }
3085         if (result == null) {
3086             ComponentParametersView filter = new ComponentParametersView(true);
3087             filter.setIgnoreAttributes(false);
3088             getUpdatedComponentRes = getToscaElement(component.getUniqueId(), filter);
3089             if (getUpdatedComponentRes.isRight()) {
3090                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_UPDATED_RESOURCE_STATUS_IS, component.getUniqueId(),
3091                     getUpdatedComponentRes.right().value());
3092                 result = Either.right(status);
3093             }
3094         }
3095         if (result == null) {
3096             Optional<AttributeDefinition> newProperty = ((Resource) getUpdatedComponentRes.left().value()).getAttributes().stream()
3097                 .filter(p -> p.getName().equals(newAttributeDef.getName())).findAny();
3098             if (newProperty.isPresent()) {
3099                 result = Either.left(newProperty.get());
3100             } else {
3101                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FIND_RECENTLY_ADDED_PROPERTY_ON_THE_RESOURCE_STATUS_IS,
3102                     newAttributeDef.getName(), component.getUniqueId(), StorageOperationStatus.NOT_FOUND);
3103                 result = Either.right(StorageOperationStatus.NOT_FOUND);
3104             }
3105         }
3106         return result;
3107     }
3108
3109     public Either<InputDefinition, StorageOperationStatus> updateInputOfComponent(Component component, InputDefinition newInputDefinition) {
3110         Either<Component, StorageOperationStatus> getUpdatedComponentRes = null;
3111         Either<InputDefinition, StorageOperationStatus> result = null;
3112         StorageOperationStatus status = getToscaElementOperation(component)
3113             .updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.INPUTS, VertexTypeEnum.INPUTS, newInputDefinition,
3114                 JsonPresentationFields.NAME);
3115         if (status != StorageOperationStatus.OK) {
3116             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update the input {} to the component {}. Status is {}. ",
3117                 newInputDefinition.getName(), component.getName(), status);
3118             result = Either.right(status);
3119         }
3120         if (result == null) {
3121             ComponentParametersView filter = new ComponentParametersView(true);
3122             filter.setIgnoreInputs(false);
3123             getUpdatedComponentRes = getToscaElement(component.getUniqueId(), filter);
3124             if (getUpdatedComponentRes.isRight()) {
3125                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_UPDATED_RESOURCE_STATUS_IS, component.getUniqueId(),
3126                     getUpdatedComponentRes.right().value());
3127                 result = Either.right(status);
3128             }
3129         }
3130         if (result == null) {
3131             Optional<InputDefinition> updatedInput = getUpdatedComponentRes.left().value().getInputs().stream()
3132                 .filter(p -> p.getName().equals(newInputDefinition.getName())).findAny();
3133             if (updatedInput.isPresent()) {
3134                 result = Either.left(updatedInput.get());
3135             } else {
3136                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find recently updated inputs {} on the resource {}. Status is {}. ",
3137                     newInputDefinition.getName(), component.getUniqueId(), StorageOperationStatus.NOT_FOUND);
3138                 result = Either.right(StorageOperationStatus.NOT_FOUND);
3139             }
3140         }
3141         return result;
3142     }
3143
3144     /**
3145      * method - ename the group instances after referenced container name renamed flow - VF rename -(triggers)-> Group rename
3146      *
3147      * @param containerComponent  - container such as service
3148      * @param componentInstance   - context component
3149      * @param componentInstanceId - id
3150      * @return - successfull/failed status
3151      **/
3152     public Either<StorageOperationStatus, StorageOperationStatus> cleanAndAddGroupInstancesToComponentInstance(Component containerComponent,
3153                                                                                                                ComponentInstance componentInstance,
3154                                                                                                                String componentInstanceId) {
3155         String uniqueId = componentInstance.getUniqueId();
3156         StorageOperationStatus status = nodeTemplateOperation
3157             .deleteToscaDataDeepElementsBlockOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_GROUPS,
3158                 uniqueId);
3159         if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
3160             CommonUtility
3161                 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete group instances for container {}. error {] ", componentInstanceId, status);
3162             return Either.right(status);
3163         }
3164         if (componentInstance.getGroupInstances() != null) {
3165             status = addGroupInstancesToComponentInstance(containerComponent, componentInstance, componentInstance.getGroupInstances());
3166             if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
3167                 CommonUtility
3168                     .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add group instances for container {}. error {] ", componentInstanceId,
3169                         status);
3170                 return Either.right(status);
3171             }
3172         }
3173         return Either.left(status);
3174     }
3175
3176     public StorageOperationStatus addGroupInstancesToComponentInstance(Component containerComponent, ComponentInstance componentInstance,
3177                                                                        List<GroupDefinition> groups,
3178                                                                        Map<String, List<ArtifactDefinition>> groupInstancesArtifacts) {
3179         return nodeTemplateOperation.addGroupInstancesToComponentInstance(containerComponent, componentInstance, groups, groupInstancesArtifacts);
3180     }
3181
3182     public Either<List<GroupDefinition>, StorageOperationStatus> updateGroupsOnComponent(Component component,
3183                                                                                          List<GroupDataDefinition> updatedGroups) {
3184         return groupsOperation.updateGroups(component, updatedGroups, PromoteVersionEnum.MINOR);
3185     }
3186
3187     public Either<List<GroupInstance>, StorageOperationStatus> updateGroupInstancesOnComponent(Component component, String instanceId,
3188                                                                                                List<GroupInstance> updatedGroupInstances) {
3189         return groupsOperation.updateGroupInstances(component, instanceId, updatedGroupInstances);
3190     }
3191
3192     public StorageOperationStatus addGroupInstancesToComponentInstance(Component containerComponent, ComponentInstance componentInstance,
3193                                                                        List<GroupInstance> groupInstances) {
3194         return nodeTemplateOperation.addGroupInstancesToComponentInstance(containerComponent, componentInstance, groupInstances);
3195     }
3196
3197     public StorageOperationStatus addDeploymentArtifactsToComponentInstance(Component containerComponent, ComponentInstance componentInstance,
3198                                                                             Map<String, ArtifactDefinition> deploymentArtifacts) {
3199         return nodeTemplateOperation.addDeploymentArtifactsToComponentInstance(containerComponent, componentInstance, deploymentArtifacts);
3200     }
3201
3202     public StorageOperationStatus updateComponentInstanceProperty(Component containerComponent, String componentInstanceId,
3203                                                                   ComponentInstanceProperty property) {
3204         return nodeTemplateOperation.updateComponentInstanceProperty(containerComponent, componentInstanceId, property);
3205     }
3206
3207     public StorageOperationStatus updateComponentInstanceProperties(Component containerComponent, String componentInstanceId,
3208                                                                     List<ComponentInstanceProperty> properties) {
3209         return nodeTemplateOperation.updateComponentInstanceProperties(containerComponent, componentInstanceId, properties);
3210     }
3211
3212     public StorageOperationStatus updateComponentInstanceAttributes(final Component containerComponent, final String componentInstanceId,
3213                                                                     final List<ComponentInstanceAttribute> attributes) {
3214         return nodeTemplateOperation.updateComponentInstanceAttributes(containerComponent, componentInstanceId, attributes);
3215     }
3216
3217     public StorageOperationStatus addComponentInstanceProperty(Component containerComponent, String componentInstanceId,
3218                                                                ComponentInstanceProperty property) {
3219         return nodeTemplateOperation.addComponentInstanceProperty(containerComponent, componentInstanceId, property);
3220     }
3221
3222     public StorageOperationStatus updateComponentInstanceAttribute(final Component containerComponent, final String componentInstanceId,
3223                                                                    final ComponentInstanceAttribute attribute) {
3224         return nodeTemplateOperation.updateComponentInstanceAttribute(containerComponent, componentInstanceId, attribute);
3225     }
3226
3227     public StorageOperationStatus addComponentInstanceAttribute(Component containerComponent, String componentInstanceId,
3228                                                                 ComponentInstanceAttribute attribute) {
3229         return nodeTemplateOperation.addComponentInstanceAttribute(containerComponent, componentInstanceId, attribute);
3230     }
3231
3232     public StorageOperationStatus updateComponentInstanceInput(Component containerComponent, String componentInstanceId,
3233                                                                ComponentInstanceInput property) {
3234         return nodeTemplateOperation.updateComponentInstanceInput(containerComponent, componentInstanceId, property);
3235     }
3236
3237     public StorageOperationStatus updateComponentInstanceOutput(Component containerComponent, String componentInstanceId,
3238                                                                 ComponentInstanceOutput property) {
3239         return nodeTemplateOperation.updateComponentInstanceOutput(containerComponent, componentInstanceId, property);
3240     }
3241
3242     public StorageOperationStatus updateComponentInstanceInputs(Component containerComponent, String componentInstanceId,
3243                                                                 List<ComponentInstanceInput> instanceInputs) {
3244         return nodeTemplateOperation.updateComponentInstanceInputs(containerComponent, componentInstanceId, instanceInputs);
3245     }
3246
3247     public StorageOperationStatus updateComponentInstanceOutputs(Component containerComponent, String componentInstanceId,
3248                                                                  List<ComponentInstanceOutput> instanceInputs) {
3249         return nodeTemplateOperation.updateComponentInstanceOutputs(containerComponent, componentInstanceId, instanceInputs);
3250     }
3251
3252     public StorageOperationStatus addComponentInstanceInput(Component containerComponent, String componentInstanceId,
3253                                                             ComponentInstanceInput property) {
3254         return nodeTemplateOperation.addComponentInstanceInput(containerComponent, componentInstanceId, property);
3255     }
3256
3257     public StorageOperationStatus addComponentInstanceOutput(Component containerComponent, String componentInstanceId,
3258                                                              ComponentInstanceOutput property) {
3259         return nodeTemplateOperation.addComponentInstanceOutput(containerComponent, componentInstanceId, property);
3260     }
3261
3262     public void setNodeTypeOperation(NodeTypeOperation nodeTypeOperation) {
3263         this.nodeTypeOperation = nodeTypeOperation;
3264     }
3265
3266     public void setTopologyTemplateOperation(TopologyTemplateOperation topologyTemplateOperation) {
3267         this.topologyTemplateOperation = topologyTemplateOperation;
3268     }
3269
3270     public StorageOperationStatus deleteComponentInstanceInputsFromTopologyTemplate(Component containerComponent,
3271                                                                                     List<InputDefinition> inputsToDelete) {
3272         return topologyTemplateOperation.deleteToscaDataElements(containerComponent.getUniqueId(), EdgeLabelEnum.INPUTS,
3273             inputsToDelete.stream().map(PropertyDataDefinition::getName).collect(Collectors.toList()));
3274     }
3275
3276     public StorageOperationStatus deleteComponentInstanceOutputsFromTopologyTemplate(final Component containerComponent,
3277                                                                                      final List<OutputDefinition> outputsToDelete) {
3278         return topologyTemplateOperation.deleteToscaDataElements(containerComponent.getUniqueId(), EdgeLabelEnum.OUTPUTS,
3279             outputsToDelete.stream().map(AttributeDataDefinition::getName).collect(Collectors.toList()));
3280     }
3281
3282     public StorageOperationStatus updateComponentInstanceCapabiltyProperty(Component containerComponent, String componentInstanceUniqueId,
3283                                                                            String capabilityPropertyKey, ComponentInstanceProperty property) {
3284         return nodeTemplateOperation
3285             .updateComponentInstanceCapabilityProperty(containerComponent, componentInstanceUniqueId, capabilityPropertyKey, property);
3286     }
3287
3288     public StorageOperationStatus updateComponentInstanceCapabilityProperties(Component containerComponent, String componentInstanceUniqueId) {
3289         return convertComponentInstanceProperties(containerComponent, componentInstanceUniqueId).map(instanceCapProps -> topologyTemplateOperation
3290                 .updateComponentInstanceCapabilityProperties(containerComponent, componentInstanceUniqueId, instanceCapProps))
3291             .orElse(StorageOperationStatus.NOT_FOUND);
3292     }
3293
3294     public StorageOperationStatus updateComponentInstanceRequirement(String containerComponentId, String componentInstanceUniqueId,
3295                                                                      RequirementDataDefinition requirementDataDefinition) {
3296         return nodeTemplateOperation.updateComponentInstanceRequirement(containerComponentId, componentInstanceUniqueId, requirementDataDefinition);
3297     }
3298
3299     public CapabilityDataDefinition updateComponentInstanceCapability(final String containerComponentId, final String componentInstanceUniqueId,
3300                                                                       final CapabilityDataDefinition capabilityDataDefinition) {
3301
3302         return nodeTemplateOperation.updateComponentInstanceCapabilities(containerComponentId, componentInstanceUniqueId, capabilityDataDefinition);
3303     }
3304
3305     public StorageOperationStatus updateComponentInstanceInterfaces(Component containerComponent, String componentInstanceUniqueId) {
3306         MapInterfaceDataDefinition mapInterfaceDataDefinition = convertComponentInstanceInterfaces(containerComponent, componentInstanceUniqueId);
3307         return topologyTemplateOperation.updateComponentInstanceInterfaces(containerComponent, componentInstanceUniqueId, mapInterfaceDataDefinition);
3308     }
3309
3310     public StorageOperationStatus updateComponentInterfaces(final Component component, final String componentInterfaceUpdatedKey) {
3311         MapInterfaceDataDefinition mapInterfaceDataDefinition = convertComponentInterfaces(component.getInterfaces());
3312         return topologyTemplateOperation.updateComponentInterfaces(component.getUniqueId(), mapInterfaceDataDefinition, componentInterfaceUpdatedKey);
3313     }
3314
3315     public Either<InterfaceDefinition, StorageOperationStatus> addInterfaceToComponent(final String interfaceName,
3316                                                                                        final InterfaceDefinition interfaceDefinition,
3317                                                                                        final Component component) {
3318
3319         final boolean match = component.getInterfaces().keySet().stream().anyMatch(s -> s.equals(interfaceName));
3320         StorageOperationStatus status;
3321         final ToscaElementOperation toscaElementOperation = getToscaElementOperation(component);
3322         if (match) {
3323             status = toscaElementOperation.updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.INTERFACE_ARTIFACTS,
3324                 VertexTypeEnum.INTERFACE_ARTIFACTS, interfaceDefinition, JsonPresentationFields.TYPE);
3325         } else {
3326             status = toscaElementOperation.addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.INTERFACE_ARTIFACTS,
3327                 VertexTypeEnum.INTERFACE_ARTIFACTS, interfaceDefinition, JsonPresentationFields.TYPE);
3328         }
3329
3330         if (status != StorageOperationStatus.OK) {
3331             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add the interface {} to the component {}. Status is {}. ",
3332                 interfaceName, component.getName(), status);
3333             return Either.right(status);
3334         }
3335         final ComponentParametersView filter = new ComponentParametersView(true);
3336         filter.setIgnoreInterfaces(false);
3337         filter.setIgnoreInterfaceInstances(false);
3338         final Either<Component, StorageOperationStatus> getUpdatedComponentRes = getToscaElement(component.getUniqueId(), filter);
3339         if (getUpdatedComponentRes.isRight()) {
3340             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to get updated component {}. Status is {}. ",
3341                 component.getUniqueId(), getUpdatedComponentRes.right().value());
3342             return Either.right(getUpdatedComponentRes.right().value());
3343         }
3344         InterfaceDefinition newInterfaceDefinition = null;
3345         final Map<String, InterfaceDefinition> interfaces = (getUpdatedComponentRes.left().value()).getInterfaces();
3346         if (MapUtils.isNotEmpty(interfaces)) {
3347             final Optional<String> interfaceNameOptional = interfaces.keySet().stream().filter(key -> key.equals(interfaceName)).findAny();
3348             if (interfaceNameOptional.isPresent()) {
3349                 newInterfaceDefinition = interfaces.get(interfaceNameOptional.get());
3350             }
3351         }
3352         if (newInterfaceDefinition == null) {
3353             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find recently added interface {} on the component {}. Status is {}. ",
3354                 interfaceName, component.getUniqueId(), StorageOperationStatus.NOT_FOUND);
3355             return Either.right(StorageOperationStatus.NOT_FOUND);
3356         }
3357         return Either.left(newInterfaceDefinition);
3358     }
3359
3360     public StorageOperationStatus updateComponentCalculatedCapabilitiesProperties(Component containerComponent) {
3361         Map<String, MapCapabilityProperty> mapCapabiltyPropertyMap = convertComponentCapabilitiesProperties(containerComponent);
3362         return nodeTemplateOperation.overrideComponentCapabilitiesProperties(containerComponent, mapCapabiltyPropertyMap);
3363     }
3364
3365     public StorageOperationStatus deleteAllCalculatedCapabilitiesRequirements(String topologyTemplateId) {
3366         StorageOperationStatus status = topologyTemplateOperation
3367             .removeToscaData(topologyTemplateId, EdgeLabelEnum.CALCULATED_CAPABILITIES);
3368         if (status == StorageOperationStatus.OK) {
3369             status = topologyTemplateOperation
3370                 .removeToscaData(topologyTemplateId, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
3371         }
3372         if (status == StorageOperationStatus.OK) {
3373             status = topologyTemplateOperation
3374                 .removeToscaData(topologyTemplateId, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES);
3375         }
3376         return status;
3377     }
3378
3379     public Either<Component, StorageOperationStatus> shouldUpgradeToLatestDerived(Resource clonedResource) {
3380         String componentId = clonedResource.getUniqueId();
3381         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
3382         if (getVertexEither.isRight()) {
3383             log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
3384             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value()));
3385         }
3386         GraphVertex nodeTypeV = getVertexEither.left().value();
3387         ToscaElement toscaElementToUpdate = ModelConverter.convertToToscaElement(clonedResource);
3388         Either<ToscaElement, StorageOperationStatus> shouldUpdateDerivedVersion = nodeTypeOperation
3389             .shouldUpdateDerivedVersion(toscaElementToUpdate, nodeTypeV);
3390         if (shouldUpdateDerivedVersion.isRight() && StorageOperationStatus.OK != shouldUpdateDerivedVersion.right().value()) {
3391             log.debug("Failed to update derived version for node type {} derived {}, error: {}", componentId, clonedResource.getDerivedFrom().get(0),
3392                 shouldUpdateDerivedVersion.right().value());
3393             return Either.right(shouldUpdateDerivedVersion.right().value());
3394         }
3395         if (shouldUpdateDerivedVersion.isLeft()) {
3396             return Either.left(ModelConverter.convertFromToscaElement(shouldUpdateDerivedVersion.left().value()));
3397         }
3398         return Either.left(clonedResource);
3399     }
3400
3401     /**
3402      * Returns list of ComponentInstanceProperty belonging to component instance capability specified by name, type and ownerId
3403      */
3404     public Either<List<ComponentInstanceProperty>, StorageOperationStatus> getComponentInstanceCapabilityProperties(String componentId,
3405                                                                                                                     String instanceId,
3406                                                                                                                     String capabilityName,
3407                                                                                                                     String capabilityType,
3408                                                                                                                     String ownerId) {
3409         return topologyTemplateOperation.getComponentInstanceCapabilityProperties(componentId, instanceId, capabilityName, capabilityType, ownerId);
3410     }
3411
3412     private MapInterfaceDataDefinition convertComponentInstanceInterfaces(Component currComponent, String componentInstanceId) {
3413         MapInterfaceDataDefinition mapInterfaceDataDefinition = new MapInterfaceDataDefinition();
3414         List<ComponentInstanceInterface> componentInterface = currComponent.getComponentInstancesInterfaces().get(componentInstanceId);
3415         if (CollectionUtils.isNotEmpty(componentInterface)) {
3416             componentInterface.stream().forEach(interfaceDef -> mapInterfaceDataDefinition.put(interfaceDef.getUniqueId(), interfaceDef));
3417         }
3418         return mapInterfaceDataDefinition;
3419     }
3420
3421     private MapInterfaceDataDefinition convertComponentInterfaces(final Map<String, InterfaceDefinition> interfaces) {
3422         final MapInterfaceDataDefinition mapInterfaceDataDefinition = new MapInterfaceDataDefinition();
3423         if (MapUtils.isNotEmpty(interfaces)) {
3424             interfaces.values().stream().forEach(interfaceDef -> mapInterfaceDataDefinition.put(interfaceDef.getType(), interfaceDef));
3425         }
3426         return mapInterfaceDataDefinition;
3427     }
3428
3429     private Map<String, MapCapabilityProperty> convertComponentCapabilitiesProperties(Component currComponent) {
3430         Map<String, MapCapabilityProperty> map = ModelConverter.extractCapabilityPropertiesFromGroups(currComponent.getGroups(), true);
3431         map.putAll(ModelConverter.extractCapabilityProperteisFromInstances(currComponent.getComponentInstances(), true));
3432         return map;
3433     }
3434
3435     private Optional<MapCapabilityProperty> convertComponentInstanceProperties(Component component, String instanceId) {
3436         return component.fetchInstanceById(instanceId)
3437             .map(ci -> ModelConverter.convertToMapOfMapCapabilityProperties(ci.getCapabilities(), instanceId, ci.getOriginType().isAtomicType()));
3438     }
3439
3440     public Either<PolicyDefinition, StorageOperationStatus> associatePolicyToComponent(String componentId, PolicyDefinition policyDefinition,
3441                                                                                        int counter) {
3442         Either<PolicyDefinition, StorageOperationStatus> result = null;
3443         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither;
3444         getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata);
3445         if (getVertexEither.isRight()) {
3446             log.error(COULDNT_FETCH_A_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
3447             result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value()));
3448         } else {
3449             if (getVertexEither.left().value().getLabel() != TOPOLOGY_TEMPLATE) {
3450                 log.error("Policy association to component of Tosca type {} is not allowed. ", getVertexEither.left().value().getLabel());
3451                 result = Either.right(StorageOperationStatus.BAD_REQUEST);
3452             }
3453         }
3454         if (result == null) {
3455             StorageOperationStatus status = topologyTemplateOperation
3456                 .addPolicyToToscaElement(getVertexEither.left().value(), policyDefinition, counter);
3457             if (status != StorageOperationStatus.OK) {
3458                 return Either.right(status);
3459             }
3460         }
3461         if (result == null) {
3462             result = Either.left(policyDefinition);
3463         }
3464         return result;
3465     }
3466
3467     public StorageOperationStatus associatePoliciesToComponent(String componentId, List<PolicyDefinition> policies) {
3468         log.debug("#associatePoliciesToComponent - associating policies for component {}.", componentId);
3469         return janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata)
3470             .either(containerVertex -> topologyTemplateOperation.addPoliciesToToscaElement(containerVertex, policies),
3471                 DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
3472     }
3473
3474     public Either<PolicyDefinition, StorageOperationStatus> updatePolicyOfComponent(String componentId, PolicyDefinition policyDefinition,
3475                                                                                     PromoteVersionEnum promoteVersionEnum) {
3476         Either<PolicyDefinition, StorageOperationStatus> result = null;
3477         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither;
3478         getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
3479         if (getVertexEither.isRight()) {
3480             log.error(COULDNT_FETCH_A_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
3481             result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value()));
3482         }
3483         if (result == null) {
3484             policyDefinition.setVersion(GroupUtils.updateVersion(promoteVersionEnum, policyDefinition.getVersion()));
3485             StorageOperationStatus status = topologyTemplateOperation.updatePolicyOfToscaElement(getVertexEither.left().value(), policyDefinition);
3486             if (status != StorageOperationStatus.OK) {
3487                 return Either.right(status);
3488             }
3489         }
3490         if (result == null) {
3491             result = Either.left(policyDefinition);
3492         }
3493         return result;
3494     }
3495
3496     public StorageOperationStatus updatePoliciesOfComponent(String componentId, List<PolicyDefinition> policyDefinition) {
3497         log.debug("#updatePoliciesOfComponent - updating policies for component {}", componentId);
3498         return janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse).right()
3499             .map(DaoStatusConverter::convertJanusGraphStatusToStorageStatus)
3500             .either(containerVertex -> topologyTemplateOperation.updatePoliciesOfToscaElement(containerVertex, policyDefinition), err -> err);
3501     }
3502
3503     public StorageOperationStatus removePolicyFromComponent(String componentId, String policyId) {
3504         StorageOperationStatus status = null;
3505         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
3506         if (getVertexEither.isRight()) {
3507             log.error(COULDNT_FETCH_A_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
3508             status = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value());
3509         }
3510         if (status == null) {
3511             status = topologyTemplateOperation.removePolicyFromToscaElement(getVertexEither.left().value(), policyId);
3512         }
3513         return status;
3514     }
3515
3516     public boolean canAddGroups(String componentId) {
3517         GraphVertex vertex = janusGraphDao.getVertexById(componentId).left().on(this::onJanusGraphError);
3518         return topologyTemplateOperation.hasEdgeOfType(vertex, EdgeLabelEnum.GROUPS);
3519     }
3520
3521     GraphVertex onJanusGraphError(JanusGraphOperationStatus toe) {
3522         throw new StorageException(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(toe));
3523     }
3524
3525     public CatalogUpdateTimestamp updateCatalogTimes() {
3526         long now = System.currentTimeMillis();
3527         GraphVertex catalogRoot = janusGraphDao.getVertexByLabel(VertexTypeEnum.CATALOG_ROOT).left().on(this::onJanusGraphError);
3528         Long currentTime = (Long) catalogRoot.getMetadataProperty(GraphPropertyEnum.CURRENT_CATALOG_UPDATE_TIME);
3529         catalogRoot.addMetadataProperty(GraphPropertyEnum.PREV_CATALOG_UPDATE_TIME, currentTime);
3530         catalogRoot.addMetadataProperty(GraphPropertyEnum.CURRENT_CATALOG_UPDATE_TIME, now);
3531         janusGraphDao.updateVertex(catalogRoot).left().on(this::onJanusGraphError);
3532         return new CatalogUpdateTimestamp(currentTime, now);
3533     }
3534
3535     public CatalogUpdateTimestamp getCatalogTimes() {
3536         GraphVertex catalogRoot = janusGraphDao.getVertexByLabel(VertexTypeEnum.CATALOG_ROOT).left().on(this::onJanusGraphError);
3537         Long currentTime = (Long) catalogRoot.getMetadataProperty(GraphPropertyEnum.CURRENT_CATALOG_UPDATE_TIME);
3538         Long prevTime = (Long) catalogRoot.getMetadataProperty(GraphPropertyEnum.PREV_CATALOG_UPDATE_TIME);
3539         return new CatalogUpdateTimestamp(prevTime == null ? 0 : prevTime.longValue(), currentTime == null ? 0 : currentTime.longValue());
3540     }
3541
3542     public void updateNamesOfCalculatedCapabilitiesRequirements(String componentId) {
3543         topologyTemplateOperation.updateNamesOfCalculatedCapabilitiesRequirements(componentId, getTopologyTemplate(componentId));
3544     }
3545
3546     public void revertNamesOfCalculatedCapabilitiesRequirements(String componentId) {
3547         topologyTemplateOperation.revertNamesOfCalculatedCapabilitiesRequirements(componentId, getTopologyTemplate(componentId));
3548     }
3549
3550     private TopologyTemplate getTopologyTemplate(String componentId) {
3551         return (TopologyTemplate) topologyTemplateOperation.getToscaElement(componentId, getFilterComponentWithCapProperties()).left()
3552             .on(this::throwStorageException);
3553     }
3554
3555     private ComponentParametersView getFilterComponentWithCapProperties() {
3556         ComponentParametersView filter = new ComponentParametersView();
3557         filter.setIgnoreCapabiltyProperties(false);
3558         return filter;
3559     }
3560
3561     private ToscaElement throwStorageException(StorageOperationStatus status) {
3562         throw new StorageException(status);
3563     }
3564
3565     public Either<Boolean, StorageOperationStatus> isComponentInUse(String componentId) {
3566         final List<EdgeLabelEnum> forbiddenEdgeLabelEnums = Arrays
3567             .asList(EdgeLabelEnum.INSTANCE_OF, EdgeLabelEnum.PROXY_OF, EdgeLabelEnum.ALLOTTED_OF);
3568         Either<GraphVertex, JanusGraphOperationStatus> vertexById = janusGraphDao.getVertexById(componentId);
3569         if (vertexById.isLeft()) {
3570             for (EdgeLabelEnum edgeLabelEnum : forbiddenEdgeLabelEnums) {
3571                 Iterator<Edge> edgeItr = vertexById.left().value().getVertex().edges(Direction.IN, edgeLabelEnum.name());
3572                 if (edgeItr != null && edgeItr.hasNext()) {
3573                     return Either.left(true);
3574                 }
3575             }
3576         }
3577         return Either.left(false);
3578     }
3579
3580     public Either<List<Component>, StorageOperationStatus> getComponentListByInvariantUuid(String componentInvariantUuid,
3581                                                                                            Map<GraphPropertyEnum, Object> additionalPropertiesToMatch) {
3582         Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
3583         if (MapUtils.isNotEmpty(additionalPropertiesToMatch)) {
3584             propertiesToMatch.putAll(additionalPropertiesToMatch);
3585         }
3586         propertiesToMatch.put(GraphPropertyEnum.INVARIANT_UUID, componentInvariantUuid);
3587         Either<List<GraphVertex>, JanusGraphOperationStatus> vertexEither = janusGraphDao
3588             .getByCriteria(null, propertiesToMatch, JsonParseFlagEnum.ParseMetadata);
3589         if (vertexEither.isRight()) {
3590             log.debug("Couldn't fetch metadata for component with type {} and invariantUUId {}, error: {}", componentInvariantUuid,
3591                 vertexEither.right().value());
3592             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(vertexEither.right().value()));
3593         }
3594         List<GraphVertex> vertexList = vertexEither.isLeft() ? vertexEither.left().value() : null;
3595         if (vertexList == null || vertexList.isEmpty()) {
3596             log.debug("Component with invariantUUId {} was not found", componentInvariantUuid);
3597             return Either.right(StorageOperationStatus.NOT_FOUND);
3598         }
3599         ArrayList<Component> components = new ArrayList<>();
3600         for (GraphVertex vertex : vertexList) {
3601             Either<Component, StorageOperationStatus> toscaElementByOperation = getToscaElementByOperation(vertex);
3602             if (toscaElementByOperation.isRight()) {
3603                 log.debug("Could not fetch the following Component by Invariant UUID {}", vertex.getUniqueId());
3604                 return Either.right(toscaElementByOperation.right().value());
3605             }
3606             components.add(toscaElementByOperation.left().value());
3607         }
3608         return Either.left(components);
3609     }
3610
3611     public Either<List<Component>, StorageOperationStatus> getParentComponents(String componentId) {
3612         List<Component> parentComponents = new ArrayList<>();
3613         final List<EdgeLabelEnum> relationEdgeLabelEnums = Arrays.asList(EdgeLabelEnum.INSTANCE_OF, EdgeLabelEnum.PROXY_OF);
3614         Either<GraphVertex, JanusGraphOperationStatus> vertexById = janusGraphDao.getVertexById(componentId);
3615         if (vertexById.isLeft()) {
3616             for (EdgeLabelEnum edgeLabelEnum : relationEdgeLabelEnums) {
3617                 Either<GraphVertex, JanusGraphOperationStatus> parentVertexEither = janusGraphDao
3618                     .getParentVertex(vertexById.left().value(), edgeLabelEnum, JsonParseFlagEnum.ParseJson);
3619                 if (parentVertexEither.isLeft()) {
3620                     Either<Component, StorageOperationStatus> componentEither = getToscaElement(parentVertexEither.left().value().getUniqueId());
3621                     if (componentEither.isLeft()) {
3622                         parentComponents.add(componentEither.left().value());
3623                     }
3624                 }
3625             }
3626         }
3627         return Either.left(parentComponents);
3628     }
3629
3630     public void updateCapReqPropertiesOwnerId(String componentId) {
3631         topologyTemplateOperation.updateCapReqPropertiesOwnerId(componentId, getTopologyTemplate(componentId));
3632     }
3633
3634     public <T extends Component> Either<T, StorageOperationStatus> getLatestByServiceName(String serviceName) {
3635         return getLatestByName(GraphPropertyEnum.NAME, serviceName, null);
3636     }
3637 }