NonceManager { synchronized boolean verify(final String key, final String timestamp, final String nonce, final long now) { final long stamp = timestampUnit.toMillis(longValue(timestamp)); if (mapSize + 1 > maximumMapSize) { gc(now); if (mapSize + 1 > maximumMapSize) { return false; } } if (stamp + maxAge < now || stamp - maxAge > now) { return false; } Map<String, Set<String>> keyToNonces = tsToKeyNoncePairs.get(stamp); if (keyToNonces == null) { keyToNonces = new HashMap<>(); tsToKeyNoncePairs.put(stamp, keyToNonces); } Set<String> nonces = keyToNonces.get(key); if (nonces == null) { nonces = new HashSet<>(); keyToNonces.put(key, nonces); } final boolean result = nonces.add(nonce); if (result) { mapSize++; } if (++gcCounter >= gcPeriod) { gc(now); } return result; } NonceManager(final long maxAge, final int gcPeriod, final TimeUnit timestampUnit, final long maximumCacheSize); synchronized boolean verify(final String key, final String timestamp, final String nonce);  }
@Test public void testDuplicateNonce() { NonceManager nonces = new NonceManager(1000, 50, TimeUnit.SECONDS, 2000000); String stamp = stamp(); boolean accepted; accepted = nonces.verify("nonce-key", stamp, "nonce"); assertTrue(accepted); accepted = nonces.verify("nonce-key", stamp, "nonce"); assertFalse(accepted); }