import java.util.*;
import java.util.concurrent.*;
import java.time.Instant;
import java.time.Duration;
public class TimestampAnomalyDetector {
private final int windowSize; // Time window for anomaly detection (in seconds)
private final int maxRequestsPerWindow; // Maximum requests allowed within the window
private final Queue<Long> timestamps; // Queue to store timestamps
private final Semaphore semaphore; // Semaphore for rate limiting
private final List<TimestampAnomaly> anomalies; // List to store detected anomalies
public TimestampAnomalyDetector(int windowSize, int maxRequestsPerWindow) {
this.windowSize = windowSize;
this.maxRequestsPerWindow = maxRequestsPerWindow;
this.timestamps = new LinkedList<>();
this.semaphore = new Semaphore(maxRequestsPerWindow);
this.anomalies = new ArrayList<>();
}
public synchronized boolean allowRequest() throws InterruptedException {
semaphore.acquire(); // Acquire a permit from the semaphore (rate limiting)
return true;
}
public synchronized void releaseRequest() {
semaphore.release(); // Release the permit
}
public TimestampAnomaly detectAnomalies() {
// Process timestamps and detect anomalies
long currentTime = Instant.now().getEpochSecond();
// Remove timestamps outside the current window
while (!timestamps.isEmpty() && (currentTime - timestamps.peek() > windowSize)) {
timestamps.poll();
}
// Check if the number of timestamps exceeds the rate limit
if (timestamps.size() > maxRequestsPerWindow) {
List<TimestampAnomaly> anomaly = new ArrayList<>();
anomaly.add(new TimestampAnomaly("Timestamp Exceeded Rate Limit", timestamps.size(), currentTime));
anomalies.addAll(anomaly);
timestamps.clear(); // Reset the timestamps
return anomaly.get(0);
}
return null; // No anomaly detected
}
public void addTimestamp(long timestamp) throws InterruptedException {
// Add a new timestamp to the queue
timestamps.offer(timestamp);
// Simulate processing time
try {
Thread.sleep(100); // Simulate some processing time
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
public List<TimestampAnomaly> getAnomalies() {
return anomalies;
}
// Inner class to represent a timestamp anomaly
public static class TimestampAnomaly {
private final String message;
private final int count;
private final long timestamp;
public TimestampAnomaly(String message, int count, long timestamp) {
this.message = message;
this.count = count;
this.timestamp = timestamp;
}
public String getMessage() {
return message;
}
public int getCount() {
return count;
}
public long getTimestamp() {
return timestamp;
}
}
public static void main(String[] args) throws InterruptedException {
// Example usage
TimestampAnomalyDetector detector = new TimestampAnomalyDetector(60, 10); // 60 seconds window, 10 requests/window
for (int i = 0; i < 15; i++) {
long timestamp = Instant.now().getEpochSecond() - (15 - i) * 30; // Generate timestamps
detector.addTimestamp(timestamp);
TimestampAnomaly anomaly = detector.detectAnomalies();
if (anomaly != null) {
System.out.println("Anomaly detected: " + anomaly.getMessage() + " at timestamp: " + anomaly.getTimestamp());
}
Thread.sleep(500);
}
List<TimestampAnomaly> allAnomalies = detector.getAnomalies();
System.out.println("Total Anomalies: " + allAnomalies.size());
}
}
Add your comment