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