diff --git a/src/main/java/com/billpaymentservice/bbps/config/RateLimitingFilter.java b/src/main/java/com/billpaymentservice/bbps/config/RateLimitingFilter.java deleted file mode 100644 index 14ff370..0000000 --- a/src/main/java/com/billpaymentservice/bbps/config/RateLimitingFilter.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.billpaymentservice.bbps.config; - -import java.io.IOException; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import jakarta.servlet.FilterChain; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.core.annotation.Order; -import org.springframework.stereotype.Component; -import org.springframework.web.filter.OncePerRequestFilter; -import com.billpaymentservice.bbps.util.BBPSConstant; -import com.billpaymentservice.bbps.dto.ResponseModel; - -import io.github.resilience4j.ratelimiter.RateLimiter; -import io.github.resilience4j.ratelimiter.RateLimiterRegistry; -import com.fasterxml.jackson.databind.ObjectMapper; - -@Component -@Order(1) -public class RateLimitingFilter extends OncePerRequestFilter { - - private final RateLimiterRegistry rateLimiterRegistry; - private static final Logger LOGGER = LoggerFactory.getLogger(RateLimitingFilter.class); - - // Har MID ke liye alag limiter - private final Map limiterCache = new ConcurrentHashMap<>(); - - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); - - public RateLimitingFilter(RateLimiterRegistry rateLimiterRegistry) { - this.rateLimiterRegistry = rateLimiterRegistry; - } - - @Override - protected void doFilterInternal(HttpServletRequest request, - HttpServletResponse response, - FilterChain filterChain) - throws ServletException, IOException { - String mid = request.getHeader("mid"); - if(mid == null) { - mid = "GLOBAL"; - } - - // Validate MID - if (mid == null || mid.isBlank()) { - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - response.setContentType("application/json"); - - ResponseModel apiResponse = new ResponseModel<>("mid cannot be null or blank", "FAILURE", HttpServletResponse.SC_BAD_REQUEST, null); - response.getWriter().write(OBJECT_MAPPER.writeValueAsString(apiResponse)); - return; - } - - try { - RateLimiter rateLimiter = limiterCache.computeIfAbsent( - mid, - key -> rateLimiterRegistry.rateLimiter("default") - ); - - // Rate limit check - if (!rateLimiter.acquirePermission()) { - - // Prefer existing constant if it maps to 429, otherwise fallback to literal 429 - int tooManyRequestsStatus =429; - - response.setStatus(tooManyRequestsStatus); - response.setContentType("application/json"); - - ResponseModel apiResponse = new ResponseModel<>("Rate limit exceeded for MID: " + mid, "FAILURE", tooManyRequestsStatus, null); - response.getWriter().write(OBJECT_MAPPER.writeValueAsString(apiResponse)); - return; - } - - // Proceed with the chain and catch downstream exceptions to return consistent model - try { - filterChain.doFilter(request, response); - } catch (Exception ex) { - LOGGER.error("Unhandled exception in filter chain for MID: {}", mid, ex); - if (!response.isCommitted()) { - response.reset(); - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - response.setContentType("application/json"); - ResponseModel apiResponse = new ResponseModel<>("Internal server error", "FAILURE", HttpServletResponse.SC_INTERNAL_SERVER_ERROR, null); - response.getWriter().write(OBJECT_MAPPER.writeValueAsString(apiResponse)); - } - } - - } catch (Exception e) { - LOGGER.error("Error while rate limiting request", e); - if (!response.isCommitted()) { - response.reset(); - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - response.setContentType("application/json"); - ResponseModel apiResponse = new ResponseModel<>("Internal server error", "FAILURE", HttpServletResponse.SC_INTERNAL_SERVER_ERROR, null); - response.getWriter().write(OBJECT_MAPPER.writeValueAsString(apiResponse)); - } - return; - } - } - - @Override - protected boolean shouldNotFilter(HttpServletRequest request) { - - String path = request.getRequestURI(); - - return path.startsWith("/swagger") - || path.startsWith("/v3/api-docs") - || path.startsWith("/actuator"); - } -} \ No newline at end of file diff --git a/src/main/java/com/billpaymentservice/bbps/entites/Auditable.java b/src/main/java/com/billpaymentservice/bbps/entites/Auditable.java index 2359759..7ecb803 100644 --- a/src/main/java/com/billpaymentservice/bbps/entites/Auditable.java +++ b/src/main/java/com/billpaymentservice/bbps/entites/Auditable.java @@ -1,6 +1,7 @@ package com.billpaymentservice.bbps.entites; -import java.time.LocalDateTime; +import java.io.Serializable; +import java.util.Date; import jakarta.persistence.Column; import jakarta.persistence.EntityListeners; @@ -9,33 +10,34 @@ import lombok.Getter; import lombok.Setter; /** - * Base mapped superclass for audit fields. All JPA entities should extend this to - * get automatic population of createdAt/updatedAt/isDeleted via AuditListener. + * Base mapped superclass for audit fields. All JPA entities should extend this + * to get automatic population of createdAt/updatedAt/isDeleted via + * AuditListener. */ @MappedSuperclass @EntityListeners(AuditListener.class) @Getter @Setter -public abstract class Auditable { - @Column(name = "create_date_time") - private LocalDateTime createDateTime; +public abstract class Auditable implements Serializable { + @Column(name = "create_date_time") + private Date createDateTime; - @Column(name = "updated_date_time") - private LocalDateTime updatedDateTime; + @Column(name = "updated_date_time") + private Date updatedDateTime; - @Column(name = "create_by") - private LocalDateTime createdBy; + @Column(name = "create_by") + private String createdBy; - @Column(name = "updated_by") - private LocalDateTime updatedBy; + @Column(name = "updated_by") + private String updatedBy; - @Column(name = "created_epoch_date") - private Long createdEpochDate; + @Column(name = "created_epoch_date") + private Long createdEpochDate; - @Column(name = "modified_epoch_date") - private Long modifiedEpochDate; + @Column(name = "modified_epoch_date") + private Long modifiedEpochDate; + + @Column(name = "is_deleted") + private Boolean isDeleted = Boolean.FALSE; - @Column(name = "is_deleted") - private Boolean isDeleted = Boolean.FALSE; - } \ No newline at end of file diff --git a/src/main/java/com/billpaymentservice/bbps/entites/ComplaintResponseEntity.java b/src/main/java/com/billpaymentservice/bbps/entites/ComplaintResponseEntity.java index 88bdb17..a4b128a 100644 --- a/src/main/java/com/billpaymentservice/bbps/entites/ComplaintResponseEntity.java +++ b/src/main/java/com/billpaymentservice/bbps/entites/ComplaintResponseEntity.java @@ -77,6 +77,9 @@ public class ComplaintResponseEntity extends Auditable { @Column(name = "user_id") private String userId; + @Column(name = "mid") + private String mid; + @OneToMany(fetch = FetchType.LAZY) @JoinColumn(name = "ticket_id", referencedColumnName = "ticket_id", insertable = false, updatable = false) private Set complaintStatusList = new HashSet<>(); diff --git a/src/main/java/com/billpaymentservice/bbps/serviceImpl/ComplainServiceImpl.java b/src/main/java/com/billpaymentservice/bbps/serviceImpl/ComplainServiceImpl.java index 6676433..59a7b29 100644 --- a/src/main/java/com/billpaymentservice/bbps/serviceImpl/ComplainServiceImpl.java +++ b/src/main/java/com/billpaymentservice/bbps/serviceImpl/ComplainServiceImpl.java @@ -197,7 +197,7 @@ public class ComplainServiceImpl implements ComplainService { ComplaintResponse responseWrapper = objectMapper.convertValue(dataMap, ComplaintResponse.class); String saveComplaintResponseEntity = mapperHelper.saveComplaintResponseEntity(responseWrapper, requestId, - txnId, userId, requestTxnId); + txnId, userId, requestTxnId, mid); LOGGER.info("Save Complaint Response Count" + saveComplaintResponseEntity); ResponseModel responseModel = new ResponseModel(responseWrapper.getMessage(), responseWrapper.getStatus(), Integer.parseInt(responseWrapper.getStatusCode()), responseWrapper); diff --git a/src/main/java/com/billpaymentservice/bbps/util/BillerMapperHelper.java b/src/main/java/com/billpaymentservice/bbps/util/BillerMapperHelper.java index d67ac8b..580aeb8 100644 --- a/src/main/java/com/billpaymentservice/bbps/util/BillerMapperHelper.java +++ b/src/main/java/com/billpaymentservice/bbps/util/BillerMapperHelper.java @@ -6,6 +6,7 @@ import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Collections; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -528,6 +529,7 @@ public class BillerMapperHelper { entity.setNpciTicketStatus(dto.getNpciTicketStatus()); entity.setCreatedTime(dto.getCreatedTime()); entity.setUserId(userId); + entity.setCreateDateTime(new Date()); try { ComplainStatus saved = complaintStatusRepository.save(entity); @@ -558,7 +560,7 @@ public class BillerMapperHelper { entity.setReqId(reqId); entity.setTxnId(txnId); entity.setUserId(userId); - + entity.setCreateDateTime(new Date()); complaintHistoryRepository.save(entity); savedCount++; } @@ -673,6 +675,7 @@ public class BillerMapperHelper { entity.setPage(String.valueOf(responseWrapper.getPage())); entity.setPageSize(String.valueOf(responseWrapper.getPageSize())); entity.setUserId(userId); + entity.setCreateDateTime(new Date()); } @@ -852,6 +855,7 @@ public class BillerMapperHelper { entity.setTotalPages(String.valueOf(responseWrapper.getTotalPages())); entity.setTotalElements(String.valueOf(responseWrapper.getTotalElements())); entity.setUserId(userId); + entity.setCreateDateTime(new Date()); } @@ -962,9 +966,9 @@ public class BillerMapperHelper { LocalDateTime bmCreatedOn = parseToLocalDateTime(responseWrapper.getCreationDate()); LocalDateTime bmUpdatedOn = parseToLocalDateTime(responseWrapper.getModifiedDate()); - if (bmUpdatedOn != null) { - billMaster.setUpdatedDateTime(bmUpdatedOn); - } +// if (bmUpdatedOn != null) { +// billMaster.setUpdatedDateTime(bmUpdatedOn); +// } billMaster.setCreatedEpochDate(responseWrapper.getCreatedEpochDate()); billMaster.setModifiedEpochDate(responseWrapper.getModifiedEpochDate()); @@ -1091,21 +1095,27 @@ public class BillerMapperHelper { record.setClientUserId(request.getClientUserId()); record.setInternalTxnId(txnId); - if (apiResponse != null && - apiResponse.getResponseData() != null) { - record.setAmount(Optional.ofNullable(apiResponse.getResponseData().getAmount( - )).orElse("0.00")); - - record.setTxnId(Optional.ofNullable(apiResponse.getResponseData().getTxnId()) - .orElse("DUMMY_TXN")); - record.setQrString(Optional.ofNullable(apiResponse.getResponseData(). - getQrString()).orElse("NO_QR")); // parse createdOn string into LocalDateTime and set on Auditable - LocalDateTime createdOn =parseToLocalDateTime(apiResponse.getResponseData().getCreatedOn()); - - record.setTxnStatus("PENDING"); } else { record.setAmount("0.00"); - record.setTxnStatus("PENDING"); } - - + if (apiResponse != null && apiResponse.getResponseData() != null) { + record.setAmount(Optional.ofNullable(apiResponse.getResponseData().getAmount()).orElse("0.00")); + + record.setTxnId(Optional.ofNullable(apiResponse.getResponseData().getTxnId()).orElse("DUMMY_TXN")); + record.setQrString(Optional.ofNullable(apiResponse.getResponseData().getQrString()).orElse("NO_QR")); // parse + // createdOn + // string + // into + // LocalDateTime + // and + // set + // on + // Auditable + LocalDateTime createdOn = parseToLocalDateTime(apiResponse.getResponseData().getCreatedOn()); + + record.setTxnStatus("PENDING"); + } else { + record.setAmount("0.00"); + record.setTxnStatus("PENDING"); + } + // store the original request body and raw response record.setRequestBody(requestJson); record.setResponseBody(rawResponse); @@ -1151,7 +1161,7 @@ public class BillerMapperHelper { // Persist complaint response entity public String saveComplaintResponseEntity(ComplaintResponse responseWrapper, String requestId, String txnId, - String userId, String requestTxnId) { + String userId, String requestTxnId, String mid) { if (responseWrapper == null || responseWrapper.getTicketDetails() == null) { return "No data"; } @@ -1164,6 +1174,8 @@ public class BillerMapperHelper { complaintResponseEntity.setTicketDesp(responseWrapper.getTicketDetails().getTicketDesp()); complaintResponseEntity.setTicketDesr(responseWrapper.getTicketDetails().getTicketDesr()); complaintResponseEntity.setRequestTxnId(requestTxnId); + complaintResponseEntity.setMid(mid); + complaintResponseEntity.setCreateDateTime(new Date()); complaintResponseEntity.setMessage(responseWrapper.getMessage()); complaintResponseEntity.setRemarks(responseWrapper.getRemarks()); @@ -1273,7 +1285,7 @@ public class BillerMapperHelper { } } - public ComplaintResponseDto toDto(ComplaintResponseEntity e) { + public ComplaintResponseDto toDto(ComplaintResponseEntity e) { ComplaintResponseDto dto = new ComplaintResponseDto(); dto.setTicketId(e.getTicketId());