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