Skip to content

Commit

Permalink
Update currencyService to accept bidRequest as parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
BraslavskiyAndrey committed Oct 21, 2020
1 parent d5fbcba commit 2fb0215
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 62 deletions.
18 changes: 2 additions & 16 deletions src/main/java/org/prebid/server/auction/ExchangeService.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
import org.prebid.server.proto.openrtb.ext.request.ExtBidderConfigFpd;
import org.prebid.server.proto.openrtb.ext.request.ExtImpPrebid;
import org.prebid.server.proto.openrtb.ext.request.ExtRequest;
import org.prebid.server.proto.openrtb.ext.request.ExtRequestCurrency;
import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebid;
import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebidBidderConfig;
import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebidCache;
Expand Down Expand Up @@ -189,18 +188,6 @@ private static ExtRequestTargeting targeting(BidRequest bidRequest) {
return prebid != null ? prebid.getTargeting() : null;
}

private static Map<String, Map<String, BigDecimal>> currencyRates(BidRequest bidRequest) {
final ExtRequestPrebid prebid = extRequestPrebid(bidRequest);
final ExtRequestCurrency currency = prebid != null ? prebid.getCurrency() : null;
return currency != null ? currency.getRates() : null;
}

private static Boolean usepbsrates(BidRequest bidRequest) {
final ExtRequestPrebid prebid = extRequestPrebid(bidRequest);
final ExtRequestCurrency currency = prebid != null ? prebid.getCurrency() : null;
return currency != null ? currency.getUsepbsrates() : null;
}

