aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvasraz <vasyl.razinkov@est.tech>2023-02-09 17:57:56 +0000
committerVasyl Razinkov <vasyl.razinkov@est.tech>2023-02-10 09:45:37 +0000
commitf7dee08d8e56fc023aeb6f12aa2f688978545e01 (patch)
tree06e6c3a764def525bab0f32514fa397ed23db6e5
parent9c057c26f14de77dff432403941322edaca7ea4e (diff)
Add support for delete property from non-normative data type
Signed-off-by: Vasyl Razinkov <vasyl.razinkov@est.tech> Change-Id: I668b1e7f7d00e97b7827d759766e105fdd53ed53 Issue-ID: SDC-4378
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/servlets/DataTypeServlet.java42
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadServlet.java23
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DataTypeOperation.java34
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ModelOperation.java75
-rw-r--r--catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ModelOperationTest.java2
-rw-r--r--catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.html9
-rw-r--r--catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.ts26
-rw-r--r--catalog-ui/src/app/ng2/services/data-type.service.ts33
-rw-r--r--common-app-api/src/main/java/org/openecomp/sdc/common/api/Constants.java10
9 files changed, 183 insertions, 71 deletions
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/DataTypeServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/DataTypeServlet.java
index 05c1fb7ad3..3a62600433 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/DataTypeServlet.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/DataTypeServlet.java
@@ -35,6 +35,7 @@ import java.util.List;
import java.util.Optional;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
@@ -63,7 +64,6 @@ import org.openecomp.sdc.common.api.Constants;
import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
import org.openecomp.sdc.common.log.wrappers.Logger;
import org.springframework.stereotype.Controller;
-import org.apache.commons.lang3.StringUtils;
@Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
@Path("/v1/catalog/data-types")
@@ -162,10 +162,10 @@ public class DataTypeServlet extends BeGenericServlet {
String.format("Property model is not the same as the data type model. Must be '%s'", model));
}
if (StringUtils.isEmpty(dataType.getModel())) {
- dataType.setModel("SDC AID");
+ dataType.setModel(Constants.DEFAULT_MODEL_NAME);
}
final PropertyDefinitionDto property = dataTypeOperation.createProperty(id, propertyDefinitionDto);
- dataTypeOperation.addPropertyToAdditionalTypeDataType(dataType, property);
+ dataTypeOperation.updatePropertyInAdditionalTypeDataType(dataType, property, true);
dataTypeBusinessLogic.updateApplicationDataTypeCache(id);
return Response.status(Status.CREATED).entity(property).build();
}
@@ -204,7 +204,7 @@ public class DataTypeServlet extends BeGenericServlet {
dataType.setModel(Constants.DEFAULT_MODEL_NAME);
}
final PropertyDefinitionDto property = dataTypeOperation.updateProperty(id, propertyDefinitionDto);
- dataTypeOperation.addPropertyToAdditionalTypeDataType(dataType, property);
+ dataTypeOperation.updatePropertyInAdditionalTypeDataType(dataType, property, true);
dataTypeBusinessLogic.updateApplicationDataTypeCache(id);
return Response.status(Status.CREATED).entity(property).build();
}
@@ -224,4 +224,38 @@ public class DataTypeServlet extends BeGenericServlet {
return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK),
gson.toJson(dataTypeOperation.getAllDataTypeModels(dataTypeName)));
}
+
+ @DELETE
+ @Path("{dataTypeId}/{propertyId}")
+ public Response deleteProperty(@Parameter(in = ParameterIn.PATH, required = true, description = "The data type id")
+ @PathParam("dataTypeId") final String dataTypeId,
+ @Parameter(in = ParameterIn.PATH, required = true, description = "The property id to delete")
+ @PathParam("propertyId") final String propertyId) {
+ final Optional<DataTypeDataDefinition> dataTypeOptional = dataTypeOperation.getDataTypeByUid(dataTypeId);
+ dataTypeOptional.orElseThrow(() -> {
+ throw new OperationException(ActionStatus.DATA_TYPE_NOT_FOUND, String.format("Failed to find data type '%s'", dataTypeId));
+ });
+ final DataTypeDataDefinition dataTypeDataDefinition = dataTypeOptional.get();
+ if (StringUtils.isEmpty(dataTypeDataDefinition.getModel())) {
+ dataTypeDataDefinition.setModel(Constants.DEFAULT_MODEL_NAME);
+ }
+ final PropertyDefinitionDto propertyDefinitionDto;
+ try {
+ propertyDefinitionDto = dataTypeOperation.deleteProperty(dataTypeDataDefinition, propertyId);
+ dataTypeOperation.updatePropertyInAdditionalTypeDataType(dataTypeDataDefinition, propertyDefinitionDto, false);
+ } catch (OperationException e) {
+ final PropertyDefinitionDto dto = new PropertyDefinitionDto();
+ dto.setName(extractNameFromPropertyId(propertyId));
+ dataTypeOperation.updatePropertyInAdditionalTypeDataType(dataTypeDataDefinition, dto, false);
+ throw e;
+ } finally {
+ dataTypeBusinessLogic.updateApplicationDataTypeCache(dataTypeId);
+ }
+ return Response.status(Status.OK).entity(propertyDefinitionDto).build();
+ }
+
+ private String extractNameFromPropertyId(final String propertyId) {
+ final String[] split = propertyId.split("\\.");
+ return split[split.length - 1];
+ }
}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadServlet.java
index 8974704199..f7ea9bb407 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadServlet.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadServlet.java
@@ -137,7 +137,7 @@ public class TypesUploadServlet extends AbstractValidationsServlet {
@PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
public Response uploadCapabilityType(@Parameter(description = "FileInputStream") @FormDataParam("capabilityTypeZip") File file,
@Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator,
- @Parameter(description = "model") @FormDataParam("model") String modelName,
+ @Parameter(description = "model name") @FormDataParam("model") String modelName,
@Parameter(description = "includeToModelImport") @FormDataParam("includeToModelImport") boolean includeToModelDefaultImports) {
ConsumerFourParam<Wrapper<Response>, String, String, Boolean> createElementsMethod = (responseWrapper, ymlPayload, model, includeToModelImport) ->
createElementsType(responseWrapper, () -> capabilityTypeImportManager.createCapabilityTypes(ymlPayload, modelName,
@@ -157,10 +157,10 @@ public class TypesUploadServlet extends AbstractValidationsServlet {
@PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
public Response uploadRelationshipType(@Parameter(description = "FileInputStream") @FormDataParam("relationshipTypeZip") File file,
@Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator,
- @Parameter(description = "model") @FormDataParam("model") String modelName,
+ @Parameter(description = "model name") @FormDataParam("model") String modelName,
@Parameter(description = "includeToModelImport") @FormDataParam("includeToModelImport") boolean includeToModelDefaultImports) {
- return uploadElementTypeServletLogic(
- this::createRelationshipTypes, file, request, creator, NodeTypeEnum.RelationshipType.getName(), modelName, includeToModelDefaultImports);
+ return uploadElementTypeServletLogic(this::createRelationshipTypes, file, request, creator, NodeTypeEnum.RelationshipType.getName(),
+ modelName, includeToModelDefaultImports);
}
@POST
@@ -174,7 +174,7 @@ public class TypesUploadServlet extends AbstractValidationsServlet {
@PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
public Response uploadInterfaceLifecycleType(@Parameter(description = "FileInputStream") @FormDataParam("interfaceLifecycleTypeZip") File file,
@Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator,
- @Parameter(description = "model") @FormDataParam("model") String modelName,
+ @Parameter(description = "model name") @FormDataParam("model") String modelName,
@Parameter(description = "includeToModelImport") @FormDataParam("includeToModelImport") boolean includeToModelDefaultImports) {
ConsumerTwoParam<Wrapper<Response>, String> createElementsMethod = (responseWrapper, ymlPayload) ->
createElementsType(responseWrapper, () -> interfaceLifecycleTypeImportManager.createLifecycleTypes(ymlPayload, modelName,
@@ -230,7 +230,7 @@ public class TypesUploadServlet extends AbstractValidationsServlet {
@PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
public Response uploadDataTypes(@Parameter(description = "FileInputStream") @FormDataParam("dataTypesZip") File file,
@Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator,
- @Parameter(description = "model") @FormDataParam("model") String modelName,
+ @Parameter(description = "model name") @FormDataParam("model") String modelName,
@Parameter(description = "includeToModelImport") @FormDataParam("includeToModelImport") boolean includeToModelDefaultImports) {
return uploadElementTypeServletLogic(this::createDataTypes, file, request, creator, NodeTypeEnum.DataType.getName(), modelName,
includeToModelDefaultImports);
@@ -247,7 +247,7 @@ public class TypesUploadServlet extends AbstractValidationsServlet {
@PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
public Response uploadDataTypesYaml(@Parameter(description = "FileInputStream") @FormDataParam("dataTypesYaml") File file,
@Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator,
- @Parameter(description = "model") @FormDataParam("model") String modelName,
+ @Parameter(description = "model name") @FormDataParam("model") String modelName,
@Parameter(description = "includeToModelImport") @FormDataParam("includeToModelImport") boolean includeToModelDefaultImports) {
return uploadElementTypeServletLogicYaml(this::createDataTypes, file, request, creator, NodeTypeEnum.DataType.getName(), modelName,
includeToModelDefaultImports);
@@ -263,7 +263,7 @@ public class TypesUploadServlet extends AbstractValidationsServlet {
@ApiResponse(responseCode = "409", description = "group types already exist")})
@PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
public Response uploadGroupTypes(@Parameter(description = "toscaTypeMetadata") @FormDataParam("toscaTypeMetadata") String toscaTypesMetaData,
- @Parameter(description = "model") @FormDataParam("model") String modelName,
+ @Parameter(description = "model name") @FormDataParam("model") String modelName,
@Parameter(description = "FileInputStream") @FormDataParam("groupTypesZip") File file,
@Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator,
@Parameter(description = "includeToModelImport") @FormDataParam("includeToModelImport") boolean includeToModelDefaultImports) {
@@ -282,7 +282,7 @@ public class TypesUploadServlet extends AbstractValidationsServlet {
@ApiResponse(responseCode = "409", description = "policy types already exist")})
@PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
public Response uploadPolicyTypes(@Parameter(description = "toscaTypeMetadata") @FormDataParam("toscaTypeMetadata") String toscaTypesMetaData,
- @Parameter(description = "model") @FormDataParam("model") String modelName,
+ @Parameter(description = "model name") @FormDataParam("model") String modelName,
@Parameter(description = "FileInputStream") @FormDataParam("policyTypesZip") File file,
@Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator,
@Parameter(description = "includeToModelImport") @FormDataParam("includeToModelImport") boolean includeToModelDefaultImports) {
@@ -331,8 +331,6 @@ public class TypesUploadServlet extends AbstractValidationsServlet {
final Wrapper<Response> responseWrapper = doUploadTypeValidations(request, userId, file);
if (responseWrapper.isEmpty()) {
fillZipContents(yamlStringWrapper, file);
- }
- if (responseWrapper.isEmpty()) {
createElementsMethod.accept(responseWrapper, yamlStringWrapper.getInnerElement(), modelName, includeToModelDefaultImports);
}
return responseWrapper.getInnerElement();
@@ -353,11 +351,12 @@ public class TypesUploadServlet extends AbstractValidationsServlet {
final String url = request.getMethod() + " " + request.getRequestURI();
log.debug(START_HANDLE_REQUEST_OF, url);
final Wrapper<Response> responseWrapper = doUploadTypeValidations(request, userId, file);
+ final String yamlAsString = getFileAsString(file);
if (responseWrapper.isEmpty()) {
- final String yamlAsString = getFileAsString(file);
log.debug("received yaml: {}", yamlAsString);
createElementsMethod.accept(responseWrapper, yamlAsString, modelName, includeToModelDefaultImports);
}
+
return responseWrapper.getInnerElement();
} catch (final Exception e) {
log.debug(CREATE_FAILED_WITH_EXCEPTION, elementTypeName, e);
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DataTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DataTypeOperation.java
index 391add9a94..f79f1501e7 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DataTypeOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DataTypeOperation.java
@@ -303,8 +303,38 @@ public class DataTypeOperation extends AbstractOperation {
return PropertyDefinitionDtoMapper.mapFrom(propertyData);
}
- public void addPropertyToAdditionalTypeDataType(DataTypeDataDefinition dataTypeDataDefinition, PropertyDefinitionDto property) {
- modelOperation.addPropertyToAdditionalType(ElementTypeEnum.DATA_TYPE, property, dataTypeDataDefinition.getModel(), dataTypeDataDefinition.getName());
+ public void updatePropertyInAdditionalTypeDataType(final DataTypeDataDefinition dataTypeDataDefinition,
+ final PropertyDefinitionDto property,
+ final boolean isAdd) {
+ modelOperation.updatePropertyInAdditionalType(ElementTypeEnum.DATA_TYPE, property, dataTypeDataDefinition.getModel(),
+ dataTypeDataDefinition.getName(), isAdd);
+ }
+
+ public PropertyDefinitionDto deleteProperty(final DataTypeDataDefinition dataTypeDataDefinition, final String propertyId) {
+ final List<PropertyDefinition> propertiesData = findAllProperties(dataTypeDataDefinition.getUniqueId());
+ final String dataTypeDataDefinitionName = dataTypeDataDefinition.getName();
+ if (CollectionUtils.isEmpty(propertiesData)) {
+ throw new OperationException(ActionStatus.PROPERTY_NOT_FOUND,
+ String.format("Failed to find property '%s' for data type '%s'", propertyId, dataTypeDataDefinitionName));
+ }
+ Optional<PropertyDefinition> optionalPropertyDefinition = propertiesData.stream()
+ .filter(propertyDataDefinition -> propertyDataDefinition.getUniqueId().equals(propertyId)).findAny();
+ optionalPropertyDefinition.orElseThrow(() -> {
+ throw new OperationException(ActionStatus.PROPERTY_NOT_FOUND,
+ String.format("Failed to find property '%s' for data type '%s'", propertyId, dataTypeDataDefinitionName));
+ });
+ final Either<PropertyData, JanusGraphOperationStatus> statusEither = propertyOperation.deletePropertyFromGraph(propertyId);
+ if (statusEither.isRight()) {
+ throw new OperationException(ActionStatus.PROPERTY_NOT_FOUND,
+ String.format("Failed to delete property '%s' from data type '%s'", propertyId, dataTypeDataDefinitionName));
+ }
+ final PropertyDefinition propertyDefinition = optionalPropertyDefinition.get();
+ final PropertyData propertyData = statusEither.left().value();
+ final PropertyDataDefinition propertyDataDefinition = propertyData.getPropertyDataDefinition();
+ propertyDataDefinition.setName(propertyDefinition.getName());
+ propertyDataDefinition.setPropertyConstraints(propertyData.getConstraints());
+ propertiesData.remove(propertyDefinition);
+ return PropertyDefinitionDtoMapper.mapFrom(propertyDataDefinition);
}
}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ModelOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ModelOperation.java
index 311b4719bd..19289411c3 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ModelOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ModelOperation.java
@@ -18,6 +18,8 @@
*/
package org.openecomp.sdc.be.model.operations.impl;
+import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.DATA_TYPES;
+import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.PROPERTIES;
import static org.openecomp.sdc.common.api.Constants.ADDITIONAL_TYPE_DEFINITIONS;
import fj.data.Either;
@@ -220,11 +222,11 @@ public class ModelOperation {
public List<Model> findAllModels() {
return findModelsByCriteria(Collections.emptyMap());
}
-
+
public List<Model> findModels(final ModelTypeEnum modelType) {
final Map<GraphPropertyEnum, Object> propertyCriteria = new EnumMap<>(GraphPropertyEnum.class);
propertyCriteria.put(GraphPropertyEnum.MODEL_TYPE, modelType.getValue());
-
+
return findModelsByCriteria(propertyCriteria);
}
@@ -259,7 +261,7 @@ public class ModelOperation {
if (optionalModelTypeEnum.isPresent()) {
modelType = optionalModelTypeEnum.get();
}
-
+
final Either<ImmutablePair<ModelData, GraphEdge>, JanusGraphOperationStatus> parentNode =
janusGraphGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Model), UniqueIdBuilder.buildModelUid(modelName),
GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Model, ModelData.class);
@@ -298,8 +300,8 @@ public class ModelOperation {
}
Map<String, Object> typesYamlMap = new Yaml().loadAs(typesYaml, Map.class);
- if (typesYamlMap.containsKey("data_types")){
- typesYamlMap = (Map<String, Object>) typesYamlMap.get("data_types");
+ if (typesYamlMap.containsKey(DATA_TYPES.getElementName())) {
+ typesYamlMap = (Map<String, Object>) typesYamlMap.get(DATA_TYPES.getElementName());
}
removeExistingTypesFromDefaultImports(elementTypeEnum, typesYamlMap, rebuiltModelImportList);
@@ -378,7 +380,7 @@ public class ModelOperation {
if (deleteParentNodeByModel.isRight()) {
final var janusGraphOperationStatus = deleteParentNodeByModel.right().value();
log.error(EcompLoggerErrorCode.DATA_ERROR, ModelOperation.class.getName(),
- "Failed to delete model {} on JanusGraph with status {}", new Object[] {model.getName(), janusGraphOperationStatus});
+ "Failed to delete model {} on JanusGraph with status {}", model.getName(), janusGraphOperationStatus);
throw new OperationException(ActionStatus.COULD_NOT_DELETE_MODEL, model.getName());
}
}
@@ -397,28 +399,28 @@ public class ModelOperation {
final Map<String, Object> existingTypeContent = getExistingTypes(elementTypeEnum, additionalTypeDefinitionsImportOptional.get());
final Set<String> existingTypeNames = existingTypeContent.keySet();
- final Map<String, Object> typesToUpate = new HashMap<>();
-
Map<String, Object> newTypesYaml = new Yaml().load(typesYaml);
- if (newTypesYaml.containsKey("data_types")){
- newTypesYaml = (Map<String, Object>) newTypesYaml.get("data_types");
+ if (newTypesYaml.containsKey(DATA_TYPES.getElementName())) {
+ newTypesYaml = (Map<String, Object>) newTypesYaml.get(DATA_TYPES.getElementName());
}
+ final Map<String, Object> typesToUpate = new HashMap<>();
newTypesYaml.entrySet().stream().filter(entry -> existingTypeNames.contains(entry.getKey())).forEach(newTypeToUpdate -> {
- final Map<String, Object> propertiesInNewDef = (Map<String, Object>) ((Map<String, Object>) newTypeToUpdate.getValue()).get("properties");
+ final Map<String, Object> propertiesInNewDef =
+ (Map<String, Object>) ((Map<String, Object>) newTypeToUpdate.getValue()).get(PROPERTIES.getElementName());
final Map<String, Object> existingProperties =
- (Map<String, Object>) ((Map<String, Object>) existingTypeContent.get(newTypeToUpdate.getKey())).get("properties");
+ (Map<String, Object>) ((Map<String, Object>) existingTypeContent.get(newTypeToUpdate.getKey())).get(PROPERTIES.getElementName());
final List<Entry<String, Object>> propertiesMissingFromNewDef = MapUtils.isEmpty(existingProperties) ? Collections.emptyList()
- : existingProperties.entrySet().stream()
- .filter(existingPropEntry -> !propertiesInNewDef.keySet().contains(existingPropEntry.getKey()))
- .collect(Collectors.toList());
+ : existingProperties.entrySet().stream()
+ .filter(existingPropEntry -> !propertiesInNewDef.keySet().contains(existingPropEntry.getKey()))
+ .collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(propertiesMissingFromNewDef)) {
typesToUpate.put(newTypeToUpdate.getKey(), newTypeToUpdate.getValue());
propertiesMissingFromNewDef
- .forEach(existingPropToAdd -> propertiesInNewDef.put(existingPropToAdd.getKey(), existingPropToAdd.getValue()));
+ .forEach(existingPropToAdd -> propertiesInNewDef.put(existingPropToAdd.getKey(), existingPropToAdd.getValue()));
}
});
if (MapUtils.isNotEmpty(typesToUpate)) {
@@ -426,48 +428,51 @@ public class ModelOperation {
}
}
}
-
- private Optional<ToscaImportByModel> getAdditionalTypes(final String modelName) {
+
+ private Optional<ToscaImportByModel> getAdditionalTypes(final String modelName) {
final List<ToscaImportByModel> modelImportList = toscaModelImportCassandraDao.findAllByModel(modelName);
return modelImportList.stream().filter(t -> ADDITIONAL_TYPE_DEFINITIONS_PATH.equals(Path.of(t.getFullPath()))).findAny();
}
private Map<String, Object> getExistingTypes(final ElementTypeEnum elementTypeEnum, final ToscaImportByModel additionalTypeDefinitionsImport) {
final Map<String, Object> existingContent = new Yaml().load(additionalTypeDefinitionsImport.getContent());
- return (Map<String, Object>) existingContent.get(elementTypeEnum.getToscaEntryName());
+ return (Map<String, Object>) existingContent.get(elementTypeEnum.getToscaEntryName());
}
- public void addPropertyToAdditionalType(final ElementTypeEnum elementTypeEnum, final PropertyDefinitionDto property,
- final String modelName, final String name) {
+ public void updatePropertyInAdditionalType(final ElementTypeEnum elementTypeEnum, final PropertyDefinitionDto property,
+ final String modelName, final String name, boolean isAdd) {
final List<ToscaImportByModel> modelImportList = toscaModelImportCassandraDao.findAllByModel(modelName);
final Optional<ToscaImportByModel> additionalTypeDefinitionsImportOptional = modelImportList.stream()
- .filter(t -> ADDITIONAL_TYPE_DEFINITIONS_PATH.equals(Path.of(t.getFullPath()))).findAny();
- final ToscaImportByModel additionalTypeDefinitionsImport;
- final List<ToscaImportByModel> rebuiltModelImportList;
+ .filter(t -> ADDITIONAL_TYPE_DEFINITIONS_PATH.equals(Path.of(t.getFullPath()))).findAny();
if (additionalTypeDefinitionsImportOptional.isEmpty()) {
return;
}
- additionalTypeDefinitionsImport = additionalTypeDefinitionsImportOptional.get();
- rebuiltModelImportList = modelImportList.stream()
- .filter(toscaImportByModel -> !ADDITIONAL_TYPE_DEFINITIONS_PATH.equals(Path.of(toscaImportByModel.getFullPath())))
- .collect(Collectors.toList());
+ final ToscaImportByModel additionalTypeDefinitionsImport = additionalTypeDefinitionsImportOptional.get();
+ final List<ToscaImportByModel> rebuiltModelImportList = modelImportList.stream()
+ .filter(toscaImportByModel -> !ADDITIONAL_TYPE_DEFINITIONS_PATH.equals(Path.of(toscaImportByModel.getFullPath())))
+ .collect(Collectors.toList());
final Map<String, Object> originalContent = new Yaml().load(additionalTypeDefinitionsImport.getContent());
- additionalTypeDefinitionsImport.setContent(buildPropertyAdditionalTypeDefinitionContent(elementTypeEnum, name, property, originalContent));
+ additionalTypeDefinitionsImport.setContent(
+ buildPropertyAdditionalTypeDefinitionContent(elementTypeEnum, name, property, originalContent, isAdd));
rebuiltModelImportList.add(additionalTypeDefinitionsImport);
toscaModelImportCassandraDao.saveAll(modelName, rebuiltModelImportList);
}
private String buildPropertyAdditionalTypeDefinitionContent(final ElementTypeEnum elementTypeEnum, final String name,
- final PropertyDefinitionDto property, final Map<String, Object> originalContent) {
+ final PropertyDefinitionDto property, final Map<String, Object> originalContent,
+ boolean isAdd) {
final Map<String, Object> originalTypeContent = (Map<String, Object>) originalContent.get(elementTypeEnum.getToscaEntryName());
Map<String, Object> typeContent = (Map<String, Object>) originalTypeContent.get(name);
- Map<String, Object> typeProperties = (Map<String, Object>) typeContent.get("properties");
- if (typeProperties == null) {
+ Map<String, Object> typeProperties = (Map<String, Object>) typeContent.get(PROPERTIES.getElementName());
+ if (MapUtils.isEmpty(typeProperties)) {
typeProperties = new HashMap<>();
}
- Map<String, Object> typeProp = constructProperty(property);
- typeProperties.put(property.getName(), typeProp);
- typeContent.put("properties", typeProperties);
+ if (isAdd) {
+ typeProperties.put(property.getName(), constructProperty(property));
+ } else {
+ typeProperties.remove(property.getName());
+ }
+ typeContent.put(PROPERTIES.getElementName(), typeProperties);
return new YamlUtil().objectToYaml(originalContent);
}
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ModelOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ModelOperationTest.java
index 8fe89216fa..1bd4d9dbac 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ModelOperationTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ModelOperationTest.java
@@ -613,7 +613,7 @@ class ModelOperationTest extends ModelTestBase {
property.setRequired(true);
String dataTypeName = "tosca.datatypes.nfv.PreviouslyExistingType1";
- modelOperation.addPropertyToAdditionalType(ElementTypeEnum.DATA_TYPE, property, modelName, dataTypeName);
+ modelOperation.updatePropertyInAdditionalType(ElementTypeEnum.DATA_TYPE, property, modelName, dataTypeName, true);
ArgumentCaptor<List<ToscaImportByModel>> importListArgumentCaptor = ArgumentCaptor.forClass(List.class);
verify(toscaModelImportCassandraDao).saveAll(eq(modelName), importListArgumentCaptor.capture());
diff --git a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.html b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.html
index e657520ee4..12b2d992a8 100644
--- a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.html
+++ b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.html
@@ -32,14 +32,15 @@
<div class="table-header head-row hand flex-item" *ngFor="let header of tableHeadersList" (click)="onUpdateSort(header.property)">{{header.title}}
<span *ngIf="tableSortBy === header.property" class="table-header-sort-arrow" [ngClass]="{'down': tableColumnReverse, 'up': !tableColumnReverse}"></span>
</div>
+ <div class="table-no-text-header head-row flex-item" *ngIf="!isViewOnly"><span class="delete-col-header"></span></div>
</div>
<div class="body">
<div *ngIf="filteredProperties.length === 0" class="no-row-text">
{{'PROPERTY_LIST_EMPTY_MESSAGE' | translate}}
</div>
- <div *ngFor="let property of filteredProperties" [attr.data-tests-id]="'property-row-' + property.name" class="flex-container data-row" (click)="onNameClick(property)">
- <div class="table-col-general flex-item text" [title]="property.name">
+ <div *ngFor="let property of filteredProperties" [attr.data-tests-id]="'property-row-' + property.name" class="flex-container data-row">
+ <div class="table-col-general flex-item text" [title]="property.name" (click)="onNameClick(property)">
<a [attr.data-tests-id]="'property-name-' + property.name" [ngClass]="{'disabled': false}">{{property.name}}</a>
</div>
<div class="table-col-general flex-item text" [title]="property.type">
@@ -54,6 +55,10 @@
<div class="table-col-general flex-item text" [title]="property.description || ''">
<span [attr.data-tests-id]="'property-description-' + property.name" [title]="property.description">{{property.description}}</span>
</div>
+ <div class="table-btn-col flex-item" *ngIf="!isViewOnly">
+ <button class="table-delete-btn" data-ng-if="!property.ownerId || property.ownerId==component.uniqueId"
+ (click)="delete(property); $event.stopPropagation();" data-ng-class="{'disabled': isViewOnly}"></button>
+ </div>
</div>
</div>
diff --git a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.ts b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.ts
index 60edd13c2d..f9eaa1332d 100644
--- a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.ts
+++ b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.ts
@@ -32,6 +32,8 @@ import {TranslateService} from "../../../shared/translator/translate.service";
import {AddPropertyComponent, PropertyValidationEvent} from "./add-property/add-property.component";
import {IWorkspaceViewModelScope} from "../../../../view-models/workspace/workspace-view-model";
import {SdcUiServices} from "onap-ui-angular/dist";
+import {PropertyModel} from "../../../../models/properties";
+import {SdcUiCommon, SdcUiComponents} from "onap-ui-angular";
import {ToscaTypeHelper} from "../../../../utils/tosca-type-helper";
@Component({
@@ -249,9 +251,31 @@ export class TypeWorkspacePropertiesComponent implements OnInit {
}
return null;
}
+
+ delete(property: PropertyModel) {
+ let onOk: Function = (): void => {
+ this.dataTypeService.deleteProperty(this.dataType.uniqueId, property.uniqueId).subscribe((response) => {
+ const props = this.properties;
+ props.splice(props.findIndex(p => p.uniqueId === response), 1);
+ this.filter();
+ }, (error) => {
+ console.error(error);
+ });
+ };
+ let title: string = this.translateService.translate("PROPERTY_VIEW_DELETE_MODAL_TITLE");
+ let message: string = this.translateService.translate("PROPERTY_VIEW_DELETE_MODAL_TEXT", {'name': property.name});
+ const okButton = {
+ testId: "OK",
+ text: "OK",
+ type: SdcUiCommon.ButtonType.info,
+ callback: onOk,
+ closeModal: true
+ } as SdcUiComponents.ModalButtonComponent;
+ this.modalServiceSdcUI.openInfoModal(title, message, 'delete-modal', [okButton]);
+ };
}
interface TableHeader {
title: string;
property: string;
-} \ No newline at end of file
+}
diff --git a/catalog-ui/src/app/ng2/services/data-type.service.ts b/catalog-ui/src/app/ng2/services/data-type.service.ts
index 38714c96da..636217fb68 100644
--- a/catalog-ui/src/app/ng2/services/data-type.service.ts
+++ b/catalog-ui/src/app/ng2/services/data-type.service.ts
@@ -20,9 +20,15 @@
import * as _ from "lodash";
import {Inject, Injectable} from '@angular/core';
-import {DataTypeModel, DataTypesMap, PropertyFEModel, DerivedFEProperty, PropertyBEModel} from "app/models";
-import { DataTypesService } from "app/services/data-types-service";
-import { PROPERTY_DATA } from "app/utils";
+import {
+ DataTypeModel,
+ DataTypesMap,
+ DerivedFEProperty,
+ PropertyBEModel,
+ PropertyFEModel
+} from "app/models";
+import {DataTypesService} from "app/services/data-types-service";
+import {PROPERTY_DATA} from "app/utils";
import {DerivedFEAttribute} from "../../models/attributes-outputs/derived-fe-attribute";
import {ISdcConfig} from "../config/sdc-config.config.factory";
import {SdcConfigToken} from "../config/sdc-config.config";
@@ -62,7 +68,7 @@ export class DataTypeService {
}
public getDataTypeByTypeName(typeName: string): DataTypeModel {
- if(!this.dataTypes){
+ if (!this.dataTypes) {
this.dataTypes = this.dataTypeService.getAllDataTypes();
}
if (!this.dataTypes[typeName]) console.log("MISSING Datatype: " + typeName);
@@ -97,6 +103,15 @@ export class DataTypeService {
return this.httpClient.put<PropertyBEModel>(url, property);
}
+ public deleteProperty(dataTypeId: string, propertyId: string): Observable<Object> {
+ const url = `${this.dataTypeUrl}/${dataTypeId}/${propertyId}`;
+ let headers = new HttpHeaders({'USER_ID': this.authService.getLoggedinUser().userId});
+ let options = {headers: headers};
+ return this.httpClient.delete(url, options).map((res: Response) => {
+ return propertyId;
+ });
+ }
+
public createImportedType(model: string, importingFile: File): Observable<any> {
const url = `${this.dataTypeUploadUrl}/datatypesyaml`;
const formData = new FormData();
@@ -109,7 +124,7 @@ export class DataTypeService {
return this.httpClient.post<any>(url, formData, options);
}
- public getConstraintsByParentTypeAndUniqueID(rootPropertyType, propertyName){
+ public getConstraintsByParentTypeAndUniqueID(rootPropertyType, propertyName) {
// const property = this.dataTypes[rootPropertyType].properties.filter(property =>
// property.name == propertyName);
// return property[0] && property[0].constraints ? property[0].constraints[0].validValues : null;
@@ -121,7 +136,7 @@ export class DataTypeService {
if (!dataTypeObj) return;
if (dataTypeObj.properties) {
dataTypeObj.properties.forEach((derivedProperty) => {
- if(dataTypeObj.name !== PROPERTY_DATA.OPENECOMP_ROOT || derivedProperty.name !== PROPERTY_DATA.SUPPLEMENTAL_DATA){//The requirement is to not display the property supplemental_data
+ if (dataTypeObj.name !== PROPERTY_DATA.OPENECOMP_ROOT || derivedProperty.name !== PROPERTY_DATA.SUPPLEMENTAL_DATA) {//The requirement is to not display the property supplemental_data
propertiesArray.push(new DerivedFEProperty(derivedProperty, parentName));
}
let derivedDataTypeObj: DataTypeModel = this.getDataTypeByTypeName(derivedProperty.type);
@@ -139,7 +154,7 @@ export class DataTypeService {
if (!dataTypeObj) return;
if (dataTypeObj.attributes) {
dataTypeObj.attributes.forEach((derivedAttribute) => {
- if(dataTypeObj.name !== PROPERTY_DATA.OPENECOMP_ROOT || derivedAttribute.name !== PROPERTY_DATA.SUPPLEMENTAL_DATA){//The requirement is to not display the property supplemental_data
+ if (dataTypeObj.name !== PROPERTY_DATA.OPENECOMP_ROOT || derivedAttribute.name !== PROPERTY_DATA.SUPPLEMENTAL_DATA) {//The requirement is to not display the property supplemental_data
attributesArray.push(new DerivedFEAttribute(derivedAttribute, parentName));
}
let derivedDataTypeObj: DataTypeModel = this.getDataTypeByTypeName(derivedAttribute.type);
@@ -156,8 +171,8 @@ export class DataTypeService {
* Checks for custom behavior for a given data type by checking if a function exists within data-type.service with that name
* Additional custom behavior can be added by adding a function with the given dataType name
*/
- public checkForCustomBehavior = (property:PropertyFEModel) => {
- let shortTypeName:string = property.type.split('.').pop();
+ public checkForCustomBehavior = (property: PropertyFEModel) => {
+ let shortTypeName: string = property.type.split('.').pop();
if (this[shortTypeName]) {
this[shortTypeName](property); //execute function for given type, pass property as param
}
diff --git a/common-app-api/src/main/java/org/openecomp/sdc/common/api/Constants.java b/common-app-api/src/main/java/org/openecomp/sdc/common/api/Constants.java
index 7a0feb9361..039fc8ed8a 100644
--- a/common-app-api/src/main/java/org/openecomp/sdc/common/api/Constants.java
+++ b/common-app-api/src/main/java/org/openecomp/sdc/common/api/Constants.java
@@ -19,6 +19,10 @@
*/
package org.openecomp.sdc.common.api;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class Constants {
public static final String APPLICATION_NAME = "application-name";
@@ -62,8 +66,6 @@ public final class Constants {
public static final String RESOURCE_SUPPORTED_VERSION = "0.0.1";
public static final String ARTIFACT_ID_FORMAT = "%s:%s:%s"; // resourceName:resourceVersion:artifactName
public static final String ADDITIONAL_TYPE_DEFINITIONS = "additional_type_definitions.yaml";
-
-
public static final String SERVICE_ARTIFACT_ID_FORMAT = "%s:%s:%s:%s"; // serviceName:serviceVersion:nodeTemplateName:artifactName
public static final String CONTENT_DISPOSITION = "content-disposition";
public static final String DOWNLOAD_ARTIFACT_LOGIC_ATTR = "downloadArtifactLogic";
@@ -156,8 +158,6 @@ public final class Constants {
public static final String INITIAL_COUNT = "initial_count";
public static final String VF_MODULE_TYPE = "vf_module_type";
public static final String VOLUME_GROUP = "volume_group";
- public static final String ASD_DEPLOYMENT_ITEM= "tosca.artifacts.asd.deploymentItem";
+ public static final String ASD_DEPLOYMENT_ITEM = "tosca.artifacts.asd.deploymentItem";
- private Constants() {
- }
}