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