Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.mosip.authentication.common.service.exception.IdAuthExceptionHandler Maven / Gradle / Ivy
package io.mosip.authentication.common.service.exception;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.context.request.async.AsyncRequestTimeoutException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import io.mosip.authentication.common.service.util.IdaRequestResponsConsumerUtil;
import io.mosip.authentication.core.authtype.dto.AuthtypeResponseDto;
import io.mosip.authentication.core.autntxn.dto.AutnTxnResponseDto;
import io.mosip.authentication.core.constant.IdAuthCommonConstants;
import io.mosip.authentication.core.constant.IdAuthenticationErrorConstants;
import io.mosip.authentication.core.dto.ObjectWithIdVersionTransactionID;
import io.mosip.authentication.core.dto.ObjectWithMetadata;
import io.mosip.authentication.core.exception.IDAuthenticationUnknownException;
import io.mosip.authentication.core.exception.IDDataValidationException;
import io.mosip.authentication.core.exception.IdAuthenticationAppException;
import io.mosip.authentication.core.exception.IdAuthenticationBaseException;
import io.mosip.authentication.core.hotlist.dto.HotlistResponseDTO;
import io.mosip.authentication.core.indauth.dto.ActionableAuthError;
import io.mosip.authentication.core.indauth.dto.AuthError;
import io.mosip.authentication.core.indauth.dto.AuthResponseDTO;
import io.mosip.authentication.core.indauth.dto.KycAuthResponseDTO;
import io.mosip.authentication.core.indauth.dto.KycResponseDTO;
import io.mosip.authentication.core.indauth.dto.ResponseDTO;
import io.mosip.authentication.core.logger.IdaLogger;
import io.mosip.authentication.core.otp.dto.OtpResponseDTO;
import io.mosip.idrepository.core.exception.RestServiceException;
import io.mosip.kernel.core.exception.BaseCheckedException;
import io.mosip.kernel.core.exception.ExceptionUtils;
import io.mosip.kernel.core.logger.spi.Logger;
import io.mosip.kernel.core.util.DateUtils;
import io.mosip.kernel.core.util.StringUtils;
/**
* The Class IDAExceptionHandler - Spring MVC Exceptions as defined in
* {@link ResponseEntityExceptionHandler} and any other Exceptions occurs and
* returns custom exception response {@link AuthResponseDTO}.
*
* @author Manoj SP
* @author Mamta A
*/
@RestControllerAdvice
public class IdAuthExceptionHandler extends ResponseEntityExceptionHandler {
/** The Constant ID_AUTHENTICATION_APP_EXCEPTION. */
private static final String ID_AUTHENTICATION_APP_EXCEPTION = "IdAuthenticationAppException";
/** The Constant PREFIX_HANDLING_EXCEPTION. */
private static final String PREFIX_HANDLING_EXCEPTION = "Handling exception :";
/** The Constant EVENT_EXCEPTION. */
private static final String EVENT_EXCEPTION = "Exception";
private static final String INTERNAL = "/internal";
/** The mosip logger. */
private static Logger mosipLogger = IdaLogger.getLogger(IdAuthExceptionHandler.class);
@Autowired
private HttpServletRequest servletRequest;
/**
* Instantiates a new id auth exception handler.
*/
public IdAuthExceptionHandler() {
//Default constructor
}
/**
* Handle all exceptions.
*
* @param ex the ex
* @param request the request
* @return the response entity
*/
@ExceptionHandler(Exception.class)
protected ResponseEntity handleAllExceptions(Exception ex, WebRequest request) {
mosipLogger.debug(IdAuthCommonConstants.SESSION_ID, EVENT_EXCEPTION, "Entered handleAllExceptions",
PREFIX_HANDLING_EXCEPTION + ex.getClass().toString());
mosipLogger.error(IdAuthCommonConstants.SESSION_ID, EVENT_EXCEPTION, ex.getClass().getName(),
ex.toString() + "\n Request : " + request + "\n Status returned : " + HttpStatus.OK + "\n"
+ ExceptionUtils.getStackTrace(ex));
IDAuthenticationUnknownException unknownException = new IDAuthenticationUnknownException(
IdAuthenticationErrorConstants.UNABLE_TO_PROCESS);
mosipLogger.debug(IdAuthCommonConstants.SESSION_ID, EVENT_EXCEPTION, "Changing exception",
"Returing exception as " + ex.getClass().toString());
return new ResponseEntity<>(buildExceptionResponse(unknownException, servletRequest), HttpStatus.OK);
}
/**
* Method to handle all exception and return as customized response object.
*
* @param ex Exception
* @param errorMessage List of error messages
* @param headers Http headers
* @param status Http status
* @param request Web request
* @return Customized response object
*
* @see org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler#handleExceptionInternal(java.lang.Exception,
* java.lang.Object, org.springframework.http.HttpHeaders,
* org.springframework.http.HttpStatus,
* org.springframework.web.context.request.WebRequest)
*/
@Override
protected ResponseEntity handleExceptionInternal(Exception ex, @Nullable Object errorMessage,
HttpHeaders headers, HttpStatus status, WebRequest request) {
mosipLogger.debug(IdAuthCommonConstants.SESSION_ID, EVENT_EXCEPTION, "Entered handleExceptionInternal",
PREFIX_HANDLING_EXCEPTION + ex.getClass().toString());
mosipLogger.error(IdAuthCommonConstants.SESSION_ID, "Spring MVC Exception", ex.getClass().getName(),
ex.toString() + "Error message Object : "
+ Optional.ofNullable(errorMessage).orElseGet(() -> "null").toString() + "\nStatus returned: "
+ Optional.ofNullable(status).orElseGet(() -> HttpStatus.OK).toString() + "\n"
+ ExceptionUtils.getStackTrace(ex));
if (servletRequest.getRequestURL().toString().endsWith("notify")
&& ex instanceof HttpMessageNotReadableException
&& ex.getCause().getClass().isAssignableFrom(InvalidFormatException.class)
&& Objects.nonNull(((InvalidFormatException) ex.getCause()).getPath())
&& Objects.nonNull(((InvalidFormatException) ex.getCause()).getPath().get(2))) {
int index = ((InvalidFormatException) ex.getCause()).getPath().get(2).getIndex();
if (ex.getCause().getMessage().contains("eventType") && Objects.nonNull(index)) {
ex = new IdAuthenticationAppException(
IdAuthenticationErrorConstants.INVALID_INPUT_PARAMETER.getErrorCode(),
String.format(IdAuthenticationErrorConstants.INVALID_INPUT_PARAMETER.getErrorMessage(),
"request/events/" + index + "/eventType"));
} else if (ex.getCause().getMessage().contains("expiryTimestamp") && Objects.nonNull(index)) {
ex = new IdAuthenticationAppException(
IdAuthenticationErrorConstants.INVALID_INPUT_PARAMETER.getErrorCode(),
String.format(IdAuthenticationErrorConstants.INVALID_INPUT_PARAMETER.getErrorMessage(),
"request/events/" + index + "/expiryTimestamp"));
} else {
ex = new IdAuthenticationAppException(IdAuthenticationErrorConstants.UNABLE_TO_PROCESS.getErrorCode(),
IdAuthenticationErrorConstants.UNABLE_TO_PROCESS.getErrorMessage());
}
return new ResponseEntity<>(buildExceptionResponse(ex, servletRequest), HttpStatus.OK);
} else if (ex instanceof ServletException || ex instanceof BeansException
|| ex instanceof HttpMessageConversionException || ex instanceof AsyncRequestTimeoutException) {
ex = new IdAuthenticationAppException(IdAuthenticationErrorConstants.UNABLE_TO_PROCESS.getErrorCode(),
IdAuthenticationErrorConstants.UNABLE_TO_PROCESS.getErrorMessage());
return new ResponseEntity<>(buildExceptionResponse(ex, servletRequest), HttpStatus.OK);
} else {
return handleAllExceptions(ex, request);
}
}
/**
* Method to handle and customize the response.
*
* @param ex Exception
* @param request Web request
* @return ResponseEntity containing error response object and http status.
*/
@ExceptionHandler(IdAuthenticationBaseException.class)
protected ResponseEntity handleIdAppException(IdAuthenticationBaseException ex, WebRequest request) {
mosipLogger.debug(IdAuthCommonConstants.SESSION_ID, ID_AUTHENTICATION_APP_EXCEPTION,
"Entered handleIdUsageException", PREFIX_HANDLING_EXCEPTION + ex.getClass().toString());
mosipLogger.error(IdAuthCommonConstants.SESSION_ID, ID_AUTHENTICATION_APP_EXCEPTION, ex.getErrorCode(),
ex.toString() + "\n Status returned: " + HttpStatus.OK + ExceptionUtils.getStackTrace(ex));
BaseCheckedException e = ex;
while (e.getCause() != null) {
if (e.getCause() instanceof BaseCheckedException
&& !e.getCause().getClass().isAssignableFrom(RestServiceException.class)) {
e = (BaseCheckedException) e.getCause();
} else if (e.getCause() instanceof BaseCheckedException) {
if(e.getCause() instanceof IdAuthenticationBaseException) {
e = (IdAuthenticationBaseException) e.getCause();
} else {
e = new IdAuthenticationAppException(((BaseCheckedException) e.getCause()).getErrorCode(),
((BaseCheckedException) e.getCause()).getErrorText());
}
break;
} else {
break;
}
}
return new ResponseEntity<>(buildExceptionResponse(e, servletRequest), HttpStatus.OK);
}
/**
* Constructs exception response body for all exceptions.
*
* @param ex the exception occurred
* @param request the request
* @return Object .
*/
public static Object buildExceptionResponse(Exception ex, HttpServletRequest request) {
List errors = getAuthErrors(ex);
return buildExceptionResponse(ex, request, errors);
}
public static Object buildExceptionResponse(Exception ex, HttpServletRequest request, List errors) {
mosipLogger.debug(IdAuthCommonConstants.SESSION_ID, "Building exception response",
"Entered buildExceptionResponse", PREFIX_HANDLING_EXCEPTION + ex.getClass().toString());
String type = null;
String contextPath = request.getRequestURL().toString();
String[] splitedContext = contextPath.split("/");
String requestReceived = splitedContext.length >= 5 ? splitedContext[5] : "";
if (requestReceived.equalsIgnoreCase("internal")) {
String reqUrl = request.getRequestURL().toString();
type = fetchInternalAuthtype(reqUrl);
}
if (errors != null && !errors.isEmpty()) {
Object response = frameErrorResponse(requestReceived, type, errors);
//Try copying ID, version and transaction ID from request metadata
if(request instanceof ObjectWithMetadata && response instanceof ObjectWithIdVersionTransactionID) {
ObjectWithMetadata requestWithMetadata = (ObjectWithMetadata) request;
ObjectWithIdVersionTransactionID responsWithMetadata = (ObjectWithIdVersionTransactionID) response;
if(requestWithMetadata.getMetadata() != null) {
IdaRequestResponsConsumerUtil.setIdVersionToResponse(requestWithMetadata, responsWithMetadata);
IdaRequestResponsConsumerUtil.setTransactionIdToResponse(requestWithMetadata, responsWithMetadata);
}
}
//Try copying ID, version and transaction ID from exception metadata
if(ex instanceof ObjectWithMetadata && response instanceof ObjectWithIdVersionTransactionID) {
ObjectWithMetadata exceptionWithMetadata = (ObjectWithMetadata) ex;
ObjectWithIdVersionTransactionID responsWithMetadata = (ObjectWithIdVersionTransactionID) response;
if(exceptionWithMetadata.getMetadata() != null) {
IdaRequestResponsConsumerUtil.setIdVersionToResponse(exceptionWithMetadata, responsWithMetadata);
IdaRequestResponsConsumerUtil.setTransactionIdToResponse(exceptionWithMetadata, responsWithMetadata);
}
}
if(ex instanceof ObjectWithMetadata) {
ObjectWithMetadata exceptionWithMetadata = (ObjectWithMetadata) ex;
//This errors list is used some times by the caller for storing in auth transaction
exceptionWithMetadata.putMetadata(IdAuthCommonConstants.ERRORS, errors);
}
mosipLogger.debug(IdAuthCommonConstants.SESSION_ID, "Response", ex.getClass().getName(),
response.toString());
return response;
}
return null;
}
public static List getAuthErrors(Exception ex) {
List errors;
if (ex instanceof IdAuthenticationBaseException) {
IdAuthenticationBaseException baseException = (IdAuthenticationBaseException) ex;
List errorCodes = ((BaseCheckedException) ex).getCodes();
List errorMessages = ((BaseCheckedException) ex).getErrorTexts();
// Retrived error codes and error messages are in reverse order.
Collections.reverse(errorCodes);
Collections.reverse(errorMessages);
if (ex instanceof IDDataValidationException) {
IDDataValidationException validationException = (IDDataValidationException) ex;
List args = validationException.getArgs();
List actionArgs = validationException.getActionargs();
errors = IntStream.range(0, errorCodes.size()).mapToObj(i -> {
String errorMessage;
if (args != null && !args.isEmpty()) {
if(args.get(i) != null) {
errorMessage = String.format(errorMessages.get(i), args.get(i));
} else {
errorMessage = errorMessages.get(i);
}
} else {
errorMessage = errorMessages.get(i);
}
String actionMessage;
if (args != null && !args.isEmpty() && actionArgs != null && !actionArgs.isEmpty()) {
if(actionArgs.get(i) != null && args.get(i) != null) {
actionMessage = String.format(actionArgs.get(i), args.get(i));
} else {
actionMessage = actionArgs.get(i);
}
} else {
if(actionArgs != null && actionArgs.size() > (i + 1)) {
actionMessage = actionArgs.get(i);
} else {
actionMessage = null;
}
}
return createAuthError(validationException, errorCodes.get(i), errorMessage, actionMessage);
}).distinct().collect(Collectors.toList());
} else {
errors = IntStream.range(0, errorCodes.size())
.mapToObj(i -> createAuthError(baseException, errorCodes.get(i), errorMessages.get(i), null))
.distinct().collect(Collectors.toList());
}
} else {
errors = Collections.emptyList();
}
return errors;
}
private static String fetchInternalAuthtype(String reqURL) {
String type = null;
if (reqURL != null && !reqURL.isEmpty()) {
String[] path = reqURL.split(INTERNAL);
if (path.length > 1 && path[1] != null && !path[1].isEmpty()) {
String[] urlPath = path[1].split("/");
String contextPath = urlPath[1];
if (!StringUtils.isEmpty(contextPath)) {
if (contextPath.equalsIgnoreCase(IdAuthCommonConstants.OTP)) {
type = IdAuthCommonConstants.OTP;
} else if (contextPath.equalsIgnoreCase(IdAuthCommonConstants.AUTH_TRANSACTIONS)) {
type = IdAuthCommonConstants.AUTH_TRANSACTIONS;
} else if (contextPath.equalsIgnoreCase(IdAuthCommonConstants.AUTH_TYPE)) {
type = IdAuthCommonConstants.AUTH_TYPE;
}else if (contextPath.equalsIgnoreCase(IdAuthCommonConstants.PUBLICKEY)) {
type = IdAuthCommonConstants.PUBLICKEY;
}else if (contextPath.equalsIgnoreCase(IdAuthCommonConstants.ENCRYPT)) {
type = IdAuthCommonConstants.ENCRYPT;
}else if (contextPath.equalsIgnoreCase(IdAuthCommonConstants.DECRYPT)) {
type = IdAuthCommonConstants.DECRYPT;
}else if (contextPath.equalsIgnoreCase(IdAuthCommonConstants.VERIFY)) {
type = IdAuthCommonConstants.VERIFY;
}else if (contextPath.equalsIgnoreCase(IdAuthCommonConstants.VALIDATESIGN)) {
type = IdAuthCommonConstants.VALIDATESIGN;
}else if (contextPath.equalsIgnoreCase(IdAuthCommonConstants.HOTLIST)) {
type = IdAuthCommonConstants.HOTLIST;
}
}
}
}
return type;
}
/**
* This method used to construct response respective to the request received
*
* @param requestReceived the fetched for the servlet path
* @param errors the errors
* @return the object
*/
private static Object frameErrorResponse(String requestReceived, String type, List errors) {
String responseTime = DateUtils.formatToISOString(DateUtils.getUTCCurrentDateTime());
switch (requestReceived) {
case "kyc":
KycAuthResponseDTO kycAuthResponseDTO = new KycAuthResponseDTO();
KycResponseDTO kycResponse = new KycResponseDTO();
kycResponse.setKycStatus(false);
kycAuthResponseDTO.setResponse(kycResponse);
kycAuthResponseDTO.setErrors(errors);
kycAuthResponseDTO.setResponseTime(responseTime);
return kycAuthResponseDTO;
case "otp":
OtpResponseDTO otpResponseDTO = new OtpResponseDTO();
otpResponseDTO.setErrors(errors);
otpResponseDTO.setResponseTime(responseTime);
return otpResponseDTO;
case "internal":
if (Objects.nonNull(type) && type.equalsIgnoreCase(IdAuthCommonConstants.OTP)) {
OtpResponseDTO internalotpresponsedto = new OtpResponseDTO();
internalotpresponsedto.setErrors(errors);
internalotpresponsedto.setResponseTime(responseTime);
return internalotpresponsedto;
} else if (Objects.nonNull(type) && type.equalsIgnoreCase(IdAuthCommonConstants.AUTH_TRANSACTIONS)) {
AutnTxnResponseDto autnTxnResponseDto = new AutnTxnResponseDto();
autnTxnResponseDto.setErrors(errors);
autnTxnResponseDto.setResponseTime(responseTime);
return autnTxnResponseDto;
} else if (Objects.nonNull(type) && type.equalsIgnoreCase(IdAuthCommonConstants.AUTH_TYPE)) {
AuthtypeResponseDto authtypeResponseDto = new AuthtypeResponseDto();
authtypeResponseDto.setErrors(errors);
authtypeResponseDto.setResponseTime(responseTime);
return authtypeResponseDto;
}else if (Objects.nonNull(type) && type.equalsIgnoreCase(IdAuthCommonConstants.DECRYPT)) {
AuthtypeResponseDto authtypeResponseDto = new AuthtypeResponseDto();
authtypeResponseDto.setErrors(errors);
authtypeResponseDto.setResponseTime(responseTime);
return authtypeResponseDto;
}else if (Objects.nonNull(type) && type.equalsIgnoreCase(IdAuthCommonConstants.ENCRYPT)) {
AuthtypeResponseDto authtypeResponseDto = new AuthtypeResponseDto();
authtypeResponseDto.setErrors(errors);
authtypeResponseDto.setResponseTime(responseTime);
return authtypeResponseDto;
}else if (Objects.nonNull(type) && type.equalsIgnoreCase(IdAuthCommonConstants.PUBLICKEY)) {
AuthtypeResponseDto authtypeResponseDto = new AuthtypeResponseDto();
authtypeResponseDto.setErrors(errors);
authtypeResponseDto.setResponseTime(responseTime);
return authtypeResponseDto;
}else if (Objects.nonNull(type) && type.equalsIgnoreCase(IdAuthCommonConstants.VERIFY)) {
AuthtypeResponseDto authtypeResponseDto = new AuthtypeResponseDto();
authtypeResponseDto.setErrors(errors);
authtypeResponseDto.setResponseTime(responseTime);
return authtypeResponseDto;
}else if (Objects.nonNull(type) && type.equalsIgnoreCase(IdAuthCommonConstants.VALIDATESIGN)) {
AuthtypeResponseDto authtypeResponseDto = new AuthtypeResponseDto();
authtypeResponseDto.setErrors(errors);
authtypeResponseDto.setResponseTime(responseTime);
return authtypeResponseDto;
}else if (Objects.nonNull(type) && type.equalsIgnoreCase(IdAuthCommonConstants.HOTLIST)) {
HotlistResponseDTO hotlistResponseDto = new HotlistResponseDTO();
hotlistResponseDto.setErrors(errors);
hotlistResponseDto.setResponseTime(responseTime);
return hotlistResponseDto;
}
default:
AuthResponseDTO authResp = new AuthResponseDTO();
ResponseDTO res = new ResponseDTO();
authResp.setErrors(errors);
authResp.setResponse(res);
authResp.setResponseTime(responseTime);
return authResp;
}
}
/**
* Creates the auth error based on ActionItem.
*
* @param authException the auth exception
* @param errorCode the error code
* @param errorMessage the error message
* @param actionMessage the action message
* @return the auth error
*/
private static AuthError createAuthError(IdAuthenticationBaseException authException, String errorCode,
String errorMessage, String actionMessage) {
String actionMessageEx = authException.getActionMessage();
AuthError err;
if (actionMessageEx == null) {
actionMessageEx = actionMessage;
}
if (actionMessageEx == null || actionMessageEx.isEmpty()) {
err = new AuthError(errorCode, errorMessage);
} else {
err = new ActionableAuthError(errorCode, errorMessage, actionMessageEx);
}
return err;
}
}