Upgrade SDC from Titan to Janus Graph
[sdc.git] / catalog-model / src / main / java / org / openecomp / sdc / be / model / operations / impl / CapabilityTypeOperation.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.operations.impl;
22
23 import fj.data.Either;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.stream.Collectors;
28 import org.apache.commons.collections.MapUtils;
29 import org.apache.commons.lang3.StringUtils;
30 import org.apache.commons.lang3.tuple.ImmutablePair;
31 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
32 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
33 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
34 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
35 import org.openecomp.sdc.be.dao.janusgraph.HealingJanusGraphGenericDao;
36 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
37 import org.openecomp.sdc.be.model.CapabilityTypeDefinition;
38 import org.openecomp.sdc.be.model.PropertyDefinition;
39 import org.openecomp.sdc.be.model.operations.api.DerivedFromOperation;
40 import org.openecomp.sdc.be.model.operations.api.ICapabilityTypeOperation;
41 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
42 import org.openecomp.sdc.be.model.operations.api.TypeOperations;
43 import org.openecomp.sdc.be.resources.data.CapabilityTypeData;
44 import org.openecomp.sdc.be.resources.data.PropertyData;
45 import org.openecomp.sdc.common.log.wrappers.Logger;
46 import org.springframework.beans.factory.annotation.Autowired;
47 import org.springframework.stereotype.Component;
48
49 @Component("capability-type-operation")
50 public class CapabilityTypeOperation extends AbstractOperation implements ICapabilityTypeOperation {
51     @Autowired
52     private PropertyOperation propertyOperation;
53     @Autowired
54     private DerivedFromOperation derivedFromOperation;
55
56     public CapabilityTypeOperation() {
57         super();
58     }
59
60     private static final Logger log = Logger.getLogger(CapabilityTypeOperation.class.getName());
61     private static final String DATA_TYPE_CANNOT_BE_FOUND_IN_GRAPH_STATUS_IS = "Data type {} cannot be found in graph."
62             + " status is {}";
63     private static final String FAILED_TO_FETCH_PROPERTIES_OF_DATA_TYPE = "Failed to fetch properties of data type {}";
64
65
66     /**
67      * FOR TEST ONLY
68      *
69      * @param janusGraphGenericDao
70      */
71     public void setJanusGraphGenericDao(HealingJanusGraphGenericDao janusGraphGenericDao) {
72         this.janusGraphGenericDao = janusGraphGenericDao;
73     }
74
75     @Override
76     public Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType(CapabilityTypeDefinition capabilityTypeDefinition, boolean inTransaction) {
77
78         Either<CapabilityTypeDefinition, StorageOperationStatus> result = null;
79
80         try {
81             Either<CapabilityTypeDefinition, StorageOperationStatus> validationRes = validateUpdateProperties(capabilityTypeDefinition);
82             if (validationRes.isRight()) {
83                 log.error("#addCapabilityType - One or all properties of capability type {} not valid. status is {}", capabilityTypeDefinition, validationRes.right().value());
84                 return result;
85             }
86             
87             Either<CapabilityTypeData, StorageOperationStatus> eitherStatus = addCapabilityTypeToGraph(capabilityTypeDefinition);
88
89             result = eitherStatus.left()
90                         .map(CapabilityTypeData::getUniqueId)
91                         .left()
92                         .bind(uniqueId -> getCapabilityType(uniqueId, inTransaction));
93             
94             if(result.isLeft()) {
95                 log.debug("#addCapabilityType - The returned CapabilityTypeDefinition is {}", result.left().value());
96             }
97             
98             return result;
99         }
100
101         finally {
102             if (!inTransaction) {
103                 if (result == null || result.isRight()) {
104                     log.error("#addCapabilityType - Going to execute rollback on graph.");
105                     janusGraphGenericDao.rollback();
106                 } else {
107                     log.debug("#addCapabilityType - Going to execute commit on graph.");
108                     janusGraphGenericDao.commit();
109                 }
110             }
111         }
112
113     }
114     
115     public Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> getAllCapabilityTypePropertiesFromAllDerivedFrom(String firstParentType) {
116         return propertyOperation.getAllTypePropertiesFromAllDerivedFrom(firstParentType, NodeTypeEnum.CapabilityType, CapabilityTypeData.class);
117     }
118
119     public Either<CapabilityTypeDefinition, StorageOperationStatus> validateUpdateProperties(CapabilityTypeDefinition capabilityTypeDefinition) {
120         JanusGraphOperationStatus error = null;
121         if (MapUtils.isNotEmpty(capabilityTypeDefinition.getProperties()) && capabilityTypeDefinition.getDerivedFrom() != null) {
122             Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> allPropertiesRes =
123                                         getAllCapabilityTypePropertiesFromAllDerivedFrom(capabilityTypeDefinition.getDerivedFrom());
124             if (allPropertiesRes.isRight() && !allPropertiesRes.right().value().equals(
125                 JanusGraphOperationStatus.NOT_FOUND)) {
126                 error = allPropertiesRes.right().value();
127                 log.debug("Couldn't fetch derived from property nodes for capability type {}, error: {}", capabilityTypeDefinition.getType(), error);
128             }
129             if (error == null && !allPropertiesRes.left().value().isEmpty()) {
130                 Map<String, PropertyDefinition> derivedFromProperties = allPropertiesRes.left().value();
131                 capabilityTypeDefinition.getProperties().entrySet().stream().filter(e -> derivedFromProperties.containsKey(e.getKey()) && e.getValue().getType() == null)
132                         .forEach(e -> e.getValue().setType(derivedFromProperties.get(e.getKey()).getType()));
133
134                 List<PropertyDefinition> properties = capabilityTypeDefinition.getProperties().values().stream().collect(Collectors.toList());
135                 Either<List<PropertyDefinition>, JanusGraphOperationStatus> validatePropertiesRes = propertyOperation.validatePropertiesUniqueness(allPropertiesRes.left().value(),
136                         properties);
137                 if (validatePropertiesRes.isRight()) {
138                     error = validatePropertiesRes.right().value();
139                 }
140             }
141         }
142         if (error == null) {
143             return Either.left(capabilityTypeDefinition);
144         }
145         return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error));
146     }
147     
148
149     /**
150      *
151      * convert between graph Node object to Java object
152      *
153      * @param capabilityTypeData
154      * @return
155      */
156     protected CapabilityTypeDefinition convertCTDataToCTDefinition(CapabilityTypeData capabilityTypeData) {
157         log.debug("The object returned after create capability is {}", capabilityTypeData);
158
159         return new CapabilityTypeDefinition(capabilityTypeData.getCapabilityTypeDataDefinition());
160     }
161
162     /**
163      *
164      * Add capability type to graph.
165      *
166      * 1. Add capability type node
167      *
168      * 2. Add edge between the former node to its parent(if exists)
169      *
170      * 3. Add property node and associate it to the node created at #1. (per property & if exists)
171      *
172      * @param capabilityTypeDefinition
173      * @return
174      */
175     private Either<CapabilityTypeData, StorageOperationStatus> addCapabilityTypeToGraph(CapabilityTypeDefinition capabilityTypeDefinition) {
176
177         log.debug("Got capability type {}", capabilityTypeDefinition);
178
179         String ctUniqueId = UniqueIdBuilder.buildCapabilityTypeUid(capabilityTypeDefinition.getType());
180         CapabilityTypeData capabilityTypeData = buildCapabilityTypeData(capabilityTypeDefinition, ctUniqueId);
181
182         log.debug("Before adding capability type to graph. capabilityTypeData = {}", capabilityTypeData);
183         Either<CapabilityTypeData, JanusGraphOperationStatus> createCTResult = janusGraphGenericDao
184             .createNode(capabilityTypeData, CapabilityTypeData.class);
185         log.debug("After adding capability type to graph. status is = {}", createCTResult);
186
187         if (createCTResult.isRight()) {
188             JanusGraphOperationStatus operationStatus = createCTResult.right().value();
189             log.error("Failed to capability type {} to graph. status is {}", capabilityTypeDefinition.getType(), operationStatus);
190             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(operationStatus));
191         }
192
193         CapabilityTypeData resultCTD = createCTResult.left().value();
194         Map<String, PropertyDefinition> propertiesMap = capabilityTypeDefinition.getProperties();
195         Either<Map<String, PropertyData>, JanusGraphOperationStatus> addPropertiesToCapablityType = propertyOperation.addPropertiesToElementType(resultCTD.getUniqueId(), NodeTypeEnum.CapabilityType, propertiesMap);
196         if (addPropertiesToCapablityType.isRight()) {
197             log.error("Failed add properties {} to capability {}", propertiesMap, capabilityTypeDefinition.getType());
198             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(addPropertiesToCapablityType.right().value()));
199         }
200
201         return addDerivedFromRelation(capabilityTypeDefinition, ctUniqueId)
202                 .left()
203                 .map(updatedDerivedFrom -> createCTResult.left().value());
204
205
206     }
207
208     private CapabilityTypeData buildCapabilityTypeData(CapabilityTypeDefinition capabilityTypeDefinition, String ctUniqueId) {
209
210         CapabilityTypeData capabilityTypeData = new CapabilityTypeData(capabilityTypeDefinition);
211
212         capabilityTypeData.getCapabilityTypeDataDefinition().setUniqueId(ctUniqueId);
213         Long creationDate = capabilityTypeData.getCapabilityTypeDataDefinition().getCreationTime();
214         if (creationDate == null) {
215             creationDate = System.currentTimeMillis();
216         }
217         capabilityTypeData.getCapabilityTypeDataDefinition().setCreationTime(creationDate);
218         capabilityTypeData.getCapabilityTypeDataDefinition().setModificationTime(creationDate);
219         return capabilityTypeData;
220     }
221
222     @Override
223     public Either<CapabilityTypeDefinition, StorageOperationStatus> getCapabilityType(String uniqueId, boolean inTransaction) {
224
225         Either<CapabilityTypeDefinition, StorageOperationStatus> result = null;
226         try {
227
228             Either<CapabilityTypeDefinition, JanusGraphOperationStatus> ctResult = this.getCapabilityTypeByUid(uniqueId);
229
230             if (ctResult.isRight()) {
231                 JanusGraphOperationStatus status = ctResult.right().value();
232                 if (status != JanusGraphOperationStatus.NOT_FOUND) {
233                     log.error("Failed to retrieve information on capability type {}. status is {}", uniqueId, status);
234                 }
235                 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(ctResult.right().value()));
236                 return result;
237             }
238
239             result = Either.left(ctResult.left().value());
240
241             return result;
242         } finally {
243             if (!inTransaction) {
244                 log.debug("Going to execute commit on graph.");
245                 janusGraphGenericDao.commit();
246             }
247         }
248     }
249
250
251     public Either<CapabilityTypeDefinition, JanusGraphOperationStatus> getCapabilityTypeByType(String capabilityType) {
252         // Optimization: In case of Capability Type its unique ID is the same as type
253         return getCapabilityTypeByUid(capabilityType);
254     }
255
256     /**
257      * Build Capability type object from graph by unique id
258      *
259      * @param uniqueId
260      * @return
261      */
262     public Either<CapabilityTypeDefinition, JanusGraphOperationStatus> getCapabilityTypeByUid(String uniqueId) {
263
264         Either<CapabilityTypeDefinition, JanusGraphOperationStatus> result = null;
265
266         Either<CapabilityTypeData, JanusGraphOperationStatus> capabilityTypesRes = janusGraphGenericDao
267             .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), uniqueId, CapabilityTypeData.class);
268
269         if (capabilityTypesRes.isRight()) {
270             JanusGraphOperationStatus status = capabilityTypesRes.right().value();
271             log.debug("Capability type {} cannot be found in graph. status is {}", uniqueId, status);
272             return Either.right(status);
273         }
274
275         CapabilityTypeData ctData = capabilityTypesRes.left().value();
276         CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition(ctData.getCapabilityTypeDataDefinition());
277
278         Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> propertiesStatus =
279                 OperationUtils.fillProperties(uniqueId, propertyOperation, NodeTypeEnum.CapabilityType);
280         if (propertiesStatus.isRight() && propertiesStatus.right().value() != JanusGraphOperationStatus.OK) {
281             log.error("Failed to fetch properties of capability type {}", uniqueId);
282             return Either.right(propertiesStatus.right().value());
283         }
284
285         if (propertiesStatus.isLeft()) {
286             capabilityTypeDefinition.setProperties(propertiesStatus.left().value());
287         }
288
289         Either<ImmutablePair<CapabilityTypeData, GraphEdge>, JanusGraphOperationStatus> parentNode = janusGraphGenericDao
290             .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), uniqueId, GraphEdgeLabels.DERIVED_FROM,
291                 NodeTypeEnum.CapabilityType, CapabilityTypeData.class);
292         log.debug("After retrieving DERIVED_FROM node of {}. status is {}", uniqueId, parentNode);
293         if (parentNode.isRight()) {
294             JanusGraphOperationStatus janusGraphOperationStatus = parentNode.right().value();
295             if (janusGraphOperationStatus != JanusGraphOperationStatus.NOT_FOUND) {
296                 log.error("Failed to find the parent capability of capability type {}. status is {}", uniqueId,
297                     janusGraphOperationStatus);
298                 result = Either.right(janusGraphOperationStatus);
299                 return result;
300             }
301         } else {
302             // derived from node was found
303             ImmutablePair<CapabilityTypeData, GraphEdge> immutablePair = parentNode.left().value();
304             CapabilityTypeData parentCT = immutablePair.getKey();
305             capabilityTypeDefinition.setDerivedFrom(parentCT.getCapabilityTypeDataDefinition().getType());
306         }
307         result = Either.left(capabilityTypeDefinition);
308
309         return result;
310     }
311
312     public Either<Boolean, StorageOperationStatus> isCapabilityTypeDerivedFrom(String childCandidateType, String parentCandidateType) {
313         return derivedFromOperation.isTypeDerivedFrom(childCandidateType, parentCandidateType, null, NodeTypeEnum.CapabilityType, CapabilityTypeData.class, t -> t.getCapabilityTypeDataDefinition().getType());
314     }
315     
316     
317     @Override
318     public Either<CapabilityTypeDefinition, StorageOperationStatus> updateCapabilityType(CapabilityTypeDefinition capabilityTypeDefNew, 
319                                                                                          CapabilityTypeDefinition capabilityTypeDefOld) {
320         log.debug("updating capability type {}", capabilityTypeDefNew.getType());
321         updateCapabilityTypeData(capabilityTypeDefNew, capabilityTypeDefOld);
322         return updateCapabilityTypeOnGraph(capabilityTypeDefNew, capabilityTypeDefOld);
323     }
324     
325     
326     private Either<CapabilityTypeDefinition, StorageOperationStatus> updateCapabilityTypeOnGraph(CapabilityTypeDefinition capabilityTypeDefinitionNew, CapabilityTypeDefinition capabilityTypeDefinitionOld) {
327         return janusGraphGenericDao
328             .updateNode(new CapabilityTypeData(capabilityTypeDefinitionNew), CapabilityTypeData.class)
329                 .right()
330                 .map(DaoStatusConverter::convertJanusGraphStatusToStorageStatus)
331                 .left()
332                 .bind(updatedNode -> updateProperties(capabilityTypeDefinitionNew.getUniqueId(), capabilityTypeDefinitionNew.getProperties()))
333                 .left()
334                 .bind(updatedProperties -> updateDerivedFrom(capabilityTypeDefinitionNew, capabilityTypeDefinitionOld.getDerivedFrom()))
335                 .right()
336                 .bind(result -> TypeOperations.mapOkStatus(result, null))
337                 .left()
338                 .map(updatedDerivedFrom -> capabilityTypeDefinitionNew);
339     }
340
341     private Either<Map<String, PropertyData>, StorageOperationStatus> updateProperties(String capabilityTypeId, Map<String, PropertyDefinition> properties) {
342         log.debug("#updateCapabilityTypeProperties - updating properties for capability type with id {}", capabilityTypeId);
343         return propertyOperation.mergePropertiesAssociatedToNode(NodeTypeEnum.CapabilityType, capabilityTypeId, properties)
344                 .right()
345                 .map(DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
346     }
347
348     private Either<GraphRelation, StorageOperationStatus> updateDerivedFrom(CapabilityTypeDefinition updatedCapabilityType, String currDerivedFromCapabilityType) {
349         if( StringUtils.equals(updatedCapabilityType.getDerivedFrom(), currDerivedFromCapabilityType)) {
350             return Either.right(StorageOperationStatus.OK);
351         }
352         
353         StorageOperationStatus status = isLegalToReplaceParent(currDerivedFromCapabilityType, updatedCapabilityType.getDerivedFrom(), updatedCapabilityType.getType());
354         if ( status != StorageOperationStatus.OK) {
355             return Either.right(status);
356         }
357         
358         String capabilityTypeId = updatedCapabilityType.getUniqueId();
359         log.debug("#updateCapabilityTypeDerivedFrom - updating capability type derived from relation for capability type with id {}. old derived type {}. new derived type {}", capabilityTypeId, currDerivedFromCapabilityType, updatedCapabilityType.getDerivedFrom());
360         StorageOperationStatus deleteDerivedRelationStatus = deleteDerivedFromCapabilityType(capabilityTypeId, currDerivedFromCapabilityType);
361         if (deleteDerivedRelationStatus != StorageOperationStatus.OK) {
362             return Either.right(deleteDerivedRelationStatus);
363         }
364         return addDerivedFromRelation(updatedCapabilityType, capabilityTypeId);
365     }
366     
367     private StorageOperationStatus isLegalToReplaceParent(String oldTypeParent, String newTypeParent, String childType) {
368         return derivedFromOperation.isUpdateParentAllowed(oldTypeParent, newTypeParent, childType, NodeTypeEnum.CapabilityType, CapabilityTypeData.class, t -> t.getCapabilityTypeDataDefinition().getType());
369     }
370
371     private Either<GraphRelation, StorageOperationStatus> addDerivedFromRelation(CapabilityTypeDefinition capabilityTypeDef, String ptUniqueId) {
372         String derivedFrom = capabilityTypeDef.getDerivedFrom();
373         if (derivedFrom == null) {
374             return Either.left(null);
375         }
376         log.debug("#addDerivedFromRelationBefore - adding derived from relation between capability type {} to its parent {}", capabilityTypeDef.getType(), derivedFrom);
377         return this.getCapabilityType(derivedFrom, true)
378                 .left()
379                 .bind(derivedFromCapabilityType -> derivedFromOperation.addDerivedFromRelation(ptUniqueId, derivedFromCapabilityType.getUniqueId(), NodeTypeEnum.CapabilityType));
380     }
381
382     private StorageOperationStatus deleteDerivedFromCapabilityType(String capabilityTypeId, String derivedFromType) {
383         if (derivedFromType == null) {
384             return StorageOperationStatus.OK;
385         }
386         log.debug("#deleteDerivedFromCapabilityType - deleting derivedFrom relation for capability type with id {} and its derived type {}", capabilityTypeId, derivedFromType);
387         return getCapabilityType(derivedFromType, true)
388                 .either(derivedFromNode -> derivedFromOperation.removeDerivedFromRelation(capabilityTypeId, derivedFromNode.getUniqueId(), NodeTypeEnum.CapabilityType),
389                         err -> err);
390     }  
391     
392     private void updateCapabilityTypeData(CapabilityTypeDefinition updatedTypeDefinition, CapabilityTypeDefinition currTypeDefinition) {
393         updatedTypeDefinition.setUniqueId(currTypeDefinition.getUniqueId());
394         updatedTypeDefinition.setCreationTime(currTypeDefinition.getCreationTime());
395     }
396
397
398     /**
399      * FOR TEST ONLY
400      *
401      * @param propertyOperation
402      */
403     public void setPropertyOperation(PropertyOperation propertyOperation) {
404         this.propertyOperation = propertyOperation;
405     }
406
407     @Override
408     public Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType(CapabilityTypeDefinition capabilityTypeDefinition) {
409
410         return addCapabilityType(capabilityTypeDefinition, true);
411     }
412
413     @Override
414     public Either<CapabilityTypeDefinition, StorageOperationStatus> getCapabilityType(String uniqueId) {
415         return getCapabilityType(uniqueId, true);
416     }
417     public Either<Map<String, CapabilityTypeDefinition>, JanusGraphOperationStatus> getAllCapabilityTypes() {
418
419         Map<String, CapabilityTypeDefinition> capabilityTypes = new HashMap<>();
420         Either<Map<String, CapabilityTypeDefinition>, JanusGraphOperationStatus> result = Either.left(capabilityTypes);
421
422         Either<List<CapabilityTypeData>, JanusGraphOperationStatus> getAllCapabilityTypes =
423                 janusGraphGenericDao
424                     .getByCriteria(NodeTypeEnum.CapabilityType, null, CapabilityTypeData.class);
425         if (getAllCapabilityTypes.isRight()) {
426             JanusGraphOperationStatus status = getAllCapabilityTypes.right().value();
427             if (status != JanusGraphOperationStatus.NOT_FOUND) {
428                 return Either.right(status);
429             } else {
430                 return result;
431             }
432         }
433
434         List<CapabilityTypeData> list = getAllCapabilityTypes.left().value();
435         if (list != null) {
436
437             log.trace("Number of data types to load is {}", list.size());
438             //Set properties
439             for (CapabilityTypeData capabilityTypeData : list) {
440
441                 log.trace("Going to fetch data type {}. uid is {}",
442                         capabilityTypeData.getCapabilityTypeDataDefinition().getType(),
443                         capabilityTypeData.getUniqueId());
444                 Either<CapabilityTypeDefinition, JanusGraphOperationStatus> capabilityTypesByUid =
445                         getAndAddPropertiesANdDerivedFrom(capabilityTypeData.getUniqueId(), capabilityTypes);
446                 if (capabilityTypesByUid.isRight()) {
447                     JanusGraphOperationStatus status = capabilityTypesByUid.right().value();
448                     if (status == JanusGraphOperationStatus.NOT_FOUND) {
449                         status = JanusGraphOperationStatus.INVALID_ID;
450                     }
451                     return Either.right(status);
452                 }
453             }
454         }
455
456         return result;
457     }
458
459     private void fillDerivedFrom(String uniqueId, CapabilityTypeDefinition capabilityType) {
460         log.debug("#fillDerivedFrom - fetching capability type {} derived node", capabilityType.getType());
461         derivedFromOperation.getDerivedFromChild(uniqueId, NodeTypeEnum.CapabilityType, CapabilityTypeData.class)
462                 .right()
463                 .bind(this::handleDerivedFromNotExist)
464                 .left()
465                 .map(derivedFrom -> setDerivedFrom(capabilityType, derivedFrom));
466
467     }
468
469     private Either<CapabilityTypeData, StorageOperationStatus> handleDerivedFromNotExist(StorageOperationStatus err) {
470         if (err == StorageOperationStatus.NOT_FOUND) {
471             return Either.left(null);
472         }
473         return Either.right(err);
474     }
475
476     private CapabilityTypeData setDerivedFrom(CapabilityTypeDefinition capabilityTypeDefinition, CapabilityTypeData derivedFrom) {
477         if (derivedFrom != null) {
478             capabilityTypeDefinition.setDerivedFrom(derivedFrom.getCapabilityTypeDataDefinition().getType());
479         }
480         return derivedFrom;
481     }
482
483     private Either<CapabilityTypeDefinition, JanusGraphOperationStatus> getAndAddPropertiesANdDerivedFrom(
484             String uniqueId, Map<String, CapabilityTypeDefinition> capabilityTypeDefinitionMap) {
485         if (capabilityTypeDefinitionMap.containsKey(uniqueId)) {
486             return Either.left(capabilityTypeDefinitionMap.get(uniqueId));
487         }
488
489         Either<CapabilityTypeData, JanusGraphOperationStatus> capabilityTypesRes =
490                 janusGraphGenericDao
491                     .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), uniqueId,
492                         CapabilityTypeData.class);
493
494         if (capabilityTypesRes.isRight()) {
495             JanusGraphOperationStatus status = capabilityTypesRes.right().value();
496             log.debug(DATA_TYPE_CANNOT_BE_FOUND_IN_GRAPH_STATUS_IS, uniqueId, status);
497             return Either.right(status);
498         }
499
500         CapabilityTypeData ctData = capabilityTypesRes.left().value();
501         CapabilityTypeDefinition capabilityTypeDefinition =
502                 new CapabilityTypeDefinition(ctData.getCapabilityTypeDataDefinition());
503
504         Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> propertiesStatus =
505                 OperationUtils.fillProperties(uniqueId, propertyOperation, NodeTypeEnum.CapabilityType);
506
507         if (propertiesStatus.isRight() && propertiesStatus.right().value() != JanusGraphOperationStatus.OK) {
508             log.error(FAILED_TO_FETCH_PROPERTIES_OF_DATA_TYPE, uniqueId);
509             return Either.right(propertiesStatus.right().value());
510         }
511
512         if (propertiesStatus.isLeft()) {
513             capabilityTypeDefinition.setProperties(propertiesStatus.left().value());
514         }
515
516         fillDerivedFrom(uniqueId, capabilityTypeDefinition);
517
518         capabilityTypeDefinitionMap.put(capabilityTypeDefinition.getType(), capabilityTypeDefinition);
519
520         return Either.left(capabilityTypeDefinition);
521     }
522 }