f02fc2da7d8d266edf1cbb90ae28ed054f9cdada
[sdc.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2019 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 package org.openecomp.sdc.be.model.operations.impl;
21
22 import static org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR;
23
24 import fj.data.Either;
25 import java.util.ArrayList;
26 import java.util.Collections;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30 import org.apache.commons.collections.MapUtils;
31 import org.apache.commons.lang3.tuple.ImmutablePair;
32 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
33 import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
34 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
35 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
36 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
37 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
38 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
39 import org.openecomp.sdc.be.model.PropertyDefinition;
40 import org.openecomp.sdc.be.model.RelationshipTypeDefinition;
41 import org.openecomp.sdc.be.model.operations.api.DerivedFromOperation;
42 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
43 import org.openecomp.sdc.be.resources.data.ModelData;
44 import org.openecomp.sdc.be.resources.data.PropertyData;
45 import org.openecomp.sdc.be.resources.data.RelationshipTypeData;
46 import org.openecomp.sdc.be.resources.data.UniqueIdData;
47 import org.openecomp.sdc.common.log.wrappers.Logger;
48 import org.springframework.beans.factory.annotation.Autowired;
49 import org.springframework.stereotype.Component;
50
51 @Component("relationship-type-operation")
52 public class RelationshipTypeOperation extends AbstractOperation {
53
54     private static final Logger logger = Logger.getLogger(RelationshipTypeOperation.class.getName());
55     private static final String RELATIONSHIP_TYPE_CANNOT_BE_FOUND_IN_GRAPH_STATUS_IS =
56         "Relationship type {} cannot be " + "found in " + "graph status is {}";
57     private static final String FAILED_TO_FETCH_PROPERTIES_OF_RELATIONSHIP_TYPE = "Failed to fetch properties of " + "relationship type {}";
58     @Autowired
59     private PropertyOperation propertyOperation;
60     @Autowired
61     private DerivedFromOperation derivedFromOperation;
62
63     public Either<RelationshipTypeDefinition, JanusGraphOperationStatus> getRelationshipTypeByUid(String uniqueId) {
64         Either<RelationshipTypeDefinition, JanusGraphOperationStatus> result;
65         Either<RelationshipTypeData, JanusGraphOperationStatus> relationshipTypesRes = janusGraphGenericDao
66             .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.RelationshipType), uniqueId, RelationshipTypeData.class);
67         if (relationshipTypesRes.isRight()) {
68             JanusGraphOperationStatus status = relationshipTypesRes.right().value();
69             logger.debug("Relationship type {} cannot be found in graph. status is {}", uniqueId, status);
70             return Either.right(status);
71         }
72         return getRelationshipTypeDefinition(relationshipTypesRes.left().value());
73     }
74     
75     public Either<RelationshipTypeDefinition, JanusGraphOperationStatus> getRelationshipTypeDefinition(final RelationshipTypeData relationshipTypeData) {
76         RelationshipTypeDefinition relationshipTypeDefinition = new RelationshipTypeDefinition(
77             relationshipTypeData.getRelationshipTypeDataDefinition());
78         Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> propertiesStatus = OperationUtils
79             .fillProperties(relationshipTypeData.getUniqueId(), propertyOperation, NodeTypeEnum.RelationshipType);
80         if (propertiesStatus.isRight() && propertiesStatus.right().value() != JanusGraphOperationStatus.OK) {
81             logger.error(BUSINESS_PROCESS_ERROR, "Failed to fetch properties of relationship type {}", relationshipTypeData.getUniqueId());
82             return Either.right(propertiesStatus.right().value());
83         }
84         if (propertiesStatus.isLeft()) {
85             relationshipTypeDefinition.setProperties(propertiesStatus.left().value());
86         }
87         Either<ImmutablePair<RelationshipTypeData, GraphEdge>, JanusGraphOperationStatus> parentNode = janusGraphGenericDao
88             .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.RelationshipType), relationshipTypeData.getUniqueId(), GraphEdgeLabels.DERIVED_FROM,
89                 NodeTypeEnum.RelationshipType, RelationshipTypeData.class);
90         logger.debug("After retrieving DERIVED_FROM node of {}. status is {}", relationshipTypeData.getUniqueId(), parentNode);
91         if (parentNode.isRight()) {
92             JanusGraphOperationStatus janusGraphOperationStatus = parentNode.right().value();
93             if (janusGraphOperationStatus != JanusGraphOperationStatus.NOT_FOUND) {
94                 logger.error(BUSINESS_PROCESS_ERROR, "Failed to find the parent relationship of relationship type {}. status is {}", relationshipTypeData.getUniqueId(), janusGraphOperationStatus);
95                 return Either.right(janusGraphOperationStatus);
96             }
97         } else {
98             // derived from node was found
99             ImmutablePair<RelationshipTypeData, GraphEdge> immutablePair = parentNode.left().value();
100             RelationshipTypeData parentCT = immutablePair.getKey();
101             relationshipTypeDefinition.setDerivedFrom(parentCT.getRelationshipTypeDataDefinition().getType());
102         }
103         
104         final Either<ImmutablePair<ModelData, GraphEdge>, JanusGraphOperationStatus> model = janusGraphGenericDao.getParentNode(
105             UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.RelationshipType), relationshipTypeData.getUniqueId(), GraphEdgeLabels.MODEL_ELEMENT, 
106             NodeTypeEnum.Model, ModelData.class);
107         if (model.isLeft()) {
108             relationshipTypeDefinition.setModel(model.left().value().getLeft().getName());
109         }
110         return Either.left(relationshipTypeDefinition);
111     }
112
113     private Either<RelationshipTypeDefinition, StorageOperationStatus> validateUpdateProperties(
114         RelationshipTypeDefinition relationshipTypeDefinition) {
115         JanusGraphOperationStatus error = null;
116         if (MapUtils.isNotEmpty(relationshipTypeDefinition.getProperties()) && relationshipTypeDefinition.getDerivedFrom() != null) {
117             final Either<RelationshipTypeData, JanusGraphOperationStatus> derivedFromNode = janusGraphGenericDao.getNode(GraphPropertiesDictionary.TYPE.getProperty(), 
118                 relationshipTypeDefinition.getDerivedFrom(), RelationshipTypeData.class, relationshipTypeDefinition.getModel());
119             if (derivedFromNode.isRight()) {
120                 logger.error(BUSINESS_PROCESS_ERROR, "Failed to find the derived from type for  {}. status is {}", relationshipTypeDefinition.getUniqueId(), derivedFromNode.right().value());
121                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(derivedFromNode.right().value()));
122             }
123             Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> allPropertiesRes = getAllRelationshipTypePropertiesFromAllDerivedFrom(
124                 derivedFromNode.left().value().getUniqueId());
125             if (allPropertiesRes.isRight() && !JanusGraphOperationStatus.NOT_FOUND.equals(allPropertiesRes.right().value())) {
126                 error = allPropertiesRes.right().value();
127                 logger.debug("Couldn't fetch derived from property nodes for relationship type {}, error: {}", relationshipTypeDefinition.getType(),
128                     error);
129             }
130             error = getJanusGraphOperationStatus(relationshipTypeDefinition, error, allPropertiesRes);
131         }
132         if (error == null) {
133             return Either.left(relationshipTypeDefinition);
134         }
135         return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error));
136     }
137
138     private JanusGraphOperationStatus getJanusGraphOperationStatus(RelationshipTypeDefinition relationshipTypeDefinition,
139                                                                    JanusGraphOperationStatus error,
140                                                                    Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> allPropertiesRes) {
141         if (error == null && !allPropertiesRes.left().value().isEmpty()) {
142             Map<String, PropertyDefinition> derivedFromProperties = allPropertiesRes.left().value();
143             relationshipTypeDefinition.getProperties().entrySet().stream()
144                 .filter(e -> derivedFromProperties.containsKey(e.getKey()) && e.getValue().getType() == null)
145                 .forEach(e -> e.getValue().setType(derivedFromProperties.get(e.getKey()).getType()));
146             List<PropertyDefinition> properties = new ArrayList<>(relationshipTypeDefinition.getProperties().values());
147             Either<List<PropertyDefinition>, JanusGraphOperationStatus> validatePropertiesRes = propertyOperation
148                 .validatePropertiesUniqueness(allPropertiesRes.left().value(), properties);
149             if (validatePropertiesRes.isRight()) {
150                 error = validatePropertiesRes.right().value();
151             }
152         }
153         return error;
154     }
155
156     private Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> getAllRelationshipTypePropertiesFromAllDerivedFrom(
157         String firstParentUid) {
158         return propertyOperation.getAllTypePropertiesFromAllDerivedFrom(firstParentUid, NodeTypeEnum.RelationshipType, RelationshipTypeData.class);
159     }
160
161     public Either<RelationshipTypeDefinition, StorageOperationStatus> addRelationshipType(RelationshipTypeDefinition relationshipTypeDefinition,
162                                                                                           boolean inTransaction) {
163         Either<RelationshipTypeDefinition, StorageOperationStatus> result = null;
164         try {
165             Either<RelationshipTypeDefinition, StorageOperationStatus> validationRes = validateUpdateProperties(relationshipTypeDefinition);
166             if (validationRes.isRight()) {
167                 logger
168                     .error("#addRelationshipType - One or all properties of relationship type {} not valid. status is {}", relationshipTypeDefinition,
169                         validationRes.right().value());
170                 return validationRes;
171             }
172             Either<RelationshipTypeData, StorageOperationStatus> eitherStatus = addRelationshipTypeToGraph(relationshipTypeDefinition);
173             result = eitherStatus.left().map(RelationshipTypeData::getUniqueId).left().bind(uniqueId -> getRelationshipType(uniqueId, inTransaction));
174             if (result.isLeft()) {
175                 logger.debug("#addRelationshipType - The returned RelationshipTypeDefinition is {}", result.left().value());
176             }
177             return result;
178         } finally {
179             if (!inTransaction) {
180                 if (result == null || result.isRight()) {
181                     logger.error("#addRelationshipType - Going to execute rollback on graph.");
182                     janusGraphGenericDao.rollback();
183                 } else {
184                     logger.debug("#addRelationshipType - Going to execute commit on graph.");
185                     janusGraphGenericDao.commit();
186                 }
187             }
188         }
189     }
190
191     public Either<RelationshipTypeDefinition, StorageOperationStatus> getRelationshipType(String uniqueId, boolean inTransaction) {
192         Either<RelationshipTypeDefinition, StorageOperationStatus> result;
193         try {
194             Either<RelationshipTypeDefinition, JanusGraphOperationStatus> ctResult = this.getRelationshipTypeByUid(uniqueId);
195             if (ctResult.isRight()) {
196                 JanusGraphOperationStatus status = ctResult.right().value();
197                 if (status != JanusGraphOperationStatus.NOT_FOUND) {
198                     logger.error("Failed to retrieve information on relationship type {}. status is {}", uniqueId, status);
199                 }
200                 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(ctResult.right().value()));
201                 return result;
202             }
203             result = Either.left(ctResult.left().value());
204             return result;
205         } finally {
206             if (!inTransaction) {
207                 logger.debug("Going to execute commit on graph.");
208                 janusGraphGenericDao.commit();
209             }
210         }
211     }
212
213     private Either<RelationshipTypeData, StorageOperationStatus> addRelationshipTypeToGraph(RelationshipTypeDefinition relationshipTypeDefinition) {
214         logger.debug("Got relationship type {}", relationshipTypeDefinition);
215         String ctUniqueId = UniqueIdBuilder.buildRelationshipTypeUid(relationshipTypeDefinition.getModel(), relationshipTypeDefinition.getType());
216         RelationshipTypeData relationshipTypeData = buildRelationshipTypeData(relationshipTypeDefinition, ctUniqueId);
217         logger.debug("Before adding relationship type to graph. relationshipTypeData = {}", relationshipTypeData);
218         Either<RelationshipTypeData, JanusGraphOperationStatus> createCTResult = janusGraphGenericDao
219             .createNode(relationshipTypeData, RelationshipTypeData.class);
220         logger.debug("After adding relationship type to graph. status is = {}", createCTResult);
221         if (createCTResult.isRight()) {
222             JanusGraphOperationStatus operationStatus = createCTResult.right().value();
223             logger.error("Failed to relationship type {} to graph. status is {}", relationshipTypeDefinition.getType(), operationStatus);
224             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(operationStatus));
225         }
226         RelationshipTypeData resultCTD = createCTResult.left().value();
227         Map<String, PropertyDefinition> propertiesMap = relationshipTypeDefinition.getProperties();
228         Either<Map<String, PropertyData>, JanusGraphOperationStatus> addPropertiesToRelationshipType = propertyOperation
229             .addPropertiesToElementType(resultCTD.getUniqueId(), NodeTypeEnum.RelationshipType, propertiesMap);
230         if (addPropertiesToRelationshipType.isRight()) {
231             logger.error("Failed add properties {} to relationship {}", propertiesMap, relationshipTypeDefinition.getType());
232             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(addPropertiesToRelationshipType.right().value()));
233         }
234         final Either<GraphRelation, StorageOperationStatus> modelRelationship = addRelationshipToModel(relationshipTypeDefinition);
235         if (modelRelationship.isRight()) {
236             return Either.right(modelRelationship.right().value());
237         }
238
239         return addDerivedFromRelation(relationshipTypeDefinition, ctUniqueId).left().map(updatedDerivedFrom -> createCTResult.left().value());
240     }
241
242     private RelationshipTypeData buildRelationshipTypeData(RelationshipTypeDefinition relationshipTypeDefinition, String ctUniqueId) {
243         RelationshipTypeData relationshipTypeData = new RelationshipTypeData(relationshipTypeDefinition);
244         relationshipTypeData.getRelationshipTypeDataDefinition().setUniqueId(ctUniqueId);
245         Long creationDate = relationshipTypeData.getRelationshipTypeDataDefinition().getCreationTime();
246         if (creationDate == null) {
247             creationDate = System.currentTimeMillis();
248         }
249         relationshipTypeData.getRelationshipTypeDataDefinition().setCreationTime(creationDate);
250         relationshipTypeData.getRelationshipTypeDataDefinition().setModificationTime(creationDate);
251         return relationshipTypeData;
252     }
253
254     private Either<GraphRelation, StorageOperationStatus> addDerivedFromRelation(RelationshipTypeDefinition relationshipTypeDefinition,
255                                                                                  String relationshipTypeUniqueId) {
256         String derivedFrom = relationshipTypeDefinition.getDerivedFrom();
257         if (derivedFrom == null) {
258             return Either.left(null);
259         }
260         logger.debug("#addDerivedFromRelation - adding derived from relation between relationship type {} to its parent " + "{}",
261             relationshipTypeDefinition.getType(), derivedFrom);
262         return getRelationshipTypeByTypeAndModel(derivedFrom, relationshipTypeDefinition.getModel()).right().map(DaoStatusConverter::convertJanusGraphStatusToStorageStatus).left().bind(
263             derivedFromRelationship -> derivedFromOperation
264                 .addDerivedFromRelation(relationshipTypeUniqueId, derivedFromRelationship.getUniqueId(), NodeTypeEnum.RelationshipType));
265     }
266     
267     private Either<GraphRelation, StorageOperationStatus> addRelationshipToModel(final RelationshipTypeDefinition relationshipTypeDefinition) {
268         final String model = relationshipTypeDefinition.getModel();
269         if (model == null) {
270             return Either.left(null);
271         }
272         final GraphNode from = new UniqueIdData(NodeTypeEnum.Model, UniqueIdBuilder.buildModelUid(model));
273         final GraphNode to = new UniqueIdData(NodeTypeEnum.RelationshipType, relationshipTypeDefinition.getUniqueId());
274         logger.info("Connecting model {} to type {}", from, to);
275         return janusGraphGenericDao.createRelation(from , to, GraphEdgeLabels.MODEL_ELEMENT, Collections.emptyMap()).right().map(DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
276     }
277
278     private Either<RelationshipTypeDefinition, JanusGraphOperationStatus> getRelationshipTypeByTypeAndModel(final String relationshipType, final String model) {
279         final Either<RelationshipTypeData, JanusGraphOperationStatus> relationshipTypesRes = janusGraphGenericDao
280             .getNode(GraphPropertiesDictionary.TYPE.getProperty(), relationshipType, RelationshipTypeData.class, model);
281         if (relationshipTypesRes.isRight()) {
282             final JanusGraphOperationStatus status = relationshipTypesRes.right().value();
283             logger.debug("Relationship type {} cannot be found in graph. status is {}", relationshipType, status);
284             return Either.right(status);
285         }
286         return getRelationshipTypeDefinition(relationshipTypesRes.left().value());
287     }
288
289     public Either<RelationshipTypeDefinition, StorageOperationStatus> updateRelationshipType(RelationshipTypeDefinition newRelationshipTypeDefinition,
290                                                                                              RelationshipTypeDefinition oldRelationshipTypeDefinition,
291                                                                                              boolean inTransaction) {
292         logger.debug("updating relationship type {}", newRelationshipTypeDefinition.getType());
293         Either<RelationshipTypeDefinition, StorageOperationStatus> updateRelationshipEither = null;
294         try {
295             updateRelationshipEither = updateRelationshipTypeOnGraph(newRelationshipTypeDefinition, oldRelationshipTypeDefinition);
296         } finally {
297             if (!inTransaction) {
298                 if (updateRelationshipEither == null || updateRelationshipEither.isRight()) {
299                     janusGraphGenericDao.rollback();
300                 } else {
301                     janusGraphGenericDao.commit();
302                 }
303             }
304         }
305         return updateRelationshipEither;
306     }
307
308     private Either<RelationshipTypeDefinition, StorageOperationStatus> updateRelationshipTypeOnGraph(
309         RelationshipTypeDefinition newRelationshipTypeDefinition, RelationshipTypeDefinition oldRelationshipTypeDefinition) {
310         updateRelationshipTypeData(newRelationshipTypeDefinition, oldRelationshipTypeDefinition);
311         return janusGraphGenericDao.updateNode(new RelationshipTypeData(newRelationshipTypeDefinition), RelationshipTypeData.class).right()
312             .map(DaoStatusConverter::convertJanusGraphStatusToStorageStatus).left().bind(
313                 updatedNode -> updateRelationshipTypeProperties(newRelationshipTypeDefinition.getUniqueId(),
314                     newRelationshipTypeDefinition.getProperties())).left().bind(
315                 updatedProperties -> updateRelationshipTypeDerivedFrom(newRelationshipTypeDefinition, oldRelationshipTypeDefinition.getDerivedFrom()))
316             .left().map(updatedDerivedFrom -> newRelationshipTypeDefinition);
317     }
318
319     private Either<Map<String, PropertyData>, StorageOperationStatus> updateRelationshipTypeProperties(String relationshipTypeId,
320                                                                                                        Map<String, PropertyDefinition> properties) {
321         logger.debug("#updateRelationshipTypeProperties - updating relationship type properties for relationship type with " + "id {}",
322             relationshipTypeId);
323         return propertyOperation.deletePropertiesAssociatedToNode(NodeTypeEnum.RelationshipType, relationshipTypeId).left()
324             .bind(deleteProps -> addPropertiesToRelationshipType(relationshipTypeId, properties));
325     }
326
327     private Either<GraphRelation, StorageOperationStatus> updateRelationshipTypeDerivedFrom(RelationshipTypeDefinition newRelationshipTypeDefinition,
328                                                                                             String currDerivedFromRelationshipType) {
329         String relationshipTypeId = newRelationshipTypeDefinition.getUniqueId();
330         logger.debug("#updateRelationshipTypeDerivedFrom - updating relationship derived from relation for relationship "
331                 + "type with id {}. old derived type {}. new derived type {}", relationshipTypeId, currDerivedFromRelationshipType,
332             newRelationshipTypeDefinition.getDerivedFrom());
333         StorageOperationStatus deleteDerivedRelationStatus = deleteDerivedFromRelationshipType(relationshipTypeId, newRelationshipTypeDefinition.getModel(), currDerivedFromRelationshipType);
334         if (deleteDerivedRelationStatus != StorageOperationStatus.OK) {
335             return Either.right(deleteDerivedRelationStatus);
336         }
337         return addDerivedFromRelation(newRelationshipTypeDefinition, relationshipTypeId);
338     }
339
340     private void updateRelationshipTypeData(RelationshipTypeDefinition newRelationshipTypeDefinition,
341                                             RelationshipTypeDefinition oldRelationshipTypeDefinition) {
342         newRelationshipTypeDefinition.setUniqueId(oldRelationshipTypeDefinition.getUniqueId());
343         newRelationshipTypeDefinition.setCreationTime(oldRelationshipTypeDefinition.getCreationTime());
344         newRelationshipTypeDefinition.setModificationTime(System.currentTimeMillis());
345     }
346
347     private Either<Map<String, PropertyData>, StorageOperationStatus> addPropertiesToRelationshipType(String relationshipTypeId,
348                                                                                                       Map<String, PropertyDefinition> properties) {
349         logger.debug("#addPropertiesToRelationshipType - adding relationship type properties for relationship type with " + "id {}",
350             relationshipTypeId);
351         return propertyOperation.addPropertiesToElementType(relationshipTypeId, NodeTypeEnum.RelationshipType, properties).right()
352             .map(DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
353     }
354
355     private StorageOperationStatus deleteDerivedFromRelationshipType(final String relationshipTypeId, final String modelName, final String derivedFromType) {
356         if (derivedFromType == null) {
357             return StorageOperationStatus.OK;
358         }
359         logger
360             .debug("#deleteDerivedFromRelationshipType - deleting derivedFrom relation for relationship type with id " + "{} and its derived type {}",
361                 relationshipTypeId, derivedFromType);
362         return getRelationshipTypeByTypeAndModel(derivedFromType, modelName).either(derivedFromNode -> derivedFromOperation
363                 .removeDerivedFromRelation(relationshipTypeId, derivedFromNode.getUniqueId(), NodeTypeEnum.RelationshipType),
364             DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
365     }
366
367     public Either<Map<String, RelationshipTypeDefinition>, JanusGraphOperationStatus> getAllRelationshipTypes() {
368         Map<String, RelationshipTypeDefinition> relationshipTypeDefinitionMap = new HashMap<>();
369         Either<Map<String, RelationshipTypeDefinition>, JanusGraphOperationStatus> result = Either.left(relationshipTypeDefinitionMap);
370         Either<List<RelationshipTypeData>, JanusGraphOperationStatus> getAllRelationshipTypes = janusGraphGenericDao
371             .getByCriteria(NodeTypeEnum.RelationshipType, null, RelationshipTypeData.class);
372         if (getAllRelationshipTypes.isRight()) {
373             JanusGraphOperationStatus status = getAllRelationshipTypes.right().value();
374             if (status != JanusGraphOperationStatus.NOT_FOUND) {
375                 return Either.right(status);
376             } else {
377                 return result;
378             }
379         }
380         List<RelationshipTypeData> list = getAllRelationshipTypes.left().value();
381         if (list != null) {
382             logger.trace("Number of relationship types to load is {}", list.size());
383             //Set properties
384             Either<Map<String, RelationshipTypeDefinition>, JanusGraphOperationStatus> status = getMapJanusGraphOperationStatusEither(
385                 relationshipTypeDefinitionMap, list);
386             if (status != null) {
387                 return status;
388             }
389         }
390         return result;
391     }
392
393     private Either<Map<String, RelationshipTypeDefinition>, JanusGraphOperationStatus> getMapJanusGraphOperationStatusEither(
394         Map<String, RelationshipTypeDefinition> relationshipTypeDefinitionMap, List<RelationshipTypeData> list) {
395         for (RelationshipTypeData relationshipTypeData : list) {
396             logger.trace("Going to fetch relationship type {}. uid is {}", relationshipTypeData.getRelationshipTypeDataDefinition().getType(),
397                 relationshipTypeData.getUniqueId());
398             Either<RelationshipTypeDefinition, JanusGraphOperationStatus> relationshipTypesByUid = getAndAddPropertiesANdDerivedFrom(
399                 relationshipTypeData.getUniqueId(), relationshipTypeDefinitionMap);
400             if (relationshipTypesByUid.isRight()) {
401                 JanusGraphOperationStatus status = relationshipTypesByUid.right().value();
402                 if (status == JanusGraphOperationStatus.NOT_FOUND) {
403                     status = JanusGraphOperationStatus.INVALID_ID;
404                 }
405                 return Either.right(status);
406             }
407         }
408         return null;
409     }
410
411     private Either<RelationshipTypeDefinition, JanusGraphOperationStatus> getAndAddPropertiesANdDerivedFrom(String uniqueId,
412                                                                                                             Map<String, RelationshipTypeDefinition> relationshipTypeDefinitionMap) {
413         if (relationshipTypeDefinitionMap.containsKey(uniqueId)) {
414             return Either.left(relationshipTypeDefinitionMap.get(uniqueId));
415         }
416         Either<RelationshipTypeData, JanusGraphOperationStatus> relationshipTypesRes = janusGraphGenericDao
417             .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.RelationshipType), uniqueId, RelationshipTypeData.class);
418         if (relationshipTypesRes.isRight()) {
419             JanusGraphOperationStatus status = relationshipTypesRes.right().value();
420             logger.debug(RELATIONSHIP_TYPE_CANNOT_BE_FOUND_IN_GRAPH_STATUS_IS, uniqueId, status);
421             return Either.right(status);
422         }
423         RelationshipTypeData ctData = relationshipTypesRes.left().value();
424         RelationshipTypeDefinition relationshipTypeDefinition = new RelationshipTypeDefinition(ctData.getRelationshipTypeDataDefinition());
425         Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> propertiesStatus = OperationUtils
426             .fillProperties(uniqueId, propertyOperation, NodeTypeEnum.RelationshipType);
427         if (propertiesStatus.isRight() && propertiesStatus.right().value() != JanusGraphOperationStatus.OK) {
428             logger.error(FAILED_TO_FETCH_PROPERTIES_OF_RELATIONSHIP_TYPE, uniqueId);
429             return Either.right(propertiesStatus.right().value());
430         }
431         if (propertiesStatus.isLeft()) {
432             relationshipTypeDefinition.setProperties(propertiesStatus.left().value());
433         }
434         fillDerivedFrom(uniqueId, relationshipTypeDefinition);
435         relationshipTypeDefinitionMap.put(relationshipTypeDefinition.getType(), relationshipTypeDefinition);
436         return Either.left(relationshipTypeDefinition);
437     }
438
439     private void fillDerivedFrom(String uniqueId, RelationshipTypeDefinition relationshipType) {
440         logger.debug("#fillDerivedFrom - fetching relationship type {} derived node", relationshipType.getType());
441         derivedFromOperation.getDerivedFromChild(uniqueId, NodeTypeEnum.RelationshipType, RelationshipTypeData.class).right()
442             .bind(this::handleDerivedFromNotExist).left().map(derivedFrom -> setDerivedFrom(relationshipType, derivedFrom));
443     }
444
445     private Either<RelationshipTypeData, StorageOperationStatus> handleDerivedFromNotExist(StorageOperationStatus err) {
446         if (err == StorageOperationStatus.NOT_FOUND) {
447             return Either.left(null);
448         }
449         return Either.right(err);
450     }
451
452     private RelationshipTypeData setDerivedFrom(RelationshipTypeDefinition relationshipTypeDefinition, RelationshipTypeData derivedFrom) {
453         if (derivedFrom != null) {
454             relationshipTypeDefinition.setDerivedFrom(derivedFrom.getRelationshipTypeDataDefinition().getType());
455         }
456         return derivedFrom;
457     }
458 }