Skip to content

Commit 80e6a5f

Browse files
PgamSsp: Add currency conversion (#3540)
1 parent 658790c commit 80e6a5f

3 files changed

Lines changed: 83 additions & 5 deletions

File tree

src/main/java/org/prebid/server/bidder/pgamssp/PgamSspBidder.java

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,19 @@
1414
import org.prebid.server.bidder.model.BidderCall;
1515
import org.prebid.server.bidder.model.BidderError;
1616
import org.prebid.server.bidder.model.HttpRequest;
17+
import org.prebid.server.bidder.model.Price;
1718
import org.prebid.server.bidder.model.Result;
19+
import org.prebid.server.currency.CurrencyConversionService;
1820
import org.prebid.server.exception.PreBidException;
1921
import org.prebid.server.json.DecodeException;
2022
import org.prebid.server.json.JacksonMapper;
2123
import org.prebid.server.proto.openrtb.ext.ExtPrebid;
2224
import org.prebid.server.proto.openrtb.ext.request.pgamssp.PgamSspImpExt;
2325
import org.prebid.server.proto.openrtb.ext.response.BidType;
26+
import org.prebid.server.util.BidderUtil;
2427
import org.prebid.server.util.HttpUtil;
2528

29+
import java.math.BigDecimal;
2630
import java.util.ArrayList;
2731
import java.util.Collections;
2832
import java.util.List;
@@ -35,12 +39,18 @@ public class PgamSspBidder implements Bidder<BidRequest> {
3539
};
3640
private static final String PUBLISHER_IMP_EXT_TYPE = "publisher";
3741
private static final String NETWORK_IMP_EXT_TYPE = "network";
42+
private static final String DEFAULT_BID_CURRENCY = "USD";
3843

3944
private final String endpointUrl;
45+
private final CurrencyConversionService currencyConversionService;
4046
private final JacksonMapper mapper;
4147

42-
public PgamSspBidder(String endpointUrl, JacksonMapper mapper) {
48+
public PgamSspBidder(String endpointUrl,
49+
CurrencyConversionService currencyConversionService,
50+
JacksonMapper mapper) {
51+
4352
this.endpointUrl = HttpUtil.validateUrl(Objects.requireNonNull(endpointUrl));
53+
this.currencyConversionService = Objects.requireNonNull(currencyConversionService);
4454
this.mapper = Objects.requireNonNull(mapper);
4555
}
4656

@@ -51,7 +61,7 @@ public Result<List<HttpRequest<BidRequest>>> makeHttpRequests(BidRequest request
5161
for (Imp imp : request.getImp()) {
5262
try {
5363
final PgamSspImpExt impExt = parseImpExt(imp);
54-
final BidRequest modifiedBidRequest = makeRequest(request, imp, impExt);
64+
final BidRequest modifiedBidRequest = makeRequest(request, modifyImp(imp, request), impExt);
5565
httpRequests.add(makeHttpRequest(modifiedBidRequest, imp.getId()));
5666
} catch (PreBidException e) {
5767
return Result.withError(BidderError.badInput(e.getMessage()));
@@ -61,6 +71,31 @@ public Result<List<HttpRequest<BidRequest>>> makeHttpRequests(BidRequest request
6171
return Result.withValues(httpRequests);
6272
}
6373

74+
private Imp modifyImp(Imp imp, BidRequest bidRequest) {
75+
final Price resolvedBidFloor = resolveBidFloor(imp, bidRequest);
76+
return imp.toBuilder()
77+
.bidfloor(resolvedBidFloor.getValue())
78+
.bidfloorcur(resolvedBidFloor.getCurrency())
79+
.build();
80+
}
81+
82+
private Price resolveBidFloor(Imp imp, BidRequest bidRequest) {
83+
final Price initialBidFloorPrice = Price.of(imp.getBidfloorcur(), imp.getBidfloor());
84+
return BidderUtil.shouldConvertBidFloor(initialBidFloorPrice, DEFAULT_BID_CURRENCY)
85+
? convertBidFloor(initialBidFloorPrice, bidRequest)
86+
: initialBidFloorPrice;
87+
}
88+
89+
private Price convertBidFloor(Price bidFloorPrice, BidRequest bidRequest) {
90+
final BigDecimal convertedPrice = currencyConversionService.convertCurrency(
91+
bidFloorPrice.getValue(),
92+
bidRequest,
93+
bidFloorPrice.getCurrency(),
94+
DEFAULT_BID_CURRENCY);
95+
96+
return Price.of(DEFAULT_BID_CURRENCY, convertedPrice);
97+
}
98+
6499
private PgamSspImpExt parseImpExt(Imp imp) throws PreBidException {
65100
try {
66101
return mapper.mapper().convertValue(imp.getExt(), PGAMSSP_EXT_TYPE_REFERENCE).getBidder();

src/main/java/org/prebid/server/spring/config/bidder/PgamSspConfiguration.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import org.prebid.server.bidder.BidderDeps;
44
import org.prebid.server.bidder.pgamssp.PgamSspBidder;
5+
import org.prebid.server.currency.CurrencyConversionService;
56
import org.prebid.server.json.JacksonMapper;
67
import org.prebid.server.spring.config.bidder.model.BidderConfigurationProperties;
78
import org.prebid.server.spring.config.bidder.util.BidderDepsAssembler;
@@ -29,13 +30,14 @@ BidderConfigurationProperties configurationProperties() {
2930

3031
@Bean
3132
BidderDeps pgamsspBidderDeps(BidderConfigurationProperties pgamsspConfigurationProperties,
33+
CurrencyConversionService currencyConversionService,
3234
@NotBlank @Value("${external-url}") String externalUrl,
3335
JacksonMapper mapper) {
3436

3537
return BidderDepsAssembler.forBidder(BIDDER_NAME)
3638
.withConfig(pgamsspConfigurationProperties)
3739
.usersyncerCreator(UsersyncerCreator.create(externalUrl))
38-
.bidderCreator(config -> new PgamSspBidder(config.getEndpoint(), mapper))
40+
.bidderCreator(config -> new PgamSspBidder(config.getEndpoint(), currencyConversionService, mapper))
3941
.assemble();
4042
}
4143
}

src/test/java/org/prebid/server/bidder/pgamssp/PgamSspBidderTest.java

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,23 @@
88
import com.iab.openrtb.response.BidResponse;
99
import com.iab.openrtb.response.SeatBid;
1010
import io.vertx.core.http.HttpMethod;
11+
import org.assertj.core.api.BDDAssertions;
12+
import org.junit.jupiter.api.BeforeEach;
1113
import org.junit.jupiter.api.Test;
14+
import org.junit.jupiter.api.extension.ExtendWith;
15+
import org.mockito.Mock;
16+
import org.mockito.junit.jupiter.MockitoExtension;
1217
import org.prebid.server.VertxTest;
1318
import org.prebid.server.bidder.model.BidderBid;
1419
import org.prebid.server.bidder.model.BidderCall;
1520
import org.prebid.server.bidder.model.HttpRequest;
1621
import org.prebid.server.bidder.model.HttpResponse;
1722
import org.prebid.server.bidder.model.Result;
23+
import org.prebid.server.currency.CurrencyConversionService;
1824
import org.prebid.server.proto.openrtb.ext.ExtPrebid;
1925
import org.prebid.server.proto.openrtb.ext.request.pgamssp.PgamSspImpExt;
2026

27+
import java.math.BigDecimal;
2128
import java.util.Arrays;
2229
import java.util.List;
2330
import java.util.Set;
@@ -27,6 +34,9 @@
2734
import static org.assertj.core.api.Assertions.assertThat;
2835
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
2936
import static org.assertj.core.api.Assertions.tuple;
37+
import static org.mockito.ArgumentMatchers.any;
38+
import static org.mockito.ArgumentMatchers.anyString;
39+
import static org.mockito.BDDMockito.given;
3040
import static org.prebid.server.bidder.model.BidderError.badInput;
3141
import static org.prebid.server.bidder.model.BidderError.badServerResponse;
3242
import static org.prebid.server.proto.openrtb.ext.response.BidType.banner;
@@ -37,15 +47,46 @@
3747
import static org.prebid.server.util.HttpUtil.CONTENT_TYPE_HEADER;
3848
import static org.springframework.util.MimeTypeUtils.APPLICATION_JSON_VALUE;
3949

50+
@ExtendWith(MockitoExtension.class)
4051
public class PgamSspBidderTest extends VertxTest {
4152

4253
private static final String ENDPOINT_URL = "http://test-url.com";
4354

44-
private final PgamSspBidder target = new PgamSspBidder(ENDPOINT_URL, jacksonMapper);
55+
@Mock
56+
private CurrencyConversionService currencyConversionService;
57+
58+
private PgamSspBidder target;
59+
60+
@BeforeEach
61+
public void setUp() {
62+
target = new PgamSspBidder(ENDPOINT_URL, currencyConversionService, jacksonMapper);
63+
}
4564

4665
@Test
4766
public void creationShouldFailOnInvalidEndpointUrl() {
48-
assertThatIllegalArgumentException().isThrownBy(() -> new PgamSspBidder("invalid_url", jacksonMapper));
67+
assertThatIllegalArgumentException().isThrownBy(() ->
68+
new PgamSspBidder("invalid_url", currencyConversionService, jacksonMapper));
69+
}
70+
71+
@Test
72+
public void makeHttpRequestsShouldConvertCurrencyIfRequestCurrencyDoesNotMatchBidderCurrency() {
73+
// given
74+
given(currencyConversionService.convertCurrency(any(), any(), anyString(), anyString()))
75+
.willReturn(BigDecimal.TEN);
76+
77+
final BidRequest bidRequest = givenBidRequest(
78+
impBuilder -> impBuilder.bidfloor(BigDecimal.ONE).bidfloorcur("EUR"));
79+
80+
// when
81+
final Result<List<HttpRequest<BidRequest>>> result = target.makeHttpRequests(bidRequest);
82+
83+
// then
84+
assertThat(result.getErrors()).isEmpty();
85+
assertThat(result.getValue())
86+
.extracting(HttpRequest::getPayload)
87+
.flatExtracting(BidRequest::getImp)
88+
.extracting(Imp::getBidfloor, Imp::getBidfloorcur)
89+
.containsExactly(BDDAssertions.tuple(BigDecimal.TEN, "USD"));
4990
}
5091

5192
@Test

0 commit comments

Comments
 (0)