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