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