updated code

This commit is contained in:
Mohd-Arham
2025-12-19 12:15:32 +05:30
parent d3ae7decc8
commit 0197f6951f
5 changed files with 58 additions and 157 deletions
@@ -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<String, RateLimiter> 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<Object> 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<Object> 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<Object> 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<Object> 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");
}
}
@@ -1,6 +1,7 @@
package com.billpaymentservice.bbps.entites; package com.billpaymentservice.bbps.entites;
import java.time.LocalDateTime; import java.io.Serializable;
import java.util.Date;
import jakarta.persistence.Column; import jakarta.persistence.Column;
import jakarta.persistence.EntityListeners; import jakarta.persistence.EntityListeners;
@@ -9,33 +10,34 @@ import lombok.Getter;
import lombok.Setter; import lombok.Setter;
/** /**
* Base mapped superclass for audit fields. All JPA entities should extend this to * Base mapped superclass for audit fields. All JPA entities should extend this
* get automatic population of createdAt/updatedAt/isDeleted via AuditListener. * to get automatic population of createdAt/updatedAt/isDeleted via
* AuditListener.
*/ */
@MappedSuperclass @MappedSuperclass
@EntityListeners(AuditListener.class) @EntityListeners(AuditListener.class)
@Getter @Getter
@Setter @Setter
public abstract class Auditable { public abstract class Auditable implements Serializable {
@Column(name = "create_date_time") @Column(name = "create_date_time")
private LocalDateTime createDateTime; private Date createDateTime;
@Column(name = "updated_date_time") @Column(name = "updated_date_time")
private LocalDateTime updatedDateTime; private Date updatedDateTime;
@Column(name = "create_by") @Column(name = "create_by")
private LocalDateTime createdBy; private String createdBy;
@Column(name = "updated_by") @Column(name = "updated_by")
private LocalDateTime updatedBy; private String updatedBy;
@Column(name = "created_epoch_date") @Column(name = "created_epoch_date")
private Long createdEpochDate; private Long createdEpochDate;
@Column(name = "modified_epoch_date") @Column(name = "modified_epoch_date")
private Long modifiedEpochDate; private Long modifiedEpochDate;
@Column(name = "is_deleted")
private Boolean isDeleted = Boolean.FALSE;
@Column(name = "is_deleted")
private Boolean isDeleted = Boolean.FALSE;
} }
@@ -77,6 +77,9 @@ public class ComplaintResponseEntity extends Auditable {
@Column(name = "user_id") @Column(name = "user_id")
private String userId; private String userId;
@Column(name = "mid")
private String mid;
@OneToMany(fetch = FetchType.LAZY) @OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "ticket_id", referencedColumnName = "ticket_id", insertable = false, updatable = false) @JoinColumn(name = "ticket_id", referencedColumnName = "ticket_id", insertable = false, updatable = false)
private Set<ComplainStatus> complaintStatusList = new HashSet<>(); private Set<ComplainStatus> complaintStatusList = new HashSet<>();
@@ -197,7 +197,7 @@ public class ComplainServiceImpl implements ComplainService {
ComplaintResponse responseWrapper = objectMapper.convertValue(dataMap, ComplaintResponse.class); ComplaintResponse responseWrapper = objectMapper.convertValue(dataMap, ComplaintResponse.class);
String saveComplaintResponseEntity = mapperHelper.saveComplaintResponseEntity(responseWrapper, requestId, String saveComplaintResponseEntity = mapperHelper.saveComplaintResponseEntity(responseWrapper, requestId,
txnId, userId, requestTxnId); txnId, userId, requestTxnId, mid);
LOGGER.info("Save Complaint Response Count" + saveComplaintResponseEntity); LOGGER.info("Save Complaint Response Count" + saveComplaintResponseEntity);
ResponseModel responseModel = new ResponseModel(responseWrapper.getMessage(), responseWrapper.getStatus(), ResponseModel responseModel = new ResponseModel(responseWrapper.getMessage(), responseWrapper.getStatus(),
Integer.parseInt(responseWrapper.getStatusCode()), responseWrapper); Integer.parseInt(responseWrapper.getStatusCode()), responseWrapper);
@@ -6,6 +6,7 @@ import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -528,6 +529,7 @@ public class BillerMapperHelper {
entity.setNpciTicketStatus(dto.getNpciTicketStatus()); entity.setNpciTicketStatus(dto.getNpciTicketStatus());
entity.setCreatedTime(dto.getCreatedTime()); entity.setCreatedTime(dto.getCreatedTime());
entity.setUserId(userId); entity.setUserId(userId);
entity.setCreateDateTime(new Date());
try { try {
ComplainStatus saved = complaintStatusRepository.save(entity); ComplainStatus saved = complaintStatusRepository.save(entity);
@@ -558,7 +560,7 @@ public class BillerMapperHelper {
entity.setReqId(reqId); entity.setReqId(reqId);
entity.setTxnId(txnId); entity.setTxnId(txnId);
entity.setUserId(userId); entity.setUserId(userId);
entity.setCreateDateTime(new Date());
complaintHistoryRepository.save(entity); complaintHistoryRepository.save(entity);
savedCount++; savedCount++;
} }
@@ -673,6 +675,7 @@ public class BillerMapperHelper {
entity.setPage(String.valueOf(responseWrapper.getPage())); entity.setPage(String.valueOf(responseWrapper.getPage()));
entity.setPageSize(String.valueOf(responseWrapper.getPageSize())); entity.setPageSize(String.valueOf(responseWrapper.getPageSize()));
entity.setUserId(userId); entity.setUserId(userId);
entity.setCreateDateTime(new Date());
} }
@@ -852,6 +855,7 @@ public class BillerMapperHelper {
entity.setTotalPages(String.valueOf(responseWrapper.getTotalPages())); entity.setTotalPages(String.valueOf(responseWrapper.getTotalPages()));
entity.setTotalElements(String.valueOf(responseWrapper.getTotalElements())); entity.setTotalElements(String.valueOf(responseWrapper.getTotalElements()));
entity.setUserId(userId); entity.setUserId(userId);
entity.setCreateDateTime(new Date());
} }
@@ -962,9 +966,9 @@ public class BillerMapperHelper {
LocalDateTime bmCreatedOn = parseToLocalDateTime(responseWrapper.getCreationDate()); LocalDateTime bmCreatedOn = parseToLocalDateTime(responseWrapper.getCreationDate());
LocalDateTime bmUpdatedOn = parseToLocalDateTime(responseWrapper.getModifiedDate()); LocalDateTime bmUpdatedOn = parseToLocalDateTime(responseWrapper.getModifiedDate());
if (bmUpdatedOn != null) { // if (bmUpdatedOn != null) {
billMaster.setUpdatedDateTime(bmUpdatedOn); // billMaster.setUpdatedDateTime(bmUpdatedOn);
} // }
billMaster.setCreatedEpochDate(responseWrapper.getCreatedEpochDate()); billMaster.setCreatedEpochDate(responseWrapper.getCreatedEpochDate());
billMaster.setModifiedEpochDate(responseWrapper.getModifiedEpochDate()); billMaster.setModifiedEpochDate(responseWrapper.getModifiedEpochDate());
@@ -1091,21 +1095,27 @@ public class BillerMapperHelper {
record.setClientUserId(request.getClientUserId()); record.setClientUserId(request.getClientUserId());
record.setInternalTxnId(txnId); record.setInternalTxnId(txnId);
if (apiResponse != null && if (apiResponse != null && apiResponse.getResponseData() != null) {
apiResponse.getResponseData() != null) { record.setAmount(Optional.ofNullable(apiResponse.getResponseData().getAmount()).orElse("0.00"));
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
record.setTxnId(Optional.ofNullable(apiResponse.getResponseData().getTxnId()) // createdOn
.orElse("DUMMY_TXN")); // string
record.setQrString(Optional.ofNullable(apiResponse.getResponseData(). // into
getQrString()).orElse("NO_QR")); // parse createdOn string into LocalDateTime and set on Auditable // LocalDateTime
LocalDateTime createdOn =parseToLocalDateTime(apiResponse.getResponseData().getCreatedOn()); // and
// set
record.setTxnStatus("PENDING"); } else { record.setAmount("0.00"); // on
record.setTxnStatus("PENDING"); } // 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 // store the original request body and raw response
record.setRequestBody(requestJson); record.setRequestBody(requestJson);
record.setResponseBody(rawResponse); record.setResponseBody(rawResponse);
@@ -1151,7 +1161,7 @@ public class BillerMapperHelper {
// Persist complaint response entity // Persist complaint response entity
public String saveComplaintResponseEntity(ComplaintResponse responseWrapper, String requestId, String txnId, 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) { if (responseWrapper == null || responseWrapper.getTicketDetails() == null) {
return "No data"; return "No data";
} }
@@ -1164,6 +1174,8 @@ public class BillerMapperHelper {
complaintResponseEntity.setTicketDesp(responseWrapper.getTicketDetails().getTicketDesp()); complaintResponseEntity.setTicketDesp(responseWrapper.getTicketDetails().getTicketDesp());
complaintResponseEntity.setTicketDesr(responseWrapper.getTicketDetails().getTicketDesr()); complaintResponseEntity.setTicketDesr(responseWrapper.getTicketDetails().getTicketDesr());
complaintResponseEntity.setRequestTxnId(requestTxnId); complaintResponseEntity.setRequestTxnId(requestTxnId);
complaintResponseEntity.setMid(mid);
complaintResponseEntity.setCreateDateTime(new Date());
complaintResponseEntity.setMessage(responseWrapper.getMessage()); complaintResponseEntity.setMessage(responseWrapper.getMessage());
complaintResponseEntity.setRemarks(responseWrapper.getRemarks()); 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(); ComplaintResponseDto dto = new ComplaintResponseDto();
dto.setTicketId(e.getTicketId()); dto.setTicketId(e.getTicketId());