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