Skip to content

Commit

Permalink
AdOcean adapter - add support for mobile apps (#1317)
Browse files Browse the repository at this point in the history
  • Loading branch information
nickluck8 committed Aug 9, 2021
1 parent 771c57c commit c2a9054
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 31 deletions.
32 changes: 28 additions & 4 deletions src/main/java/org/prebid/server/bidder/adocean/AdoceanBidder.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.prebid.server.bidder.adocean;

import com.fasterxml.jackson.core.type.TypeReference;
import com.iab.openrtb.request.App;
import com.iab.openrtb.request.Banner;
import com.iab.openrtb.request.BidRequest;
import com.iab.openrtb.request.Device;
Expand Down Expand Up @@ -56,7 +57,7 @@ public class AdoceanBidder implements Bidder<Void> {
private static final TypeReference<ExtPrebid<?, ExtImpAdocean>> ADOCEAN_EXT_TYPE_REFERENCE =
new TypeReference<ExtPrebid<?, ExtImpAdocean>>() {
};
private static final String VERSION = "1.1.0";
private static final String VERSION = "1.2.0";
private static final int MAX_URI_LENGTH = 8000;
private static final String MEASUREMENT_CODE_TEMPLATE = " <script> +function() { "
+ "var wu = \"%s\"; "
Expand Down Expand Up @@ -188,14 +189,14 @@ private HttpRequest<Void> createSingleRequest(BidRequest request, Imp imp, ExtIm

return HttpRequest.<Void>builder()
.method(HttpMethod.GET)
.uri(buildUrl(imp.getId(), extImpAdocean, consentString, request.getTest(), request.getUser(),
slaveSizes))
.uri(buildUrl(imp.getId(), extImpAdocean, consentString, request, slaveSizes))
.headers(getHeaders(request))
.build();
}

private String buildUrl(String impid, ExtImpAdocean extImpAdocean, String consentString, Integer test, User user,
private String buildUrl(String impid, ExtImpAdocean extImpAdocean, String consentString, BidRequest bidRequest,
Map<String, String> slaveSizes) {
final Integer test = bidRequest.getTest();
final String url = endpointUrl.replace("{{Host}}", Objects.toString(extImpAdocean.getEmitterDomain(), ""));
final int randomizedPart = Objects.equals(test, 1) ? 10000000 : 10000000 + (int) (Math.random() * 89999999);
final String updateUrl = String.format("%s/_%s/ad.json", url, randomizedPart);
Expand All @@ -212,10 +213,33 @@ private String buildUrl(String impid, ExtImpAdocean extImpAdocean, String consen
uriBuilder.addParameter("gdpr", "1");
}

final User user = bidRequest.getUser();
if (user != null && StringUtils.isNotEmpty(user.getBuyeruid())) {
uriBuilder.addParameter("hcuserid", user.getBuyeruid());
}

final App app = bidRequest.getApp();
if (app != null) {
uriBuilder.addParameter("app", "1");
uriBuilder.addParameter("appname", app.getName());
uriBuilder.addParameter("appbundle", app.getBundle());
uriBuilder.addParameter("appdomain", app.getDomain());
}

final Device device = bidRequest.getDevice();
if (device != null) {
if (StringUtils.isNotEmpty(device.getIfa())) {
uriBuilder.addParameter("ifa", device.getIfa());
} else {
uriBuilder.addParameter("dpidmd5", device.getDpidmd5());
}

uriBuilder.addParameter("devos", device.getOs());
uriBuilder.addParameter("devosv", device.getOsv());
uriBuilder.addParameter("devmodel", device.getModel());
uriBuilder.addParameter("devmake", device.getMake());
}

final List<String> sizeValues = setSlaveSizesParam(slaveSizes, Objects.equals(test, 1));

if (CollectionUtils.isNotEmpty(sizeValues)) {
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/bidder-config/adocean.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ adapters:
meta-info:
maintainer-email: aoteam@gemius.com
app-media-types:
- banner
site-media-types:
- banner
supported-vendors:
Expand Down
100 changes: 96 additions & 4 deletions src/test/java/org/prebid/server/bidder/adocean/AdoceanBidderTest.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.prebid.server.bidder.adocean;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.iab.openrtb.request.App;
import com.iab.openrtb.request.Banner;
import com.iab.openrtb.request.BidRequest;
import com.iab.openrtb.request.Device;
Expand Down Expand Up @@ -111,10 +112,10 @@ public void makeHttpRequestsShouldCreateRequestForEveryValidImp() {
+ "in imp with id : notValidImp"));
assertThat(result.getValue()).hasSize(2)
.extracting(HttpRequest::getUri)
.containsExactly("https://myao.adocean.pl/_10000000/ad.json?pbsrv_v=1.1.0&id=masterId&nc=1"
.containsExactly("https://myao.adocean.pl/_10000000/ad.json?pbsrv_v=1.2.0&id=masterId&nc=1"
+ "&nosecure=1&aid=adoceanmyaozpniqismex%3Aao-test&gdpr_consent=consent&gdpr=1"
+ "&hcuserid=testBuyerUid&aosspsizes=myaozpniqismex"
+ "%7E300x250_600x320", "https://em.dom/_10000000/ad.json?pbsrv_v=1.1.0&id="
+ "%7E300x250_600x320", "https://em.dom/_10000000/ad.json?pbsrv_v=1.2.0&id="
+ "masterId2&nc=1&nosecure=1&aid=slaveId%3Ai2-test&gdpr_consent=consent&gdpr=1"
+ "&hcuserid=testBuyerUid&aosspsizes=slaveId%7E577x333");
}
Expand Down Expand Up @@ -175,7 +176,7 @@ public void makeHttpRequestsShouldCreateRequestWithoutSizeIfBannerSizesNotPresen
assertThat(result.getErrors()).isEmpty();
assertThat(result.getValue())
.extracting(HttpRequest::getUri)
.containsExactly("https://myao.adocean.pl/_10000000/ad.json?pbsrv_v=1.1.0&id=masterId&nc=1&nosecure=1"
.containsExactly("https://myao.adocean.pl/_10000000/ad.json?pbsrv_v=1.2.0&id=masterId&nc=1&nosecure=1"
+ "&aid=adoceanmyaozpniqismex%3Aao-test&gdpr_consent=consent&gdpr=1");
}

Expand Down Expand Up @@ -210,7 +211,7 @@ public void makeHttpRequestsShouldUpdateRequestsForSimilarSlaveIds() {
// then
assertThat(result.getValue()).hasSize(1)
.extracting(HttpRequest::getUri)
.containsExactlyInAnyOrder("https://myao.adocean.pl/_10000000/ad.json?pbsrv_v=1.1.0&id=masterId&nc=1"
.containsExactlyInAnyOrder("https://myao.adocean.pl/_10000000/ad.json?pbsrv_v=1.2.0&id=masterId&nc=1"
+ "&nosecure=1&aid=slaveId%3Aao-test&gdpr_consent=consent&gdpr=1&hcuserid=testBuyerUid"
+ "&aosspsizes=slaveId%7E300x250_600x320&aid=slaveId2%3Ai2-test&aosspsizes=slaveId2%7E577x333");
}
Expand Down Expand Up @@ -360,6 +361,97 @@ public void makeBidsShouldReturnEmptyListOfBids() throws JsonProcessingException
assertThat(result.getValue()).isEqualTo(Collections.emptyList());
}

@Test
public void makeHttpRequestsShouldBuildUrlIfAppIsPresent() {
// given
final BidRequest bidRequest = BidRequest.builder()
.user(User.builder()
.ext(ExtUser.builder()
.consent("consent").build())
.build())
.imp(singletonList(Imp.builder()
.id("ao-test")
.ext(mapper.valueToTree(ExtPrebid.of(null,
ExtImpAdocean.of("myao.adocean.pl", "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7",
"adoceanmyaozpniqismex"))))
.build()))
.test(1)
.app(App.builder().name("name").bundle("bundle").domain("domain").build())
.build();

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

// then
assertThat(result.getValue()).hasSize(1)
.extracting(HttpRequest::getUri)
.containsExactlyInAnyOrder("https://myao.adocean.pl/_10000000/ad.json?pbsrv_v=1.2.0"
+ "&id=tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7&nc=1&nosecure=1"
+ "&aid=adoceanmyaozpniqismex%3Aao-test&gdpr_consent=consent"
+ "&gdpr=1&app=1&appname=name&appbundle=bundle&appdomain=domain");
}

@Test
public void makeHttpRequestsShouldBuildUrlIfDeviceWithIfaIsPresent() {
// given
final BidRequest bidRequest = BidRequest.builder()
.user(User.builder()
.ext(ExtUser.builder()
.consent("consent").build())
.build())
.imp(singletonList(Imp.builder()
.id("ao-test")
.ext(mapper.valueToTree(ExtPrebid.of(null,
ExtImpAdocean.of("myao.adocean.pl", "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7",
"adoceanmyaozpniqismex"))))
.build()))
.test(1)
.device(Device.builder().ifa("ifa").os("os").osv("osv").model("model").make("make").build())
.build();

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

// then
assertThat(result.getValue()).hasSize(1)
.extracting(HttpRequest::getUri)
.containsExactlyInAnyOrder("https://myao.adocean.pl/_10000000/ad.json?pbsrv_v=1.2.0"
+ "&id=tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7"
+ "&nc=1&nosecure=1&aid=adoceanmyaozpniqismex%3Aao-test"
+ "&gdpr_consent=consent&gdpr=1&ifa=ifa&devos=os&devosv=osv&devmodel=model&devmake=make");
}

@Test
public void makeHttpRequestsShouldBuildUrlIfDeviceWithIfaIsNotPresent() {
// given
final BidRequest bidRequest = BidRequest.builder()
.user(User.builder()
.ext(ExtUser.builder()
.consent("consent").build())
.build())
.imp(singletonList(Imp.builder()
.id("ao-test")
.ext(mapper.valueToTree(ExtPrebid.of(null,
ExtImpAdocean.of("myao.adocean.pl", "tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7",
"adoceanmyaozpniqismex"))))
.build()))
.test(1)
.device(Device.builder().dpidmd5("dpidmd5").os("os").osv("osv").model("model").make("make").build())
.build();

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

// then
assertThat(result.getValue()).hasSize(1)
.extracting(HttpRequest::getUri)
.containsExactlyInAnyOrder("https://myao.adocean.pl/_10000000/ad.json?pbsrv_v=1.2.0"
+ "&id=tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7"
+ "&nc=1&nosecure=1&aid=adoceanmyaozpniqismex%3Aao-test"
+ "&gdpr_consent=consent&gdpr=1&dpidmd5=dpidmd5&devos=os&devosv=osv"
+ "&devmodel=model&devmake=make");
}

private static AdoceanResponseAdUnit adoceanResponseCreator(
Function<AdoceanResponseAdUnit.AdoceanResponseAdUnitBuilder,
AdoceanResponseAdUnit.AdoceanResponseAdUnitBuilder> adoceanCustomizer) {
Expand Down
4 changes: 1 addition & 3 deletions src/test/java/org/prebid/server/it/AdoceanTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class AdoceanTest extends IntegrationTest {
public void openrtb2AuctionShouldRespondWithBidsFromAdocean() throws IOException, JSONException {

WIRE_MOCK_RULE.stubFor(get(WireMock.urlPathEqualTo("/adocean-exchange/_10000000/ad.json"))
.withQueryParam("pbsrv_v", equalTo("1.1.0"))
.withQueryParam("pbsrv_v", equalTo("1.2.0"))
.withQueryParam("id", equalTo("tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7"))
.withQueryParam("nc", equalTo("1"))
.withQueryParam("nosecure", equalTo("1"))
Expand All @@ -36,7 +36,6 @@ public void openrtb2AuctionShouldRespondWithBidsFromAdocean() throws IOException
.withHeader("Content-Type", WireMock.equalTo("application/json;charset=UTF-8"))
.withHeader("Host", equalTo("localhost:8090"))
.withHeader("X-Forwarded-For", equalTo("193.168.244.1"))
.withHeader("Referer", equalTo("http://www.example.com"))
.withHeader("User-Agent", equalTo("userAgent"))
.withRequestBody(WireMock.absent())
.willReturn(WireMock.aResponse()
Expand All @@ -50,7 +49,6 @@ public void openrtb2AuctionShouldRespondWithBidsFromAdocean() throws IOException

// when
final Response response = given(SPEC)
.header("Referer", "http://www.example.com")
.header("X-Forwarded-For", "193.168.244.1")
.header("User-Agent", "userAgent")
.header("Origin", "http://www.example.com")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,16 @@
"language": "en",
"ifa": "ifaId",
"ua": "userAgent",
"ip": "193.168.244.1"
"ip": "193.168.244.1",
"os": "devos",
"osv": "devosv",
"model": "devmodel",
"make": "devmake"
},
"site": {
"publisher": {
"id": "publisherId",
"page": "http://www.example.com"
}
"app": {
"name": "appname",
"bundle": "appbundle",
"domain": "appdomain"
},
"at": 1,
"tmax": 5000,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
"prebid": {
"type": "banner",
"targeting": {
"hb_env": "mobile-app",
"hb_env_adocean": "mobile-app",
"hb_pb": "10.00",
"hb_cache_host_adocean": "{{ cache.host }}",
"hb_cache_path": "{{ cache.path }}",
Expand Down Expand Up @@ -50,7 +52,7 @@
"httpcalls": {
"adocean": [
{
"uri": "{{ adocean.exchange_uri }}/_10000000/ad.json?pbsrv_v=1.1.0&id=tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7&nc=1&nosecure=1&aid=adoceanmyaozpniqismex%3AimpId12&gdpr_consent=consentValue&gdpr=1&hcuserid=AO-UID&aosspsizes=myaozpniqismex%7E300x250",
"uri": "{{ adocean.exchange_uri }}/_10000000/ad.json?pbsrv_v=1.2.0&id=tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7&nc=1&nosecure=1&aid=adoceanmyaozpniqismex%3AimpId12&gdpr_consent=consentValue&gdpr=1&hcuserid=AO-UID&app=1&appname=appname&appbundle=appbundle&appdomain=appdomain&ifa=ifaId&devos=devos&devosv=devosv&devmodel=devmodel&devmake=devmake&aosspsizes=myaozpniqismex%7E300x250",
"responsebody": "[{\"id\":\"adoceanmyaozpniqismex\",\"price\":\"10\",\"winurl\":\"https://win-url.com\",\"statsUrl\":\"https://stats-url.com\",\"code\":\" <!-- code 1 --> \",\"currency\":\"EUR\",\"width\":\"300\",\"height\":\"250\",\"crid\":\"0af345b42983cc4bc0\",\"error\":\"false\"},{\"id\":\"adoceanmyaozpniqismexs\",\"price\":\"12\",\"winurl\":\"https://win-url.com\",\"statsUrl\":\"https://stats-url.com\",\"code\":\" <!-- code 1 --> \",\"currency\":\"EUR\",\"width\":\"300\",\"height\":\"250\",\"crid\":\"0af345b42983cc4bc0\",\"error\":\"false\"}]",
"status": 200
}
Expand Down Expand Up @@ -90,21 +92,14 @@
}
}
],
"site": {
"domain": "www.example.com",
"page": "http://www.example.com",
"publisher": {
"id": "publisherId",
"domain": "example.com"
},
"ext": {
"amp": 0
}
},
"device": {
"ua": "userAgent",
"dnt": 2,
"ip": "193.168.244.1",
"make": "devmake",
"model": "devmodel",
"os": "devos",
"osv": "devosv",
"pxratio": 4.2,
"language": "en",
"ifa": "ifaId"
Expand All @@ -117,6 +112,11 @@
},
"test": 1,
"at": 1,
"app": {
"name": "appname",
"bundle": "appbundle",
"domain": "appdomain"
},
"tmax": 5000,
"cur": [
"EUR"
Expand Down Expand Up @@ -163,7 +163,7 @@
},
"auctiontimestamp": 1000,
"channel": {
"name": "web"
"name": "app"
}
}
}
Expand All @@ -178,4 +178,4 @@
"auctiontimestamp": 1000
}
}
}
}

0 comments on commit c2a9054

Please sign in to comment.