RateLimitDecorator.java
package com.designpatterns.structural.decorator.applied;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class RateLimitDecorator extends TransactionProcessorDecorator {
private final int maxCallsPerPayer;
private final Map<String, Integer> callCounts = new ConcurrentHashMap<>();
public RateLimitDecorator(TransactionProcessor delegate, int maxCallsPerPayer) {
super(delegate);
this.maxCallsPerPayer = maxCallsPerPayer;
}
@Override
public ProcessingResult process(Transaction transaction) {
int count = callCounts.merge(transaction.payerId(), 1, Integer::sum);
if (count > maxCallsPerPayer) {
String note = "rate-limit: payer exceeded " + maxCallsPerPayer + " requests";
return new ProcessingResult(transaction.id(), false, List.of(note));
}
return delegate.process(transaction).withNote("rate-limit: within quota (" + count + "/" + maxCallsPerPayer + ")");
}
}