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