Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 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
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.8-alpha-122-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>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
</dependencies>

<build>
Expand Down
16 changes: 13 additions & 3 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.vertx.OptOutTrafficFilter.MalformedTrafficFilterConfigException;
import com.uid2.optout.vertx.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,23 @@ 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("Failed to initialize SQS log producer, delta production will be disabled: " + e.getMessage(), e);
} catch (MalformedTrafficFilterConfigException e) {
LOGGER.error("The traffic filter config is malformed, refusing to process messages, delta production will be disabled: " + e.getMessage(), e);
} catch (MalformedTrafficCalcConfigException e) {
LOGGER.error("The traffic calc config is malformed, refusing to process messages, delta production will be disabled: " + e.getMessage(), e);
}
}

Expand Down
57 changes: 49 additions & 8 deletions src/main/java/com/uid2/optout/vertx/DeltaProductionResult.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
package com.uid2.optout.vertx;

import io.vertx.core.json.JsonObject;

/**
* Result object containing statistics from delta production.
* Data class containing statistics from delta production.
*
* This class holds the counts and provides JSON encoding methods.
* API response status is determined by the caller based on these statistics.
*/
public class DeltaProductionResult {
private final int deltasProduced;
private final int entriesProcessed;

private final int droppedRequestFilesProduced;
private final int droppedRequestsProcessed;

/*
* indicates that there are still messages in the queue, however,
* not enough time has elapsed to produce a delta file.
* We produce in batches of (5 minutes)
*/
private final boolean stoppedDueToMessagesTooRecent;
private final boolean stoppedDueToRecentMessages;

public DeltaProductionResult(int deltasProduced, int entriesProcessed, boolean stoppedDueToMessagesTooRecent) {
public DeltaProductionResult(int deltasProduced, int entriesProcessed, int droppedRequestFilesProduced, int droppedRequestsProcessed, boolean stoppedDueToRecentMessages) {
this.deltasProduced = deltasProduced;
this.entriesProcessed = entriesProcessed;
this.stoppedDueToMessagesTooRecent = stoppedDueToMessagesTooRecent;
this.droppedRequestFilesProduced = droppedRequestFilesProduced;
this.droppedRequestsProcessed = droppedRequestsProcessed;
this.stoppedDueToRecentMessages = stoppedDueToRecentMessages;
}

public int getDeltasProduced() {
Expand All @@ -28,8 +37,40 @@ public int getEntriesProcessed() {
return entriesProcessed;
}

public boolean stoppedDueToMessagesTooRecent() {
return stoppedDueToMessagesTooRecent;
public boolean stoppedDueToRecentMessages() {
return stoppedDueToRecentMessages;
}

public int getDroppedRequestFilesProduced() {
return droppedRequestFilesProduced;
}

public int getDroppedRequestsProcessed() {
return droppedRequestsProcessed;
}

/**
* Convert to JSON with just the production counts.
*/
public JsonObject toJson() {
return new JsonObject()
.put("deltas_produced", deltasProduced)
.put("entries_processed", entriesProcessed)
.put("dropped_request_files_produced", droppedRequestFilesProduced)
.put("dropped_requests_processed", droppedRequestsProcessed);
}

/**
* Convert to JSON with status and counts.
*/
public JsonObject toJsonWithStatus(String status) {
return toJson().put("status", status);
}
}

/**
* Convert to JSON with status, reason/error, and counts.
*/
public JsonObject toJsonWithStatus(String status, String reasonKey, String reasonValue) {
return toJsonWithStatus(status).put(reasonKey, reasonValue);
}
}
11 changes: 5 additions & 6 deletions src/main/java/com/uid2/optout/vertx/OptOutServiceVerticle.java
Original file line number Diff line number Diff line change
Expand Up @@ -365,21 +365,23 @@ private void handleQueue(RoutingContext routingContext) {
String email = body != null ? body.getString(EMAIL) : null;
String phone = body != null ? body.getString(PHONE) : null;

HttpServerResponse resp = routingContext.response();

// while old delta production is enabled, response is handled by replicate logic

// Validate parameters - same as replicate
if (identityHash == null || params.getAll(IDENTITY_HASH).size() != 1) {
LOGGER.warn("handleQueue: Invalid identity_hash parameter");
// this.sendBadRequestError(resp);
return;
}
if (advertisingId == null || params.getAll(ADVERTISING_ID).size() != 1) {
LOGGER.warn("handleQueue: Invalid advertising_id parameter");

// this.sendBadRequestError(resp);
return;
}

if (!this.isGetOrPost(req)) {
LOGGER.warn("handleQueue: Invalid HTTP method: {}", req.method());
// this.sendBadRequestError(resp);
return;
}
Expand Down Expand Up @@ -408,8 +410,6 @@ private void handleQueue(RoutingContext routingContext) {
}
}, res -> {
if (res.failed()) {
// this.sendInternalServerError(resp, "Failed to queue message: " + res.cause().getMessage());
LOGGER.error("Failed to queue message: " + res.cause().getMessage());
} else {
String messageId = (String) res.result();

Expand All @@ -426,8 +426,7 @@ private void handleQueue(RoutingContext routingContext) {
}
});
} catch (Exception ex) {
// this.sendInternalServerError(resp, ex.getMessage());
LOGGER.error("Error processing queue request: " + ex.getMessage(), ex);
LOGGER.error("handleQueue: Error processing queue request");
}
}

Expand Down
Loading
Loading