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