2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.openecomp.sdc.be.model.operations.impl;
23 import fj.data.Either;
24 import java.util.HashMap;
25 import java.util.List;
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;
49 @Component("capability-type-operation")
50 public class CapabilityTypeOperation extends AbstractOperation implements ICapabilityTypeOperation {
52 private PropertyOperation propertyOperation;
54 private DerivedFromOperation derivedFromOperation;
56 public CapabilityTypeOperation() {
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."
63 private static final String FAILED_TO_FETCH_PROPERTIES_OF_DATA_TYPE = "Failed to fetch properties of data type {}";
69 * @param janusGraphGenericDao
71 public void setJanusGraphGenericDao(HealingJanusGraphGenericDao janusGraphGenericDao) {
72 this.janusGraphGenericDao = janusGraphGenericDao;
76 public Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType(CapabilityTypeDefinition capabilityTypeDefinition, boolean inTransaction) {
78 Either<CapabilityTypeDefinition, StorageOperationStatus> result = null;
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());
87 Either<CapabilityTypeData, StorageOperationStatus> eitherStatus = addCapabilityTypeToGraph(capabilityTypeDefinition);
89 result = eitherStatus.left()
90 .map(CapabilityTypeData::getUniqueId)
92 .bind(uniqueId -> getCapabilityType(uniqueId, inTransaction));
95 log.debug("#addCapabilityType - The returned CapabilityTypeDefinition is {}", result.left().value());
102 if (!inTransaction) {
103 if (result == null || result.isRight()) {
104 log.error("#addCapabilityType - Going to execute rollback on graph.");
105 janusGraphGenericDao.rollback();
107 log.debug("#addCapabilityType - Going to execute commit on graph.");
108 janusGraphGenericDao.commit();
115 public Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> getAllCapabilityTypePropertiesFromAllDerivedFrom(String firstParentType) {
116 return propertyOperation.getAllTypePropertiesFromAllDerivedFrom(firstParentType, NodeTypeEnum.CapabilityType, CapabilityTypeData.class);
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);
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()));
134 List<PropertyDefinition> properties = capabilityTypeDefinition.getProperties().values().stream().collect(Collectors.toList());
135 Either<List<PropertyDefinition>, JanusGraphOperationStatus> validatePropertiesRes = propertyOperation.validatePropertiesUniqueness(allPropertiesRes.left().value(),
137 if (validatePropertiesRes.isRight()) {
138 error = validatePropertiesRes.right().value();
143 return Either.left(capabilityTypeDefinition);
145 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error));
151 * convert between graph Node object to Java object
153 * @param capabilityTypeData
156 protected CapabilityTypeDefinition convertCTDataToCTDefinition(CapabilityTypeData capabilityTypeData) {
157 log.debug("The object returned after create capability is {}", capabilityTypeData);
159 return new CapabilityTypeDefinition(capabilityTypeData.getCapabilityTypeDataDefinition());
164 * Add capability type to graph.
166 * 1. Add capability type node
168 * 2. Add edge between the former node to its parent(if exists)
170 * 3. Add property node and associate it to the node created at #1. (per property & if exists)
172 * @param capabilityTypeDefinition
175 private Either<CapabilityTypeData, StorageOperationStatus> addCapabilityTypeToGraph(CapabilityTypeDefinition capabilityTypeDefinition) {
177 log.debug("Got capability type {}", capabilityTypeDefinition);
179 String ctUniqueId = UniqueIdBuilder.buildCapabilityTypeUid(capabilityTypeDefinition.getType());
180 CapabilityTypeData capabilityTypeData = buildCapabilityTypeData(capabilityTypeDefinition, ctUniqueId);
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);
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));
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()));
201 return addDerivedFromRelation(capabilityTypeDefinition, ctUniqueId)
203 .map(updatedDerivedFrom -> createCTResult.left().value());
208 private CapabilityTypeData buildCapabilityTypeData(CapabilityTypeDefinition capabilityTypeDefinition, String ctUniqueId) {
210 CapabilityTypeData capabilityTypeData = new CapabilityTypeData(capabilityTypeDefinition);
212 capabilityTypeData.getCapabilityTypeDataDefinition().setUniqueId(ctUniqueId);
213 Long creationDate = capabilityTypeData.getCapabilityTypeDataDefinition().getCreationTime();
214 if (creationDate == null) {
215 creationDate = System.currentTimeMillis();
217 capabilityTypeData.getCapabilityTypeDataDefinition().setCreationTime(creationDate);
218 capabilityTypeData.getCapabilityTypeDataDefinition().setModificationTime(creationDate);
219 return capabilityTypeData;
223 public Either<CapabilityTypeDefinition, StorageOperationStatus> getCapabilityType(String uniqueId, boolean inTransaction) {
225 Either<CapabilityTypeDefinition, StorageOperationStatus> result = null;
228 Either<CapabilityTypeDefinition, JanusGraphOperationStatus> ctResult = this.getCapabilityTypeByUid(uniqueId);
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);
235 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(ctResult.right().value()));
239 result = Either.left(ctResult.left().value());
243 if (!inTransaction) {
244 log.debug("Going to execute commit on graph.");
245 janusGraphGenericDao.commit();
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);
257 * Build Capability type object from graph by unique id
262 public Either<CapabilityTypeDefinition, JanusGraphOperationStatus> getCapabilityTypeByUid(String uniqueId) {
264 Either<CapabilityTypeDefinition, JanusGraphOperationStatus> result = null;
266 Either<CapabilityTypeData, JanusGraphOperationStatus> capabilityTypesRes = janusGraphGenericDao
267 .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), uniqueId, CapabilityTypeData.class);
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);
275 CapabilityTypeData ctData = capabilityTypesRes.left().value();
276 CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition(ctData.getCapabilityTypeDataDefinition());
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());
285 if (propertiesStatus.isLeft()) {
286 capabilityTypeDefinition.setProperties(propertiesStatus.left().value());
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);
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());
307 result = Either.left(capabilityTypeDefinition);
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());
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);
326 private Either<CapabilityTypeDefinition, StorageOperationStatus> updateCapabilityTypeOnGraph(CapabilityTypeDefinition capabilityTypeDefinitionNew, CapabilityTypeDefinition capabilityTypeDefinitionOld) {
327 return janusGraphGenericDao
328 .updateNode(new CapabilityTypeData(capabilityTypeDefinitionNew), CapabilityTypeData.class)
330 .map(DaoStatusConverter::convertJanusGraphStatusToStorageStatus)
332 .bind(updatedNode -> updateProperties(capabilityTypeDefinitionNew.getUniqueId(), capabilityTypeDefinitionNew.getProperties()))
334 .bind(updatedProperties -> updateDerivedFrom(capabilityTypeDefinitionNew, capabilityTypeDefinitionOld.getDerivedFrom()))
336 .bind(result -> TypeOperations.mapOkStatus(result, null))
338 .map(updatedDerivedFrom -> capabilityTypeDefinitionNew);
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)
345 .map(DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
348 private Either<GraphRelation, StorageOperationStatus> updateDerivedFrom(CapabilityTypeDefinition updatedCapabilityType, String currDerivedFromCapabilityType) {
349 if( StringUtils.equals(updatedCapabilityType.getDerivedFrom(), currDerivedFromCapabilityType)) {
350 return Either.right(StorageOperationStatus.OK);
353 StorageOperationStatus status = isLegalToReplaceParent(currDerivedFromCapabilityType, updatedCapabilityType.getDerivedFrom(), updatedCapabilityType.getType());
354 if ( status != StorageOperationStatus.OK) {
355 return Either.right(status);
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);
364 return addDerivedFromRelation(updatedCapabilityType, capabilityTypeId);
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());
371 private Either<GraphRelation, StorageOperationStatus> addDerivedFromRelation(CapabilityTypeDefinition capabilityTypeDef, String ptUniqueId) {
372 String derivedFrom = capabilityTypeDef.getDerivedFrom();
373 if (derivedFrom == null) {
374 return Either.left(null);
376 log.debug("#addDerivedFromRelationBefore - adding derived from relation between capability type {} to its parent {}", capabilityTypeDef.getType(), derivedFrom);
377 return this.getCapabilityType(derivedFrom, true)
379 .bind(derivedFromCapabilityType -> derivedFromOperation.addDerivedFromRelation(ptUniqueId, derivedFromCapabilityType.getUniqueId(), NodeTypeEnum.CapabilityType));
382 private StorageOperationStatus deleteDerivedFromCapabilityType(String capabilityTypeId, String derivedFromType) {
383 if (derivedFromType == null) {
384 return StorageOperationStatus.OK;
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),
392 private void updateCapabilityTypeData(CapabilityTypeDefinition updatedTypeDefinition, CapabilityTypeDefinition currTypeDefinition) {
393 updatedTypeDefinition.setUniqueId(currTypeDefinition.getUniqueId());
394 updatedTypeDefinition.setCreationTime(currTypeDefinition.getCreationTime());
401 * @param propertyOperation
403 public void setPropertyOperation(PropertyOperation propertyOperation) {
404 this.propertyOperation = propertyOperation;
408 public Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType(CapabilityTypeDefinition capabilityTypeDefinition) {
410 return addCapabilityType(capabilityTypeDefinition, true);
414 public Either<CapabilityTypeDefinition, StorageOperationStatus> getCapabilityType(String uniqueId) {
415 return getCapabilityType(uniqueId, true);
417 public Either<Map<String, CapabilityTypeDefinition>, JanusGraphOperationStatus> getAllCapabilityTypes() {
419 Map<String, CapabilityTypeDefinition> capabilityTypes = new HashMap<>();
420 Either<Map<String, CapabilityTypeDefinition>, JanusGraphOperationStatus> result = Either.left(capabilityTypes);
422 Either<List<CapabilityTypeData>, JanusGraphOperationStatus> getAllCapabilityTypes =
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);
434 List<CapabilityTypeData> list = getAllCapabilityTypes.left().value();
437 log.trace("Number of data types to load is {}", list.size());
439 for (CapabilityTypeData capabilityTypeData : list) {
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;
451 return Either.right(status);
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)
463 .bind(this::handleDerivedFromNotExist)
465 .map(derivedFrom -> setDerivedFrom(capabilityType, derivedFrom));
469 private Either<CapabilityTypeData, StorageOperationStatus> handleDerivedFromNotExist(StorageOperationStatus err) {
470 if (err == StorageOperationStatus.NOT_FOUND) {
471 return Either.left(null);
473 return Either.right(err);
476 private CapabilityTypeData setDerivedFrom(CapabilityTypeDefinition capabilityTypeDefinition, CapabilityTypeData derivedFrom) {
477 if (derivedFrom != null) {
478 capabilityTypeDefinition.setDerivedFrom(derivedFrom.getCapabilityTypeDataDefinition().getType());
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));
489 Either<CapabilityTypeData, JanusGraphOperationStatus> capabilityTypesRes =
491 .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), uniqueId,
492 CapabilityTypeData.class);
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);
500 CapabilityTypeData ctData = capabilityTypesRes.left().value();
501 CapabilityTypeDefinition capabilityTypeDefinition =
502 new CapabilityTypeDefinition(ctData.getCapabilityTypeDataDefinition());
504 Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> propertiesStatus =
505 OperationUtils.fillProperties(uniqueId, propertyOperation, NodeTypeEnum.CapabilityType);
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());
512 if (propertiesStatus.isLeft()) {
513 capabilityTypeDefinition.setProperties(propertiesStatus.left().value());
516 fillDerivedFrom(uniqueId, capabilityTypeDefinition);
518 capabilityTypeDefinitionMap.put(capabilityTypeDefinition.getType(), capabilityTypeDefinition);
520 return Either.left(capabilityTypeDefinition);