Repository navigation
New adapter: OCM - #4652
New adapter: OCM#4652ocm-ntinos wants to merge 2 commits into
Conversation
The OCM endpoint is itself a Prebid Server that expects `placementId` as a stored request ID. This adapter modifies the outgoing BidRequest to conform to the OCM exchange's expectations: * Propagates `publisherId` to request-level publisher objects. * Reduces `tmax` to account for round-trip latency and downstream processing. * Moves `user.buyeruid` to `user.id`. * Removes host-specific Prebid extensions that would be misinterpreted by the OCM exchange.
The order of `BidRequest` field modifications within the `OcmBidder` was adjusted for consistency. Test JSONs were simplified by removing fields not critical to OCM's core bid request transformation logic, making tests clearer and more focused on relevant parameters.
| * Orange Click Media publisher identifier. It is propagated to the request-level publisher id, | ||
| * so every impression in a single request must carry the same value. | ||
| */ | ||
| @JsonProperty("publisherId") |
There was a problem hiding this comment.
I don't think those are needed.
| * not discard the rest of the seat. | ||
| */ | ||
| @Override | ||
| public final Result<List<BidderBid>> makeBids(BidderCall<BidRequest> httpCall, BidRequest bidRequest) { |
There was a problem hiding this comment.
| public final Result<List<BidderBid>> makeBids(BidderCall<BidRequest> httpCall, BidRequest bidRequest) { | |
| public Result<List<BidderBid>> makeBids(BidderCall<BidRequest> httpCall, BidRequest bidRequest) { |
| return Result.withError(BidderError.badInput(e.getMessage())); | ||
| } | ||
|
|
||
| tmaxBufferMs = resolveTmaxBufferMs(tmaxBufferMs, extImpOcm.getTmaxBufferMs()); |
There was a problem hiding this comment.
Wondering if we could use the tmax-deduction-ms instead? - https://github.com/prebid/prebid-server-java/blob/master/docs/config-app.md#adapters
| extImpOcm = parseImpExt(imp); | ||
| validateImpExt(extImpOcm, imp.getId()); | ||
| publisherId = resolvePublisherId(publisherId, extImpOcm.getPublisherId(), imp.getId()); | ||
| } catch (PreBidException e) { | ||
| return Result.withError(BidderError.badInput(e.getMessage())); | ||
| } |
There was a problem hiding this comment.
Just making sure it's expected that any errors during parsing of imp.ext fails whole request not a single impression. Given ```publisherId` requirement it makes sense.
| return dooh != null | ||
| ? dooh.toBuilder().publisher(modifyPublisher(dooh.getPublisher(), publisherId)).build() | ||
| : null; | ||
| } |
There was a problem hiding this comment.
Since there is not a dooh-media-types in the https://github.com/ocm-ntinos/prebid-server-java/blob/fe7f2ecebb872c9077c6f229c337a085477d6e61/src/main/resources/bidder-config/ocm.yaml I'm not sure it's needed.
| public void makeHttpRequestsShouldReportPublisherIdFirstWhenBothParamsAreBlank() { | ||
| // given | ||
| final BidRequest bidRequest = givenBidRequest(givenImp(imp -> imp.id("imp1").ext(givenImpExt(null, null)))); |
There was a problem hiding this comment.
To be consistent with the test name it should be
| public void makeHttpRequestsShouldReportPublisherIdFirstWhenBothParamsAreBlank() { | |
| // given | |
| final BidRequest bidRequest = givenBidRequest(givenImp(imp -> imp.id("imp1").ext(givenImpExt(null, null)))); | |
| public void makeHttpRequestsShouldReportPublisherIdFirstWhenBothParamsAreBlank() { | |
| // given | |
| final BidRequest bidRequest = givenBidRequest(givenImp(imp -> imp.id("imp1").ext(givenImpExt(" ", " ")))); |
🔧 Type of changes
✨ What's the context?
Adds a bid adapter for Orange Click Media (bidder code
ocm, GVL vendor ID 1148). It is the PBS-Java port of the Go adapter in prebid/prebid-server#4982. The docs are in prebid/prebid.github.io#6732.The OCM endpoint is itself a Prebid Server that holds stored impression configurations. The adapter therefore turns the publisher's params into references that server can resolve:
placementIdis sent asimp.ext.prebid.storedrequest.id.imp.ext.bidderis removed and otherimp.extmembers are kept.publisherIdbecomes the request-level publisher ID on every distribution channel present (site, app, dooh), andpublisher.ext.prebid.parentAccountis removed. All impressions in a request must share onepublisherId; a mismatch rejects the request as bad input.tmaxBufferMsparam (default 250) is deducted fromtmaxbefore forwarding. When impressions disagree, the largest buffer wins. The result never exceeds the originaltmax, and never drops below the buffer unless the originaltmaxwas already lower. A missingtmaxis left as is.🧠 Rationale behind the change
Because the endpoint is another PBS, the forwarded request is cleaned of data that only the host can act on. The receiving PBS would otherwise act on it a second time under the OCM account, or reject the whole auction:
ext.prebid.storedrequestandext.prebid.profileswere already resolved by the host. Forwarded, they would be looked up again under the OCM account, and an unknown ID fails the auction.ext.prebid.bidderparamsholds only OCM's global params, which are already merged into the impressions. Forwarded, the receiving PBS would merge them into every stored impression and add OCM back.ext.prebid.bidadjustmentfactorsandbidadjustmentsare applied by the host. They are keyed by the requested bidder name, which may be an alias the receiving PBS does not know, and an unknown bidder inbidadjustmentfactorsfails validation.user.buyeruid(OCM's own user ID) is moved touser.id. Left inbuyeruid, the receiving PBS would hand it to every one of its bidders, because a setbuyeruidtakes precedence there.The bidder ships disabled (
enabled: false). If it were enabled on the OCM server itself, a stored request namingocmwould call itself. Hosts enable it withadapters.ocm.enabled=true.Responses: the media type comes from
bid.mtype. Only whenmtypeis unset does the adapter fall back tobid.ext.prebid.type, since an upstream PBS passes through whatever its winning adapter set. An unsupportedmtyperejects only that bid. Video bids keepdurationandprimary_categoryfrombid.ext.prebid.video. The response currency is used when present, otherwise USD.Trade-off: the Java adapter cleans more of the request than the Go one, because PBS-Java core differs (profiles,
buyeruidprecedence, the global bidder-params merge, and alias/adjustment handling).🔎 New Bid Adapter Checklist
🧪 Test plan
OcmBidderTest: 64 unit tests covering param validation, the publisher ID mismatch, the stored-request mapping, publisher handling for site, app and dooh, thetmaxbuffer cases, the host-only data removal, thebuyeruidmove, media-type resolution (mtypeand the fallback), errors on individual bids, currency, video metadata, and no changes to the incoming request.OcmTest: integration test through/openrtb2/auctionwith WireMock.OcmBidder: 98.8% of lines and 97.5% of branches covered.🏎 Quality check