Skip to content

New Adapter: Adswag - #4597

Open
westerschmal wants to merge 2 commits into
prebid:masterfrom
adswag:new-adapter-adswag
Open

New Adapter: Adswag#4597
westerschmal wants to merge 2 commits into
prebid:masterfrom
adswag:new-adapter-adswag

Conversation

@westerschmal

Copy link
Copy Markdown

🔧 Type of changes

  • new bid adapter

✨ What's the context?

Adds the Adswag bid adapter — our own port of the Go adapter (prebid/prebid-server#4908, opened alongside by us, the adapter maintainers). Adswag is directly-integrated European supply: banner, video and audio; site and app; EU-hosted endpoint https://bid.adswag.ai/prebid/bid; GVL vendor 1417; GPP supported; geoscope EEA.

🧠 Rationale behind the change

Same semantics as the Go adapter: per-imp param validation (publisherId required; invalid imps dropped with a bad-input error, valid ones proceed), imp.ext rewritten to imp.ext.adswag.placement_id, publisher id promoted to site.publisher.id/app.publisher.id, everything else passes through in-band. Response side resolves media type per bid (banner/video/audio), backfills w/h/mtype, defaults currency to EUR, and synthesizes iframe markup only for legacy serve-url-only display bids (current production sends markup in adm). modifying-vast-xml-allowed: false — our ad server owns VAST composition and measurement beacons. Consent-gated usersync redirect on ev.adswag.ai (uid only with vendor-1417 + Purpose-1 consent).

🔎 New Bid Adapter Checklist

  • verify email contact works — prebid@adswag.ai (monitored)
  • NO fully dynamic hostnames — static endpoint in bidder-config yaml
  • geographic host parameters are NOT required
  • direct use of HTTP is prohibited - implements Bidder<BidRequest> via the standard HttpRequest/BidderBid types
  • if the ORTB is just forwarded to the endpoint, use the generic adapter - not applicable: the adapter rewrites imp.ext, promotes the publisher id, and resolves media types/markup on the response
  • cover an adapter configuration with an integration test — AdswagTest (WireMock exchange) + IT fixtures

🧪 Test plan

  • AdswagBidderTest: 21/21 (includes a captured-production-response mapping test; fixture tokens synthetic)
  • IT AdswagTest: 1/1 (full Spring boot + WireMock)
  • BidderParamValidatorTest 25/25 and ApplicationTest 27/27 (config/schema consistency gates, re-run with the adswag yaml registered)
  • checkstyle: 0 violations on the added files (JDK 25, Maven 3.9.16)
  • Live bidder params for validating bids (verified against production 2026-08-13, €2.50 EUR test bids): { "publisherId": "prebid-test", "placementId": "prebid-test-display" } (display imps must include 300x250; prebid-test-video / prebid-test-audio for video/audio)

🏎 Quality check

  • Are your changes following our code style guidelines?
  • Are there any breaking changes in your code? — No
  • Does your test coverage exceed 90%? — Yes
  • Are there any erroneous console logs, debuggers or leftover code in your changes? — No

Docs PR (one bidder page, pbs + pbs_app_supported metadata): prebid/prebid.github.io#6702

Port of the Go adapter (prebid/prebid-server#4908), authored by the Adswag team. Banner, video, audio; site and app; GVL vendor 1417; consent-gated usersync redirect.
@westerschmal

Copy link
Copy Markdown
Author

All five workflows on this PR are currently pending "approve workflows" (first-time contributor), so no checks have run yet. Could a maintainer approve the workflow runs when convenient? The adapter is ready for review. Thanks!

Comment thread src/main/java/org/prebid/server/bidder/adswag/AdswagBidder.java Outdated
Comment thread src/main/java/org/prebid/server/bidder/adswag/AdswagBidder.java Outdated
Comment on lines +185 to +187
if (StringUtils.isBlank(body)) {
return Result.empty();
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

No need for this check. Inline body

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Kept this one, with apologies: the Adswag endpoint answers a no-bid on this path as an empty-body HTTP 200 (alongside the conventional 204), and core only substitutes a safe body for 204 (HttpBidderRequester#toHttpCallWithSafeResponseBody), so removing the check would surface every no-bid as a bad_server_response decode error. Happy to drop it if you'd prefer we require 204-only no-bids from the endpoint instead.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@westerschmal It's safe to remove, because mapper.decodeValue(body, BidResponse.class); will return null and you have

if (bidResponse == null || CollectionUtils.isEmpty(bidResponse.getSeatbid())) {
            return Collections.emptyList();
        }

Comment thread src/main/java/org/prebid/server/bidder/adswag/AdswagBidder.java Outdated
Comment thread src/main/java/org/prebid/server/bidder/adswag/AdswagBidder.java Outdated
Comment thread src/test/java/org/prebid/server/bidder/adswag/AdswagBidderTest.java Outdated
Comment thread src/test/java/org/prebid/server/bidder/adswag/AdswagBidderTest.java Outdated
Comment thread src/test/java/org/prebid/server/bidder/adswag/AdswagBidderTest.java Outdated
Comment thread src/test/java/org/prebid/server/bidder/adswag/AdswagBidderTest.java Outdated
Comment thread src/test/java/org/prebid/server/bidder/adswag/AdswagBidderTest.java Outdated
- remove explanatory comments and javadoc
- drop redundant null check in validateImpExt; unnamed lambda parameter
- restructure bid materialization into per-type methods behind a switch
  expression; iframe markup via text block (output unchanged)
- tests: text blocks for markup constants, givenBidRequest/givenImp
  helper idiom, explanations removed
- drop the live-captured fixture and its test; adm passthrough is now
  covered by a synthetic case

The empty-body no-bid check in makeBids is deliberately kept: the
endpoint answers no-bid as an empty-body HTTP 200 as well as 204, and
core only shields makeBids for 204.
@westerschmal

Copy link
Copy Markdown
Author

Review addressed in 221dfc4 — all points taken, with one exception argued on its thread: the empty-body check in makeBids stays for now because the endpoint answers no-bid as an empty-body HTTP 200 and core only shields 204. Unit tests (22) + the WireMock IT and checkstyle are green locally.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants