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