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