diff --git a/README.md b/README.md index 6d00657..a7cc141 100644 --- a/README.md +++ b/README.md @@ -215,3 +215,9 @@ Without the annotation, it defaults to the controller class name, method name, a ## License MIT License + +## Configuration + +| Property | Default | Description | +|---|---|---| +| `logdispatch.health.rate-limit-per-minute` | 60 | Maximum requests per minute for the health check endpoint | diff --git a/src/main/java/in/maheshlangote/logdispatch/LogDispatchHealthController.java b/src/main/java/in/maheshlangote/logdispatch/LogDispatchHealthController.java index ee43fef..33d113e 100644 --- a/src/main/java/in/maheshlangote/logdispatch/LogDispatchHealthController.java +++ b/src/main/java/in/maheshlangote/logdispatch/LogDispatchHealthController.java @@ -6,6 +6,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import org.springframework.beans.factory.annotation.Value; import java.time.Instant; import java.util.HashMap; @@ -23,10 +24,12 @@ public class LogDispatchHealthController { private final Instant startupTime; - // Rate Limiting (60 requests per minute per IP) + // Rate Limiting (configurable requests per minute per IP) private final ConcurrentHashMap requestCounts = new ConcurrentHashMap<>(); private long currentWindowStart = System.currentTimeMillis(); - private static final int MAX_REQUESTS_PER_MINUTE = 60; + @Value("${logdispatch.health.rate-limit-per-minute:60}") + private int maxRequestsPerMinute; + private static final long WINDOW_SIZE_MS = 60000; /** @@ -37,12 +40,12 @@ public LogDispatchHealthController() { } /** - * Returns the health status and uptime of the application. - * Enforces a rate limit of 60 requests per minute per IP. - * - * @param request the HTTP request, used to determine the client IP - * @return a ResponseEntity containing the status, startup time, and uptime - */ + * Returns the health status and uptime of the application. + * Enforces a configurable rate limit per IP. + * + * @param request the HTTP request, used to determine the client IP + * @return a ResponseEntity containing the status, startup time, and uptime + */ @GetMapping public ResponseEntity> healthCheck(HttpServletRequest request) { String clientIp = getClientIp(request); @@ -50,7 +53,7 @@ public ResponseEntity> healthCheck(HttpServletRequest reques if (!isAllowed(clientIp)) { Map errorResponse = new HashMap<>(); errorResponse.put("status", "RATE_LIMITED"); - errorResponse.put("message", "Too many requests. Limit is 60 requests per minute."); + errorResponse.put("message", "Too many requests. Limit is " + maxRequestsPerMinute + " requests per minute."); return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS).body(errorResponse); } @@ -77,7 +80,7 @@ private boolean isAllowed(String ip) { } int count = requestCounts.computeIfAbsent(ip, k -> new AtomicInteger(0)).incrementAndGet(); - return count <= MAX_REQUESTS_PER_MINUTE; + return count <= maxRequestsPerMinute; } private String getClientIp(HttpServletRequest request) { diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..9ad281c --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,3 @@ +logdispatch: + health: + rate-limit-per-minute: 60