Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
fa305b8
fix test
Ian-Nara Dec 2, 2025
695f6b4
threshold in reading
Ian-Nara Dec 2, 2025
9dab244
factgoring in the queue attributes adjustment
Ian-Nara Dec 3, 2025
0fbbc6f
[CI Pipeline] Released Snapshot version: 4.5.1-alpha-114-SNAPSHOT
Dec 4, 2025
18262c3
Update .trivyignore
Ian-Nara Dec 4, 2025
f7cecde
[CI Pipeline] Released Snapshot version: 4.5.2-alpha-115-SNAPSHOT
Dec 4, 2025
104860f
Merge branch 'ian-UID2-6151-add-traffic-filter-class' into ian-UID2-6…
Ian-Nara Dec 4, 2025
663abd3
Merge branch 'ian-UID2-6345-circuit-breaker' of github.com:IABTechLab…
Ian-Nara Dec 4, 2025
d23c792
update naming
Ian-Nara Dec 4, 2025
d03eb73
[CI Pipeline] Released Snapshot version: 4.5.3-alpha-117-SNAPSHOT
Dec 4, 2025
b09ac28
update logging
Ian-Nara Dec 4, 2025
980c055
Merge branch 'ian-UID2-6345-circuit-breaker' of github.com:IABTechLab…
Ian-Nara Dec 4, 2025
de8ae4a
[CI Pipeline] Released Snapshot version: 4.5.4-alpha-118-SNAPSHOT
Dec 4, 2025
7603858
Update name
Ian-Nara Dec 5, 2025
c867bd5
Merge branch 'ian-UID2-6345-circuit-breaker' of github.com:IABTechLab…
Ian-Nara Dec 5, 2025
b4bd7c8
Merge branch 'ian-UID2-6151-add-traffic-filter-class' into ian-UID2-6…
Ian-Nara Dec 5, 2025
29a16ac
remove if block for DEFAULT
Ian-Nara Dec 5, 2025
a200825
[CI Pipeline] Released Snapshot version: 4.5.5-alpha-119-SNAPSHOT
Dec 5, 2025
bcf1709
[CI Pipeline] Released Snapshot version: 4.5.6-alpha-120-SNAPSHOT
Dec 5, 2025
5b7124e
commons logging missing?
Ian-Nara Dec 5, 2025
b807339
Merge branch 'ian-UID2-6345-circuit-breaker' of github.com:IABTechLab…
Ian-Nara Dec 5, 2025
1e63135
[CI Pipeline] Released Snapshot version: 4.5.7-alpha-121-SNAPSHOT
Dec 5, 2025
b22ea64
Merge branch 'main' into ian-UID2-6345-circuit-breaker
Ian-Nara Dec 6, 2025
5442674
whitespace
Ian-Nara Dec 6, 2025
1697197
Merge branch 'ian-UID2-6345-circuit-breaker' of github.com:IABTechLab…
Ian-Nara Dec 6, 2025
d2364e0
improve config error logging details
Ian-Nara Dec 6, 2025
03fe8a9
[CI Pipeline] Released Snapshot version: 4.5.8-alpha-122-SNAPSHOT
Dec 6, 2025
1bc84d5
remove unneeded variable
Ian-Nara Dec 6, 2025
dd57abc
Merge branch 'ian-UID2-6345-circuit-breaker' of github.com:IABTechLab…
Ian-Nara Dec 6, 2025
b85a017
refactoring circuit breaker and delta producer
Ian-Nara Dec 7, 2025
a2b3439
update comments
Ian-Nara Dec 7, 2025
fa1bd62
more refactoring
Ian-Nara Dec 7, 2025
6dbccec
update logging
Ian-Nara Dec 7, 2025
da7ac07
update logging and tests
Ian-Nara Dec 7, 2025
c6be5a1
update test
Ian-Nara Dec 7, 2025
521118d
update logging
Ian-Nara Dec 7, 2025
51b59a4
update traffic calculator
Ian-Nara Dec 7, 2025
daf4d84
update test
Ian-Nara Dec 7, 2025
a05eb90
logging in lowercase
Ian-Nara Dec 7, 2025
0a0790a
test format
Ian-Nara Dec 7, 2025
28d20d6
git diff detect file move
Ian-Nara Dec 7, 2025
b5793e0
git diff detect filel move
Ian-Nara Dec 7, 2025
64c244c
update test
Ian-Nara Dec 7, 2025
3a72d0f
update test
Ian-Nara Dec 7, 2025
65d811b
file rename/relocate
Ian-Nara Dec 7, 2025
04654af
move files
Ian-Nara Dec 7, 2025
aadf9c6
[CI Pipeline] Released Snapshot version: 4.5.9-alpha-123-SNAPSHOT
Dec 7, 2025
8aeb191
improve calculator visibility
Ian-Nara Dec 7, 2025
24b0d69
Merge branch 'ian-UID2-6345-circuit-breaker-refactored' of github.com…
Ian-Nara Dec 7, 2025
f1f252f
[CI Pipeline] Released Snapshot version: 4.5.10-alpha-124-SNAPSHOT
Dec 7, 2025
d3a121b
update logging
Ian-Nara Dec 7, 2025
9da20ee
Merge branch 'ian-UID2-6345-circuit-breaker-refactored' of github.com…
Ian-Nara Dec 7, 2025
01474e4
[CI Pipeline] Released Snapshot version: 4.5.11-alpha-126-SNAPSHOT
Dec 7, 2025
e8a8f1a
fix traffic calulator processing too many files
Ian-Nara Dec 7, 2025
5ea93f2
Merge branch 'ian-UID2-6345-circuit-breaker-refactored' of github.com…
Ian-Nara Dec 7, 2025
e3a8085
[CI Pipeline] Released Snapshot version: 4.5.12-alpha-127-SNAPSHOT
Dec 7, 2025
337ca99
use sliding window, not fixed boundaries
Ian-Nara Dec 8, 2025
d0511da
denylisted deduplication
Ian-Nara Dec 8, 2025
acf87c6
Merge branch 'ian-UID2-6345-circuit-breaker-refactored' of github.com…
Ian-Nara Dec 8, 2025
9e8e6ab
increase calculator accuracy
Ian-Nara Dec 8, 2025
5b99a60
[CI Pipeline] Released Snapshot version: 4.5.13-alpha-128-SNAPSHOT
Dec 8, 2025
df98d9d
improve calculator logs and visibility
Ian-Nara Dec 8, 2025
7282a03
standardizing logs
Ian-Nara Dec 8, 2025
98b386b
Merge branch 'ian-UID2-6345-circuit-breaker-refactored' of github.com…
Ian-Nara Dec 8, 2025
bf665a0
standardize error logging for alerts
Ian-Nara Dec 8, 2025
e31e2b3
add todos
Ian-Nara Dec 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.uid2</groupId>
<artifactId>uid2-optout</artifactId>
<version>4.5.0</version>
<version>4.5.13-alpha-128-SNAPSHOT</version>
<name>uid2-optout</name>
<url>https://github.com/IABTechLab/uid2-optout</url>

