import static org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR;
+import com.fasterxml.jackson.core.ObjectCodec;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.collect.Maps;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import com.google.gson.JsonParser;
+import com.google.gson.JsonSerializationContext;
+import com.google.gson.JsonSerializer;
+import fj.data.Either;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import org.openecomp.sdc.be.datatypes.elements.PropertyRule;
import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
+import org.openecomp.sdc.be.model.Component;
import org.openecomp.sdc.be.model.ComponentInstanceProperty;
import org.openecomp.sdc.be.model.DataTypeDefinition;
import org.openecomp.sdc.be.model.IComplexDefaultValue;
import org.openecomp.sdc.be.model.PropertyConstraint;
import org.openecomp.sdc.be.model.PropertyDefinition;
+import org.openecomp.sdc.be.model.validation.ToscaFunctionValidator;
import org.openecomp.sdc.be.model.operations.api.DerivedFromOperation;
import org.openecomp.sdc.be.model.operations.api.IPropertyOperation;
import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter;
import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
import org.openecomp.sdc.be.resources.data.DataTypeData;
+import org.openecomp.sdc.be.resources.data.ModelData;
import org.openecomp.sdc.be.resources.data.PropertyData;
import org.openecomp.sdc.be.resources.data.PropertyValueData;
import org.openecomp.sdc.be.resources.data.ResourceMetadataData;
import org.openecomp.sdc.be.resources.data.UniqueIdData;
import org.openecomp.sdc.common.log.wrappers.Logger;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-import com.fasterxml.jackson.core.ObjectCodec;
-import com.fasterxml.jackson.databind.DeserializationContext;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.google.common.collect.Maps;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonDeserializationContext;
-import com.google.gson.JsonDeserializer;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParseException;
-import com.google.gson.JsonParser;
-import com.google.gson.JsonSerializationContext;
-import com.google.gson.JsonSerializer;
-import fj.data.Either;
-@Component("property-operation")
+@org.springframework.stereotype.Component("property-operation")
public class PropertyOperation extends AbstractOperation implements IPropertyOperation {
private static final String AFTER_RETRIEVING_DERIVED_FROM_NODE_OF_STATUS_IS = "After retrieving DERIVED_FROM node of {}. status is {}";
private static final String THE_VALUE_OF_PROPERTY_FROM_TYPE_IS_INVALID = "The value {} of property from type {} is invalid";
private static final String PROPERTY = "Property";
private static final String UPDATE_DATA_TYPE = "UpdateDataType";
- private static Logger log = Logger.getLogger(PropertyOperation.class.getName());
- private DerivedFromOperation derivedFromOperation;
+ private static final Logger log = Logger.getLogger(PropertyOperation.class.getName());
+ private final DerivedFromOperation derivedFromOperation;
+ private ToscaFunctionValidator toscaFunctionValidator;
+ private DataTypeOperation dataTypeOperation;
@Autowired
- public PropertyOperation(HealingJanusGraphGenericDao janusGraphGenericDao, DerivedFromOperation derivedFromOperation) {
+ public PropertyOperation(final HealingJanusGraphGenericDao janusGraphGenericDao, final DerivedFromOperation derivedFromOperation) {
this.janusGraphGenericDao = janusGraphGenericDao;
this.derivedFromOperation = derivedFromOperation;
}
+ @Autowired
+ public void setToscaFunctionValidator(final ToscaFunctionValidator toscaFunctionValidator) {
+ this.toscaFunctionValidator = toscaFunctionValidator;
+ }
+
+ //circular dependency DataTypeOperation->ModelOperation->ModelElementOperation->PropertyOperation
+ @Autowired
+ public void setDataTypeOperation(DataTypeOperation dataTypeOperation) {
+ this.dataTypeOperation = dataTypeOperation;
+ }
+
public PropertyDefinition convertPropertyDataToPropertyDefinition(PropertyData propertyDataResult, String propertyName, String resourceId) {
log.debug("The object returned after create property is {}", propertyDataResult);
PropertyDefinition propertyDefResult = new PropertyDefinition(propertyDataResult.getPropertyDataDefinition());
}
return true;
}
+
+ public boolean isPropertyTypeValid(final IComplexDefaultValue property, final Map<String, DataTypeDefinition> dataTypes) {
+ if (property == null) {
+ return false;
+ }
+ return ToscaPropertyType.isValidType(property.getType()) != null || dataTypes.containsKey(property.getType());
+ }
@Override
public ImmutablePair<String, Boolean> isPropertyInnerTypeValid(IComplexDefaultValue property, Map<String, DataTypeDefinition> dataTypes) {
return Either.left(true);
}
- public Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> getAllDataTypes() {
- Map<String, DataTypeDefinition> dataTypes = new HashMap<>();
- Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> result = Either.left(dataTypes);
- Either<List<DataTypeData>, JanusGraphOperationStatus> getAllDataTypes = janusGraphGenericDao
- .getByCriteria(NodeTypeEnum.DataType, null, DataTypeData.class);
- if (getAllDataTypes.isRight()) {
- JanusGraphOperationStatus status = getAllDataTypes.right().value();
- if (status != JanusGraphOperationStatus.NOT_FOUND) {
- return Either.right(status);
- } else {
- return result;
- }
- }
- List<DataTypeData> list = getAllDataTypes.left().value();
- if (list != null) {
- log.trace("Number of data types to load is {}", list.size());
- List<String> collect = list.stream().map(p -> p.getDataTypeDataDefinition().getName()).collect(Collectors.toList());
- log.trace("The data types to load are {}", collect);
- for (DataTypeData dataTypeData : list) {
- log.trace("Going to fetch data type {}. uid is {}", dataTypeData.getDataTypeDataDefinition().getName(), dataTypeData.getUniqueId());
+ public Either<Map<String, Map<String, DataTypeDefinition>>, JanusGraphOperationStatus> getAllDataTypes() {
+ final Map<String, Map<String, DataTypeDefinition>> dataTypes = new HashMap<>();
+ Either<Map<String, Map<String, DataTypeDefinition>>, JanusGraphOperationStatus> result = Either.left(dataTypes);
+ final Map<String, DataTypeDefinition> allDataTypesFound = new HashMap<>();
+
+ final Map<String, List<String>> dataTypeUidstoModels = dataTypeOperation.getAllDataTypeUidsToModels();
+
+ if (dataTypeUidstoModels != null) {
+ log.trace("Number of data types to load is {}", dataTypeUidstoModels.size());
+ for (Map.Entry<String, List<String>> entry : dataTypeUidstoModels.entrySet()) {
+ log.trace("Going to fetch data type with uid {}", entry.getKey());
Either<DataTypeDefinition, JanusGraphOperationStatus> dataTypeByUid = this
- .getAndAddDataTypeByUid(dataTypeData.getUniqueId(), dataTypes);
+ .getAndAddDataTypeByUid(entry.getKey(), allDataTypesFound);
if (dataTypeByUid.isRight()) {
JanusGraphOperationStatus status = dataTypeByUid.right().value();
if (status == JanusGraphOperationStatus.NOT_FOUND) {
}
return Either.right(status);
}
+ for (final String model: entry.getValue()) {
+ if (!dataTypes.containsKey(model)) {
+ dataTypes.put(model, new HashMap<String, DataTypeDefinition>());
+ }
+ DataTypeDefinition dataTypeDefinition = allDataTypesFound.get(entry.getKey());
+ dataTypes.get(model).put(dataTypeDefinition.getName(), dataTypeDefinition);
+ }
}
+
}
if (log.isTraceEnabled()) {
if (result.isRight()) {
log.trace("After fetching all data types {}", result);
} else {
- Map<String, DataTypeDefinition> map = result.left().value();
+ Map<String, Map<String, DataTypeDefinition>> map = result.left().value();
if (map != null) {
String types = map.keySet().stream().collect(Collectors.joining(",", "[", "]"));
log.trace("After fetching all data types {} ", types);
log.error(FAILED_TO_FETCH_PROPERTIES_OF_DATA_TYPE, uniqueId);
return Either.right(propertiesStatus);
}
- allDataTypes.put(dataTypeDefinition.getName(), dataTypeDefinition);
+ allDataTypes.put(dataTypeDefinition.getUniqueId(), dataTypeDefinition);
String derivedFrom = dataTypeDefinition.getDerivedFromName();
if (allDataTypes.containsKey(derivedFrom)) {
DataTypeDefinition parentDataTypeDefinition = allDataTypes.get(derivedFrom);
}
DataTypeDefinition parentDataTypeDefinition = dataTypeByUid.left().value();
dataTypeDefinition.setDerivedFrom(parentDataTypeDefinition);
+ final var model = getModel(uniqueId);
+ if (StringUtils.isNotEmpty(model)) {
+ dataTypeDefinition.setModel(model);
+ }
}
result = Either.left(dataTypeDefinition);
return result;
}
+ private String getModel(final String uniqueId) {
+ final Either<ImmutablePair<ModelData, GraphEdge>, JanusGraphOperationStatus> model = janusGraphGenericDao.getParentNode(
+ UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, GraphEdgeLabels.MODEL_ELEMENT,
+ NodeTypeEnum.Model, ModelData.class);
+ return model.isLeft() ? model.left().value().getLeft().getName() : StringUtils.EMPTY;
+ }
+
public Either<String, JanusGraphOperationStatus> checkInnerType(PropertyDataDefinition propDataDef) {
String propertyType = propDataDef.getType();
ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
return getInnerType(type, propDataDef::getSchema);
}
- public Either<List<DataTypeData>, JanusGraphOperationStatus> getAllDataTypeNodes() {
- final Either<List<DataTypeData>, JanusGraphOperationStatus> getAllDataTypes =
- janusGraphGenericDao.getByCriteria(NodeTypeEnum.DataType, null, DataTypeData.class);
- if (getAllDataTypes.isRight() && getAllDataTypes.right().value() == JanusGraphOperationStatus.NOT_FOUND) {
- return Either.left(Collections.emptyList());
- }
- return getAllDataTypes;
- }
-
public Either<Object, Boolean> validateAndUpdatePropertyValue(String propertyType, String value, boolean isValidate, String innerType,
Map<String, DataTypeDefinition> dataTypes) {
log.trace("Going to validate property value and its type. type = {}, value = {}", propertyType, value);
- ToscaPropertyType type = getType(propertyType);
+ final ToscaPropertyType type = getType(propertyType);
if (isValidate) {
if (type == null) {
DataTypeDefinition dataTypeDefinition = dataTypes.get(propertyType);
return validateAndUpdatePropertyValue(propertyType, value, true, innerType, dataTypes);
}
+ public Either<Object, Boolean> validateAndUpdatePropertyValue(final Component containerComponent, final PropertyDataDefinition property,
+ final Map<String, DataTypeDefinition> dataTypes) {
+ if (property.isToscaFunction()) {
+ toscaFunctionValidator.validate(property, containerComponent);
+ property.setValue(property.getToscaFunction().getValue());
+ return Either.left(property.getValue());
+ }
+ Either<String, JanusGraphOperationStatus> checkInnerType = checkInnerType(property);
+ if (checkInnerType.isRight()) {
+ return Either.right(false);
+ }
+ final String innerType = checkInnerType.left().value();
+ return validateAndUpdatePropertyValue(property.getType(), property.getValue(), true, innerType, dataTypes);
+ }
+
public <T extends GraphNode> Either<List<PropertyDefinition>, StorageOperationStatus> getAllPropertiesRec(String uniqueId, NodeTypeEnum nodeType,
Class<T> clazz) {
return this.findPropertiesOfNode(nodeType, uniqueId).right().bind(this::handleNotFoundProperties).left()
String oldDerivedFromName = oldDataTypeDefinition.getDerivedFromName();
String dataTypeName = newDataTypeDefinition.getName();
List<PropertyDefinition> propertiesToAdd = new ArrayList<>();
- if (isPropertyOmitted(newProperties, oldProperties, dataTypeName) || isPropertyTypeChanged(dataTypeName, newProperties, oldProperties,
- propertiesToAdd) || isDerivedFromNameChanged(dataTypeName, newDerivedFromName, oldDerivedFromName)) {
+ if (isPropertyTypeChanged(dataTypeName, newProperties, oldProperties, propertiesToAdd)
+ || isDerivedFromNameChanged(dataTypeName, newDerivedFromName, oldDerivedFromName)) {
log.debug("The new data type {} is invalid.", dataTypeName);
result = Either.right(StorageOperationStatus.CANNOT_UPDATE_EXISTING_ENTITY);
return result;
}
- if (propertiesToAdd == null || propertiesToAdd.isEmpty()) {
+ if (CollectionUtils.isEmpty(propertiesToAdd)) {
log.debug("No new properties has been defined in the new data type {}", newDataTypeDefinition);
result = Either.right(StorageOperationStatus.OK);
return result;
return entryType;
}
- private boolean isPropertyOmitted(List<PropertyDefinition> newProperties, List<PropertyDefinition> oldProperties, String dataTypeName) {
- boolean isValid = validateChangeInCaseOfEmptyProperties(newProperties, oldProperties, dataTypeName);
- if (!isValid) {
- log.debug("At least one property is missing in the new data type {}", dataTypeName);
- return false;
- }
- if (newProperties != null && oldProperties != null) {
- List<String> newProps = newProperties.stream().map(PropertyDataDefinition::getName).collect(Collectors.toList());
- List<String> oldProps = oldProperties.stream().map(PropertyDataDefinition::getName).collect(Collectors.toList());
- if (!newProps.containsAll(oldProps)) {
- StringJoiner joiner = new StringJoiner(",", "[", "]");
- newProps.forEach(joiner::add);
- log.debug("Properties {} in data type {} are missing, but they already defined in the existing data type", joiner.toString(),
- dataTypeName);
- return true;
- }
- }
- return false;
- }
-
- private boolean validateChangeInCaseOfEmptyProperties(List<PropertyDefinition> newProperties, List<PropertyDefinition> oldProperties,
- String dataTypeName) {
- if (newProperties != null) {
- if (newProperties.isEmpty()) {
- newProperties = null;
- }
- }
- if (oldProperties != null) {
- if (oldProperties.isEmpty()) {
- oldProperties = null;
- }
- }
- if ((newProperties == null && oldProperties == null) || (newProperties != null && oldProperties != null)) {
- return true;
- }
- return false;
- }
-
private boolean isDerivedFromNameChanged(String dataTypeName, String newDerivedFromName, String oldDerivedFromName) {
if (newDerivedFromName != null) {
boolean isEqual = newDerivedFromName.equals(oldDerivedFromName);
return null;
}
}
+
}