Skip to content

Commit

Permalink
Pangle: add appid & placementid to bidder param (#1319)
Browse files Browse the repository at this point in the history
  • Loading branch information
nickluck8 authored Jun 17, 2021
1 parent 65c8316 commit 02e44d0
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 22 deletions.
35 changes: 28 additions & 7 deletions src/main/java/org/prebid/server/bidder/pangle/PangleBidder.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
import org.prebid.server.bidder.model.HttpRequest;
import org.prebid.server.bidder.model.Result;
import org.prebid.server.bidder.pangle.model.BidExt;
import org.prebid.server.bidder.pangle.model.NetworkIds;
import org.prebid.server.bidder.pangle.model.PangleBidExt;
import org.prebid.server.bidder.pangle.model.WrappedImpExtBidder;
import org.prebid.server.exception.PreBidException;
import org.prebid.server.json.DecodeException;
import org.prebid.server.json.JacksonMapper;
import org.prebid.server.proto.openrtb.ext.request.ExtImpPrebid;
import org.prebid.server.proto.openrtb.ext.request.pangle.ExtImpPangle;
import org.prebid.server.proto.openrtb.ext.response.BidType;
import org.prebid.server.util.HttpUtil;

Expand Down Expand Up @@ -54,8 +56,9 @@ public Result<List<HttpRequest<BidRequest>>> makeHttpRequests(BidRequest request
for (Imp imp : request.getImp()) {
try {
final WrappedImpExtBidder extBidder = parseImpExt(imp);
final ExtImpPangle extImpPangle = extBidder.getBidder();
final Integer adType = resolveAdType(imp, extBidder);
final Imp modifiedImp = modifyImp(imp, adType, extBidder);
final Imp modifiedImp = modifyImp(imp, adType, extBidder, extImpPangle);

requests.add(createRequest(request, modifiedImp, extBidder.getBidder().getToken()));
} catch (PreBidException e) {
Expand Down Expand Up @@ -101,13 +104,35 @@ private static int resolveAdType(Imp imp, WrappedImpExtBidder extBidder) {
throw new PreBidException("not a supported adtype");
}

private Imp modifyImp(Imp imp, Integer adType, WrappedImpExtBidder extBidder) {
final WrappedImpExtBidder updatedImpExt = extBidder.toBuilder().adType(adType).build();
private Imp modifyImp(Imp imp, Integer adType, WrappedImpExtBidder extBidder, ExtImpPangle bidderImpExt) {
final NetworkIds modifiedNetworkIds = getNetworkIds(bidderImpExt);

final WrappedImpExtBidder updatedImpExt = extBidder.toBuilder()
.adType(adType)
.isPrebid(true)
.networkids(modifiedNetworkIds == null ? extBidder.getNetworkids() : modifiedNetworkIds)
.build();

return imp.toBuilder()
.ext(mapper.mapper().convertValue(updatedImpExt, ObjectNode.class))
.build();
}

private static NetworkIds getNetworkIds(ExtImpPangle bidderImpExt) {
if (bidderImpExt != null) {
final String appid = bidderImpExt.getAppid();
final String placementid = bidderImpExt.getPlacementid();

if (StringUtils.isNotEmpty(appid) && StringUtils.isNotEmpty(placementid)) {
return NetworkIds.of(appid, placementid);
} else if (StringUtils.isNotEmpty(appid) || StringUtils.isNotEmpty(placementid)) {
throw new PreBidException("only one of appid or placementid is provided");
}
}

return null;
}

private HttpRequest<BidRequest> createRequest(BidRequest request, Imp imp, String token) {
final BidRequest outgoingRequest = request.toBuilder().imp(Collections.singletonList(imp)).build();

Expand Down Expand Up @@ -164,17 +189,13 @@ private BidderBid createBid(Bid bid, String currency, List<BidderError> errors)
final BidType bidType;
switch (adType) {
case 1:
bidType = BidType.banner;
break;
case 2:
bidType = BidType.banner;
break;
case 5:
bidType = BidType.xNative;
break;
case 7:
bidType = BidType.video;
break;
case 8:
bidType = BidType.video;
break;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.prebid.server.bidder.pangle.model;

import lombok.AllArgsConstructor;
import lombok.Value;

@Value
@AllArgsConstructor(staticName = "of")
public class NetworkIds {

String appid;

String placementid;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,8 @@ public class WrappedImpExtBidder {

@JsonProperty("adtype")
Integer adType;

Boolean isPrebid;

NetworkIds networkids;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@
public class ExtImpPangle {

String token;

String appid;

String placementid;
}
18 changes: 18 additions & 0 deletions src/main/resources/static/bidder-params/pangle.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,24 @@
"pattern": ".+"
}
},
"appid": {
"type": "string",
"description": "App ID",
"pattern": "[0-9]+"
},
"placementid": {
"type": "string",
"description": "Placement ID",
"pattern": "[0-9]+"
},
"dependencies": {
"placementid": [
"appid"
],
"appid": [
"placementid"
]
},
"required": [
"token"
]
Expand Down
129 changes: 117 additions & 12 deletions src/test/java/org/prebid/server/bidder/pangle/PangleBidderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.prebid.server.bidder.model.HttpResponse;
import org.prebid.server.bidder.model.Result;
import org.prebid.server.bidder.pangle.model.BidExt;
import org.prebid.server.bidder.pangle.model.NetworkIds;
import org.prebid.server.bidder.pangle.model.PangleBidExt;
import org.prebid.server.bidder.pangle.model.WrappedImpExtBidder;
import org.prebid.server.proto.openrtb.ext.ExtPrebid;
Expand Down Expand Up @@ -86,7 +87,8 @@ public void makeHttpRequestsShouldUpdateImpExtWithAdTypeSevenIfVideoIsPresentAnd
final BidRequest bidRequest = BidRequest.builder()
.imp(singletonList(Imp.builder()
.video(Video.builder().build())
.ext(mapper.valueToTree(WrappedImpExtBidder.of(extPrebid, ExtImpPangle.of("token"), null)))
.ext(mapper.valueToTree(WrappedImpExtBidder.of(extPrebid, ExtImpPangle.of(
"token", null, null), null, true, null)))
.build()))
.build();

Expand All @@ -95,7 +97,7 @@ public void makeHttpRequestsShouldUpdateImpExtWithAdTypeSevenIfVideoIsPresentAnd

// then
final ObjectNode expectedExt = mapper
.valueToTree(WrappedImpExtBidder.of(extPrebid, ExtImpPangle.of("token"), 7));
.valueToTree(WrappedImpExtBidder.of(extPrebid, ExtImpPangle.of("token", null, null), 7, true, null));
assertThat(result.getErrors()).isEmpty();
assertThat(result.getValue())
.extracting(HttpRequest::getPayload)
Expand All @@ -111,7 +113,8 @@ public void makeHttpRequestsShouldUpdateImpExtWithAdTypeEightIfVideoIsPresentAnd
.imp(singletonList(Imp.builder()
.instl(1)
.video(Video.builder().build())
.ext(mapper.valueToTree(WrappedImpExtBidder.of(null, ExtImpPangle.of("token"), null)))
.ext(mapper.valueToTree(WrappedImpExtBidder.of(null, ExtImpPangle.of(
"token", null, null), null, true, null)))
.build()))
.build();

Expand All @@ -120,7 +123,8 @@ public void makeHttpRequestsShouldUpdateImpExtWithAdTypeEightIfVideoIsPresentAnd

// then
final ObjectNode expectedExt = mapper
.valueToTree(WrappedImpExtBidder.of(null, ExtImpPangle.of("token"), 8));
.valueToTree(WrappedImpExtBidder.of(null,
ExtImpPangle.of("token", null, null), 8, true, null));
assertThat(result.getErrors()).isEmpty();
assertThat(result.getValue())
.extracting(HttpRequest::getPayload)
Expand All @@ -136,7 +140,8 @@ public void makeHttpRequestsShouldUpdateImpExtWithAdTypeTwoIfBannerIsPresentAndI
.imp(singletonList(Imp.builder()
.instl(1)
.banner(Banner.builder().build())
.ext(mapper.valueToTree(WrappedImpExtBidder.of(null, ExtImpPangle.of("token"), null)))
.ext(mapper.valueToTree(WrappedImpExtBidder.of(null, ExtImpPangle.of(
"token", null, null), null, true, null)))
.build()))
.build();

Expand All @@ -145,7 +150,7 @@ public void makeHttpRequestsShouldUpdateImpExtWithAdTypeTwoIfBannerIsPresentAndI

// then
final ObjectNode expectedExt = mapper
.valueToTree(WrappedImpExtBidder.of(null, ExtImpPangle.of("token"), 2));
.valueToTree(WrappedImpExtBidder.of(null, ExtImpPangle.of("token", null, null), 2, true, null));
assertThat(result.getErrors()).isEmpty();
assertThat(result.getValue())
.extracting(HttpRequest::getPayload)
Expand All @@ -160,7 +165,8 @@ public void makeHttpRequestsShouldUpdateImpExtWithAdTypeOneIfBannerIsPresent() {
final BidRequest bidRequest = BidRequest.builder()
.imp(singletonList(Imp.builder()
.banner(Banner.builder().build())
.ext(mapper.valueToTree(WrappedImpExtBidder.of(null, ExtImpPangle.of("token"), null)))
.ext(mapper.valueToTree(WrappedImpExtBidder.of(null, ExtImpPangle.of(
"token", null, null), null, true, null)))
.build()))
.build();

Expand All @@ -169,7 +175,8 @@ public void makeHttpRequestsShouldUpdateImpExtWithAdTypeOneIfBannerIsPresent() {

// then
final ObjectNode expectedExt = mapper
.valueToTree(WrappedImpExtBidder.of(null, ExtImpPangle.of("token"), 1));
.valueToTree(WrappedImpExtBidder.of(null, ExtImpPangle.of(
"token", null, null), 1, true, null));
assertThat(result.getErrors()).isEmpty();
assertThat(result.getValue())
.extracting(HttpRequest::getPayload)
Expand All @@ -184,7 +191,8 @@ public void makeHttpRequestsShouldUpdateImpExtWithAdTypeFiveIfNativeRequestIsPre
final BidRequest bidRequest = BidRequest.builder()
.imp(singletonList(Imp.builder()
.xNative(Native.builder().request("someRequest").build())
.ext(mapper.valueToTree(WrappedImpExtBidder.of(null, ExtImpPangle.of("token"), null)))
.ext(mapper.valueToTree(WrappedImpExtBidder.of(null, ExtImpPangle.of(
"token", null, null), null, true, null)))
.build()))
.build();

Expand All @@ -193,7 +201,8 @@ public void makeHttpRequestsShouldUpdateImpExtWithAdTypeFiveIfNativeRequestIsPre

// then
final ObjectNode expectedExt = mapper
.valueToTree(WrappedImpExtBidder.of(null, ExtImpPangle.of("token"), 5));
.valueToTree(WrappedImpExtBidder.of(null, ExtImpPangle.of(
"token", null, null), 5, true, null));
assertThat(result.getErrors()).isEmpty();
assertThat(result.getValue())
.extracting(HttpRequest::getPayload)
Expand All @@ -208,7 +217,8 @@ public void makeHttpRequestsShouldReturnErrorForNotSupportedAdType() {
final BidRequest bidRequest = BidRequest.builder()
.imp(singletonList(Imp.builder()
.audio(Audio.builder().build())
.ext(mapper.valueToTree(WrappedImpExtBidder.of(null, ExtImpPangle.of("token"), null)))
.ext(mapper.valueToTree(WrappedImpExtBidder.of(null, ExtImpPangle.of(
"token", null, null), null, true, null)))
.build()))
.build();

Expand Down Expand Up @@ -470,6 +480,101 @@ public void makeBidsShouldReturnErrorsAndResult() throws JsonProcessingException
assertThat(result.getErrors()).hasSize(1);
}

@Test
public void makeHttpRequestsShouldUpdateImpExtWithNetworkIds() {
// given
final BidRequest bidRequest = BidRequest.builder()
.imp(singletonList(Imp.builder()
.banner(Banner.builder().w(1).h(1).build())
.ext(mapper.valueToTree(WrappedImpExtBidder.of(null, ExtImpPangle.of(
"token", "2", "2"),
null, true, NetworkIds.of("1", "1"))))
.build()))
.build();

// when
final Result<List<HttpRequest<BidRequest>>> result = pangleBidder.makeHttpRequests(bidRequest);

// then
final ObjectNode expectedExt = mapper
.valueToTree(WrappedImpExtBidder.of(null, ExtImpPangle.of(
"token", "2", "2"),
1, true, NetworkIds.of("2", "2")));
assertThat(result.getErrors()).isEmpty();
assertThat(result.getValue())
.extracting(HttpRequest::getPayload)
.flatExtracting(BidRequest::getImp)
.extracting(Imp::getExt)
.containsExactly(expectedExt);
}

@Test
public void makeHttpRequestsShouldAddErrorAndSkipImpressionIfAppIdIsNotPresentAndPlacementIdIsPresent() {
// given
final BidRequest bidRequest = BidRequest.builder()
.imp(singletonList(Imp.builder()
.banner(Banner.builder().w(1).h(1).build())
.ext(mapper.valueToTree(WrappedImpExtBidder.of(null, ExtImpPangle.of(
"token", null, "1"),
null, true, NetworkIds.of("1", "1"))))
.build()))
.build();

// when
final Result<List<HttpRequest<BidRequest>>> result = pangleBidder.makeHttpRequests(bidRequest);

// then
assertThat(result.getErrors()).hasSize(1);
assertThat(result.getValue()).isEmpty();
}

@Test
public void makeHttpRequestsShouldAddErrorAndSkipImpressionIfPlacementIdIsNotPresentAndAppIdIsPresent() {
// given
final BidRequest bidRequest = BidRequest.builder()
.imp(singletonList(Imp.builder()
.banner(Banner.builder().w(1).h(1).build())
.ext(mapper.valueToTree(WrappedImpExtBidder.of(null, ExtImpPangle.of(
"token", "1", null),
null, true, NetworkIds.of("1", "1"))))
.build()))
.build();

// when
final Result<List<HttpRequest<BidRequest>>> result = pangleBidder.makeHttpRequests(bidRequest);

// then
assertThat(result.getErrors()).hasSize(1);
assertThat(result.getValue()).isEmpty();
}

@Test
public void makeHttpRequestsShouldNotUpdateImpExtWithNetworkIdsIfNetworkIdsAreAbsent() {
// given
final BidRequest bidRequest = BidRequest.builder()
.imp(singletonList(Imp.builder()
.banner(Banner.builder().w(1).h(1).build())
.ext(mapper.valueToTree(WrappedImpExtBidder.of(null, ExtImpPangle.of(
"token", null, null),
null, true, null)))
.build()))
.build();

// when
final Result<List<HttpRequest<BidRequest>>> result = pangleBidder.makeHttpRequests(bidRequest);

// then
final ObjectNode expectedExt = mapper
.valueToTree(WrappedImpExtBidder.of(null,
ExtImpPangle.of("token", null, null), 1, true, null));
assertThat(result.getErrors()).isEmpty();
assertThat(result.getValue())
.extracting(HttpRequest::getPayload)
.flatExtracting(BidRequest::getImp)
.extracting(Imp::getExt)
.containsExactly(expectedExt);
}

private static BidRequest givenBidRequest(
Function<Imp.ImpBuilder, Imp.ImpBuilder> impCustomizer,
Function<BidRequest.BidRequestBuilder, BidRequest.BidRequestBuilder> requestCustomizer) {
Expand All @@ -487,7 +592,7 @@ private static Imp givenImp(Function<Imp.ImpBuilder, Imp.ImpBuilder> impCustomiz
return impCustomizer.apply(Imp.builder()
.id("123"))
.banner(Banner.builder().build())
.ext(mapper.valueToTree(ExtPrebid.of(null, ExtImpPangle.of("token"))))
.ext(mapper.valueToTree(ExtPrebid.of(null, ExtImpPangle.of("token", null, null))))
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
"prebid": {
"bidder": {
"pangle": {
"token": ".token"
"token": ".token",
"appid": "1",
"placementid": "1"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,16 @@
},
"ext": {
"bidder": {
"token": ".token"
"token": ".token",
"appid": "1",
"placementid": "1"
},
"adtype" : 1
"adtype": 1,
"is_prebid": true,
"networkids": {
"appid": "1",
"placementid": "1"
}
}
}
],
Expand Down

0 comments on commit 02e44d0

Please sign in to comment.