Expand Down Expand Up @@ -160,6 +160,11 @@
<groupId>software.amazon.awssdk</groupId>
<artifactId>sqs</artifactId>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this?

Copy link
Contributor Author

@Ian-Nara Ian-Nara Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is due to uid2-shared version update:

uid2-shared:11.1.91
  └── com.google.http-client:google-http-client:1.45.0
        └── org.apache.httpcomponents:httpclient:4.5.14
              └── commons-logging (required at runtime)

cabdce5

<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
</dependencies>

<build>
Expand Down
1 change: 1 addition & 0 deletions src/main/java/com/uid2/optout/Const.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public static class Config extends com.uid2.shared.Const.Config {
public static final String OptOutTrafficCalcThresholdMultiplierProp = "traffic_calc_threshold_multiplier";
public static final String OptOutTrafficCalcEvaluationWindowSecondsProp = "traffic_calc_evaluation_window_seconds";
public static final String OptOutTrafficCalcAllowlistRangesProp = "traffic_calc_allowlist_ranges";
public static final String OptOutSqsDeltaWindowSecondsProp = "optout_sqs_delta_window_seconds";
}

public static class Event {
Expand Down
17 changes: 13 additions & 4 deletions src/main/java/com/uid2/optout/Main.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.uid2.optout;

import com.uid2.optout.vertx.*;
import com.uid2.optout.traffic.OptOutTrafficFilter.MalformedTrafficFilterConfigException;
import com.uid2.optout.traffic.OptOutTrafficCalculator.MalformedTrafficCalcConfigException;
import com.uid2.shared.ApplicationVersion;
import com.uid2.shared.Utils;
import com.uid2.shared.attest.AttestationResponseHandler;
Expand All @@ -27,7 +29,6 @@
import io.vertx.config.ConfigRetriever;
import io.vertx.core.*;
import io.vertx.core.http.HttpServerOptions;
import io.vertx.core.http.impl.HttpUtils;
import io.vertx.core.json.JsonObject;
import io.vertx.micrometer.MetricsDomain;
import org.slf4j.Logger;
Expand Down Expand Up @@ -296,14 +297,22 @@ public void run(String[] args) throws IOException {
fsSqs = CloudUtils.createStorage(optoutBucket, sqsConfig);
}

// Deploy SQS log producer with its own storage instance
OptOutSqsLogProducer sqsLogProducer = new OptOutSqsLogProducer(this.config, fsSqs, sqsCs);
// Create SQS-specific cloud storage instance for dropped requests (different bucket)
String optoutBucketDroppedRequests = this.config.getString(Const.Config.OptOutS3BucketDroppedRequestsProp);
ICloudStorage fsSqsDroppedRequests = CloudUtils.createStorage(optoutBucketDroppedRequests, config);

// Deploy SQS log producer with its own storage instance
OptOutSqsLogProducer sqsLogProducer = new OptOutSqsLogProducer(this.config, fsSqs, fsSqsDroppedRequests, sqsCs, Const.Event.DeltaProduce, null);
futs.add(this.deploySingleInstance(sqsLogProducer));

LOGGER.info("SQS log producer deployed - bucket: {}, folder: {}",
this.config.getString(Const.Config.OptOutS3BucketProp), sqsFolder);
} catch (IOException e) {
LOGGER.error("Failed to initialize SQS log producer: " + e.getMessage(), e);
LOGGER.error("circuit_breaker_config_error: failed to initialize SQS log producer, delta production will be disabled: {}", e.getMessage(), e);
} catch (MalformedTrafficFilterConfigException e) {
LOGGER.error("circuit_breaker_config_error: traffic filter config is malformed, delta production will be disabled: {}", e.getMessage(), e);
} catch (MalformedTrafficCalcConfigException e) {
LOGGER.error("circuit_breaker_config_error: traffic calc config is malformed, delta production will be disabled: {}", e.getMessage(), e);
}
}

