package net.gepafin.tendermanagement.util; import com.fasterxml.jackson.databind.ObjectMapper; import io.jsonwebtoken.Claims; import jakarta.persistence.Table; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import net.gepafin.tendermanagement.config.CachedBodyHttpServletRequest; import net.gepafin.tendermanagement.config.jwt.TokenProvider; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.UserActionEntity; import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.entities.VersionHistoryEntity; import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.model.util.LogResponse; import net.gepafin.tendermanagement.repositories.UserActionsRepository; import net.gepafin.tendermanagement.repositories.VersionHistoryRepository; import net.gepafin.tendermanagement.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.context.annotation.RequestScope; @Slf4j @Component @RequestScope public class LoggingUtil { @Autowired private UserActionsRepository userActionsRepository; @Autowired private VersionHistoryRepository versionHistoryRepository; @Autowired private UserService userService; @Autowired TokenProvider tokenProvider; public UserActionEntity logUserAction(UserActionRequest userActionRequest) { UserActionEntity userAction = new UserActionEntity(); try { String token = tokenProvider.extractTokenFromRequest(userActionRequest.getRequest()); Claims claims = tokenProvider.getClaimsFromToken(token); Long userId = claims.get(GepafinConstant.USER_ID, Long.class); Long loginAttemptId = claims.get(GepafinConstant.LOGIN_ATTEMPT_ID, Long.class); UserEntity userEntity = userService.validateUser(userId); String requestBody = null; if (userActionRequest.getRequest() instanceof CachedBodyHttpServletRequest cachedRequest) { requestBody = cachedRequest.getCachedBodyAsString(); } userAction.setActionType(userActionRequest.getActionType().getValue()); userAction.setUserId(userId); userAction.setActionContext(userActionRequest.getActionContext().getValue()); userAction.setMethodType(userActionRequest.getRequest().getMethod()); userAction.setHubId(userEntity.getHub().getId()); userAction.setUrl(userActionRequest.getRequest().getRequestURI()); userAction.setLoginAttemptId(loginAttemptId); userAction.setIpAddress(IpAddressUtils.getClientIp(userActionRequest.getRequest())); userAction.setRequestBody(requestBody); userAction.setResponse(null); userActionsRepository.save(userAction); userActionRequest.getRequest().setAttribute(GepafinConstant.USER_ACTION_ID, userAction.getId()); } catch (Exception e) { log.error("Error logging user action: {}", e.getMessage(), e); } return userAction; } // @Transactional // public UserActionEntity updateUserAction(HttpServletResponse response, UserActionEntity userAction) { // try { // String requestBody = null; // if (userAction. instanceof CachedBodyHttpServletRequest cachedRequest) { // requestBody = cachedRequest.getCachedBodyAsString(); // } // // LogResponse logResponse = new LogResponse<>(); // logResponse.setStatus(response.getStatus()); // logResponse.setStatusCode(String.valueOf(response.getStatus())); // logResponse.setMessage("SUCCESS"); // // String serializedResponse; // try { // ObjectMapper objectMapper = new ObjectMapper(); // serializedResponse = objectMapper.writeValueAsString(logResponse); // } catch (Exception e) { // serializedResponse = "Error serializing LogResponse: " + e.getMessage(); // } // // userAction.setResponse(serializedResponse); // userActionsRepository.save(userAction); // } catch (Exception e) { // log.error("Error updating user action: {}", e.getMessage(), e); // } // return userAction; // } public void logVersionHistory(VersionHistoryRequest versionHistoryRequest, Long recordId, Long userActionId, String tableName) { try { VersionHistoryEntity history = new VersionHistoryEntity(); String token = tokenProvider.extractTokenFromRequest(versionHistoryRequest.getRequest()); Claims claims = tokenProvider.getClaimsFromToken(token); Long userId = claims.get(GepafinConstant.USER_ID, Long.class); String oldData = Utils.convertEntityToJsonForLogging(versionHistoryRequest.getOldData()); String newData = Utils.convertEntityToJsonForLogging(versionHistoryRequest.getNewData()); history.setUserActionId(userActionId); history.setActionType(versionHistoryRequest.getActionType().getValue()); history.setOldData(oldData); history.setNewData(newData); history.setRecordId(recordId); history.setTableName(tableName); history.setUserId(userId); versionHistoryRepository.save(history); } catch (Exception e) { log.error("Error logging version history: {}", e.getMessage(), e); } } public String getTableName(Class entityClass) { try { if (entityClass.isAnnotationPresent(Table.class)) { Table tableAnnotation = entityClass.getAnnotation(Table.class); return tableAnnotation.name(); } } catch (Exception e) { log.error("Error retrieving table name: {}", e.getMessage(), e); } return null; } public void addVersionHistory(VersionHistoryRequest versionHistoryRequest) { try { Long userActionId = (Long) versionHistoryRequest.getRequest().getAttribute(GepafinConstant.USER_ACTION_ID); Long recordId = versionHistoryRequest.getNewData().getId(); String tableName = getTableName(versionHistoryRequest.getNewData().getClass()); logVersionHistory(versionHistoryRequest, recordId, userActionId, tableName); } catch (Exception e) { log.error("Error adding version history: {}", e.getMessage(), e); } } }