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