Expand Down
113 changes: 113 additions & 0 deletions src/main/java/com/uid2/optout/delta/DeltaFileWriter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package com.uid2.optout.delta;

import com.uid2.shared.optout.OptOutConst;
import com.uid2.shared.optout.OptOutEntry;
import com.uid2.shared.optout.OptOutUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

/**
* Handles binary writing of delta file entries.
*
* Delta files have the following format:
* - Start entry: null hash (32 bytes) + null hash (32 bytes) + timestamp (8 bytes)
* - Opt-out entries: hash (32 bytes) + id (32 bytes) + timestamp (7 bytes) + metadata (1 byte)
* - End entry: ones hash (32 bytes) + ones hash (32 bytes) + timestamp (8 bytes)
*
* Each entry is 72 bytes (OptOutConst.EntrySize)
*/
public class DeltaFileWriter {
private static final Logger LOGGER = LoggerFactory.getLogger(DeltaFileWriter.class);

private ByteBuffer buffer;

/**
* Create a DeltaFileWriter with the specified initial buffer size.
*
* @param bufferSize Initial buffer size in bytes
*/
public DeltaFileWriter(int bufferSize) {
this.buffer = ByteBuffer.allocate(bufferSize).order(ByteOrder.LITTLE_ENDIAN);
}

/**
* Write the start-of-delta sentinel entry.
* Uses null hash bytes and the window start timestamp.
*
* @param stream Output stream to write to
* @param windowStart Window start timestamp (epoch seconds)
* @throws IOException if write fails
*/
public void writeStartOfDelta(ByteArrayOutputStream stream, long windowStart) throws IOException {
ensureCapacity(OptOutConst.EntrySize);

buffer.put(OptOutUtils.nullHashBytes);
buffer.put(OptOutUtils.nullHashBytes);
buffer.putLong(windowStart);

flushToStream(stream);
}

/**
* Write a single opt-out entry.
*
* @param stream Output stream to write to
* @param hashBytes Hash bytes (32 bytes)
* @param idBytes ID bytes (32 bytes)
* @param timestamp Entry timestamp (epoch seconds)
* @throws IOException if write fails
*/
public void writeOptOutEntry(ByteArrayOutputStream stream, byte[] hashBytes, byte[] idBytes, long timestamp) throws IOException {
ensureCapacity(OptOutConst.EntrySize);

OptOutEntry.writeTo(buffer, hashBytes, idBytes, timestamp);

flushToStream(stream);
}

/**
* Write the end-of-delta sentinel entry.
* Uses ones hash bytes and the window end timestamp.
*
* @param stream Output stream to write to
* @param windowEnd Window end timestamp (epoch seconds)
* @throws IOException if write fails
*/
public void writeEndOfDelta(ByteArrayOutputStream stream, long windowEnd) throws IOException {
ensureCapacity(OptOutConst.EntrySize);

buffer.put(OptOutUtils.onesHashBytes);
buffer.put(OptOutUtils.onesHashBytes);
buffer.putLong(windowEnd);

flushToStream(stream);
}

/**
* Flush the buffer contents to the output stream and clear the buffer.
*/
private void flushToStream(ByteArrayOutputStream stream) throws IOException {
buffer.flip();
byte[] entry = new byte[buffer.remaining()];
buffer.get(entry);
stream.write(entry);
buffer.clear();
}

/**
* Ensure buffer has sufficient capacity, expanding if necessary.
*/
private void ensureCapacity(int dataSize) {
if (buffer.capacity() < dataSize) {
int newCapacity = Integer.highestOneBit(dataSize) << 1;
LOGGER.info("expanding buffer size: current {}, need {}, new {}", buffer.capacity(), dataSize, newCapacity);
this.buffer = ByteBuffer.allocate(newCapacity).order(ByteOrder.LITTLE_ENDIAN);
}
}
}

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.uid2.optout.vertx;
package com.uid2.optout.delta;

