Fix import VFC with attributes
[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 StorageOperationStatus deletePropertyOfComponent(Component component, String propertyName) {
2486                 return getToscaElementOperation(component).deleteToscaDataElement(component.getUniqueId(), EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, propertyName, JsonPresentationFields.NAME);
2487         }
2488
2489         public StorageOperationStatus deleteAttributeOfResource(Component component, String attributeName) {
2490                 return getToscaElementOperation(component).deleteToscaDataElement(component.getUniqueId(), EdgeLabelEnum.ATTRIBUTES, VertexTypeEnum.ATTRIBUTES, attributeName, JsonPresentationFields.NAME);
2491         }
2492
2493     public StorageOperationStatus deleteInputOfResource(Component resource, String inputName) {
2494         return getToscaElementOperation(resource).deleteToscaDataElement(resource.getUniqueId(), EdgeLabelEnum.INPUTS, VertexTypeEnum.INPUTS, inputName, JsonPresentationFields.NAME);
2495     }
2496
2497     /**
2498      * Deletes a data type from a component.
2499      * @param component the container which has the data type
2500      * @param dataTypeName the data type name to be deleted
2501      * @return Operation result.
2502      */
2503     public StorageOperationStatus deleteDataTypeOfComponent(Component component, String dataTypeName) {
2504         return getToscaElementOperation(component).deleteToscaDataElement(component.getUniqueId(), EdgeLabelEnum.DATA_TYPES, VertexTypeEnum.DATA_TYPES, dataTypeName, JsonPresentationFields.NAME);
2505     }
2506
2507         public Either<PropertyDefinition, StorageOperationStatus> updatePropertyOfComponent(Component component,
2508                                                                                                                                                                                 PropertyDefinition newPropertyDefinition) {
2509
2510                 Either<Component, StorageOperationStatus> getUpdatedComponentRes = null;
2511                 Either<PropertyDefinition, StorageOperationStatus> result = null;
2512                 StorageOperationStatus status = getToscaElementOperation(component).updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, newPropertyDefinition, JsonPresentationFields.NAME);
2513                 if (status != StorageOperationStatus.OK) {
2514                         CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add the property {} to the resource {}. Status is {}. ", newPropertyDefinition.getName(), component.getName(), status);
2515                         result = Either.right(status);
2516                 }
2517                 if (result == null) {
2518                         ComponentParametersView filter = new ComponentParametersView(true);
2519                         filter.setIgnoreProperties(false);
2520                         getUpdatedComponentRes = getToscaElement(component.getUniqueId(), filter);
2521                         if (getUpdatedComponentRes.isRight()) {
2522                                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to get updated resource {}. Status is {}. ", component.getUniqueId(), getUpdatedComponentRes.right().value());
2523                                 result = Either.right(status);
2524                         }
2525                 }
2526                 if (result == null) {
2527                         Optional<PropertyDefinition> newProperty = (getUpdatedComponentRes.left().value())
2528                                         .getProperties().stream().filter(p -> p.getName().equals(newPropertyDefinition.getName())).findAny();
2529                         if (newProperty.isPresent()) {
2530                                 result = Either.left(newProperty.get());
2531                         } else {
2532                                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find recently added property {} on the resource {}. Status is {}. ", newPropertyDefinition.getName(), component.getUniqueId(), StorageOperationStatus.NOT_FOUND);
2533                                 result = Either.right(StorageOperationStatus.NOT_FOUND);
2534                         }
2535                 }
2536                 return result;
2537         }
2538
2539
2540         public Either<AttributeDataDefinition, StorageOperationStatus> addAttributeOfResource(Component component, AttributeDataDefinition newAttributeDef) {
2541
2542         Either<Component, StorageOperationStatus> getUpdatedComponentRes = null;
2543         Either<AttributeDataDefinition, StorageOperationStatus> result = null;
2544         if (newAttributeDef.getUniqueId() == null || newAttributeDef.getUniqueId().isEmpty()) {
2545             String attUniqueId = UniqueIdBuilder.buildAttributeUid(component.getUniqueId(), newAttributeDef.getName());
2546             newAttributeDef.setUniqueId(attUniqueId);
2547             newAttributeDef.setOwnerId(component.getUniqueId());
2548         }
2549
2550         StorageOperationStatus status = getToscaElementOperation(component).addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.ATTRIBUTES, VertexTypeEnum.ATTRIBUTES, newAttributeDef, JsonPresentationFields.NAME);
2551         if (status != StorageOperationStatus.OK) {
2552             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_ADD_THE_PROPERTY_TO_THE_RESOURCE_STATUS_IS, newAttributeDef.getName(), component.getName(), status);
2553             result = Either.right(status);
2554         }
2555         if (result == null) {
2556             ComponentParametersView filter = new ComponentParametersView(true);
2557             filter.setIgnoreAttributesFrom(false);
2558             getUpdatedComponentRes = getToscaElement(component.getUniqueId(), filter);
2559             if (getUpdatedComponentRes.isRight()) {
2560                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_UPDATED_RESOURCE_STATUS_IS, component.getUniqueId(), getUpdatedComponentRes.right().value());
2561                 result = Either.right(status);
2562             }
2563         }
2564         if (result == null) {
2565             Optional<AttributeDataDefinition> newAttribute = ((Resource) getUpdatedComponentRes.left().value())
2566                 .getAttributes().stream().filter(p -> p.getName().equals(newAttributeDef.getName())).findAny();
2567             if (newAttribute.isPresent()) {
2568                 result = Either.left(newAttribute.get());
2569             } else {
2570                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FIND_RECENTLY_ADDED_PROPERTY_ON_THE_RESOURCE_STATUS_IS, newAttributeDef.getName(), component.getUniqueId(), StorageOperationStatus.NOT_FOUND);
2571                 result = Either.right(StorageOperationStatus.NOT_FOUND);
2572             }
2573         }
2574         return result;
2575     }
2576
2577     public Either<AttributeDataDefinition, StorageOperationStatus> updateAttributeOfResource(Component component, AttributeDataDefinition newAttributeDef) {
2578
2579         Either<Component, StorageOperationStatus> getUpdatedComponentRes = null;
2580         Either<AttributeDataDefinition, StorageOperationStatus> result = null;
2581         StorageOperationStatus status = getToscaElementOperation(component).updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.ATTRIBUTES, VertexTypeEnum.ATTRIBUTES, newAttributeDef, JsonPresentationFields.NAME);
2582         if (status != StorageOperationStatus.OK) {
2583             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_ADD_THE_PROPERTY_TO_THE_RESOURCE_STATUS_IS, newAttributeDef.getName(), component.getName(), status);
2584             result = Either.right(status);
2585         }
2586         if (result == null) {
2587             ComponentParametersView filter = new ComponentParametersView(true);
2588             filter.setIgnoreAttributesFrom(false);
2589             getUpdatedComponentRes = getToscaElement(component.getUniqueId(), filter);
2590             if (getUpdatedComponentRes.isRight()) {
2591                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_UPDATED_RESOURCE_STATUS_IS, component.getUniqueId(), getUpdatedComponentRes.right().value());
2592                 result = Either.right(status);
2593             }
2594         }
2595         if (result == null) {
2596             Optional<AttributeDataDefinition> newProperty = ((Resource) getUpdatedComponentRes.left().value())
2597                 .getAttributes().stream().filter(p -> p.getName().equals(newAttributeDef.getName())).findAny();
2598             if (newProperty.isPresent()) {
2599                 result = Either.left(newProperty.get());
2600             } else {
2601                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FIND_RECENTLY_ADDED_PROPERTY_ON_THE_RESOURCE_STATUS_IS, newAttributeDef.getName(), component.getUniqueId(), StorageOperationStatus.NOT_FOUND);
2602                 result = Either.right(StorageOperationStatus.NOT_FOUND);
2603             }
2604         }
2605         return result;
2606     }
2607
2608     public Either<InputDefinition, StorageOperationStatus> updateInputOfComponent(Component component, InputDefinition newInputDefinition) {
2609
2610         Either<Component, StorageOperationStatus> getUpdatedComponentRes = null;
2611         Either<InputDefinition, StorageOperationStatus> result = null;
2612         StorageOperationStatus status = getToscaElementOperation(component).updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.INPUTS, VertexTypeEnum.INPUTS, newInputDefinition, JsonPresentationFields.NAME);
2613         if (status != StorageOperationStatus.OK) {
2614             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update the input {} to the component {}. Status is {}. ", newInputDefinition.getName(), component.getName(), status);
2615             result = Either.right(status);
2616         }
2617         if (result == null) {
2618             ComponentParametersView filter = new ComponentParametersView(true);
2619             filter.setIgnoreInputs(false);
2620             getUpdatedComponentRes = getToscaElement(component.getUniqueId(), filter);
2621             if (getUpdatedComponentRes.isRight()) {
2622                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_UPDATED_RESOURCE_STATUS_IS, component.getUniqueId(), getUpdatedComponentRes.right().value());
2623                 result = Either.right(status);
2624             }
2625         }
2626         if (result == null) {
2627             Optional<InputDefinition> updatedInput = getUpdatedComponentRes.left().value().getInputs().stream().filter(p -> p.getName().equals(newInputDefinition.getName())).findAny();
2628             if (updatedInput.isPresent()) {
2629                 result = Either.left(updatedInput.get());
2630             } else {
2631                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find recently updated inputs {} on the resource {}. Status is {}. ", newInputDefinition.getName(), component.getUniqueId(), StorageOperationStatus.NOT_FOUND);
2632                 result = Either.right(StorageOperationStatus.NOT_FOUND);
2633             }
2634         }
2635         return result;
2636     }
2637
2638     /**
2639      * method - ename the group instances after referenced container name renamed flow - VF rename -(triggers)-> Group rename
2640      *
2641      * @param containerComponent  - container such as service
2642      * @param componentInstance   - context component
2643      * @param componentInstanceId - id
2644      * @return - successfull/failed status
2645      **/
2646     public Either<StorageOperationStatus, StorageOperationStatus> cleanAndAddGroupInstancesToComponentInstance(Component containerComponent, ComponentInstance componentInstance, String componentInstanceId) {
2647         String uniqueId = componentInstance.getUniqueId();
2648         StorageOperationStatus status = nodeTemplateOperation.deleteToscaDataDeepElementsBlockOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, uniqueId);
2649         if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
2650             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete group instances for container {}. error {] ", componentInstanceId, status);
2651             return Either.right(status);
2652         }
2653         if (componentInstance.getGroupInstances() != null) {
2654             status = addGroupInstancesToComponentInstance(containerComponent, componentInstance, componentInstance.getGroupInstances());
2655             if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
2656                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add group instances for container {}. error {] ", componentInstanceId, status);
2657                 return Either.right(status);
2658             }
2659         }
2660         return Either.left(status);
2661     }
2662
2663     public StorageOperationStatus addGroupInstancesToComponentInstance(Component containerComponent, ComponentInstance componentInstance, List<GroupDefinition> groups, Map<String, List<ArtifactDefinition>> groupInstancesArtifacts) {
2664         return nodeTemplateOperation.addGroupInstancesToComponentInstance(containerComponent, componentInstance, groups, groupInstancesArtifacts);
2665     }
2666
2667     public Either<List<GroupDefinition>, StorageOperationStatus> updateGroupsOnComponent(Component component, List<GroupDataDefinition> updatedGroups) {
2668         return groupsOperation.updateGroups(component, updatedGroups, PromoteVersionEnum.MINOR);
2669     }
2670
2671     public Either<List<GroupInstance>, StorageOperationStatus> updateGroupInstancesOnComponent(Component component, String instanceId, List<GroupInstance> updatedGroupInstances) {
2672         return groupsOperation.updateGroupInstances(component, instanceId, updatedGroupInstances);
2673     }
2674
2675     public StorageOperationStatus addGroupInstancesToComponentInstance(Component containerComponent, ComponentInstance componentInstance, List<GroupInstance> groupInstances) {
2676         return nodeTemplateOperation.addGroupInstancesToComponentInstance(containerComponent, componentInstance, groupInstances);
2677     }
2678
2679     public StorageOperationStatus addDeploymentArtifactsToComponentInstance(Component containerComponent, ComponentInstance componentInstance, Map<String, ArtifactDefinition> deploymentArtifacts) {
2680         return nodeTemplateOperation.addDeploymentArtifactsToComponentInstance(containerComponent, componentInstance, deploymentArtifacts);
2681     }
2682
2683     public StorageOperationStatus updateComponentInstanceProperty(Component containerComponent, String componentInstanceId, ComponentInstanceProperty property) {
2684         return nodeTemplateOperation.updateComponentInstanceProperty(containerComponent, componentInstanceId, property);
2685     }
2686
2687     public StorageOperationStatus updateComponentInstanceProperties(Component containerComponent, String componentInstanceId, List<ComponentInstanceProperty> properties) {
2688         return nodeTemplateOperation.updateComponentInstanceProperties(containerComponent, componentInstanceId, properties);
2689     }
2690
2691
2692     public StorageOperationStatus addComponentInstanceProperty(Component containerComponent, String componentInstanceId, ComponentInstanceProperty property) {
2693         return nodeTemplateOperation.addComponentInstanceProperty(containerComponent, componentInstanceId, property);
2694     }
2695
2696     public StorageOperationStatus updateComponentInstanceAttribute(Component containerComponent, String componentInstanceId, ComponentInstanceAttribute property){
2697         return nodeTemplateOperation.updateComponentInstanceAttribute(containerComponent, componentInstanceId, property);
2698     }
2699
2700     public StorageOperationStatus addComponentInstanceAttribute(Component containerComponent, String componentInstanceId, ComponentInstanceAttribute attribute){
2701         return nodeTemplateOperation.addComponentInstanceAttribute(containerComponent, componentInstanceId, attribute);
2702     }
2703
2704     public StorageOperationStatus updateComponentInstanceInput(Component containerComponent, String componentInstanceId, ComponentInstanceInput property) {
2705         return nodeTemplateOperation.updateComponentInstanceInput(containerComponent, componentInstanceId, property);
2706     }
2707
2708     public StorageOperationStatus updateComponentInstanceInputs(Component containerComponent, String componentInstanceId, List<ComponentInstanceInput> instanceInputs) {
2709         return nodeTemplateOperation.updateComponentInstanceInputs(containerComponent, componentInstanceId, instanceInputs);
2710     }
2711
2712     public StorageOperationStatus addComponentInstanceInput(Component containerComponent, String componentInstanceId, ComponentInstanceInput property) {
2713         return nodeTemplateOperation.addComponentInstanceInput(containerComponent, componentInstanceId, property);
2714     }
2715
2716     public void setNodeTypeOperation(NodeTypeOperation nodeTypeOperation) {
2717         this.nodeTypeOperation = nodeTypeOperation;
2718     }
2719
2720     public void setTopologyTemplateOperation(TopologyTemplateOperation topologyTemplateOperation) {
2721         this.topologyTemplateOperation = topologyTemplateOperation;
2722     }
2723
2724     public StorageOperationStatus deleteComponentInstanceInputsFromTopologyTemplate(Component containerComponent, List<InputDefinition> inputsToDelete) {
2725         return topologyTemplateOperation.deleteToscaDataElements(containerComponent.getUniqueId(), EdgeLabelEnum.INPUTS, inputsToDelete.stream().map(PropertyDataDefinition::getName).collect(Collectors.toList()));
2726     }
2727
2728     public StorageOperationStatus updateComponentInstanceCapabiltyProperty(Component containerComponent, String componentInstanceUniqueId, String capabilityPropertyKey, ComponentInstanceProperty property) {
2729         return nodeTemplateOperation.updateComponentInstanceCapabilityProperty(containerComponent, componentInstanceUniqueId, capabilityPropertyKey, property);
2730     }
2731
2732     public StorageOperationStatus updateComponentInstanceCapabilityProperties(Component containerComponent, String componentInstanceUniqueId) {
2733         return convertComponentInstanceProperties(containerComponent, componentInstanceUniqueId)
2734                 .map(instanceCapProps -> topologyTemplateOperation.updateComponentInstanceCapabilityProperties(containerComponent, componentInstanceUniqueId, instanceCapProps))
2735                 .orElse(StorageOperationStatus.NOT_FOUND);
2736     }
2737     
2738     public StorageOperationStatus updateComponentInstanceRequirement(String containerComponentId, String componentInstanceUniqueId, RequirementDataDefinition requirementDataDefinition) {
2739         return nodeTemplateOperation.updateComponentInstanceRequirement(containerComponentId, componentInstanceUniqueId, requirementDataDefinition);
2740     }
2741
2742     public StorageOperationStatus updateComponentInstanceInterfaces(Component containerComponent, String componentInstanceUniqueId) {
2743         MapInterfaceDataDefinition mapInterfaceDataDefinition =
2744                 convertComponentInstanceInterfaces(containerComponent, componentInstanceUniqueId);
2745         return topologyTemplateOperation
2746                 .updateComponentInstanceInterfaces(containerComponent, componentInstanceUniqueId, mapInterfaceDataDefinition);
2747     }
2748
2749         public StorageOperationStatus updateComponentCalculatedCapabilitiesProperties(Component containerComponent) {
2750                 Map<String, MapCapabilityProperty> mapCapabiltyPropertyMap =
2751         convertComponentCapabilitiesProperties(containerComponent);
2752                 return nodeTemplateOperation.overrideComponentCapabilitiesProperties(containerComponent, mapCapabiltyPropertyMap);
2753         }
2754
2755     public StorageOperationStatus deleteAllCalculatedCapabilitiesRequirements(String topologyTemplateId) {
2756         StorageOperationStatus status = topologyTemplateOperation.removeToscaData(topologyTemplateId, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES);
2757         if (status == StorageOperationStatus.OK) {
2758             status = topologyTemplateOperation.removeToscaData(topologyTemplateId, EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS);
2759         }
2760         if (status == StorageOperationStatus.OK) {
2761             status = topologyTemplateOperation.removeToscaData(topologyTemplateId, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES);
2762         }
2763         return status;
2764     }
2765
2766     public Either<Component, StorageOperationStatus> shouldUpgradeToLatestDerived(Resource clonedResource) {
2767         String componentId = clonedResource.getUniqueId();
2768         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao
2769             .getVertexById(componentId, JsonParseFlagEnum.NoParse);
2770         if (getVertexEither.isRight()) {
2771             log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
2772             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value()));
2773
2774         }
2775         GraphVertex nodeTypeV = getVertexEither.left().value();
2776
2777         ToscaElement toscaElementToUpdate = ModelConverter.convertToToscaElement(clonedResource);
2778
2779         Either<ToscaElement, StorageOperationStatus> shouldUpdateDerivedVersion = nodeTypeOperation.shouldUpdateDerivedVersion(toscaElementToUpdate, nodeTypeV);
2780         if (shouldUpdateDerivedVersion.isRight() && StorageOperationStatus.OK != shouldUpdateDerivedVersion.right().value()) {
2781             log.debug("Failed to update derived version for node type {} derived {}, error: {}", componentId, clonedResource.getDerivedFrom().get(0), shouldUpdateDerivedVersion.right().value());
2782             return Either.right(shouldUpdateDerivedVersion.right().value());
2783         }
2784         if (shouldUpdateDerivedVersion.isLeft()) {
2785             return Either.left(ModelConverter.convertFromToscaElement(shouldUpdateDerivedVersion.left().value()));
2786         }
2787         return Either.left(clonedResource);
2788     }
2789
2790     /**
2791      * Returns list of ComponentInstanceProperty belonging to component instance capability specified by name, type and ownerId
2792      */
2793     public Either<List<ComponentInstanceProperty>, StorageOperationStatus> getComponentInstanceCapabilityProperties(String componentId, String instanceId, String capabilityName, String capabilityType, String ownerId) {
2794         return topologyTemplateOperation.getComponentInstanceCapabilityProperties(componentId, instanceId, capabilityName, capabilityType, ownerId);
2795     }
2796
2797         private MapInterfaceDataDefinition convertComponentInstanceInterfaces(Component currComponent,
2798                                                                                                                                                                                                                                                                                                 String componentInstanceId) {
2799                 MapInterfaceDataDefinition mapInterfaceDataDefinition = new MapInterfaceDataDefinition();
2800                 List<ComponentInstanceInterface> componentInterface = currComponent.getComponentInstancesInterfaces().get(componentInstanceId);
2801
2802                 if(CollectionUtils.isNotEmpty(componentInterface)) {
2803                         componentInterface.stream().forEach(interfaceDef -> mapInterfaceDataDefinition.put
2804                                         (interfaceDef.getUniqueId(), interfaceDef));
2805                 }
2806
2807                 return mapInterfaceDataDefinition;
2808         }
2809
2810   private Map<String, MapCapabilityProperty> convertComponentCapabilitiesProperties(Component currComponent) {
2811     Map<String, MapCapabilityProperty> map = ModelConverter.extractCapabilityPropertiesFromGroups(currComponent.getGroups(), true);
2812     map.putAll(ModelConverter.extractCapabilityProperteisFromInstances(currComponent.getComponentInstances(), true));
2813     return map;
2814   }
2815
2816     private Optional<MapCapabilityProperty> convertComponentInstanceProperties(Component component, String instanceId) {
2817         return component.fetchInstanceById(instanceId)
2818                 .map(ci -> ModelConverter.convertToMapOfMapCapabilityProperties(ci.getCapabilities(), instanceId, ci.getOriginType().isAtomicType()));
2819     }
2820
2821     public Either<PolicyDefinition, StorageOperationStatus> associatePolicyToComponent(String componentId, PolicyDefinition policyDefinition, int counter) {
2822         Either<PolicyDefinition, StorageOperationStatus> result = null;
2823         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither;
2824         getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata);
2825         if (getVertexEither.isRight()) {
2826             log.error(COULDNT_FETCH_A_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
2827             result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value()));
2828         } else {
2829             if (getVertexEither.left().value().getLabel() != VertexTypeEnum.TOPOLOGY_TEMPLATE) {
2830                 log.error("Policy association to component of Tosca type {} is not allowed. ", getVertexEither.left().value().getLabel());
2831                 result = Either.right(StorageOperationStatus.BAD_REQUEST);
2832             }
2833         }
2834         if (result == null) {
2835             StorageOperationStatus status = topologyTemplateOperation.addPolicyToToscaElement(getVertexEither.left().value(), policyDefinition, counter);
2836             if (status != StorageOperationStatus.OK) {
2837                 return Either.right(status);
2838             }
2839         }
2840         if (result == null) {
2841             result = Either.left(policyDefinition);
2842         }
2843         return result;
2844     }
2845
2846     public StorageOperationStatus associatePoliciesToComponent(String componentId, List<PolicyDefinition> policies) {
2847         log.debug("#associatePoliciesToComponent - associating policies for component {}.", componentId);
2848         return janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata)
2849                 .either(containerVertex -> topologyTemplateOperation.addPoliciesToToscaElement(containerVertex, policies),
2850                         DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
2851     }
2852
2853     public Either<PolicyDefinition, StorageOperationStatus> updatePolicyOfComponent(String componentId, PolicyDefinition policyDefinition, PromoteVersionEnum promoteVersionEnum) {
2854         Either<PolicyDefinition, StorageOperationStatus> result = null;
2855         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither;
2856         getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
2857         if (getVertexEither.isRight()) {
2858             log.error(COULDNT_FETCH_A_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
2859             result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value()));
2860         }
2861         if (result == null) {
2862             policyDefinition.setVersion(GroupUtils.updateVersion(promoteVersionEnum, policyDefinition.getVersion()));
2863             StorageOperationStatus status = topologyTemplateOperation.updatePolicyOfToscaElement(getVertexEither.left().value(), policyDefinition);
2864             if (status != StorageOperationStatus.OK) {
2865                 return Either.right(status);
2866             }
2867         }
2868         if (result == null) {
2869             result = Either.left(policyDefinition);
2870         }
2871         return result;
2872     }
2873
2874     public StorageOperationStatus updatePoliciesOfComponent(String componentId, List<PolicyDefinition> policyDefinition) {
2875         log.debug("#updatePoliciesOfComponent - updating policies for component {}", componentId);
2876         return janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse)
2877                 .right()
2878                 .map(DaoStatusConverter::convertJanusGraphStatusToStorageStatus)
2879                 .either(containerVertex -> topologyTemplateOperation.updatePoliciesOfToscaElement(containerVertex, policyDefinition),
2880                         err -> err);
2881     }
2882
2883     public StorageOperationStatus removePolicyFromComponent(String componentId, String policyId) {
2884         StorageOperationStatus status = null;
2885         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao
2886             .getVertexById(componentId, JsonParseFlagEnum.NoParse);
2887         if (getVertexEither.isRight()) {
2888             log.error(COULDNT_FETCH_A_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
2889             status = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value());
2890         }
2891         if (status == null) {
2892             status = topologyTemplateOperation.removePolicyFromToscaElement(getVertexEither.left().value(), policyId);
2893         }
2894         return status;
2895     }
2896
2897     public boolean canAddGroups(String componentId) {
2898         GraphVertex vertex = janusGraphDao.getVertexById(componentId)
2899                 .left()
2900                 .on(this::onJanusGraphError);
2901         return topologyTemplateOperation.hasEdgeOfType(vertex, EdgeLabelEnum.GROUPS);
2902     }
2903
2904     GraphVertex onJanusGraphError(JanusGraphOperationStatus toe) {
2905         throw new StorageException(
2906                 DaoStatusConverter.convertJanusGraphStatusToStorageStatus(toe));
2907     }
2908
2909     public CatalogUpdateTimestamp updateCatalogTimes() {
2910         long now = System.currentTimeMillis();
2911
2912         GraphVertex catalogRoot = janusGraphDao.getVertexByLabel(VertexTypeEnum.CATALOG_ROOT)
2913                 .left()
2914                 .on(this::onJanusGraphError);
2915
2916         Long currentTime = (Long) catalogRoot.getMetadataProperty(GraphPropertyEnum.CURRENT_CATALOG_UPDATE_TIME);
2917         catalogRoot.addMetadataProperty(GraphPropertyEnum.PREV_CATALOG_UPDATE_TIME, currentTime);
2918         catalogRoot.addMetadataProperty(GraphPropertyEnum.CURRENT_CATALOG_UPDATE_TIME, now);
2919
2920         janusGraphDao.updateVertex(catalogRoot).left().on(this::onJanusGraphError);
2921
2922         return new CatalogUpdateTimestamp(currentTime, now);
2923     }
2924
2925     public CatalogUpdateTimestamp getCatalogTimes() {
2926
2927
2928         GraphVertex catalogRoot = janusGraphDao.getVertexByLabel(VertexTypeEnum.CATALOG_ROOT)
2929                 .left()
2930                 .on(this::onJanusGraphError);
2931
2932         Long currentTime = (Long) catalogRoot.getMetadataProperty(GraphPropertyEnum.CURRENT_CATALOG_UPDATE_TIME);
2933         Long prevTime = (Long) catalogRoot.getMetadataProperty(GraphPropertyEnum.PREV_CATALOG_UPDATE_TIME);
2934
2935         return new CatalogUpdateTimestamp(prevTime == null ? 0 : prevTime.longValue(), currentTime == null ? 0 : currentTime.longValue());
2936     }
2937
2938     public void updateNamesOfCalculatedCapabilitiesRequirements(String componentId) {
2939         topologyTemplateOperation
2940                 .updateNamesOfCalculatedCapabilitiesRequirements(componentId, getTopologyTemplate(componentId));
2941     }
2942
2943     public void revertNamesOfCalculatedCapabilitiesRequirements(String componentId) {
2944         topologyTemplateOperation
2945                 .revertNamesOfCalculatedCapabilitiesRequirements(componentId, getTopologyTemplate(componentId));
2946     }
2947
2948     private TopologyTemplate getTopologyTemplate(String componentId) {
2949         return (TopologyTemplate) topologyTemplateOperation
2950                 .getToscaElement(componentId, getFilterComponentWithCapProperties())
2951                 .left()
2952                 .on(this::throwStorageException);
2953     }
2954
2955     private ComponentParametersView getFilterComponentWithCapProperties() {
2956         ComponentParametersView filter = new ComponentParametersView();
2957         filter.setIgnoreCapabiltyProperties(false);
2958         return filter;
2959     }
2960
2961     private ToscaElement throwStorageException(StorageOperationStatus status) {
2962         throw new StorageException(status);
2963     }
2964
2965     public Either<Boolean, StorageOperationStatus> isComponentInUse(String componentId) {
2966         final List<EdgeLabelEnum> forbiddenEdgeLabelEnums = Arrays.asList(EdgeLabelEnum.INSTANCE_OF, EdgeLabelEnum.PROXY_OF, EdgeLabelEnum.ALLOTTED_OF);
2967         Either<GraphVertex, JanusGraphOperationStatus> vertexById = janusGraphDao.getVertexById(componentId);
2968         if (vertexById.isLeft()) {
2969             for (EdgeLabelEnum edgeLabelEnum : forbiddenEdgeLabelEnums) {
2970                 Iterator<Edge> edgeItr = vertexById.left().value().getVertex().edges(Direction.IN, edgeLabelEnum.name());
2971                 if(edgeItr != null && edgeItr.hasNext()){
2972                     return Either.left(true);
2973                 }
2974             }
2975         }
2976         return Either.left(false);
2977     }
2978
2979         public Either<List<Component>, StorageOperationStatus> getComponentListByInvariantUuid
2980                         (String componentInvariantUuid, Map<GraphPropertyEnum, Object> additionalPropertiesToMatch) {
2981
2982                 Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
2983                 if (MapUtils.isNotEmpty(additionalPropertiesToMatch)) {
2984                         propertiesToMatch.putAll(additionalPropertiesToMatch);
2985                 }
2986                 propertiesToMatch.put(GraphPropertyEnum.INVARIANT_UUID, componentInvariantUuid);
2987
2988                 Either<List<GraphVertex>, JanusGraphOperationStatus> vertexEither = janusGraphDao
2989         .getByCriteria(null, propertiesToMatch, JsonParseFlagEnum.ParseMetadata);
2990
2991                 if (vertexEither.isRight()) {
2992                         log.debug("Couldn't fetch metadata for component with type {} and invariantUUId {}, error: {}", componentInvariantUuid, vertexEither.right().value());
2993                         return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(vertexEither.right().value()));
2994                 }
2995                 List<GraphVertex> vertexList = vertexEither.isLeft() ? vertexEither.left().value() : null;
2996
2997                 if (vertexList == null || vertexList.isEmpty()) {
2998                         log.debug("Component with invariantUUId {} was not found", componentInvariantUuid);
2999                         return Either.right(StorageOperationStatus.NOT_FOUND);
3000                 }
3001
3002                 ArrayList<Component> components = new ArrayList<>();
3003                 for (GraphVertex vertex : vertexList) {
3004                         Either<Component, StorageOperationStatus> toscaElementByOperation = getToscaElementByOperation(vertex);
3005                         if (toscaElementByOperation.isRight()) {
3006                                 log.debug("Could not fetch the following Component by Invariant UUID {}", vertex.getUniqueId());
3007                                 return Either.right(toscaElementByOperation.right().value());
3008                         }
3009                         components.add(toscaElementByOperation.left().value());
3010                 }
3011
3012                 return Either.left(components);
3013         }
3014
3015     public Either<List<Component>, StorageOperationStatus> getParentComponents(String componentId) {
3016         List<Component> parentComponents = new ArrayList<>();
3017         final List<EdgeLabelEnum> relationEdgeLabelEnums = Arrays.asList(EdgeLabelEnum.INSTANCE_OF, EdgeLabelEnum.PROXY_OF);
3018         Either<GraphVertex, JanusGraphOperationStatus> vertexById = janusGraphDao.getVertexById(componentId);
3019         if (vertexById.isLeft()) {
3020             for (EdgeLabelEnum edgeLabelEnum : relationEdgeLabelEnums) {
3021                 Either<GraphVertex, JanusGraphOperationStatus> parentVertexEither = janusGraphDao
3022                     .getParentVertex(vertexById.left().value(), edgeLabelEnum, JsonParseFlagEnum.ParseJson);
3023                 if(parentVertexEither.isLeft()){
3024                     Either<Component, StorageOperationStatus> componentEither = getToscaElement(parentVertexEither.left().value().getUniqueId());
3025                     if(componentEither.isLeft()){
3026                         parentComponents.add(componentEither.left().value());
3027                     }
3028                 }
3029             }
3030         }
3031         return Either.left(parentComponents);
3032     }
3033     public void updateCapReqPropertiesOwnerId(String componentId) {
3034         topologyTemplateOperation
3035                 .updateCapReqPropertiesOwnerId(componentId, getTopologyTemplate(componentId));
3036     }
3037
3038     public <T extends Component> Either<T, StorageOperationStatus> getLatestByServiceName(String serviceName) {
3039         return getLatestByName(GraphPropertyEnum.NAME, serviceName);
3040
3041     }
3042 }