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;
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;
}
@@ -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<ComplainStatus> complaintStatusList = new HashSet<>();
@@ -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);
@@ -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());