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