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