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