/**
* Creates {@link BidRequestCacheInfo} based on {@link BidRequest} model.
*/
Expand Down Expand Up @@ -885,15 +872,14 @@ private BidderResponse applyBidPriceChanges(BidderResponse bidderResponse, BidRe

final String adServerCurrency = bidRequest.getCur().get(0);
final BigDecimal priceAdjustmentFactor = bidAdjustmentForBidder(bidRequest, bidderResponse.getBidder());
final Boolean usepbsrates = usepbsrates(bidRequest);

for (final BidderBid bidderBid : bidderBids) {
final Bid bid = bidderBid.getBid();
final String bidCurrency = bidderBid.getBidCurrency();
final BigDecimal price = bid.getPrice();
try {
final BigDecimal priceInAdServerCurrency = currencyService.convertCurrency(
price, currencyRates(bidRequest), adServerCurrency, bidCurrency, usepbsrates);
final BigDecimal priceInAdServerCurrency = currencyService.convertCurrency(price, bidRequest,
adServerCurrency, bidCurrency);

final BigDecimal adjustedPrice = adjustPrice(priceAdjustmentFactor, priceInAdServerCurrency);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.prebid.server.currency;

import com.iab.openrtb.request.BidRequest;
import io.vertx.core.Future;
import io.vertx.core.Vertx;
import io.vertx.core.logging.Logger;
Expand All @@ -10,6 +11,9 @@
import org.prebid.server.currency.proto.CurrencyConversionRates;
import org.prebid.server.exception.PreBidException;
import org.prebid.server.json.JacksonMapper;
import org.prebid.server.proto.openrtb.ext.request.ExtRequest;
import org.prebid.server.proto.openrtb.ext.request.ExtRequestCurrency;
import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebid;
import org.prebid.server.spring.config.model.ExternalConversionProperties;
import org.prebid.server.util.HttpUtil;
import org.prebid.server.vertx.Initializable;
Expand Down Expand Up @@ -141,13 +145,23 @@ public Map<String, Map<String, BigDecimal>> getExternalCurrencyRates() {
return externalCurrencyRates;
}

/**
* Converts price from fromCurrency to toCurrency using rates from {@link BidRequest} or external currency service.
* If bidrequest.prebid.currecy.usepbsrates is true it takes rates from prebid server, if false from request.
* Default value of usepbsrates is true.
* Throws {@link PreBidException} in case conversion is not possible.
*/
public BigDecimal convertCurrency(BigDecimal price, BidRequest bidRequest, String fromCurrency, String toCurrency) {
return convertCurrency(price, currencyRates(bidRequest), fromCurrency, toCurrency, usepbsrates(bidRequest));
}

/**
* Converts price from bidCurrency to adServerCurrency using rates and usepbsrates flag defined in request.
* If usepbsrates is true it takes rates from prebid server, if false from request. Default value of usepbsrates
* is true.
* Throws {@link PreBidException} in case conversion is not possible.
*/
public BigDecimal convertCurrency(BigDecimal price, Map<String, Map<String, BigDecimal>> requestCurrencyRates,
private BigDecimal convertCurrency(BigDecimal price, Map<String, Map<String, BigDecimal>> requestCurrencyRates,
String adServerCurrency, String bidCurrency, Boolean usepbsrates) {
// use Default USD currency if bidder left this field empty. After, when bidder will implement multi currency
// support it will be changed to throwing PrebidException.
Expand Down Expand Up @@ -178,6 +192,23 @@ public BigDecimal convertCurrency(BigDecimal price, Map<String, Map<String, BigD
return price.divide(conversionRate, DEFAULT_PRICE_PRECISION, RoundingMode.HALF_EVEN);
}

private static Map<String, Map<String, BigDecimal>> currencyRates(BidRequest bidRequest) {
final ExtRequestPrebid prebid = extRequestPrebid(bidRequest);
final ExtRequestCurrency currency = prebid != null ? prebid.getCurrency() : null;
return currency != null ? currency.getRates() : null;
}

private static ExtRequestPrebid extRequestPrebid(BidRequest bidRequest) {
final ExtRequest requestExt = bidRequest.getExt();
return requestExt != null ? requestExt.getPrebid() : null;
}

private static Boolean usepbsrates(BidRequest bidRequest) {
final ExtRequestPrebid prebid = extRequestPrebid(bidRequest);
final ExtRequestCurrency currency = prebid != null ? prebid.getCurrency() : null;
return currency != null ? currency.getUsepbsrates() : null;
}

/**
* Returns conversion rate from the given currency rates according to priority.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.prebid.server.auction;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.iab.openrtb.request.BidRequest;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
Expand All @@ -15,6 +16,9 @@
import org.prebid.server.currency.CurrencyConversionService;
import org.prebid.server.currency.proto.CurrencyConversionRates;
import org.prebid.server.exception.PreBidException;
import org.prebid.server.proto.openrtb.ext.request.ExtRequest;
import org.prebid.server.proto.openrtb.ext.request.ExtRequestCurrency;
import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebid;
import org.prebid.server.spring.config.model.ExternalConversionProperties;
import org.prebid.server.vertx.http.HttpClient;
import org.prebid.server.vertx.http.model.HttpClientResponse;
Expand Down Expand Up @@ -85,7 +89,8 @@ public void convertCurrencyShouldReturnSamePriceIfBidAndServerCurrenciesEquals()
final BigDecimal price = BigDecimal.valueOf(100);

// when
final BigDecimal convertedPrice = currencyService.convertCurrency(price, null, USD, USD, false);
final BigDecimal convertedPrice = currencyService.convertCurrency(price,
givenBidRequestWithCurrencies(null, false), USD, USD);

// then
assertThat(convertedPrice).isSameAs(price);
Expand All @@ -98,8 +103,8 @@ public void convertCurrencyShouldUseUSDByDefaultIfBidCurrencyIsNull() {
singletonMap(GBP, singletonMap(USD, BigDecimal.valueOf(1.4306)));

// when
final BigDecimal price = currencyService.convertCurrency(BigDecimal.ONE, requestConversionRates, GBP, null,
false);
final BigDecimal price = currencyService.convertCurrency(BigDecimal.ONE,
givenBidRequestWithCurrencies(requestConversionRates, false), GBP, null);

// then
assertThat(price.compareTo(BigDecimal.valueOf(0.699))).isEqualTo(0);
Expand All @@ -112,8 +117,8 @@ public void convertCurrencyShouldReturnConvertedByStraightMultiplierPrice() {
singletonMap(EUR, BigDecimal.valueOf(1.1565)));

// when
final BigDecimal price = currencyService.convertCurrency(BigDecimal.ONE, requestConversionRates, GBP, EUR,
false);
final BigDecimal price = currencyService.convertCurrency(BigDecimal.ONE,
givenBidRequestWithCurrencies(requestConversionRates, false), GBP, EUR);

// then
assertThat(price.compareTo(BigDecimal.valueOf(0.865))).isEqualTo(0);
Expand All @@ -126,8 +131,8 @@ public void convertCurrencyShouldReturnConvertedByInvertedMultiplierPrice() {
BigDecimal.valueOf(1.1565)));

// when
final BigDecimal price = currencyService.convertCurrency(BigDecimal.ONE, requestConversionRates, EUR, GBP,
false);
final BigDecimal price = currencyService.convertCurrency(BigDecimal.ONE,
givenBidRequestWithCurrencies(requestConversionRates, false), EUR, GBP);

// then
assertThat(price.compareTo(BigDecimal.valueOf(1.156))).isEqualTo(0);
Expand All @@ -141,8 +146,8 @@ public void convertCurrencyShouldReturnConvertedByIntermediateMultiplierPrice()
requestConversionRates.put(EUR, singletonMap(USD, BigDecimal.valueOf(1.2304)));

// when
final BigDecimal price = currencyService.convertCurrency(BigDecimal.ONE, requestConversionRates, EUR, GBP,
false);
final BigDecimal price = currencyService.convertCurrency(BigDecimal.ONE,
givenBidRequestWithCurrencies(requestConversionRates, false), EUR, GBP);

// then
assertThat(price.compareTo(BigDecimal.valueOf(1.163))).isEqualTo(0);
Expand All @@ -155,8 +160,8 @@ public void convertCurrencyShouldReturnConvertedBySingleDigitMultiplierPrice() {
requestConversionRates.put(EUR, singletonMap(USD, BigDecimal.valueOf(0.5)));

// when
final BigDecimal price = currencyService.convertCurrency(new BigDecimal("1.23"), requestConversionRates, EUR,
USD, false);
final BigDecimal price = currencyService.convertCurrency(new BigDecimal("1.23"),
givenBidRequestWithCurrencies(requestConversionRates, false), EUR, USD);

// then
assertThat(price.compareTo(BigDecimal.valueOf(2.460))).isEqualTo(0);
Expand All @@ -165,7 +170,8 @@ public void convertCurrencyShouldReturnConvertedBySingleDigitMultiplierPrice() {
@Test
public void convertCurrencyShouldUseLatestRatesIfRequestRatesIsNull() {
// when
final BigDecimal price = currencyService.convertCurrency(BigDecimal.ONE, null, EUR, GBP, false);
final BigDecimal price = currencyService.convertCurrency(
BigDecimal.ONE, givenBidRequestWithCurrencies(null, false), EUR, GBP);

// then
assertThat(price.compareTo(BigDecimal.valueOf(1.149))).isEqualTo(0);
Expand All @@ -178,8 +184,8 @@ public void convertCurrencyShouldUseConversionRateFromServerIfusepbsratesIsTrue(
requestConversionRates.put(EUR, singletonMap(USD, BigDecimal.valueOf(0.6)));

// when
final BigDecimal price = currencyService.convertCurrency(BigDecimal.ONE, requestConversionRates, EUR, GBP,
true);
final BigDecimal price = currencyService.convertCurrency(BigDecimal.ONE,
givenBidRequestWithCurrencies(requestConversionRates, true), EUR, GBP);

// then
assertThat(price.compareTo(BigDecimal.valueOf(1.149))).isEqualTo(0);
Expand All @@ -192,8 +198,8 @@ public void convertCurrencyShouldUseConversionRateFromRequestIfusepbsratesIsFals
BigDecimal.valueOf(0.6)));

// when
final BigDecimal price = currencyService.convertCurrency(BigDecimal.ONE, requestConversionRates, EUR, USD,
false);
final BigDecimal price = currencyService.convertCurrency(BigDecimal.ONE,
givenBidRequestWithCurrencies(requestConversionRates, false), EUR, USD);

// then
assertThat(price.compareTo(BigDecimal.valueOf(1.667))).isEqualTo(0);
Expand All @@ -206,8 +212,8 @@ public void convertCurrencyShouldUseLatestRatesIfMultiplierWasNotFoundInRequestR
singletonMap(EUR, BigDecimal.valueOf(0.8434)));

// when
final BigDecimal price = currencyService.convertCurrency(BigDecimal.ONE, requestConversionRates, EUR, UAH,
false);
final BigDecimal price = currencyService.convertCurrency(BigDecimal.ONE,
givenBidRequestWithCurrencies(requestConversionRates, false), EUR, UAH);

// then
assertThat(price.compareTo(BigDecimal.valueOf(1.156))).isEqualTo(0);
Expand All @@ -216,7 +222,8 @@ public void convertCurrencyShouldUseLatestRatesIfMultiplierWasNotFoundInRequestR
@Test
public void convertCurrencyShouldReturnSamePriceIfBidCurrencyIsNullAndServerCurrencyUSD() {
// when
final BigDecimal price = currencyService.convertCurrency(BigDecimal.ONE, emptyMap(), USD, null, false);
final BigDecimal price = currencyService.convertCurrency(BigDecimal.ONE,
givenBidRequestWithCurrencies(emptyMap(), false), USD, null);

// then
assertThat(price.compareTo(BigDecimal.ONE)).isEqualTo(0);
Expand All @@ -229,16 +236,17 @@ public void convertCurrencyShouldFailWhenRequestRatesIsNullAndNoExternalRatesPro

// when and then
assertThatExceptionOfType(PreBidException.class)
.isThrownBy(() -> currencyConversionService.convertCurrency(BigDecimal.ONE, null, EUR, GBP,
false))
.isThrownBy(() -> currencyConversionService.convertCurrency(BigDecimal.ONE,
givenBidRequestWithCurrencies(null, false), EUR, GBP))
.withMessage("no currency conversion available");
}

@Test
public void convertCurrencyShouldThrowPrebidExceptionIfServerAndRequestRatesAreNull() {
// when and then
assertThatExceptionOfType(PreBidException.class)
.isThrownBy(() -> currencyService.convertCurrency(BigDecimal.ONE, null, USD, EUR, false))
.isThrownBy(() -> currencyService.convertCurrency(BigDecimal.ONE,
givenBidRequestWithCurrencies(null, false), USD, EUR))
.withMessage("no currency conversion available");
}

Expand All @@ -255,8 +263,8 @@ public void convertCurrencyShouldThrowPrebidExceptionIfMultiplierWasNotFoundFrom

// then
assertThatExceptionOfType(PreBidException.class)
.isThrownBy(() -> currencyService.convertCurrency(BigDecimal.ONE, requestConversionRates, EUR, AUD,
false))
.isThrownBy(() -> currencyService.convertCurrency(BigDecimal.ONE,
givenBidRequestWithCurrencies(requestConversionRates, false), EUR, AUD))
.withMessage("no currency conversion available");
}

Expand All @@ -270,7 +278,8 @@ public void convertCurrencyShouldThrowExceptionWhenCurrencyServerResponseStatusN

// then
assertThatExceptionOfType(PreBidException.class)
.isThrownBy(() -> currencyService.convertCurrency(BigDecimal.ONE, null, UAH, AUD, false))
.isThrownBy(() -> currencyService.convertCurrency(BigDecimal.ONE,
givenBidRequestWithCurrencies(null, false), UAH, AUD))
.withMessage("no currency conversion available");
}

Expand All @@ -284,7 +293,8 @@ public void convertCurrencyShouldThrowExceptionWhenCurrencyServerResponseContain

// then
assertThatExceptionOfType(PreBidException.class)
.isThrownBy(() -> currencyService.convertCurrency(BigDecimal.ONE, null, UAH, AUD, false))
.isThrownBy(() -> currencyService.convertCurrency(BigDecimal.ONE,
givenBidRequestWithCurrencies(null, false), UAH, AUD))
.withMessage("no currency conversion available");
}

Expand Down Expand Up @@ -322,4 +332,12 @@ private static void givenHttpClientReturnsResponse(HttpClient httpClient, int st
given(httpClient.get(anyString(), anyLong()))
.willReturn(Future.succeededFuture(httpClientResponse));
}

private BidRequest givenBidRequestWithCurrencies(Map<String, Map<String, BigDecimal>> requestCurrencies,
Boolean usepbsrates) {
return BidRequest.builder()
.ext(ExtRequest.of(ExtRequestPrebid.builder()
.currency(ExtRequestCurrency.of(requestCurrencies, usepbsrates)).build()))
.build();
}
}
Loading

0 comments on commit 2fb0215

Please sign in to comment.