Resolved conflicts
This commit is contained in:
@@ -41,6 +41,8 @@ public class LoggingUtil {
|
||||
@Autowired
|
||||
private TokenProvider tokenProvider;
|
||||
|
||||
private static final ThreadLocal<Long> userActionIdHolder = new ThreadLocal<>();
|
||||
|
||||
public UserActionEntity logUserAction(UserActionRequest userActionRequest) {
|
||||
UserActionEntity userAction = new UserActionEntity();
|
||||
try {
|
||||
@@ -83,12 +85,22 @@ public class LoggingUtil {
|
||||
userAction.setResponse(response);
|
||||
userActionsRepository.save(userAction);
|
||||
userActionRequest.getRequest().setAttribute(GepafinConstant.USER_ACTION_ID, userAction.getId());
|
||||
userActionIdHolder.set(userAction.getId());
|
||||
} catch (Exception e) {
|
||||
log.error("Error logging user action: {}", e.getMessage(), e);
|
||||
}
|
||||
return userAction;
|
||||
}
|
||||
|
||||
public Long getUserActionId() {
|
||||
return userActionIdHolder.get();
|
||||
}
|
||||
|
||||
public void clearUserActionId() {
|
||||
userActionIdHolder.remove();
|
||||
log.info("UserActionId cleared from ThreadLocal");
|
||||
}
|
||||
|
||||
private String normalizeUrl(String url) {
|
||||
|
||||
url = url.replaceAll("(?<!:)//+", "/");
|
||||
@@ -263,6 +275,7 @@ public class LoggingUtil {
|
||||
userAction.setResponse(response);
|
||||
userActionsRepository.save(userAction);
|
||||
userActionRequest.getRequest().setAttribute(GepafinConstant.USER_ACTION_ID, userAction.getId());
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Error logging user action: {}", e.getMessage(), e);
|
||||
}
|
||||
@@ -323,10 +336,35 @@ public class LoggingUtil {
|
||||
|
||||
public UserActionEntity getUserActionLogById(Long id) {
|
||||
|
||||
return userActionsRepository.findUserActionById(id);
|
||||
return userActionsRepository.findUserActionByIdAndIsDeletedFalse(id);
|
||||
}
|
||||
public List<VersionHistoryEntity> getVersionHistoryLogById(Long id) {
|
||||
|
||||
return versionHistoryRepository.findVersionHistoryByUserActionId(id);
|
||||
}
|
||||
|
||||
public void updateUserActionWithError(Long userActionId, String errorDetails) {
|
||||
if (userActionId == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
UserActionEntity userAction = userActionsRepository.findUserActionByIdAndIsDeletedFalse(userActionId);
|
||||
if (userAction != null) {
|
||||
userAction.setResponse(errorDetails);
|
||||
userActionsRepository.save(userAction);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateUserActionWithResponse(Long userActionId, String response) {
|
||||
if (userActionId == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
UserActionEntity userAction = userActionsRepository.findUserActionByIdAndIsDeletedFalse(userActionId);
|
||||
if (userAction != null) {
|
||||
userAction.setResponse(response);
|
||||
userActionsRepository.save(userAction);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
package net.gepafin.tendermanagement.util;
|
||||
|
||||
import com.amazonaws.services.alexaforbusiness.model.UnauthorizedException;
|
||||
import jakarta.persistence.EntityNotFoundException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.gepafin.tendermanagement.constants.GepafinConstant;
|
||||
import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException;
|
||||
import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException;
|
||||
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.MissingServletRequestParameterException;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.nio.file.AccessDeniedException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
@Slf4j
|
||||
public class UserActionAspect {
|
||||
|
||||
@Autowired
|
||||
private LoggingUtil loggingUtil;
|
||||
|
||||
@Around("execution(public * net.gepafin.tendermanagement.web.rest.api.impl..*(..))")
|
||||
public Object logApiResponse(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
|
||||
Object result;
|
||||
|
||||
HttpServletRequest request = getRequestFromContext();
|
||||
try {
|
||||
Long userActionId = getUserActionIdFromRequest(request);
|
||||
|
||||
if (userActionId != null) {
|
||||
request.setAttribute(GepafinConstant.USER_ACTION_ID, userActionId);
|
||||
log.info("Stored userActionId in RequestContext: {}", userActionId);
|
||||
} else {
|
||||
userActionId = loggingUtil.getUserActionId();
|
||||
if (userActionId != null) {
|
||||
request.setAttribute(GepafinConstant.USER_ACTION_ID, userActionId);
|
||||
}
|
||||
}
|
||||
|
||||
result = joinPoint.proceed();
|
||||
|
||||
if (result instanceof ResponseEntity<?>) {
|
||||
Long storedUserActionId = (Long) request.getAttribute(GepafinConstant.USER_ACTION_ID);
|
||||
handleSuccessResponse((ResponseEntity<?>) result, storedUserActionId == null ? userActionId : storedUserActionId);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
log.error("Exception occurred: ", ex);
|
||||
handleError(ex, getUserActionIdFromRequest(request));
|
||||
throw ex;
|
||||
} finally {
|
||||
loggingUtil.clearUserActionId();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void handleSuccessResponse(ResponseEntity<?> responseEntity, Long userActionId) {
|
||||
|
||||
if (userActionId != null) {
|
||||
Map<String, Object> responseWithUserAction = new LinkedHashMap<>();
|
||||
responseWithUserAction.put(GepafinConstant.STATUS_CODE_STRING, responseEntity.getStatusCode().value());
|
||||
|
||||
// Log and update user action
|
||||
loggingUtil.updateUserActionWithResponse(userActionId, Utils.convertMapIntoJsonString(responseWithUserAction));
|
||||
log.info("Updated userActionId with response: {}", userActionId);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleError(Throwable ex, Long userActionId) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {
|
||||
|
||||
HttpStatus status = getStatusCodeFromException(ex);
|
||||
log.info("Status Code received from exception : {}", status);
|
||||
String errorMessage = ex.getMessage();
|
||||
|
||||
Map<String, Object> errorResponse = new LinkedHashMap<>();
|
||||
errorResponse.put(GepafinConstant.STATUS_CODE_STRING, status.value());
|
||||
errorResponse.put(GepafinConstant.GET_STATUS_CODE_STRING, status);
|
||||
errorResponse.put(GepafinConstant.MESSAGE_STRING, errorMessage);
|
||||
|
||||
if (userActionId != null) {
|
||||
String errorDetails = Utils.convertMapIntoJsonString(errorResponse);
|
||||
loggingUtil.updateUserActionWithError(userActionId, errorDetails);
|
||||
log.info("Updated userActionId with error details: {}", userActionId);
|
||||
}
|
||||
}
|
||||
|
||||
private HttpServletRequest getRequestFromContext() {
|
||||
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
return attributes != null ? attributes.getRequest() : null;
|
||||
}
|
||||
|
||||
private Long getUserActionIdFromRequest(HttpServletRequest request) {
|
||||
|
||||
if (request != null) {
|
||||
Object userActionIdAttr = request.getAttribute(GepafinConstant.USER_ACTION_ID);
|
||||
return userActionIdAttr != null ? Long.valueOf(userActionIdAttr.toString()) : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private HttpStatus getStatusCodeFromException(Throwable ex) {
|
||||
|
||||
if (ex instanceof ResourceNotFoundException) {
|
||||
return HttpStatus.NOT_FOUND;
|
||||
}
|
||||
|
||||
if (ex instanceof ResponseStatusException responseStatusException) {
|
||||
return (HttpStatus) responseStatusException.getStatusCode();
|
||||
}
|
||||
|
||||
if (ex instanceof CustomValidationException) {
|
||||
return HttpStatus.BAD_REQUEST;
|
||||
}
|
||||
|
||||
if (ex instanceof EntityNotFoundException) {
|
||||
return HttpStatus.NOT_FOUND;
|
||||
}
|
||||
if (ex instanceof IllegalArgumentException || ex instanceof MissingServletRequestParameterException || ex instanceof MethodArgumentNotValidException) {
|
||||
return HttpStatus.BAD_REQUEST;
|
||||
}
|
||||
if (ex instanceof AccessDeniedException) {
|
||||
return HttpStatus.FORBIDDEN;
|
||||
}
|
||||
if (ex instanceof UnauthorizedException) {
|
||||
return HttpStatus.UNAUTHORIZED;
|
||||
}
|
||||
|
||||
return HttpStatus.INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import net.gepafin.tendermanagement.config.Translator;
|
||||
import net.gepafin.tendermanagement.constants.GepafinConstant;
|
||||
import net.gepafin.tendermanagement.model.request.GlobalFilters;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
@@ -154,6 +155,9 @@ public class Utils {
|
||||
public static String convertMapIntoJsonString(Map<String, Object> map) {
|
||||
try {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.registerModule(new JavaTimeModule());
|
||||
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||||
mapper.enable(SerializationFeature.INDENT_OUTPUT);
|
||||
if (MapUtils.isNotEmpty(map)) {
|
||||
return mapper.writeValueAsString(map);
|
||||
}
|
||||
@@ -207,7 +211,7 @@ public class Utils {
|
||||
return new String(decodedBytes, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
public static String generateSecureToken() {
|
||||
public static String generateSecureSamlToken() {
|
||||
SecureRandom secureRandom = new SecureRandom();
|
||||
byte[] tokenBytes = new byte[24];
|
||||
secureRandom.nextBytes(tokenBytes);
|
||||
@@ -215,7 +219,14 @@ public class Utils {
|
||||
log.debug("Generated secure token: {}", token);
|
||||
return token;
|
||||
}
|
||||
|
||||
public static String generateSecureToken() {
|
||||
SecureRandom secureRandom = new SecureRandom();
|
||||
byte[] tokenBytes = new byte[5];
|
||||
secureRandom.nextBytes(tokenBytes);
|
||||
String token = Base64.getUrlEncoder().withoutPadding().encodeToString(tokenBytes);
|
||||
log.debug("Generated secure token: {}", token);
|
||||
return token;
|
||||
}
|
||||
public static Map<String, List<Object>> convertStringIntoMap(String jsonString) {
|
||||
try {
|
||||
return mapper.readValue(jsonString, new TypeReference<Map<String, List<Object>>>() {
|
||||
@@ -703,4 +714,22 @@ public class Utils {
|
||||
}
|
||||
return globalFilters;
|
||||
}
|
||||
|
||||
public static Map<String, Object> parseErrorResponse(String responseBody) {
|
||||
if (StringUtils.isBlank(responseBody)) {
|
||||
return defaultErrorResponse();
|
||||
}
|
||||
try {
|
||||
return mapper.readValue(responseBody, Map.class);
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to parse error response: {}", e.getMessage(), e);
|
||||
return defaultErrorResponse();
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<String, Object> defaultErrorResponse() {
|
||||
return Collections.singletonMap("message", Translator.toLocale(GepafinConstant.INVALID_VATNUMBER));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user