diff options
14 files changed, 446 insertions, 142 deletions
diff --git a/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml b/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml index 7b3ade82c7..47e2851b8e 100644 --- a/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml +++ b/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml @@ -2820,4 +2820,10 @@ errors: CAPABILITY_NOT_FOUND_IN_COMPONENT: code: 400 message: "Capability '%1' not found in '%2' '%3'." - messageId: "SVC4186"
\ No newline at end of file + messageId: "SVC4186" + + # %1 - The data type Uid + DATA_TYPE_NOT_FOUND: + code: 404 + message: "Data type '%1' was not found." + messageId: "SVC4011" diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/DataTypeBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/DataTypeBusinessLogic.java index 892536ffa7..687004a017 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/DataTypeBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/DataTypeBusinessLogic.java @@ -91,10 +91,8 @@ public class DataTypeBusinessLogic extends BaseBusinessLogic { } List<DataTypeDefinition> dataTypes = dataTypesResult.left().value(); Optional<DataTypeDefinition> findResult = dataTypes.stream().filter(e -> e.getName().equals(dataTypeName)).findAny(); - if (!findResult.isPresent()) { - return Either.right(StorageOperationStatus.NOT_FOUND); - } - return Either.left(findResult.get()); + return findResult.<Either<DataTypeDefinition, StorageOperationStatus>>map(Either::left) + .orElseGet(() -> Either.right(StorageOperationStatus.NOT_FOUND)); } /** diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java index 313a303b61..dec13a94c8 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java @@ -774,7 +774,6 @@ public class ComponentsUtils { responseEnum = ActionStatus.INVALID_CONTENT; break; default: - responseEnum = ActionStatus.GENERAL_ERROR; break; } return responseEnum; @@ -1193,7 +1192,7 @@ public class ComponentsUtils { responseEnum = ActionStatus.OK; break; case ELEMENT_NOT_FOUND: - if (elementType != null && elementType == JsonPresentationFields.PROPERTY) { + if (elementType == JsonPresentationFields.PROPERTY) { responseEnum = ActionStatus.PROPERTY_NOT_FOUND; } break; @@ -1208,7 +1207,6 @@ public class ComponentsUtils { responseEnum = ActionStatus.INVALID_ATTRIBUTE; break; default: - responseEnum = ActionStatus.GENERAL_ERROR; break; } return responseEnum; diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AbstractValidationsServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AbstractValidationsServlet.java index 1eff7ab5ac..58d1b23bd6 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AbstractValidationsServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AbstractValidationsServlet.java @@ -27,7 +27,6 @@ import com.google.gson.JsonSyntaxException; import fj.data.Either; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Type; @@ -96,13 +95,17 @@ public abstract class AbstractValidationsServlet extends BeGenericServlet { .asList(TOSCA_SIMPLE_YAML_PREFIX + "1_0_0", TOSCA_SIMPLE_YAML_PREFIX + "1_1_0", "tosca_simple_profile_for_nfv_1_0_0", TOSCA_SIMPLE_YAML_PREFIX + "1_0", TOSCA_SIMPLE_YAML_PREFIX + "1_1", TOSCA_SIMPLE_YAML_PREFIX + "1_2", TOSCA_SIMPLE_YAML_PREFIX + "1_3"); private static final List<String> TOSCA_YML_CSAR_VALID_SUFFIX = Arrays.asList(".yml", ".yaml", ".csar", ".meta"); + private static final String INVALID_JSON_WAS_RECEIVED = "Invalid json was received."; + private static final String AUDIT_BEFORE_SENDING_RESPONSE = "audit before sending response"; + private static final String VALIDATE_USER_ROLE = "validate user role"; + private static final String USER_IS_NOT_IN_APPROPRIATE_ROLE_TO_PERFORM_ACTION = "user is not in appropriate role to perform action"; protected final ComponentInstanceBusinessLogic componentInstanceBusinessLogic; protected ServletUtils servletUtils; protected ResourceImportManager resourceImportManager; protected ServiceImportManager serviceImportManager; - public AbstractValidationsServlet(ComponentInstanceBusinessLogic componentInstanceBL, - ComponentsUtils componentsUtils, ServletUtils servletUtils, ResourceImportManager resourceImportManager) { + protected AbstractValidationsServlet(ComponentInstanceBusinessLogic componentInstanceBL, + ComponentsUtils componentsUtils, ServletUtils servletUtils, ResourceImportManager resourceImportManager) { super(componentsUtils); this.servletUtils = servletUtils; this.resourceImportManager = resourceImportManager; @@ -186,11 +189,11 @@ public abstract class AbstractValidationsServlet extends BeGenericServlet { } protected void validateUserRole(Wrapper<Response> errorResponseWrapper, User user) { - log.debug("validate user role"); + log.debug(VALIDATE_USER_ROLE); if (!user.getRole().equals(Role.ADMIN.name()) && !user.getRole().equals(Role.DESIGNER.name())) { - log.info("user is not in appropriate role to perform action"); + log.info(USER_IS_NOT_IN_APPROPRIATE_ROLE_TO_PERFORM_ACTION); ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION); - log.debug("audit before sending response"); + log.debug(AUDIT_BEFORE_SENDING_RESPONSE); getComponentsUtils().auditResource(responseFormat, user, "", AuditingActionEnum.IMPORT_RESOURCE); Response response = buildErrorResponse(responseFormat); errorResponseWrapper.setInnerElement(response); @@ -251,7 +254,7 @@ public abstract class AbstractValidationsServlet extends BeGenericServlet { try (InputStream fileInputStream = new FileInputStream(file)) { byte[] data = new byte[(int) file.length()]; if (fileInputStream.read(data) == -1) { - log.info("Invalid json was received."); + log.info(INVALID_JSON_WAS_RECEIVED); ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); Response errorResp = buildErrorResponse(responseFormat); responseWrapper.setInnerElement(errorResp); @@ -268,12 +271,12 @@ public abstract class AbstractValidationsServlet extends BeGenericServlet { } protected void validateUserRole(Wrapper<Response> errorResponseWrapper, User user, ResourceAuthorityTypeEnum resourceAuthority) { - log.debug("validate user role"); + log.debug(VALIDATE_USER_ROLE); if (resourceAuthority == ResourceAuthorityTypeEnum.NORMATIVE_TYPE_BE) { if (!user.getRole().equals(Role.ADMIN.name())) { - log.info("user is not in appropriate role to perform action"); + log.info(USER_IS_NOT_IN_APPROPRIATE_ROLE_TO_PERFORM_ACTION); ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION); - log.debug("audit before sending response"); + log.debug(AUDIT_BEFORE_SENDING_RESPONSE); getComponentsUtils().auditResource(responseFormat, user, "", AuditingActionEnum.IMPORT_RESOURCE); Response response = buildErrorResponse(responseFormat); errorResponseWrapper.setInnerElement(response); @@ -306,7 +309,7 @@ public abstract class AbstractValidationsServlet extends BeGenericServlet { isValid = false; } if (!isValid) { - log.info("Invalid json was received."); + log.info(INVALID_JSON_WAS_RECEIVED); ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); getComponentsUtils().auditResource(responseFormat, user, "", AuditingActionEnum.IMPORT_RESOURCE); Response errorResp = buildErrorResponse(responseFormat); @@ -332,6 +335,7 @@ public abstract class AbstractValidationsServlet extends BeGenericServlet { return getServletUtils().getGson(); } + @Override public ComponentsUtils getComponentsUtils() { return getServletUtils().getComponentsUtils(); } @@ -470,7 +474,7 @@ public abstract class AbstractValidationsServlet extends BeGenericServlet { private void validateToscaTemplatePayloadName(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user) { String toscaTemplatePayloadName = uploadResourceInfo.getPayloadName(); - boolean isValidSuffix = isToscaTemplatePayloadNameValid(responseWrapper, toscaTemplatePayloadName); + boolean isValidSuffix = isToscaTemplatePayloadNameValid(toscaTemplatePayloadName); if (!isValidSuffix) { ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_FILE_EXTENSION); Response errorResponse = buildErrorResponse(responseFormat); @@ -479,7 +483,7 @@ public abstract class AbstractValidationsServlet extends BeGenericServlet { } } - private boolean isToscaTemplatePayloadNameValid(Wrapper<Response> responseWrapper, String toscaTemplatePayloadName) { + private boolean isToscaTemplatePayloadNameValid(String toscaTemplatePayloadName) { boolean isValidSuffix = false; if (toscaTemplatePayloadName != null && !toscaTemplatePayloadName.isEmpty()) { for (String validSuffix : TOSCA_YML_CSAR_VALID_SUFFIX) { @@ -913,21 +917,21 @@ public abstract class AbstractValidationsServlet extends BeGenericServlet { validateUserRole(responseWrapper, userWrapper.getInnerElement(), serviceAuthorityEnum); } if (responseWrapper.isEmpty()) { - validateAndFillServiceJson(responseWrapper, uploadServiceInfoWrapper, userWrapper.getInnerElement(), serviceAuthorityEnum, + validateAndFillServiceJson(responseWrapper, uploadServiceInfoWrapper, serviceAuthorityEnum, serviceInfoJsonString); } if (responseWrapper.isEmpty()) { - validateToscaTemplatePayloadName(responseWrapper, uploadServiceInfoWrapper.getInnerElement(), userWrapper.getInnerElement()); + validateToscaTemplatePayloadName(responseWrapper, uploadServiceInfoWrapper.getInnerElement()); } } protected void validateUserRole(Wrapper<Response> errorResponseWrapper, User user, ServiceAuthorityTypeEnum serviceAuthority) { - log.debug("validate user role"); + log.debug(VALIDATE_USER_ROLE); if (serviceAuthority == ServiceAuthorityTypeEnum.NORMATIVE_TYPE_BE) { if (!user.getRole().equals(Role.ADMIN.name())) { - log.info("user is not in appropriate role to perform action"); + log.info(USER_IS_NOT_IN_APPROPRIATE_ROLE_TO_PERFORM_ACTION); ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION); - log.debug("audit before sending response"); + log.debug(AUDIT_BEFORE_SENDING_RESPONSE); Response response = buildErrorResponse(responseFormat); errorResponseWrapper.setInnerElement(response); } @@ -936,7 +940,7 @@ public abstract class AbstractValidationsServlet extends BeGenericServlet { } } - protected void validateAndFillServiceJson(Wrapper<Response> responseWrapper, Wrapper<UploadServiceInfo> uploadServiceInfoWrapper, User user, + protected void validateAndFillServiceJson(Wrapper<Response> responseWrapper, Wrapper<UploadServiceInfo> uploadServiceInfoWrapper, ServiceAuthorityTypeEnum serviceAuthorityEnum, String serviceInfo) { boolean isValid; try { @@ -961,16 +965,16 @@ public abstract class AbstractValidationsServlet extends BeGenericServlet { isValid = false; } if (!isValid) { - log.info("Invalid json was received."); + log.info(INVALID_JSON_WAS_RECEIVED); ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); Response errorResp = buildErrorResponse(responseFormat); responseWrapper.setInnerElement(errorResp); } } - protected void validateToscaTemplatePayloadName(Wrapper<Response> responseWrapper, UploadServiceInfo uploadServiceInfo, User user) { + protected void validateToscaTemplatePayloadName(Wrapper<Response> responseWrapper, UploadServiceInfo uploadServiceInfo) { String toscaTemplatePayloadName = uploadServiceInfo.getPayloadName(); - boolean isValidSuffix = isToscaTemplatePayloadNameValid(responseWrapper, toscaTemplatePayloadName); + boolean isValidSuffix = isToscaTemplatePayloadNameValid(toscaTemplatePayloadName); if (!isValidSuffix) { ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_FILE_EXTENSION); Response errorResponse = buildErrorResponse(responseFormat); @@ -979,35 +983,33 @@ public abstract class AbstractValidationsServlet extends BeGenericServlet { } protected void specificServiceAuthorityValidations(Wrapper<Response> responseWrapper, Wrapper<UploadServiceInfo> uploadServiceInfoWrapper, - Wrapper<String> yamlStringWrapper, User user, HttpServletRequest request, - String serviceInfoJsonString, ServiceAuthorityTypeEnum serviceAuthorityEnum) - throws FileNotFoundException { + Wrapper<String> yamlStringWrapper, HttpServletRequest request, + String serviceInfoJsonString, ServiceAuthorityTypeEnum serviceAuthorityEnum) { if (responseWrapper.isEmpty()) { // UI Only Validation if (!serviceAuthorityEnum.isBackEndImport()) { - importUIValidations(responseWrapper, uploadServiceInfoWrapper.getInnerElement(), user, request, serviceInfoJsonString); + importUIValidations(responseWrapper, uploadServiceInfoWrapper.getInnerElement(), request, serviceInfoJsonString); } // User Defined Type Services - if (serviceAuthorityEnum.isUserTypeService() && !CsarValidationUtils - .isCsarPayloadName(uploadServiceInfoWrapper.getInnerElement().getPayloadName())) { - if (responseWrapper.isEmpty()) { - validatePayloadNameSpace(responseWrapper, uploadServiceInfoWrapper.getInnerElement(), user, yamlStringWrapper.getInnerElement()); - } + if (serviceAuthorityEnum.isUserTypeService() + && !CsarValidationUtils.isCsarPayloadName(uploadServiceInfoWrapper.getInnerElement().getPayloadName()) + && responseWrapper.isEmpty()) { + validatePayloadNameSpace(responseWrapper, uploadServiceInfoWrapper.getInnerElement(), yamlStringWrapper.getInnerElement()); } } } - protected void importUIValidations(Wrapper<Response> responseWrapper, UploadServiceInfo serviceInfo, User user, HttpServletRequest request, + protected void importUIValidations(Wrapper<Response> responseWrapper, UploadServiceInfo serviceInfo, HttpServletRequest request, String serviceInfoJsonString) { if (responseWrapper.isEmpty()) { - validateMD5(responseWrapper, user, serviceInfo, request, serviceInfoJsonString); + validateMD5(responseWrapper, request, serviceInfoJsonString); } if (responseWrapper.isEmpty() && request != null && request.getMethod() != null && request.getMethod().equals("POST")) { - validateServiceDoesNotExist(responseWrapper, user, serviceInfo.getName()); + validateServiceDoesNotExist(responseWrapper, serviceInfo.getName()); } } - protected void validatePayloadNameSpace(Wrapper<Response> responseWrapper, UploadServiceInfo serviceInfo, User user, String toscaPayload) { + protected void validatePayloadNameSpace(Wrapper<Response> responseWrapper, UploadServiceInfo serviceInfo, String toscaPayload) { boolean isValid; String nameSpace = ""; Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload); @@ -1036,7 +1038,7 @@ public abstract class AbstractValidationsServlet extends BeGenericServlet { } } - protected void validateMD5(Wrapper<Response> responseWrapper, User user, UploadServiceInfo serviceInfo, HttpServletRequest request, + protected void validateMD5(Wrapper<Response> responseWrapper, HttpServletRequest request, String serviceInfoJsonString) { boolean isValid; String recievedMD5 = request.getHeader(Constants.MD5_HEADER); @@ -1053,7 +1055,7 @@ public abstract class AbstractValidationsServlet extends BeGenericServlet { } } - protected void validateServiceDoesNotExist(Wrapper<Response> responseWrapper, User user, String serviceName) { + protected void validateServiceDoesNotExist(Wrapper<Response> responseWrapper, String serviceName) { if (serviceImportManager.isServiceExist(serviceName)) { ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.SERVICE_ALREADY_EXISTS); Response errorResponse = buildErrorResponse(responseFormat); @@ -1061,13 +1063,12 @@ public abstract class AbstractValidationsServlet extends BeGenericServlet { } } - protected void handleImportService(Wrapper<Response> responseWrapper, User user, UploadServiceInfo serviceInfoObject, String serviceUniqueId) - throws ZipException { + protected void handleImportService(Wrapper<Response> responseWrapper, User user, UploadServiceInfo serviceInfoObject) { Response response = null; ImmutablePair<Service, ActionStatus> importedServiceStatus = null; if (CsarValidationUtils.isCsarPayloadName(serviceInfoObject.getPayloadName())) { log.debug("import service from csar"); - importedServiceStatus = importServiceFromUICsar(serviceInfoObject, user, serviceUniqueId); + importedServiceStatus = importServiceFromUICsar(serviceInfoObject, user); } if (importedServiceStatus != null) { Object representation = null; @@ -1081,8 +1082,7 @@ public abstract class AbstractValidationsServlet extends BeGenericServlet { responseWrapper.setInnerElement(response); } - private ImmutablePair<Service, ActionStatus> importServiceFromUICsar(UploadServiceInfo serviceInfoObject, User user, String serviceUniqueId) - throws ZipException { + private ImmutablePair<Service, ActionStatus> importServiceFromUICsar(UploadServiceInfo serviceInfoObject, User user) { Service service = new Service(); String payloadName = serviceInfoObject.getPayloadName(); fillServiceFromServiceInfoObject(service, serviceInfoObject); @@ -1098,7 +1098,7 @@ public abstract class AbstractValidationsServlet extends BeGenericServlet { fillArtifacts(service, serviceInfoObject); } - private Map<String, byte[]> getCsarFromPayload(UploadServiceInfo innerElement) throws ZipException { + private Map<String, byte[]> getCsarFromPayload(UploadServiceInfo innerElement) { String csarUUID = innerElement.getPayloadName(); String payloadData = innerElement.getPayloadData(); return getComponentCsarFromPayload(csarUUID, payloadData); @@ -1180,7 +1180,7 @@ public abstract class AbstractValidationsServlet extends BeGenericServlet { log.debug("enter fillServicePayloadDataFromFile"); byte[] data = new byte[(int) file.length()]; if (fileInputStream.read(data) == -1) { - log.info("Invalid json was received."); + log.info(INVALID_JSON_WAS_RECEIVED); ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); Response errorResp = buildErrorResponse(responseFormat); responseWrapper.setInnerElement(errorResp); 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 new file mode 100644 index 0000000000..4456b8346e --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/DataTypeServlet.java @@ -0,0 +1,104 @@ +/* + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2022 Nordix Foundation. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.servlets; + +import com.jcabi.aspects.Loggable; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.servers.Server; +import io.swagger.v3.oas.annotations.tags.Tag; +import java.util.Optional; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.openecomp.sdc.be.components.impl.aaf.AafPermission; +import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.elements.DataTypeDataDefinition; +import org.openecomp.sdc.be.exception.BusinessException; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.jsonjanusgraph.operations.exception.OperationException; +import org.openecomp.sdc.be.model.operations.impl.DataTypeOperation; +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; + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog/data-types") +@Tag(name = "SDCE-2 APIs") +@Server(url = "/sdc2/rest") +@Controller +public class DataTypeServlet extends BeGenericServlet { + + private static final Logger log = Logger.getLogger(DataTypeServlet.class); + private final DataTypeOperation dataTypeOperation; + + public DataTypeServlet(final ComponentsUtils componentsUtils, + final DataTypeOperation dataTypeOperation) { + super(componentsUtils); + this.dataTypeOperation = dataTypeOperation; + } + + @GET + @Path("{dataTypeUid}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Get data types", method = "GET", summary = "Returns data types", responses = { + @ApiResponse(content = @Content(schema = @Schema(implementation = DataTypeDataDefinition.class))), + @ApiResponse(responseCode = "200", description = "Data type found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "404", description = "Data types not found")}) + @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) + public Response fetchDataType(@Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @PathParam("dataTypeUid") String dataTypeUid) { + final String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {} - modifier id is {}", url, userId); + final Optional<DataTypeDataDefinition> dataTypeByUid; + try { + dataTypeByUid = dataTypeOperation.getDataTypeByUid(dataTypeUid); + } catch (final BusinessException e) { + throw e; + } catch (final Exception ex) { + final String errorMsg = "Unexpected error while listing the Tosca DataType"; + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(errorMsg); + log.error(EcompLoggerErrorCode.UNKNOWN_ERROR, this.getClass().getName(), errorMsg, ex); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + if (dataTypeByUid.isEmpty()) { + throw new OperationException(ActionStatus.DATA_TYPE_NOT_FOUND, dataTypeUid); + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), dataTypeByUid); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceServlet.java index d3a2f7cca0..d314f6a01d 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceServlet.java @@ -678,10 +678,10 @@ public class ServiceServlet extends AbstractValidationsServlet { Wrapper<String> yamlStringWrapper = new Wrapper<>(); ServiceAuthorityTypeEnum serviceAuthorityTypeEnum = ServiceAuthorityTypeEnum.USER_TYPE_UI; commonServiceGeneralValidations(responseWrapper, userWrapper, uploadServiceInfoWrapper, serviceAuthorityTypeEnum, userId, data); - specificServiceAuthorityValidations(responseWrapper, uploadServiceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), request, + specificServiceAuthorityValidations(responseWrapper, uploadServiceInfoWrapper, yamlStringWrapper, request, data, serviceAuthorityTypeEnum); if (responseWrapper.isEmpty()) { - handleImportService(responseWrapper, userWrapper.getInnerElement(), uploadServiceInfoWrapper.getInnerElement(), serviceUniqueId); + handleImportService(responseWrapper, userWrapper.getInnerElement(), uploadServiceInfoWrapper.getInnerElement()); } return responseWrapper; } @@ -761,7 +761,7 @@ public class ServiceServlet extends AbstractValidationsServlet { serviceInfoJsonString); fillServicePayload(responseWrapper, uploadServiceInfoWrapper, yamlStringWrapper, modifier, serviceInfoJsonString, serviceAuthorityEnum, file); - specificServiceAuthorityValidations(responseWrapper, uploadServiceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), request, + specificServiceAuthorityValidations(responseWrapper, uploadServiceInfoWrapper, yamlStringWrapper, request, serviceInfoJsonString, serviceAuthorityEnum); log.debug("importReplaceService:get payload:{}", uploadServiceInfoWrapper.getInnerElement().getPayloadData()); ServiceMetadataDataDefinition serviceMetadataDataDefinition = (ServiceMetadataDataDefinition) oldService.getComponentMetadataDefinition() @@ -773,10 +773,10 @@ public class ServiceServlet extends AbstractValidationsServlet { uploadServiceInfoWrapper.getInnerElement().setProjectCode(oldService.getProjectCode()); if (responseWrapper.isEmpty()) { log.debug("importReplaceService:start handleImportService"); - handleImportService(responseWrapper, userWrapper.getInnerElement(), uploadServiceInfoWrapper.getInnerElement(), null); + handleImportService(responseWrapper, userWrapper.getInnerElement(), uploadServiceInfoWrapper.getInnerElement()); } return responseWrapper.getInnerElement(); - } catch (IOException | ZipException e) { + } catch (final ZipException e) { BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Import Service"); log.debug("import service failed with exception", e); return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesFetchServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesFetchServlet.java index 254bb8c92b..953fcda1bf 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesFetchServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesFetchServlet.java @@ -28,15 +28,12 @@ import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.servers.Server; -import io.swagger.v3.oas.annotations.servers.Servers; import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.tags.Tags; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import javax.inject.Inject; -import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; import javax.ws.rs.GET; @@ -53,7 +50,6 @@ import org.openecomp.sdc.be.components.impl.CapabilitiesBusinessLogic; import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic; import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; import org.openecomp.sdc.be.components.impl.InterfaceOperationBusinessLogic; -import org.openecomp.sdc.be.components.impl.PropertyBusinessLogic; import org.openecomp.sdc.be.components.impl.RelationshipTypeBusinessLogic; import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic; import org.openecomp.sdc.be.components.impl.ResourceImportManager; @@ -83,14 +79,14 @@ import org.springframework.stereotype.Controller; @Loggable(prepend = true, value = Loggable.DEBUG, trim = false) @Path("/v1/catalog") -@Tags({@Tag(name = "SDCE-2 APIs")}) -@Servers({@Server(url = "/sdc2/rest")}) +@Tag(name = "SDCE-2 APIs") +@Server(url = "/sdc2/rest") @Controller public class TypesFetchServlet extends AbstractValidationsServlet { private static final Logger log = Logger.getLogger(TypesFetchServlet.class); private static final String FAILED_TO_GET_ALL_NON_ABSTRACT = "failed to get all non abstract {}"; - private final PropertyBusinessLogic propertyBusinessLogic; + private static final String START_HANDLE_REQUEST_OF_MODIFIER_ID_IS = "Start handle request of {} | modifier id is {}"; private final RelationshipTypeBusinessLogic relationshipTypeBusinessLogic; private final CapabilitiesBusinessLogic capabilitiesBusinessLogic; private final InterfaceOperationBusinessLogic interfaceOperationBusinessLogic; @@ -103,7 +99,6 @@ public class TypesFetchServlet extends AbstractValidationsServlet { ComponentsUtils componentsUtils, ServletUtils servletUtils, ResourceImportManager resourceImportManager, - PropertyBusinessLogic propertyBusinessLogic, RelationshipTypeBusinessLogic relationshipTypeBusinessLogic, CapabilitiesBusinessLogic capabilitiesBusinessLogic, InterfaceOperationBusinessLogic interfaceOperationBusinessLogic, @@ -116,7 +111,6 @@ public class TypesFetchServlet extends AbstractValidationsServlet { servletUtils, resourceImportManager ); - this.propertyBusinessLogic = propertyBusinessLogic; this.relationshipTypeBusinessLogic = relationshipTypeBusinessLogic; this.capabilitiesBusinessLogic = capabilitiesBusinessLogic; this.interfaceOperationBusinessLogic = interfaceOperationBusinessLogic; @@ -173,7 +167,7 @@ public class TypesFetchServlet extends AbstractValidationsServlet { validateUserExist(responseWrapper, userWrapper, userId); if (responseWrapper.isEmpty()) { String url = request.getMethod() + " " + request.getRequestURI(); - log.info("Start handle request of {} | modifier id is {}", url, userId); + log.info(START_HANDLE_REQUEST_OF_MODIFIER_ID_IS, url, userId); Either<Map<String, InterfaceDefinition>, ResponseFormat> allInterfaceLifecycleTypes = interfaceOperationBusinessLogic .getAllInterfaceLifecycleTypes(modelName); if (allInterfaceLifecycleTypes.isRight()) { @@ -206,7 +200,7 @@ public class TypesFetchServlet extends AbstractValidationsServlet { @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) public Response getAllCapabilityTypesServlet(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, - @Parameter(description = "model", required = false) @QueryParam("model") String modelName) { + @Parameter(description = "model") @QueryParam("model") String modelName) { Wrapper<Response> responseWrapper = new Wrapper<>(); Wrapper<User> userWrapper = new Wrapper<>(); try { @@ -215,7 +209,7 @@ public class TypesFetchServlet extends AbstractValidationsServlet { modelName = ValidationUtils.sanitizeInputString(modelName); if (responseWrapper.isEmpty()) { String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {} | modifier id is {}", url, userId); + log.debug(START_HANDLE_REQUEST_OF_MODIFIER_ID_IS, url, userId); Either<Map<String, CapabilityTypeDefinition>, ResponseFormat> allDataTypes = capabilitiesBusinessLogic.getAllCapabilityTypes( modelName); if (allDataTypes.isRight()) { @@ -251,7 +245,7 @@ public class TypesFetchServlet extends AbstractValidationsServlet { @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) public Response getAllRelationshipTypesServlet(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, - @Parameter(description = "model", required = false) @QueryParam("model") String modelName) { + @Parameter(description = "model") @QueryParam("model") String modelName) { Wrapper<Response> responseWrapper = new Wrapper<>(); Wrapper<User> userWrapper = new Wrapper<>(); try { @@ -260,7 +254,7 @@ public class TypesFetchServlet extends AbstractValidationsServlet { modelName = ValidationUtils.sanitizeInputString(modelName); if (responseWrapper.isEmpty()) { String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {} | modifier id is {}", url, userId); + log.debug(START_HANDLE_REQUEST_OF_MODIFIER_ID_IS, url, userId); Either<Map<String, RelationshipTypeDefinition>, ResponseFormat> allDataTypes = relationshipTypeBusinessLogic .getAllRelationshipTypes(modelName); if (allDataTypes.isRight()) { @@ -296,11 +290,10 @@ public class TypesFetchServlet extends AbstractValidationsServlet { public Response getAllNodeTypesServlet( @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, - @Parameter(description = "model", required = false) @QueryParam("model") String modelName + @Parameter(description = "model") @QueryParam("model") String modelName ) { Wrapper<Response> responseWrapper = new Wrapper<>(); Wrapper<User> userWrapper = new Wrapper<>(); - ServletContext context = request.getSession().getServletContext(); Either<Map<String, Component>, Response> response; Map<String, Component> componentMap; try { @@ -309,7 +302,7 @@ public class TypesFetchServlet extends AbstractValidationsServlet { modelName = ValidationUtils.sanitizeInputString(modelName); if (responseWrapper.isEmpty()) { String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {} | modifier id is {}", url, userId); + log.debug(START_HANDLE_REQUEST_OF_MODIFIER_ID_IS, url, userId); response = getComponent(resourceBusinessLogic, true, userId, modelName); if (response.isRight()) { return response.right().value(); @@ -343,7 +336,7 @@ public class TypesFetchServlet extends AbstractValidationsServlet { @ApiResponse(responseCode = "404", description = "Tosca Artifact Types not found")}) @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) public Response getAllToscaArtifactTypes(@Parameter(description = "Model name") @QueryParam("model") String model, - @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator) { + @Context final HttpServletRequest request, @HeaderParam(Constants.USER_ID_HEADER) String creator) { try { return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), artifactsBusinessLogic.getAllToscaArtifacts(model)); } catch (final BusinessException e) { diff --git a/catalog-be/src/main/resources/config/error-configuration.yaml b/catalog-be/src/main/resources/config/error-configuration.yaml index d31d4a6203..0081525647 100644 --- a/catalog-be/src/main/resources/config/error-configuration.yaml +++ b/catalog-be/src/main/resources/config/error-configuration.yaml @@ -2820,4 +2820,10 @@ errors: CAPABILITY_NOT_FOUND_IN_COMPONENT: code: 400 message: "Capability '%1' not found in '%2' '%3'." - messageId: "SVC4186"
\ No newline at end of file + messageId: "SVC4186" + + # %1 - The data type Uid + DATA_TYPE_NOT_FOUND: + code: 404 + message: "Data type '%1' was not found." + messageId: "SVC4011" diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/DataTypeServletTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/DataTypeServletTest.java new file mode 100644 index 0000000000..39ba071a74 --- /dev/null +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/DataTypeServletTest.java @@ -0,0 +1,152 @@ +/* + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2022 Nordix Foundation. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.servlets; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Optional; +import javax.servlet.ServletContext; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.apache.http.HttpStatus; +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.test.TestProperties; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.mockito.junit.jupiter.MockitoExtension; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.elements.DataTypeDataDefinition; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.model.jsonjanusgraph.operations.exception.OperationException; +import org.openecomp.sdc.be.model.operations.impl.DataTypeOperation; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.exception.ResponseFormat; +import org.springframework.web.context.WebApplicationContext; + +@ExtendWith(MockitoExtension.class) +class DataTypeServletTest extends JerseySpringBaseTest { + + private static final String USER_ID = "cs0008"; + private static final String DATA_TYPE_UID = "ETSI SOL001 v2.5.1.tosca.datatypes.nfv.L3AddressData.datatype"; + private static final String PATH = "/v1/catalog/data-types/" + DATA_TYPE_UID; + + @InjectMocks + private DataTypeServlet dataTypeServlet; + private ComponentsUtils componentsUtils; + private DataTypeOperation dataTypeOperation; + private ServletContext servletContext; + private WebApplicationContext webApplicationContext; + private WebAppContextWrapper webAppContextWrapper; + + @Override + protected ResourceConfig configure() { + initMocks(); + MockitoAnnotations.openMocks(this); + forceSet(TestProperties.CONTAINER_PORT, "0"); + return super.configure().register(dataTypeServlet); + } + + private void initMocks() { + componentsUtils = mock(ComponentsUtils.class); + dataTypeOperation = mock(DataTypeOperation.class); + servletContext = Mockito.mock(ServletContext.class); + webApplicationContext = Mockito.mock(WebApplicationContext.class); + webAppContextWrapper = Mockito.mock(WebAppContextWrapper.class); + } + + @BeforeEach + void before() throws Exception { + super.setUp(); + when(request.getSession()).thenReturn(session); + when(session.getServletContext()).thenReturn(servletContext); + when(webApplicationContext.getBean(ComponentsUtils.class)).thenReturn(componentsUtils); + when(servletContext.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR)).thenReturn(webAppContextWrapper); + when(webAppContextWrapper.getWebAppContext(servletContext)).thenReturn(webApplicationContext); + } + + @AfterEach + void after() throws Exception { + super.tearDown(); + } + + @Test + void fetchDataTypeTest_Success() { + when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(new ResponseFormat(HttpStatus.SC_OK)); + when(dataTypeOperation.getDataTypeByUid(DATA_TYPE_UID)).thenReturn(Optional.of(new DataTypeDataDefinition())); + + final Response response = target() + .path(PATH) + .request(MediaType.APPLICATION_JSON) + .header("USER_ID", USER_ID) + .get(Response.class); + assertNotNull(response); + assertEquals(HttpStatus.SC_OK, response.getStatus()); + } + + @Test + void fetchDataTypeTest_Fail_OperationException() { + when(dataTypeOperation.getDataTypeByUid(DATA_TYPE_UID)).thenThrow(OperationException.class); + + final Response response = target() + .path(PATH) + .request(MediaType.APPLICATION_JSON) + .header("USER_ID", USER_ID) + .get(Response.class); + assertNotNull(response); + assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, response.getStatus()); + } + + @Test + void fetchDataTypeTest_Fail_EmptyOptional() { + when(dataTypeOperation.getDataTypeByUid(DATA_TYPE_UID)).thenReturn(Optional.empty()); + + final Response response = target() + .path(PATH) + .request(MediaType.APPLICATION_JSON) + .header("USER_ID", USER_ID) + .get(Response.class); + assertNotNull(response); + assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, response.getStatus()); + } + + @Test + void fetchDataTypeTest_Fail_RuntimeException() { + when(dataTypeOperation.getDataTypeByUid(DATA_TYPE_UID)).thenThrow(RuntimeException.class); + + final Response response = target() + .path(PATH) + .request(MediaType.APPLICATION_JSON) + .header("USER_ID", USER_ID) + .get(Response.class); + assertNotNull(response); + assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, response.getStatus()); + } + +} diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java index 2f5f175a17..1ca0e4d048 100644 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java @@ -22,7 +22,7 @@ package org.openecomp.sdc.be.dao.api; public enum ActionStatus { OK, ACCEPTED, CREATED, NO_CONTENT, GENERAL_ERROR, NOT_ALLOWED, MISSING_INFORMATION, RESTRICTED_OPERATION, - RESTRICTED_ACCESS, INVALID_CONTENT, INVALID_PROPERTY_VALUES, NOT_SUPPORTED, INVALID_ARTIFACT_LABEL_NAME, + RESTRICTED_ACCESS, INVALID_CONTENT, INVALID_PROPERTY_VALUES, NOT_SUPPORTED, INVALID_ARTIFACT_LABEL_NAME, // User related USER_ALREADY_EXIST, USER_INACTIVE, USER_NOT_FOUND, USER_HAS_ACTIVE_ELEMENTS, INVALID_EMAIL_ADDRESS, INVALID_ROLE, DELETE_USER_ADMIN_CONFLICT, UPDATE_USER_ADMIN_CONFLICT, CANNOT_DELETE_USER_WITH_ACTIVE_ELEMENTS, CANNOT_UPDATE_USER_WITH_ACTIVE_ELEMENTS, INVALID_USER_ID, USER_DEFINED, // CapabilityType related @@ -75,7 +75,7 @@ public enum ActionStatus { EMPTY_OCCURRENCES_LIST, INVALID_OCCURRENCES, NOT_TOPOLOGY_TOSCA_TEMPLATE, INVALID_NODE_TEMPLATE, // Data type related DATA_TYPE_ALREADY_EXIST, DATA_TYPE_NOR_PROPERTIES_NEITHER_DERIVED_FROM, DATA_TYPE_PROPERTIES_CANNOT_BE_EMPTY, DATA_TYPE_DERIVED_IS_MISSING, DATA_TYPE_PROPERTY_ALREADY_DEFINED_IN_ANCESTOR, DATA_TYPE_DUPLICATE_PROPERTY, DATA_TYPE_PROEPRTY_CANNOT_HAVE_SAME_TYPE_OF_DATA_TYPE, DATA_TYPE_CANNOT_HAVE_PROPERTIES, DATA_TYPE_CANNOT_BE_EMPTY, DATA_TYPE_CANNOT_BE_UPDATED_BAD_REQUEST, - DATA_TYPES_NOT_LOADED, + DATA_TYPES_NOT_LOADED, DATA_TYPE_NOT_FOUND, // Policy Type related TARGETS_EMPTY, TARGETS_NON_VALID, POLICY_TYPE_ALREADY_EXIST, // Group Type related diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.java index f4073baa3d..ff4dc0aabd 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.java @@ -114,10 +114,12 @@ public class CapabilityTypeOperation extends AbstractOperation implements ICapab public Either<CapabilityTypeDefinition, StorageOperationStatus> validateUpdateProperties(CapabilityTypeDefinition capabilityTypeDefinition) { JanusGraphOperationStatus error = null; if (MapUtils.isNotEmpty(capabilityTypeDefinition.getProperties()) && capabilityTypeDefinition.getDerivedFrom() != null) { - final Either<CapabilityTypeData, JanusGraphOperationStatus> derivedFromNode = janusGraphGenericDao.getNode(GraphPropertiesDictionary.TYPE.getProperty(), + final Either<CapabilityTypeData, JanusGraphOperationStatus> derivedFromNode = janusGraphGenericDao.getNode( + GraphPropertiesDictionary.TYPE.getProperty(), capabilityTypeDefinition.getDerivedFrom(), CapabilityTypeData.class, capabilityTypeDefinition.getModel()); if (derivedFromNode.isRight()) { - log.error(BUSINESS_PROCESS_ERROR, "Failed to find the derived from type for {}. status is {}", capabilityTypeDefinition.getType(), derivedFromNode.right().value()); + log.error(BUSINESS_PROCESS_ERROR, "Failed to find the derived from type for {}. status is {}", capabilityTypeDefinition.getType(), + derivedFromNode.right().value()); return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(derivedFromNode.right().value())); } Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> allPropertiesRes = getAllCapabilityTypePropertiesFromAllDerivedFrom( @@ -178,15 +180,15 @@ public class CapabilityTypeOperation extends AbstractOperation implements ICapab log.error("Failed add properties {} to capability {}", propertiesMap, capabilityTypeDefinition.getType()); return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(addPropertiesToCapablityType.right().value())); } - + final Either<GraphRelation, StorageOperationStatus> modelRelationship = addCapabilityTypeToModel(capabilityTypeDefinition); if (modelRelationship.isRight()) { return Either.right(modelRelationship.right().value()); - } - + } + return addDerivedFromRelation(capabilityTypeDefinition, ctUniqueId).left().map(updatedDerivedFrom -> createCTResult.left().value()); } - + private Either<GraphRelation, StorageOperationStatus> addCapabilityTypeToModel(final CapabilityTypeDefinition capabilityTypeDefinition) { final String model = capabilityTypeDefinition.getModel(); if (model == null) { @@ -195,7 +197,8 @@ public class CapabilityTypeOperation extends AbstractOperation implements ICapab final GraphNode from = new UniqueIdData(NodeTypeEnum.Model, UniqueIdBuilder.buildModelUid(model)); final GraphNode to = new UniqueIdData(NodeTypeEnum.CapabilityType, capabilityTypeDefinition.getUniqueId()); log.info("Connecting model {} to type {}", from, to); - return janusGraphGenericDao.createRelation(from , to, GraphEdgeLabels.MODEL_ELEMENT, Collections.emptyMap()).right().map(DaoStatusConverter::convertJanusGraphStatusToStorageStatus); + return janusGraphGenericDao.createRelation(from, to, GraphEdgeLabels.MODEL_ELEMENT, Collections.emptyMap()).right() + .map(DaoStatusConverter::convertJanusGraphStatusToStorageStatus); } private CapabilityTypeData buildCapabilityTypeData(CapabilityTypeDefinition capabilityTypeDefinition, String ctUniqueId) { @@ -237,7 +240,7 @@ public class CapabilityTypeOperation extends AbstractOperation implements ICapab // Optimization: In case of Capability Type its unique ID is the same as type return getCapabilityTypeByUid(capabilityType); } - + public Either<CapabilityTypeDefinition, JanusGraphOperationStatus> getCapabilityTypeByType(final String capabilityType, final String model) { final Either<CapabilityTypeData, JanusGraphOperationStatus> capabilityTypesRes = janusGraphGenericDao .getNode(GraphPropertiesDictionary.TYPE.getProperty(), capabilityType, CapabilityTypeData.class, model); @@ -256,7 +259,6 @@ public class CapabilityTypeOperation extends AbstractOperation implements ICapab * @return */ public Either<CapabilityTypeDefinition, JanusGraphOperationStatus> getCapabilityTypeByUid(String uniqueId) { - Either<CapabilityTypeDefinition, JanusGraphOperationStatus> result = null; Either<CapabilityTypeData, JanusGraphOperationStatus> capabilityTypesRes = janusGraphGenericDao .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), uniqueId, CapabilityTypeData.class); if (capabilityTypesRes.isRight()) { @@ -266,7 +268,7 @@ public class CapabilityTypeOperation extends AbstractOperation implements ICapab } return getCapabilityTypeDefinition(capabilityTypesRes.left().value()); } - + private Either<CapabilityTypeDefinition, JanusGraphOperationStatus> getCapabilityTypeDefinition(final CapabilityTypeData ctData) { CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition(ctData.getCapabilityTypeDataDefinition()); Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> propertiesStatus = OperationUtils @@ -285,7 +287,8 @@ public class CapabilityTypeOperation extends AbstractOperation implements ICapab if (parentNode.isRight()) { JanusGraphOperationStatus janusGraphOperationStatus = parentNode.right().value(); if (janusGraphOperationStatus != JanusGraphOperationStatus.NOT_FOUND) { - log.error(BUSINESS_PROCESS_ERROR, "Failed to find the parent capability of capability type {}. status is {}", ctData.getUniqueId(), janusGraphOperationStatus); + log.error(BUSINESS_PROCESS_ERROR, "Failed to find the parent capability of capability type {}. status is {}", ctData.getUniqueId(), + janusGraphOperationStatus); return Either.right(janusGraphOperationStatus); } } else { @@ -294,14 +297,14 @@ public class CapabilityTypeOperation extends AbstractOperation implements ICapab CapabilityTypeData parentCT = immutablePair.getKey(); capabilityTypeDefinition.setDerivedFrom(parentCT.getCapabilityTypeDataDefinition().getType()); } - + final Either<ImmutablePair<ModelData, GraphEdge>, JanusGraphOperationStatus> model = janusGraphGenericDao.getParentNode( - UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), ctData.getUniqueId(), GraphEdgeLabels.MODEL_ELEMENT, + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), ctData.getUniqueId(), GraphEdgeLabels.MODEL_ELEMENT, NodeTypeEnum.Model, ModelData.class); if (model.isLeft()) { capabilityTypeDefinition.setModel(model.left().value().getLeft().getName()); } - + return Either.left(capabilityTypeDefinition); } 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 a0963c9030..f75e3cfb17 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 @@ -24,17 +24,22 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import org.apache.commons.collections.CollectionUtils; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; import org.apache.tinkerpop.gremlin.structure.Vertex; import org.janusgraph.core.JanusGraph; import org.openecomp.sdc.be.config.BeEcompErrorManager; import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.dao.janusgraph.HealingJanusGraphGenericDao; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.datatypes.elements.DataTypeDataDefinition; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.jsonjanusgraph.operations.exception.OperationException; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.resources.data.DataTypeData; import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode; import org.slf4j.Logger; @@ -71,38 +76,38 @@ public class DataTypeOperation extends AbstractOperation { } final List<DataTypeData> allDataTypeNodesWithModel = getAllDataTypesWithModel(); - if(CollectionUtils.isNotEmpty(allDataTypeNodesWithModel)) { + if (CollectionUtils.isNotEmpty(allDataTypeNodesWithModel)) { dataTypesFound.addAll(allDataTypeNodesWithModel); } return dataTypesFound; } - + public Map<String, List<String>> getAllDataTypeUidsToModels() { final Map<String, List<String>> dataTypesFound = new HashMap<>(); final Either<List<DataTypeData>, JanusGraphOperationStatus> getAllDataTypesWithNullModel = janusGraphGenericDao.getByCriteria(NodeTypeEnum.DataType, null, DataTypeData.class); final var dataTypesValidated = validateDataType(getAllDataTypesWithNullModel, null); - - for (DataTypeData dataType: dataTypesValidated) { - if (!dataTypesFound.containsKey(dataType.getUniqueId())){ + + for (DataTypeData dataType : dataTypesValidated) { + if (!dataTypesFound.containsKey(dataType.getUniqueId())) { dataTypesFound.put(dataType.getUniqueId(), new ArrayList<>()); } dataTypesFound.get(dataType.getUniqueId()).add(null); } - + modelOperation.findAllModels() .forEach(model -> { - for (DataTypeData dataType: getAllDataTypesWithModel(model.getName())) { - if (!dataTypesFound.containsKey(dataType.getUniqueId())){ + for (DataTypeData dataType : getAllDataTypesWithModel(model.getName())) { + if (!dataTypesFound.containsKey(dataType.getUniqueId())) { dataTypesFound.put(dataType.getUniqueId(), new ArrayList<>()); } dataTypesFound.get(dataType.getUniqueId()).add(model.getName()); } - }); + }); return dataTypesFound; } - + private List<DataTypeData> getAllDataTypesWithModel(final String modelName) { final Either<List<DataTypeData>, JanusGraphOperationStatus> getAllDataTypesByModel = janusGraphGenericDao .getByCriteriaForModel(NodeTypeEnum.DataType, null, modelName, DataTypeData.class); @@ -129,7 +134,7 @@ public class DataTypeOperation extends AbstractOperation { if (getDataTypes.isRight()) { final var status = getDataTypes.right().value(); if (LOGGER.isErrorEnabled()) { - final var errorMsg= String.format("Failed to fetch data types from database with model %s. Status is %s", modelName, status); + final var errorMsg = String.format("Failed to fetch data types from database with model %s. Status is %s", modelName, status); LOGGER.error(String.valueOf(EcompLoggerErrorCode.UNKNOWN_ERROR), DataTypeOperation.class.getName(), errorMsg); BeEcompErrorManager.getInstance().logInternalConnectionError(DataTypeOperation.class.getName(), errorMsg, ErrorSeverity.ERROR); } @@ -152,4 +157,19 @@ public class DataTypeOperation extends AbstractOperation { }); } + public Optional<DataTypeDataDefinition> getDataTypeByUid(final String uniqueId) { + final Either<DataTypeData, JanusGraphOperationStatus> dataTypeEither = janusGraphGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, DataTypeData.class); + if (dataTypeEither.isRight()) { + if (JanusGraphOperationStatus.NOT_FOUND.equals(dataTypeEither.right().value())) { + return Optional.empty(); + } + final StorageOperationStatus storageOperationStatus + = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(dataTypeEither.right().value()); + LOGGER.warn("Failed to fetch data type '{}' from JanusGraph. Status is: {}", uniqueId, storageOperationStatus); + throw new OperationException(ActionStatus.GENERAL_ERROR, + String.format("Failed to fetch data type '%s' from JanusGraph. Status is: %s", uniqueId, storageOperationStatus)); + } + return Optional.of(dataTypeEither.left().value().getDataTypeDataDefinition()); + } } diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/DataTypeOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/DataTypeOperationTest.java index 1580fd34b8..0efb751124 100644 --- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/DataTypeOperationTest.java +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/DataTypeOperationTest.java @@ -19,6 +19,11 @@ package org.openecomp.sdc.be.model.operations.impl; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.when; import fj.data.Either; @@ -27,6 +32,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; @@ -34,6 +40,7 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.openecomp.sdc.be.dao.janusgraph.HealingJanusGraphGenericDao; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; +import org.openecomp.sdc.be.datatypes.elements.DataTypeDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ModelTypeEnum; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; import org.openecomp.sdc.be.model.DataTypeDefinition; @@ -110,6 +117,23 @@ class DataTypeOperationTest { assertThat(dataTypesFound).isEmpty(); } + @Test + void getDataTypeByUidTest_Success() { + doReturn(Either.left(createDataTypeData("test.data.type99", "test.data.type00099", 888L, 999L, modelName))) + .when(janusGraphGenericDao).getNode(eq("uid"), eq("dataType"), any()); + final Optional<DataTypeDataDefinition> dataType = dataTypeOperation.getDataTypeByUid("dataType"); + assertTrue(dataType.isPresent()); + assertEquals("test.data.type99", dataType.get().getName()); + assertEquals("test.data.type00099", dataType.get().getUniqueId()); + assertEquals(modelName, dataType.get().getModel()); + } + + @Test + void getDataTypeByUidTest_Fail() { + doReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND)).when(janusGraphGenericDao).getNode(eq("uid"), eq("dataType"), any()); + Optional<DataTypeDataDefinition> result = dataTypeOperation.getDataTypeByUid("dataType"); + assertTrue(result.isEmpty()); + } private void initTestData() { model = new Model(modelName, ModelTypeEnum.NORMATIVE); diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/GraphPropertyEnum.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/GraphPropertyEnum.java index ab3a05e560..311fac4e74 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/GraphPropertyEnum.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/GraphPropertyEnum.java @@ -24,49 +24,49 @@ import lombok.Getter; @Getter public enum GraphPropertyEnum { // @formatter:off - // field name ,class type ,unique ,indexed - UNIQUE_ID("uid", String.class, true, true), - LABEL("nodeLabel", String.class, false, true), - JSON("json", String.class, false, false), - METADATA("metadata", String.class, false, false), - VERSION("version", String.class, false, true), - STATE("state", String.class, false, true), - IS_HIGHEST_VERSION("highestVersion", Boolean.class, false, true), - IS_DELETED("deleted", Boolean.class, false, true), - NORMALIZED_NAME("normalizedName", String.class, false, true), - NAME("name", String.class, false, true), - TOSCA_RESOURCE_NAME("toscaResourceName", String.class, false, true), - DISTRIBUTION_STATUS("distributionStatus", String.class, false, false), - RESOURCE_TYPE("resourceType", String.class, false, true), - COMPONENT_TYPE("componentType", String.class, false, true), - UUID("uuid", String.class, false, true), - SYSTEM_NAME("systemName", String.class, false, true), - IS_ABSTRACT("abstract", Boolean.class, false, true), - INVARIANT_UUID("invariantUuid", String.class, false, true), - CSAR_UUID("csarUuid", String.class, false, true), - CSAR_VERSION_UUID("csarVersionUuid", String.class, false, true), + // field name, class type, unique, indexed + UNIQUE_ID( "uid", String.class, true, true), + LABEL( "nodeLabel", String.class, false, true), + JSON( "json", String.class, false, false), + METADATA( "metadata", String.class, false, false), + VERSION( "version", String.class, false, true), + STATE( "state", String.class, false, true), + IS_HIGHEST_VERSION( "highestVersion", Boolean.class, false, true), + IS_DELETED( "deleted", Boolean.class, false, true), + NORMALIZED_NAME( "normalizedName", String.class, false, true), + NAME( "name", String.class, false, true), + TOSCA_RESOURCE_NAME( "toscaResourceName", String.class, false, true), + DISTRIBUTION_STATUS( "distributionStatus", String.class, false, false), + RESOURCE_TYPE( "resourceType", String.class, false, true), + COMPONENT_TYPE( "componentType", String.class, false, true), + UUID( "uuid", String.class, false, true), + SYSTEM_NAME( "systemName", String.class, false, true), + IS_ABSTRACT( "abstract", Boolean.class, false, true), + INVARIANT_UUID( "invariantUuid", String.class, false, true), + CSAR_UUID( "csarUuid", String.class, false, true), + CSAR_VERSION_UUID( "csarVersionUuid", String.class, false, true), //used for user (old format, no json for users) - USERID("userId", String.class, true, true), - ROLE("role", String.class, false, false), - FIRST_NAME("firstName", String.class, false, false), - LAST_NAME("lastName", String.class, false, false), - EMAIL("email", String.class, false, false), - LAST_LOGIN_TIME("lastLoginTime", Long.class, false, false), + USERID( "userId", String.class, true, true), + ROLE( "role", String.class, false, false), + FIRST_NAME( "firstName", String.class, false, false), + LAST_NAME( "lastName", String.class, false, false), + EMAIL( "email", String.class, false, false), + LAST_LOGIN_TIME( "lastLoginTime", Long.class, false, false), //used for category (old format, no json for categories) - ICONS("icons", String.class, false, false), - METADATA_KEYS("metadataKeys", String.class, false, false), - USE_SUBSTITUTION_FOR_NESTED_SERVICES("useServiceSubstitutionForNestedServices", Boolean.class, false, false), - DATA_TYPES("data_types", Map.class, false, false), + ICONS( "icons", String.class, false, false), + METADATA_KEYS( "metadataKeys", String.class, false, false), + USE_SUBSTITUTION_FOR_NESTED_SERVICES("useServiceSubstitutionForNestedServices",Boolean.class,false,false), + DATA_TYPES( "data_types", Map.class, false, false), //Archive/Restore - IS_ARCHIVED("isArchived", Boolean.class, false, true), - IS_VSP_ARCHIVED("isVspArchived", Boolean.class, false, true), - ARCHIVE_TIME("archiveTime", Long.class, false, true), - PREV_CATALOG_UPDATE_TIME("previousUpdateTime", Long.class, false, true), - CURRENT_CATALOG_UPDATE_TIME("currentUpdateTime", Long.class, false, true), + IS_ARCHIVED( "isArchived", Boolean.class, false, true), + IS_VSP_ARCHIVED( "isVspArchived", Boolean.class, false, true), + ARCHIVE_TIME( "archiveTime", Long.class, false, true), + PREV_CATALOG_UPDATE_TIME("previousUpdateTime", Long.class, false, true), + CURRENT_CATALOG_UPDATE_TIME("currentUpdateTime",Long.class, false, true), //Healing - HEALING_VERSION("healVersion", Integer.class, false, true), - MODEL("model", String.class, false, false), - MODEL_TYPE("modelType", String.class, false, false); + HEALING_VERSION( "healVersion", Integer.class, false, true), + MODEL( "model", String.class, false, false), + MODEL_TYPE( "modelType", String.class, false, false); // @formatter:on private final String property; |