12
12
import io .micrometer .core .instrument .Counter ;
13
13
import io .micrometer .core .instrument .DistributionSummary ;
14
14
import io .micrometer .core .instrument .Gauge ;
15
+ import java .util .concurrent .atomic .AtomicLong ;
15
16
import lombok .extern .slf4j .Slf4j ;
16
17
import org .altcha .altcha .Altcha ;
17
18
import org .apache .commons .codec .digest .DigestUtils ;
@@ -29,6 +30,7 @@ public class CaptchaService {
29
30
private final Counter challengeCounter ;
30
31
private final Counter verifySuccessCounter ;
31
32
private final DistributionSummary tookTimeSummary ;
33
+ private final AtomicLong invalidatedPayloadCount = new AtomicLong (0 );
32
34
33
35
@ SuppressFBWarnings (value = { "EI_EXPOSE_REP2" }, justification = "Dependency Injection" )
34
36
public CaptchaService (final CaptchaProperties captchaProperties , final DifficultyService difficultyService ,
@@ -37,6 +39,9 @@ public CaptchaService(final CaptchaProperties captchaProperties, final Difficult
37
39
this .invalidatedPayloadRepository = invalidatedPayloadRepository ;
38
40
this .difficultyService = difficultyService ;
39
41
42
+ // Initialize counter with current count from database
43
+ this .invalidatedPayloadCount .set (invalidatedPayloadRepository .countByExpiresAtGreaterThan (Instant .now ()));
44
+
40
45
// Initialize metrics
41
46
this .challengeCounter = Counter .builder ("captcha.challenge.requests" )
42
47
.description ("Counter for captcha challenge requests" )
@@ -47,7 +52,7 @@ public CaptchaService(final CaptchaProperties captchaProperties, final Difficult
47
52
this .tookTimeSummary = DistributionSummary .builder ("captcha.verify.took.time" )
48
53
.description ("Summary of the time taken to verify captcha payloads" )
49
54
.register (registry );
50
- Gauge .builder ("captcha.invalidated.payloads" , invalidatedPayloadRepository , repo -> repo . countByExpiresAtGreaterThan ( Instant . now ()) )
55
+ Gauge .builder ("captcha.invalidated.payloads" , invalidatedPayloadCount , AtomicLong :: get )
51
56
.description ("Gauge for the number of currently invalidated payloads" )
52
57
.register (registry );
53
58
}
@@ -92,6 +97,7 @@ public boolean verify(final String siteKey, final ExtendedPayload payload) {
92
97
public void invalidatePayload (final Altcha .Payload payload ) {
93
98
final String payloadHash = getPayloadHash (payload );
94
99
final InvalidatedPayload invalidatedPayload = new InvalidatedPayload (payloadHash , Instant .now ().plusSeconds (captchaProperties .captchaTimeoutSeconds ()));
100
+ invalidatedPayloadCount .incrementAndGet ();
95
101
invalidatedPayloadRepository .save (invalidatedPayload );
96
102
log .debug ("Invalidated payloadHash: {}" , payloadHash );
97
103
}
@@ -113,4 +119,14 @@ private static String getPayloadHash(final Altcha.Payload payload) {
113
119
payload .signature ));
114
120
}
115
121
122
+
123
+ /**
124
+ * Decrements the invalidated payload counter when expired payloads are cleaned up.
125
+ * This method should be called by the ExpiredDataService when it removes expired entries.
126
+ *
127
+ * @param count the number of expired payloads that were removed
128
+ */
129
+ public void decrementInvalidatedPayloadCount (long count ) {
130
+ invalidatedPayloadCount .addAndGet (-count );
131
+ }
116
132
}
0 commit comments