11package org .prebid .server .auction ;
22
3- import com .fasterxml .jackson .databind .JsonNode ;
4- import com .fasterxml .jackson .databind .node .DecimalNode ;
5- import com .fasterxml .jackson .databind .node .ObjectNode ;
6- import com .fasterxml .jackson .databind .node .TextNode ;
73import com .iab .openrtb .request .BidRequest ;
84import com .iab .openrtb .response .Bid ;
9- import org .apache .commons .lang3 .StringUtils ;
10- import org .prebid .server .auction .adjustment .BidAdjustmentFactorResolver ;
115import org .prebid .server .auction .model .AuctionContext ;
126import org .prebid .server .auction .model .AuctionParticipation ;
137import org .prebid .server .auction .model .BidderResponse ;
8+ import org .prebid .server .bidadjustments .BidAdjustmentsProcessor ;
149import org .prebid .server .bidder .model .BidderBid ;
1510import org .prebid .server .bidder .model .BidderError ;
1611import org .prebid .server .bidder .model .BidderSeatBid ;
17- import org .prebid .server .currency .CurrencyConversionService ;
18- import org .prebid .server .exception .PreBidException ;
1912import org .prebid .server .floors .PriceFloorEnforcer ;
20- import org .prebid .server .json .JacksonMapper ;
21- import org .prebid .server .proto .openrtb .ext .request .ExtRequestBidAdjustmentFactors ;
22- import org .prebid .server .proto .openrtb .ext .request .ExtRequestPrebid ;
23- import org .prebid .server .proto .openrtb .ext .request .ImpMediaType ;
2413import org .prebid .server .util .ObjectUtil ;
25- import org .prebid .server .util .PbsUtil ;
2614import org .prebid .server .validation .ResponseBidValidator ;
2715import org .prebid .server .validation .model .ValidationResult ;
2816
29- import java .math .BigDecimal ;
3017import java .util .ArrayList ;
3118import java .util .List ;
3219import java .util .Objects ;
3522
3623public class BidsAdjuster {
3724
38- private static final String ORIGINAL_BID_CPM = "origbidcpm" ;
39- private static final String ORIGINAL_BID_CURRENCY = "origbidcur" ;
40-
4125 private final ResponseBidValidator responseBidValidator ;
42- private final CurrencyConversionService currencyService ;
43- private final BidAdjustmentFactorResolver bidAdjustmentFactorResolver ;
4426 private final PriceFloorEnforcer priceFloorEnforcer ;
27+ private final BidAdjustmentsProcessor bidAdjustmentsProcessor ;
4528 private final DsaEnforcer dsaEnforcer ;
46- private final JacksonMapper mapper ;
4729
4830 public BidsAdjuster (ResponseBidValidator responseBidValidator ,
49- CurrencyConversionService currencyService ,
50- BidAdjustmentFactorResolver bidAdjustmentFactorResolver ,
5131 PriceFloorEnforcer priceFloorEnforcer ,
52- DsaEnforcer dsaEnforcer ,
53- JacksonMapper mapper ) {
32+ BidAdjustmentsProcessor bidAdjustmentsProcessor ,
33+ DsaEnforcer dsaEnforcer ) {
5434
5535 this .responseBidValidator = Objects .requireNonNull (responseBidValidator );
56- this .currencyService = Objects .requireNonNull (currencyService );
57- this .bidAdjustmentFactorResolver = Objects .requireNonNull (bidAdjustmentFactorResolver );
5836 this .priceFloorEnforcer = Objects .requireNonNull (priceFloorEnforcer );
37+ this .bidAdjustmentsProcessor = Objects .requireNonNull (bidAdjustmentsProcessor );
5938 this .dsaEnforcer = Objects .requireNonNull (dsaEnforcer );
60- this .mapper = Objects .requireNonNull (mapper );
6139 }
6240
6341 public List <AuctionParticipation > validateAndAdjustBids (List <AuctionParticipation > auctionParticipations ,
@@ -66,12 +44,18 @@ public List<AuctionParticipation> validateAndAdjustBids(List<AuctionParticipatio
6644
6745 return auctionParticipations .stream ()
6846 .map (auctionParticipation -> validBidderResponse (auctionParticipation , auctionContext , aliases ))
69- .map (auctionParticipation -> applyBidPriceChanges (auctionParticipation , auctionContext .getBidRequest ()))
47+
48+ .map (auctionParticipation -> bidAdjustmentsProcessor .enrichWithAdjustedBids (
49+ auctionParticipation ,
50+ auctionContext .getBidRequest (),
51+ auctionContext .getBidAdjustments ()))
52+
7053 .map (auctionParticipation -> priceFloorEnforcer .enforce (
7154 auctionContext .getBidRequest (),
7255 auctionParticipation ,
7356 auctionContext .getAccount (),
7457 auctionContext .getBidRejectionTrackers ().get (auctionParticipation .getBidder ())))
58+
7559 .map (auctionParticipation -> dsaEnforcer .enforce (
7660 auctionContext .getBidRequest (),
7761 auctionParticipation ,
@@ -137,104 +121,4 @@ private BidderError makeValidationBidderError(Bid bid, ValidationResult validati
137121 final String bidId = ObjectUtil .getIfNotNullOrDefault (bid , Bid ::getId , () -> "unknown" );
138122 return BidderError .invalidBid ("BidId `" + bidId + "` validation messages: " + validationErrors );
139123 }
140-
141- private AuctionParticipation applyBidPriceChanges (AuctionParticipation auctionParticipation ,
142- BidRequest bidRequest ) {
143- if (auctionParticipation .isRequestBlocked ()) {
144- return auctionParticipation ;
145- }
146-
147- final BidderResponse bidderResponse = auctionParticipation .getBidderResponse ();
148- final BidderSeatBid seatBid = bidderResponse .getSeatBid ();
149-
150- final List <BidderBid > bidderBids = seatBid .getBids ();
151- if (bidderBids .isEmpty ()) {
152- return auctionParticipation ;
153- }
154-
155- final List <BidderBid > updatedBidderBids = new ArrayList <>(bidderBids .size ());
156- final List <BidderError > errors = new ArrayList <>(seatBid .getErrors ());
157- final String adServerCurrency = bidRequest .getCur ().getFirst ();
158-
159- for (final BidderBid bidderBid : bidderBids ) {
160- try {
161- final BidderBid updatedBidderBid =
162- updateBidderBidWithBidPriceChanges (bidderBid , bidderResponse , bidRequest , adServerCurrency );
163- updatedBidderBids .add (updatedBidderBid );
164- } catch (PreBidException e ) {
165- errors .add (BidderError .generic (e .getMessage ()));
166- }
167- }
168-
169- final BidderResponse resultBidderResponse = bidderResponse .with (seatBid .toBuilder ()
170- .bids (updatedBidderBids )
171- .errors (errors )
172- .build ());
173- return auctionParticipation .with (resultBidderResponse );
174- }
175-
176- private BidderBid updateBidderBidWithBidPriceChanges (BidderBid bidderBid ,
177- BidderResponse bidderResponse ,
178- BidRequest bidRequest ,
179- String adServerCurrency ) {
180- final Bid bid = bidderBid .getBid ();
181- final String bidCurrency = bidderBid .getBidCurrency ();
182- final BigDecimal price = bid .getPrice ();
183-
184- final BigDecimal priceInAdServerCurrency = currencyService .convertCurrency (
185- price , bidRequest , StringUtils .stripToNull (bidCurrency ), adServerCurrency );
186-
187- final BigDecimal priceAdjustmentFactor =
188- bidAdjustmentForBidder (bidderResponse .getBidder (), bidRequest , bidderBid );
189- final BigDecimal adjustedPrice = adjustPrice (priceAdjustmentFactor , priceInAdServerCurrency );
190-
191- final ObjectNode bidExt = bid .getExt ();
192- final ObjectNode updatedBidExt = bidExt != null ? bidExt : mapper .mapper ().createObjectNode ();
193-
194- updateExtWithOrigPriceValues (updatedBidExt , price , bidCurrency );
195-
196- final Bid .BidBuilder bidBuilder = bid .toBuilder ();
197- if (adjustedPrice .compareTo (price ) != 0 ) {
198- bidBuilder .price (adjustedPrice );
199- }
200-
201- if (!updatedBidExt .isEmpty ()) {
202- bidBuilder .ext (updatedBidExt );
203- }
204-
205- return bidderBid .toBuilder ().bid (bidBuilder .build ()).build ();
206- }
207-
208- private BigDecimal bidAdjustmentForBidder (String bidder , BidRequest bidRequest , BidderBid bidderBid ) {
209- final ExtRequestBidAdjustmentFactors adjustmentFactors = extBidAdjustmentFactors (bidRequest );
210- if (adjustmentFactors == null ) {
211- return null ;
212- }
213- final ImpMediaType mediaType = ImpMediaTypeResolver .resolve (
214- bidderBid .getBid ().getImpid (), bidRequest .getImp (), bidderBid .getType ());
215-
216- return bidAdjustmentFactorResolver .resolve (mediaType , adjustmentFactors , bidder );
217- }
218-
219- private static ExtRequestBidAdjustmentFactors extBidAdjustmentFactors (BidRequest bidRequest ) {
220- final ExtRequestPrebid prebid = PbsUtil .extRequestPrebid (bidRequest );
221- return prebid != null ? prebid .getBidadjustmentfactors () : null ;
222- }
223-
224- private static BigDecimal adjustPrice (BigDecimal priceAdjustmentFactor , BigDecimal price ) {
225- return priceAdjustmentFactor != null && priceAdjustmentFactor .compareTo (BigDecimal .ONE ) != 0
226- ? price .multiply (priceAdjustmentFactor )
227- : price ;
228- }
229-
230- private static void updateExtWithOrigPriceValues (ObjectNode updatedBidExt , BigDecimal price , String bidCurrency ) {
231- addPropertyToNode (updatedBidExt , ORIGINAL_BID_CPM , new DecimalNode (price ));
232- if (StringUtils .isNotBlank (bidCurrency )) {
233- addPropertyToNode (updatedBidExt , ORIGINAL_BID_CURRENCY , new TextNode (bidCurrency ));
234- }
235- }
236-
237- private static void addPropertyToNode (ObjectNode node , String propertyName , JsonNode propertyValue ) {
238- node .set (propertyName , propertyValue );
239- }
240124}
0 commit comments