Skip to content

Commit

Permalink
ConnectAd: Update bidder (#3333)
Browse files Browse the repository at this point in the history
  • Loading branch information
CTMBNara authored Jul 30, 2024
1 parent febfa08 commit 101be17
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import com.iab.openrtb.response.BidResponse;
import com.iab.openrtb.response.SeatBid;
import io.vertx.core.MultiMap;
import io.vertx.core.http.HttpMethod;
import org.apache.commons.collections4.CollectionUtils;
import org.prebid.server.bidder.Bidder;
import org.prebid.server.bidder.model.BidderBid;
Expand All @@ -34,7 +33,7 @@
import java.util.List;
import java.util.Objects;

public class ConnectadBidder implements Bidder<BidRequest> {
public class ConnectAdBidder implements Bidder<BidRequest> {

private static final TypeReference<ExtPrebid<?, ExtImpConnectAd>> CONNECTAD_EXT_TYPE_REFERENCE =
new TypeReference<>() {
Expand All @@ -44,7 +43,7 @@ public class ConnectadBidder implements Bidder<BidRequest> {
private final String endpointUrl;
private final JacksonMapper mapper;

public ConnectadBidder(String endpointUrl, JacksonMapper mapper) {
public ConnectAdBidder(String endpointUrl, JacksonMapper mapper) {
this.endpointUrl = HttpUtil.validateUrl(Objects.requireNonNull(endpointUrl));
this.mapper = Objects.requireNonNull(mapper);
}
Expand All @@ -59,7 +58,7 @@ public Result<List<HttpRequest<BidRequest>>> makeHttpRequests(BidRequest request
for (Imp imp : request.getImp()) {
try {
final ExtImpConnectAd impExt = parseImpExt(imp);
final Imp updatedImp = updateImp(imp, secure, impExt.getSiteId(), impExt.getBidfloor());
final Imp updatedImp = updateImp(imp, secure, impExt.getSiteId(), impExt.getBidFloor());
processedImps.add(updatedImp);
} catch (PreBidException e) {
errors.add(BidderError.badInput(e.getMessage()));
Expand All @@ -71,14 +70,12 @@ public Result<List<HttpRequest<BidRequest>>> makeHttpRequests(BidRequest request
}
final BidRequest outgoingRequest = request.toBuilder().imp(processedImps).build();

return Result.of(Collections.singletonList(
HttpRequest.<BidRequest>builder()
.method(HttpMethod.POST)
.uri(endpointUrl)
.headers(resolveHeaders(request.getDevice()))
.payload(outgoingRequest)
.body(mapper.encodeToBytes(outgoingRequest))
.build()),
return Result.of(
Collections.singletonList(BidderUtil.defaultRequest(
outgoingRequest,
resolveHeaders(outgoingRequest.getDevice()),
endpointUrl,
mapper)),
errors);
}

Expand All @@ -95,36 +92,46 @@ private ExtImpConnectAd parseImpExt(Imp imp) {
throw new PreBidException("Impression id=%s, has invalid Ext".formatted(imp.getId()));
}
final Integer siteId = extImpConnectAd.getSiteId();
if (siteId == null || siteId.equals(0)) {
if (siteId == null || siteId == 0) {
throw new PreBidException("Impression id=%s, has no siteId present".formatted(imp.getId()));
}
return extImpConnectAd;
}

private Imp updateImp(Imp imp, Integer secure, Integer siteId, BigDecimal bidFloor) {
final Imp.ImpBuilder updatedImp = imp.toBuilder().tagid(siteId.toString()).secure(secure);

if (BidderUtil.isValidPrice(bidFloor)) {
updatedImp.bidfloor(bidFloor).bidfloorcur("USD");
}
final boolean isValidBidFloor = BidderUtil.isValidPrice(bidFloor);
return imp.toBuilder()
.banner(updateBanner(imp.getBanner()))
.tagid(siteId.toString())
.secure(secure)
.bidfloor(isValidBidFloor ? bidFloor : imp.getBidfloor())
.bidfloorcur(isValidBidFloor ? "USD" : imp.getBidfloorcur())
.build();
}

final Banner banner = imp.getBanner();
private static Banner updateBanner(Banner banner) {
if (banner == null) {
throw new PreBidException("We need a Banner Object in the request");
}

if (banner.getW() == null && banner.getH() == null) {
if (CollectionUtils.isEmpty(banner.getFormat())) {
throw new PreBidException("At least one size is required");
}
final Format format = banner.getFormat().getFirst();
final List<Format> slicedFormatList = new ArrayList<>(banner.getFormat());
if (banner.getW() != null || banner.getH() != null) {
return banner;
}

slicedFormatList.removeFirst();
updatedImp.banner(banner.toBuilder().format(slicedFormatList).w(format.getW()).h(format.getH()).build());
final List<Format> formats = banner.getFormat();
if (CollectionUtils.isEmpty(formats)) {
throw new PreBidException("At least one size is required");
}

return updatedImp.build();
final Format firstFormat = formats.getFirst();
final List<Format> slicedFormats = new ArrayList<>(formats);
slicedFormats.removeFirst();

return banner.toBuilder()
.format(slicedFormats)
.w(firstFormat.getW())
.h(firstFormat.getH())
.build();
}

private static MultiMap resolveHeaders(Device device) {
Expand All @@ -146,7 +153,7 @@ private static MultiMap resolveHeaders(Device device) {
public final Result<List<BidderBid>> makeBids(BidderCall<BidRequest> httpCall, BidRequest bidRequest) {
try {
final BidResponse bidResponse = mapper.decodeValue(httpCall.getResponse().getBody(), BidResponse.class);
return Result.of(extractBids(bidResponse), Collections.emptyList());
return Result.withValues(extractBids(bidResponse));
} catch (DecodeException | PreBidException e) {
return Result.withError(BidderError.badServerResponse(e.getMessage()));
}
Expand All @@ -156,15 +163,13 @@ private List<BidderBid> extractBids(BidResponse bidResponse) {
if (bidResponse == null || CollectionUtils.isEmpty(bidResponse.getSeatbid())) {
return Collections.emptyList();
}
return bidsFromResponse(bidResponse);
}

private List<BidderBid> bidsFromResponse(BidResponse bidResponse) {
return bidResponse.getSeatbid().stream()
.filter(Objects::nonNull)
.map(SeatBid::getBid)
.filter(Objects::nonNull)
.flatMap(Collection::stream)
.filter(Objects::nonNull)
.map(bid -> BidderBid.of(bid, BidType.banner, bidResponse.getCur()))
.toList();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ public class ExtImpConnectAd {
@JsonProperty("siteId")
Integer siteId;

BigDecimal bidfloor;
@JsonProperty("bidfloor")
BigDecimal bidFloor;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.prebid.server.spring.config.bidder;

import org.prebid.server.bidder.BidderDeps;
import org.prebid.server.bidder.connectad.ConnectadBidder;
import org.prebid.server.bidder.connectad.ConnectAdBidder;
import org.prebid.server.json.JacksonMapper;
import org.prebid.server.spring.config.bidder.model.BidderConfigurationProperties;
import org.prebid.server.spring.config.bidder.util.BidderDepsAssembler;
Expand Down Expand Up @@ -35,7 +35,7 @@ BidderDeps connectadBidderDeps(BidderConfigurationProperties connectadConfigurat
return BidderDepsAssembler.forBidder(BIDDER_NAME)
.withConfig(connectadConfigurationProperties)
.usersyncerCreator(UsersyncerCreator.create(externalUrl))
.bidderCreator(config -> new ConnectadBidder(config.getEndpoint(), mapper))
.bidderCreator(config -> new ConnectAdBidder(config.getEndpoint(), mapper))
.assemble();
}
}
14 changes: 12 additions & 2 deletions src/main/resources/bidder-config/connectad.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
adapters:
connectad:
endpoint: http://bidder.connectad.io/API?src=pbs
# Please uncomment the appropriate endpoint URL for your datacenter
# Europe
endpoint: "http://bidder.connectad.io/API?src=pbs"
# North/South America
# endpoint: "http://bidder-us.connectad.io/API?src=pbs"
# APAC
# endpoint: "http://bidder-apac.connectad.io/API?src=pbs"
endpoint-compression: gzip
meta-info:
maintainer-email: [email protected]
app-media-types:
Expand All @@ -11,6 +18,9 @@ adapters:
vendor-id: 138
usersync:
cookie-family-name: connectad
redirect:
url: https://sync.connectad.io/ImageSyncer?gdpr={{gdpr}}&consent={{gdpr_consent}}&us_privacy={{us_privacy}}&gpp={{gpp}}&gpp_sid={{gpp_sid}}&cb={{redirect_url}}
support-cors: false
iframe:
url: https://cdn.connectad.io/connectmyusers.php?gdpr={{gdpr}}&consent={{gdpr_consent}}&us_privacy={{us_privacy}}&cb={{redirect_url}}
url: https://sync.connectad.io/iFrameSyncer?gdpr={{gdpr}}&consent={{gdpr_consent}}&us_privacy={{us_privacy}}&gpp={{gpp}}&gpp_sid={{gpp_sid}}&cb={{redirect_url}}
support-cors: false
16 changes: 12 additions & 4 deletions src/main/resources/static/bidder-params/connectad.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,29 @@
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "ConnectAd S2S dapter Params",
"description": "A schema which validates params accepted by the ConnectAd Adapter",

"type": "object",
"properties": {
"networkId": {
"type": "integer",
"type": [
"integer",
"string"
],
"description": "NetworkId"
},
"siteId": {
"type": "integer",
"type": [
"integer",
"string"
],
"description": "SiteId"
},
"bidfloor": {
"type": "number",
"description": "Requests Floorprice"
}
},
"required": ["networkId", "siteId"]
"required": [
"networkId",
"siteId"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,16 @@
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.prebid.server.proto.openrtb.ext.response.BidType.banner;

public class ConnectadBidderTest extends VertxTest {
public class ConnectAdBidderTest extends VertxTest {

private static final String ENDPOINT_URL = "https://test.endpoint.com/";

private final ConnectadBidder target = new ConnectadBidder(ENDPOINT_URL, jacksonMapper);
private final ConnectAdBidder target = new ConnectAdBidder(ENDPOINT_URL, jacksonMapper);

@Test
public void creationShouldFailOnInvalidEndpointUrl() {
Assertions.assertThatIllegalArgumentException().isThrownBy(() ->
new ConnectadBidder("invalid_url", jacksonMapper));
new ConnectAdBidder("invalid_url", jacksonMapper));
}

@Test
Expand Down

0 comments on commit 101be17

Please sign in to comment.