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