2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2021 Nordix Foundation
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 * SPDX-License-Identifier: Apache-2.0
17 * ============LICENSE_END=========================================================
19 package org.openecomp.sdc.be.model.operations.impl;
21 import static org.openecomp.sdc.common.api.Constants.ADDITIONAL_TYPE_DEFINITIONS;
23 import fj.data.Either;
24 import java.nio.charset.StandardCharsets;
25 import java.nio.file.Path;
26 import java.util.ArrayList;
27 import java.util.Collections;
28 import java.util.EnumMap;
29 import java.util.HashMap;
30 import java.util.LinkedHashMap;
31 import java.util.List;
33 import java.util.Map.Entry;
34 import java.util.Objects;
35 import java.util.Optional;
37 import java.util.stream.Collectors;
38 import org.apache.commons.collections.CollectionUtils;
39 import org.apache.commons.collections.MapUtils;
40 import org.apache.commons.lang3.StringUtils;
41 import org.apache.commons.lang3.tuple.ImmutablePair;
42 import org.onap.sdc.tosca.services.YamlUtil;
43 import org.openecomp.sdc.be.dao.api.ActionStatus;
44 import org.openecomp.sdc.be.dao.cassandra.ToscaModelImportCassandraDao;
45 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
46 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
47 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao;
48 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphGenericDao;
49 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
50 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
51 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
52 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
53 import org.openecomp.sdc.be.data.model.ToscaImportByModel;
54 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
55 import org.openecomp.sdc.be.datatypes.enums.ModelTypeEnum;
56 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
57 import org.openecomp.sdc.be.model.Model;
58 import org.openecomp.sdc.be.model.dto.PropertyDefinitionDto;
59 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.exception.ModelOperationExceptionSupplier;
60 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.exception.OperationException;
61 import org.openecomp.sdc.be.model.normatives.ElementTypeEnum;
62 import org.openecomp.sdc.be.model.operations.api.DerivedFromOperation;
63 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
64 import org.openecomp.sdc.be.resources.data.ModelData;
65 import org.openecomp.sdc.be.utils.TypeUtils;
66 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
67 import org.openecomp.sdc.common.log.wrappers.Logger;
68 import org.springframework.beans.factory.annotation.Autowired;
69 import org.springframework.stereotype.Component;
70 import org.yaml.snakeyaml.Yaml;
72 @Component("model-operation")
73 public class ModelOperation {
75 private static final Logger log = Logger.getLogger(ModelOperation.class);
76 static final Path ADDITIONAL_TYPE_DEFINITIONS_PATH = Path.of(ADDITIONAL_TYPE_DEFINITIONS);
78 private final JanusGraphGenericDao janusGraphGenericDao;
79 private final JanusGraphDao janusGraphDao;
80 private final ToscaModelImportCassandraDao toscaModelImportCassandraDao;
81 private final DerivedFromOperation derivedFromOperation;
82 private ModelElementOperation modelElementOperation;
85 public ModelOperation(final JanusGraphGenericDao janusGraphGenericDao,
86 final JanusGraphDao janusGraphDao,
87 final ToscaModelImportCassandraDao toscaModelImportCassandraDao,
88 final DerivedFromOperation derivedFromOperation) {
89 this.janusGraphGenericDao = janusGraphGenericDao;
90 this.janusGraphDao = janusGraphDao;
91 this.toscaModelImportCassandraDao = toscaModelImportCassandraDao;
92 this.derivedFromOperation = derivedFromOperation;
95 public Model createModel(final Model model, final boolean inTransaction) {
97 final var modelData = new ModelData(model.getName(), UniqueIdBuilder.buildModelUid(model.getName()), model.getModelType());
99 final Either<ModelData, JanusGraphOperationStatus> createNode = janusGraphGenericDao.createNode(modelData, ModelData.class);
100 if (createNode.isRight()) {
101 final var janusGraphOperationStatus = createNode.right().value();
102 log.error(EcompLoggerErrorCode.DATA_ERROR, ModelOperation.class.getName(), "Problem while creating model, reason {}",
103 janusGraphOperationStatus);
104 if (janusGraphOperationStatus == JanusGraphOperationStatus.JANUSGRAPH_SCHEMA_VIOLATION) {
105 throw ModelOperationExceptionSupplier.modelAlreadyExists(model.getName()).get();
107 throw new OperationException(ActionStatus.GENERAL_ERROR,
108 String.format("Failed to create model %s on JanusGraph with %s error", model, janusGraphOperationStatus));
110 addDerivedFromRelation(model);
111 result = new Model(createNode.left().value().getName(), model.getDerivedFrom(), model.getModelType());
114 if (!inTransaction) {
115 if (Objects.nonNull(result)) {
116 janusGraphGenericDao.commit();
118 janusGraphGenericDao.rollback();
124 private void addDerivedFromRelation(final Model model) {
125 final String derivedFrom = model.getDerivedFrom();
126 if (derivedFrom == null) {
129 log.debug("Adding derived from relation between model {} to its parent {}",
130 model.getName(), derivedFrom);
131 final Optional<Model> derivedFromModelOptional = this.findModelByName(derivedFrom);
132 if (derivedFromModelOptional.isPresent()) {
133 final Either<GraphRelation, StorageOperationStatus> result = derivedFromOperation.addDerivedFromRelation(
134 UniqueIdBuilder.buildModelUid(model.getName()),
135 UniqueIdBuilder.buildModelUid(derivedFromModelOptional.get().getName()), NodeTypeEnum.Model);
136 if (result.isRight()) {
137 throw new OperationException(ActionStatus.GENERAL_ERROR,
138 String.format("Failed to create relationship from model %s to derived from model %s on JanusGraph with %s error", model,
139 derivedFrom, result.right().value()));
144 public Optional<GraphVertex> findModelVertexByName(final String name) {
145 if (StringUtils.isEmpty(name)) {
146 return Optional.empty();
148 final Map<GraphPropertyEnum, Object> props = new EnumMap<>(GraphPropertyEnum.class);
149 props.put(GraphPropertyEnum.NAME, name);
150 props.put(GraphPropertyEnum.UNIQUE_ID, UniqueIdBuilder.buildModelUid(name));
151 final List<GraphVertex> modelVerticesList = findModelVerticesByCriteria(props);
152 if (modelVerticesList.isEmpty()) {
153 return Optional.empty();
155 return Optional.ofNullable(modelVerticesList.get(0));
158 public Optional<Model> findModelByName(final String name) {
159 if (StringUtils.isEmpty(name)) {
160 return Optional.empty();
162 final Optional<GraphVertex> modelVertexOpt = findModelVertexByName(name);
163 if (modelVertexOpt.isEmpty()) {
164 return Optional.empty();
167 final GraphVertex graphVertex = modelVertexOpt.get();
168 return Optional.of(convertToModel(graphVertex));
171 public void createModelImports(final String modelId, final Map<String, byte[]> zipContent) {
172 if (MapUtils.isEmpty(zipContent)) {
175 final List<ToscaImportByModel> toscaImportByModelList = zipContent.entrySet().stream()
177 final String path = entry.getKey();
178 final byte[] bytes = entry.getValue();
179 final String content = new String(bytes, StandardCharsets.UTF_8);
180 final var toscaImportByModel = new ToscaImportByModel();
181 toscaImportByModel.setModelId(modelId);
182 toscaImportByModel.setFullPath(path);
183 toscaImportByModel.setContent(content);
184 return toscaImportByModel;
185 }).collect(Collectors.toList());
186 toscaModelImportCassandraDao.replaceImports(modelId, toscaImportByModelList);
190 * Find all the model default imports, with the option to include the default imports from the parent model.
192 * @param modelId the model id
193 * @param includeParent a flag to include the parent model imports.
194 * @return the list of model default imports, or an empty list if no imports were found.
196 public List<ToscaImportByModel> findAllModelImports(final String modelId, final boolean includeParent) {
197 final List<ToscaImportByModel> toscaImportByModelList = toscaModelImportCassandraDao.findAllByModel(modelId);
199 findModelByName(modelId).ifPresent(model -> {
200 if (model.getDerivedFrom() != null) {
201 toscaImportByModelList.addAll(toscaModelImportCassandraDao.findAllByModel(model.getDerivedFrom()));
205 toscaImportByModelList.sort((o1, o2) -> {
206 final int modelIdComparison = o1.getModelId().compareTo(o2.getModelId());
207 if (modelIdComparison == 0) {
208 return o1.getFullPath().compareTo(o2.getFullPath());
210 return modelIdComparison;
212 return toscaImportByModelList;
216 * Finds all the models.
218 * @return the list of models
220 public List<Model> findAllModels() {
221 return findModelsByCriteria(Collections.emptyMap());
224 public List<Model> findModels(final ModelTypeEnum modelType) {
225 final Map<GraphPropertyEnum, Object> propertyCriteria = new EnumMap<>(GraphPropertyEnum.class);
226 propertyCriteria.put(GraphPropertyEnum.MODEL_TYPE, modelType.getValue());
228 return findModelsByCriteria(propertyCriteria);
231 private List<Model> findModelsByCriteria(final Map<GraphPropertyEnum, Object> propertyCriteria) {
232 final List<GraphVertex> modelVerticesByCriteria = findModelVerticesByCriteria(propertyCriteria);
233 if (modelVerticesByCriteria.isEmpty()) {
234 return Collections.emptyList();
237 return modelVerticesByCriteria.stream().map(this::convertToModel).collect(Collectors.toList());
240 private List<GraphVertex> findModelVerticesByCriteria(final Map<GraphPropertyEnum, Object> propertyCriteria) {
241 final Either<List<GraphVertex>, JanusGraphOperationStatus> result = janusGraphDao.getByCriteria(VertexTypeEnum.MODEL, propertyCriteria);
242 if (result.isRight()) {
243 final var janusGraphOperationStatus = result.right().value();
244 if (janusGraphOperationStatus == JanusGraphOperationStatus.NOT_FOUND) {
245 return Collections.emptyList();
247 final var operationException = ModelOperationExceptionSupplier.failedToRetrieveModels(janusGraphOperationStatus).get();
248 log.error(EcompLoggerErrorCode.DATA_ERROR, this.getClass().getName(), operationException.getMessage());
249 throw operationException;
251 return result.left().value();
254 private Model convertToModel(final GraphVertex modelGraphVertex) {
255 final String modelName = (String) modelGraphVertex.getMetadataProperty(GraphPropertyEnum.NAME);
256 final String modelTypeProperty = (String) modelGraphVertex.getMetadataProperty(GraphPropertyEnum.MODEL_TYPE);
257 ModelTypeEnum modelType = ModelTypeEnum.NORMATIVE;
258 final Optional<ModelTypeEnum> optionalModelTypeEnum = ModelTypeEnum.findByValue(modelTypeProperty);
259 if (optionalModelTypeEnum.isPresent()) {
260 modelType = optionalModelTypeEnum.get();
263 final Either<ImmutablePair<ModelData, GraphEdge>, JanusGraphOperationStatus> parentNode =
264 janusGraphGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Model), UniqueIdBuilder.buildModelUid(modelName),
265 GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Model, ModelData.class);
266 log.debug("After retrieving DERIVED_FROM node of {}. status is {}", modelName, parentNode);
267 if (parentNode.isRight()) {
268 final JanusGraphOperationStatus janusGraphOperationStatus = parentNode.right().value();
269 if (janusGraphOperationStatus != JanusGraphOperationStatus.NOT_FOUND) {
270 final var operationException = ModelOperationExceptionSupplier.failedToRetrieveModels(janusGraphOperationStatus).get();
271 log.error(EcompLoggerErrorCode.DATA_ERROR, this.getClass().getName(), operationException.getMessage());
272 throw operationException;
274 return new Model((String) modelGraphVertex.getMetadataProperty(GraphPropertyEnum.NAME), modelType);
276 final ModelData parentModel = parentNode.left().value().getKey();
277 return new Model((String) modelGraphVertex.getMetadataProperty(GraphPropertyEnum.NAME), parentModel.getName(), modelType);
281 public void addTypesToDefaultImports(final ElementTypeEnum elementTypeEnum, final String typesYaml, final String modelName) {
282 final List<ToscaImportByModel> modelImportList = toscaModelImportCassandraDao.findAllByModel(modelName);
283 final Optional<ToscaImportByModel> additionalTypeDefinitionsImportOptional = modelImportList.stream()
284 .filter(t -> ADDITIONAL_TYPE_DEFINITIONS_PATH.equals(Path.of(t.getFullPath()))).findAny();
285 final ToscaImportByModel additionalTypeDefinitionsImport;
286 final List<ToscaImportByModel> rebuiltModelImportList;
287 if (additionalTypeDefinitionsImportOptional.isPresent()) {
288 additionalTypeDefinitionsImport = additionalTypeDefinitionsImportOptional.get();
289 rebuiltModelImportList = modelImportList.stream()
290 .filter(toscaImportByModel -> !ADDITIONAL_TYPE_DEFINITIONS_PATH.equals(Path.of(toscaImportByModel.getFullPath())))
291 .collect(Collectors.toList());
293 additionalTypeDefinitionsImport = new ToscaImportByModel();
294 additionalTypeDefinitionsImport.setModelId(modelName);
295 additionalTypeDefinitionsImport.setFullPath(ADDITIONAL_TYPE_DEFINITIONS_PATH.toString());
296 additionalTypeDefinitionsImport.setContent(createAdditionalTypeDefinitionsHeader());
297 rebuiltModelImportList = new ArrayList<>(modelImportList);
300 Map<String, Object> typesYamlMap = new Yaml().loadAs(typesYaml, Map.class);
301 if (typesYamlMap.containsKey("data_types")){
302 typesYamlMap = (Map<String, Object>) typesYamlMap.get("data_types");
304 removeExistingTypesFromDefaultImports(elementTypeEnum, typesYamlMap, rebuiltModelImportList);
306 final Map<String, Object> originalContent = new Yaml().load(additionalTypeDefinitionsImport.getContent());
307 additionalTypeDefinitionsImport.setContent(buildAdditionalTypeDefinitionsContent(elementTypeEnum, typesYamlMap, originalContent));
308 rebuiltModelImportList.add(additionalTypeDefinitionsImport);
310 toscaModelImportCassandraDao.saveAll(modelName, rebuiltModelImportList);
313 private void removeExistingTypesFromDefaultImports(final ElementTypeEnum elementTypeEnum, final Map<String, Object> typesYaml,
314 final List<ToscaImportByModel> defaultImportList) {
315 defaultImportList.forEach(toscaImportByModel -> {
316 final Map<String, Object> existingImportYamlMap = new Yaml().load(toscaImportByModel.getContent());
317 final Map<String, Object> currentTypeYamlMap = (Map<String, Object>) existingImportYamlMap.get(elementTypeEnum.getToscaEntryName());
318 if (MapUtils.isNotEmpty(currentTypeYamlMap)) {
319 typesYaml.keySet().forEach(currentTypeYamlMap::remove);
321 toscaImportByModel.setContent(new YamlUtil().objectToYaml(existingImportYamlMap));
325 private String buildAdditionalTypeDefinitionsContent(final ElementTypeEnum elementTypeEnum, final Map<String, Object> typesYamlMap,
326 final Map<String, Object> originalContent) {
327 final Map<String, Object> originalTypeContent = (Map<String, Object>) originalContent.get(elementTypeEnum.getToscaEntryName());
328 if (MapUtils.isEmpty(originalTypeContent)) {
329 originalContent.put(elementTypeEnum.getToscaEntryName(), new LinkedHashMap<>(typesYamlMap));
331 originalTypeContent.putAll(typesYamlMap);
333 return new YamlUtil().objectToYaml(originalContent);
336 private String createAdditionalTypeDefinitionsHeader() {
337 return "tosca_definitions_version: tosca_simple_yaml_1_3" + "\n"
338 + "description: Auto-generated file that contains package custom types or types added after system installation." + "\n";
342 * Deletes the given model if it exists, along with its MODEL_ELEMENT edges and import files.
344 * @param model the model
345 * @param inTransaction if the operation is called in the middle of a janusgraph transaction
347 public void deleteModel(final Model model, final boolean inTransaction) {
348 boolean rollback = false;
351 final GraphVertex modelVertexByName = findModelVertexByName(model.getName()).orElse(null);
352 if (modelVertexByName == null) {
355 toscaModelImportCassandraDao.deleteAllByModel(model.getName());
356 modelElementOperation.deleteModelElements(model, inTransaction);
358 } catch (final OperationException e) {
361 } catch (final Exception e) {
363 throw new OperationException(e, ActionStatus.COULD_NOT_DELETE_MODEL, model.getName());
365 if (!inTransaction) {
367 janusGraphGenericDao.rollback();
369 janusGraphGenericDao.commit();
375 private void deleteModel(final Model model) {
376 final var modelData = new ModelData(model.getName(), UniqueIdBuilder.buildModelUid(model.getName()), model.getModelType());
377 final Either<ModelData, JanusGraphOperationStatus> deleteParentNodeByModel = janusGraphGenericDao.deleteNode(modelData, ModelData.class);
378 if (deleteParentNodeByModel.isRight()) {
379 final var janusGraphOperationStatus = deleteParentNodeByModel.right().value();
380 log.error(EcompLoggerErrorCode.DATA_ERROR, ModelOperation.class.getName(),
381 "Failed to delete model {} on JanusGraph with status {}", new Object[] {model.getName(), janusGraphOperationStatus});
382 throw new OperationException(ActionStatus.COULD_NOT_DELETE_MODEL, model.getName());
387 public void setModelElementOperation(final ModelElementOperation modelElementOperation) {
388 this.modelElementOperation = modelElementOperation;
391 @SuppressWarnings("unchecked")
392 public void updateTypesInAdditionalTypesImport(final ElementTypeEnum elementTypeEnum, final String typesYaml, final String modelName) {
393 final Optional<ToscaImportByModel> additionalTypeDefinitionsImportOptional = getAdditionalTypes(modelName);
395 if (additionalTypeDefinitionsImportOptional.isPresent()) {
397 final Map<String, Object> existingTypeContent = getExistingTypes(elementTypeEnum, additionalTypeDefinitionsImportOptional.get());
398 final Set<String> existingTypeNames = existingTypeContent.keySet();
400 final Map<String, Object> typesToUpate = new HashMap<>();
402 Map<String, Object> newTypesYaml = new Yaml().load(typesYaml);
403 if (newTypesYaml.containsKey("data_types")){
404 newTypesYaml = (Map<String, Object>) newTypesYaml.get("data_types");
406 newTypesYaml.entrySet().stream().filter(entry -> existingTypeNames.contains(entry.getKey())).forEach(newTypeToUpdate -> {
408 final Map<String, Object> propertiesInNewDef = (Map<String, Object>) ((Map<String, Object>) newTypeToUpdate.getValue()).get("properties");
409 final Map<String, Object> existingProperties =
410 (Map<String, Object>) ((Map<String, Object>) existingTypeContent.get(newTypeToUpdate.getKey())).get("properties");
412 final List<Entry<String, Object>> propertiesMissingFromNewDef = MapUtils.isEmpty(existingProperties) ? Collections.emptyList()
413 : existingProperties.entrySet().stream()
414 .filter(existingPropEntry -> !propertiesInNewDef.keySet().contains(existingPropEntry.getKey()))
415 .collect(Collectors.toList());
417 if (CollectionUtils.isNotEmpty(propertiesMissingFromNewDef)) {
418 typesToUpate.put(newTypeToUpdate.getKey(), newTypeToUpdate.getValue());
420 propertiesMissingFromNewDef
421 .forEach(existingPropToAdd -> propertiesInNewDef.put(existingPropToAdd.getKey(), existingPropToAdd.getValue()));
424 if (MapUtils.isNotEmpty(typesToUpate)) {
425 addTypesToDefaultImports(elementTypeEnum, new Yaml().dumpAsMap(typesToUpate), modelName);
430 private Optional<ToscaImportByModel> getAdditionalTypes(final String modelName) {
431 final List<ToscaImportByModel> modelImportList = toscaModelImportCassandraDao.findAllByModel(modelName);
432 return modelImportList.stream().filter(t -> ADDITIONAL_TYPE_DEFINITIONS_PATH.equals(Path.of(t.getFullPath()))).findAny();
435 private Map<String, Object> getExistingTypes(final ElementTypeEnum elementTypeEnum, final ToscaImportByModel additionalTypeDefinitionsImport) {
436 final Map<String, Object> existingContent = new Yaml().load(additionalTypeDefinitionsImport.getContent());
437 return (Map<String, Object>) existingContent.get(elementTypeEnum.getToscaEntryName());
440 public void addPropertyToAdditionalType(final ElementTypeEnum elementTypeEnum, final PropertyDefinitionDto property,
441 final String modelName, final String name) {
442 final List<ToscaImportByModel> modelImportList = toscaModelImportCassandraDao.findAllByModel(modelName);
443 final Optional<ToscaImportByModel> additionalTypeDefinitionsImportOptional = modelImportList.stream()
444 .filter(t -> ADDITIONAL_TYPE_DEFINITIONS_PATH.equals(Path.of(t.getFullPath()))).findAny();
445 final ToscaImportByModel additionalTypeDefinitionsImport;
446 final List<ToscaImportByModel> rebuiltModelImportList;
447 if (additionalTypeDefinitionsImportOptional.isEmpty()) {
450 additionalTypeDefinitionsImport = additionalTypeDefinitionsImportOptional.get();
451 rebuiltModelImportList = modelImportList.stream()
452 .filter(toscaImportByModel -> !ADDITIONAL_TYPE_DEFINITIONS_PATH.equals(Path.of(toscaImportByModel.getFullPath())))
453 .collect(Collectors.toList());
454 final Map<String, Object> originalContent = new Yaml().load(additionalTypeDefinitionsImport.getContent());
455 additionalTypeDefinitionsImport.setContent(buildPropertyAdditionalTypeDefinitionContent(elementTypeEnum, name, property, originalContent));
456 rebuiltModelImportList.add(additionalTypeDefinitionsImport);
457 toscaModelImportCassandraDao.saveAll(modelName, rebuiltModelImportList);
460 private String buildPropertyAdditionalTypeDefinitionContent(final ElementTypeEnum elementTypeEnum, final String name,
461 final PropertyDefinitionDto property, final Map<String, Object> originalContent) {
462 final Map<String, Object> originalTypeContent = (Map<String, Object>) originalContent.get(elementTypeEnum.getToscaEntryName());
463 Map<String, Object> typeContent = (Map<String, Object>) originalTypeContent.get(name);
464 Map<String, Object> typeProperties = (Map<String, Object>) typeContent.get("properties");
465 if (typeProperties == null) {
466 typeProperties = new HashMap<>();
468 Map<String, Object> typeProp = constructProperty(property);
469 typeProperties.put(property.getName(), typeProp);
470 typeContent.put("properties", typeProperties);
471 return new YamlUtil().objectToYaml(originalContent);
474 private Map<String, Object> constructProperty(final PropertyDefinitionDto property) {
475 Map<String, Object> typeProp = new HashMap<>();
476 if (property.getType() != null) {
477 typeProp.put(TypeUtils.ToscaTagNamesEnum.TYPE.getElementName(), property.getType());
479 if (property.getDescription() != null) {
480 typeProp.put(TypeUtils.ToscaTagNamesEnum.DESCRIPTION.getElementName(), property.getDescription());
482 Map<String, Object> schema = new HashMap<>();
483 if (property.getSchemaType() != null) {
484 schema.put(TypeUtils.ToscaTagNamesEnum.TYPE.getElementName(), property.getSchemaType());
485 typeProp.put(TypeUtils.ToscaTagNamesEnum.ENTRY_SCHEMA.getElementName(), schema);
487 if (property.getDefaultValue() != null) {
488 typeProp.put(TypeUtils.ToscaTagNamesEnum.DEFAULT.getElementName(), property.getDefaultValue());
490 if (property.getRequired() != null) {
491 typeProp.put(TypeUtils.ToscaTagNamesEnum.REQUIRED.getElementName(), property.getRequired());
493 if (property.getConstraints() != null) {
494 typeProp.put(TypeUtils.ToscaTagNamesEnum.CONSTRAINTS.getElementName(), property.getConstraints());