import io.vertx.core.json.JsonObject;
import java.time.Instant;
Expand All @@ -10,7 +10,7 @@
* (running, completed, failed), timing information, and result or error details.
*
*/
public class DeltaProduceJobStatus {
public class DeltaProductionJobStatus {
private final Instant startTime;
private volatile JobState state;
private volatile JsonObject result;
Expand All @@ -23,7 +23,7 @@ public enum JobState {
FAILED
}

public DeltaProduceJobStatus() {
public DeltaProductionJobStatus() {
this.startTime = Instant.now();
this.state = JobState.RUNNING;
}
Expand Down
60 changes: 60 additions & 0 deletions src/main/java/com/uid2/optout/delta/DeltaProductionMetrics.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.uid2.optout.delta;

import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.Metrics;

/**
* Metrics counters for delta production operations.
*
* Tracks:
* - Number of delta files produced
* - Number of opt-out entries processed
* - Number of dropped request files produced
* - Number of dropped requests processed
*/
public class DeltaProductionMetrics {

private final Counter deltasProduced;
private final Counter entriesProcessed;
private final Counter droppedRequestFilesProduced;
private final Counter droppedRequestsProcessed;

public DeltaProductionMetrics() {
this.deltasProduced = Counter
.builder("uid2_optout_sqs_delta_produced_total")
.description("counter for how many optout delta files are produced from SQS")
.register(Metrics.globalRegistry);

this.entriesProcessed = Counter
.builder("uid2_optout_sqs_entries_processed_total")
.description("counter for how many optout entries are processed from SQS")
.register(Metrics.globalRegistry);

this.droppedRequestFilesProduced = Counter
.builder("uid2_optout_sqs_dropped_request_files_produced_total")
.description("counter for how many optout dropped request files are produced from SQS")
.register(Metrics.globalRegistry);

this.droppedRequestsProcessed = Counter
.builder("uid2_optout_sqs_dropped_requests_processed_total")
.description("counter for how many optout dropped requests are processed from SQS")
.register(Metrics.globalRegistry);
}

/**
* Record that a delta file was produced with the given number of entries.
*/
public void recordDeltaProduced(int entryCount) {
deltasProduced.increment();
entriesProcessed.increment(entryCount);
}

/**
* Record that a dropped requests file was produced with the given number of entries.
*/
public void recordDroppedRequestsProduced(int requestCount) {
droppedRequestFilesProduced.increment();
droppedRequestsProcessed.increment(requestCount);
}
}

Loading
Loading