1717import org .prebid .server .bidder .model .BidderError ;
1818import org .prebid .server .bidder .model .HttpRequest ;
1919import org .prebid .server .bidder .model .Result ;
20+ import org .prebid .server .exception .PreBidException ;
2021import org .prebid .server .json .DecodeException ;
2122import org .prebid .server .json .JacksonMapper ;
2223import org .prebid .server .proto .openrtb .ext .request .ExtPublisher ;
3132import java .util .Collections ;
3233import java .util .List ;
3334import java .util .Objects ;
35+ import java .util .Optional ;
3436
3537public class SparteoBidder implements Bidder <BidRequest > {
3638
@@ -50,19 +52,21 @@ public Result<List<HttpRequest<BidRequest>>> makeHttpRequests(BidRequest request
5052
5153 for (Imp imp : request .getImp ()) {
5254 try {
53- final JsonNode bidderNode = imp .getExt ().get ("bidder" );
55+ final ObjectNode impExt = mapper .mapper ().convertValue (imp .getExt (), ObjectNode .class );
56+
57+ final JsonNode bidderNode = impExt .get ("bidder" );
5458 final ExtImpSparteo bidderParams = mapper .mapper ().treeToValue (bidderNode , ExtImpSparteo .class );
5559
5660 if (siteNetworkId == null && bidderParams .getNetworkId () != null ) {
5761 siteNetworkId = bidderParams .getNetworkId ();
5862 }
5963
60- final ObjectNode modifiedExt = buildImpExt (imp , bidderParams , mapper );
64+ final ObjectNode modifiedExt = buildImpExt (impExt , bidderParams , mapper );
6165
6266 modifiedImps .add (imp .toBuilder ().ext (modifiedExt ).build ());
63- } catch (NullPointerException | JsonProcessingException e ) {
67+ } catch (JsonProcessingException e ) {
6468 errors .add (BidderError .badInput (
65- String . format ( "ignoring imp id=%s, error processing ext: %s" ,
69+ "ignoring imp id=%s, error processing ext: %s" . formatted (
6670 imp .getId (), e .getMessage ())));
6771 }
6872 }
@@ -81,55 +85,30 @@ public Result<List<HttpRequest<BidRequest>>> makeHttpRequests(BidRequest request
8185 return Result .of (Collections .singletonList (call ), errors );
8286 }
8387
84- @ Override
85- public Result <List <BidderBid >> makeBids (BidderCall <BidRequest > httpCall , BidRequest bidRequest ) {
86- final List <BidderError > errors = new ArrayList <>();
87- final int statusCode = httpCall .getResponse ().getStatusCode ();
88-
89- if (statusCode == 204 ) {
90- return Result .of (Collections .emptyList (), errors );
91- }
92-
93- if (statusCode != 200 ) {
94- return Result .withError (BidderError .badServerResponse (
95- String .format ("HTTP status %d returned from Sparteo" , statusCode )));
96- }
97-
98- try {
99- final BidResponse bidResponse = mapper .decodeValue (httpCall .getResponse ().getBody (), BidResponse .class );
100- return Result .of (extractBids (bidResponse , errors ), errors );
101- } catch (DecodeException e ) {
102- return Result .withError (BidderError .badServerResponse (
103- String .format ("Failed to decode Sparteo response: %s" , e .getMessage ())));
104- }
105- }
106-
107- private ObjectNode buildImpExt (Imp imp , ExtImpSparteo bidderParams , JacksonMapper mapper )
88+ private ObjectNode buildImpExt (ObjectNode impExt , ExtImpSparteo bidderParams , JacksonMapper mapper )
10889 throws JsonProcessingException {
10990
110- final ObjectNode extMap = mapper . mapper (). convertValue ( imp . getExt (), ObjectNode . class );
91+ impExt . remove ( "bidder" );
11192
112- extMap .remove ("bidder" );
113-
114- final JsonNode sparteoNode = extMap .get ("sparteo" );
93+ final JsonNode sparteoNode = impExt .get ("sparteo" );
11594 final ObjectNode outgoingParamsNode ;
11695
11796 if (sparteoNode != null && sparteoNode .isObject () && sparteoNode .has ("params" )
11897 && sparteoNode .get ("params" ).isObject ()) {
11998 outgoingParamsNode = (ObjectNode ) sparteoNode .get ("params" );
12099 } else {
121- outgoingParamsNode = extMap .putObject ("sparteo" ).putObject ("params" );
100+ outgoingParamsNode = impExt .putObject ("sparteo" ).putObject ("params" );
122101 }
123102
124103 final ObjectNode bidderParamsAsNode = mapper .mapper ().convertValue (bidderParams , ObjectNode .class );
125104 outgoingParamsNode .setAll (bidderParamsAsNode );
126105
127- final JsonNode prebidNode = extMap .get ("prebid" );
106+ final JsonNode prebidNode = impExt .get ("prebid" );
128107 if (prebidNode != null && prebidNode .has ("adunitcode" )) {
129108 outgoingParamsNode .set ("adUnitCode" , prebidNode .get ("adunitcode" ));
130109 }
131110
132- return extMap ;
111+ return impExt ;
133112 }
134113
135114 private Site modifySite (Site site , String siteNetworkId , JacksonMapper mapper ) {
@@ -165,6 +144,17 @@ private Site modifySite(Site site, String siteNetworkId, JacksonMapper mapper) {
165144 .build ();
166145 }
167146
147+ @ Override
148+ public Result <List <BidderBid >> makeBids (BidderCall <BidRequest > httpCall , BidRequest bidRequest ) {
149+ try {
150+ final BidResponse bidResponse = mapper .decodeValue (httpCall .getResponse ().getBody (), BidResponse .class );
151+ final List <BidderError > errors = new ArrayList <>();
152+ return Result .of (extractBids (bidResponse , errors ), errors );
153+ } catch (DecodeException e ) {
154+ return Result .withError (BidderError .badServerResponse (e .getMessage ()));
155+ }
156+ }
157+
168158 private List <BidderBid > extractBids (BidResponse bidResponse , List <BidderError > errors ) {
169159 if (bidResponse == null || CollectionUtils .isEmpty (bidResponse .getSeatbid ())) {
170160 return Collections .emptyList ();
@@ -175,66 +165,54 @@ private List<BidderBid> extractBids(BidResponse bidResponse, List<BidderError> e
175165 .map (SeatBid ::getBid )
176166 .filter (Objects ::nonNull )
177167 .flatMap (Collection ::stream )
178- .map (bid -> {
179- if (bid == null ) {
180- errors .add (BidderError .badServerResponse ("Received null bid object within a seatbid." ));
181- return null ;
182- }
183- return toBidderBid (bid , bidResponse .getCur (), errors );
184- })
168+ .filter (Objects ::nonNull )
169+ .map (bid -> toBidderBid (bid , bidResponse .getCur (), errors ))
185170 .filter (Objects ::nonNull )
186171 .toList ();
187172 }
188173
189- private BidderBid toBidderBid (Bid bid , String currency , List <BidderError > errors ) {
190- try {
191- final BidType bidType = getBidTypeFromBidExtension (bid );
192- return BidderBid .of (bid , bidType , currency );
193- } catch (Exception e ) {
194- errors .add (BidderError .badServerResponse (e .getMessage ()));
195- return null ;
196- }
197- }
198-
199- private BidType getBidTypeFromBidExtension (Bid bid ) throws Exception {
200- final ObjectNode bidExtNode = bid .getExt ();
174+ private BidType getBidType (Bid bid ) throws PreBidException {
175+ final BidType bidType = Optional .ofNullable (bid .getExt ())
176+ .map (ext -> ext .get ("prebid" ))
177+ .filter (JsonNode ::isObject )
178+ .map (this ::parseExtBidPrebid )
179+ .map (ExtBidPrebid ::getType )
180+ .orElseThrow (() -> new PreBidException (
181+ "Failed to parse bid mediatype for impression \" %s\" " .formatted (bid .getImpid ())));
201182
202- if (bidExtNode == null || !bidExtNode .hasNonNull ("prebid" )) {
203- throw new Exception (
204- String .format ("Bid extension or bid.ext.prebid missing for impression id: %s" ,
205- bid .getImpid ())
206- );
183+ if (bidType == BidType .audio ) {
184+ throw new PreBidException (
185+ "Audio bid type not supported by this adapter for impression id: %s" .formatted (bid .getImpid ()));
207186 }
208187
209- final JsonNode prebidNode = bidExtNode . get ( "prebid" ) ;
210- final ExtBidPrebid extBidPrebid ;
188+ return bidType ;
189+ }
211190
191+ private ExtBidPrebid parseExtBidPrebid (JsonNode prebidNode ) {
212192 try {
213- extBidPrebid = mapper .mapper ().treeToValue (prebidNode , ExtBidPrebid .class );
193+ return mapper .mapper ().treeToValue (prebidNode , ExtBidPrebid .class );
214194 } catch (JsonProcessingException e ) {
215- throw new Exception (
216- String .format ("Failed to parse bid.ext.prebid for impression id: %s, error: %s" ,
217- bid .getImpid (),
218- e .getMessage ()
219- ),
220- e );
195+ return null ;
221196 }
197+ }
222198
223- if (extBidPrebid == null || extBidPrebid .getType () == null ) {
224- throw new Exception (
225- String .format ("Missing type in bid.ext.prebid for impression id: %s" ,
226- bid .getImpid ()
227- ));
228- }
199+ private BidderBid toBidderBid (Bid bid , String currency , List <BidderError > errors ) {
200+ try {
201+ final BidType bidType = getBidType (bid );
229202
230- final BidType bidType = extBidPrebid .getType ();
231- if (bidType == BidType .audio ) {
232- throw new Exception (
233- String .format ("Audio bid type not supported by this adapter for impression id: %s" ,
234- bid .getImpid ())
235- );
236- }
203+ final Integer mtype = switch (bidType ) {
204+ case banner -> 1 ;
205+ case video -> 2 ;
206+ case xNative -> 4 ;
207+ default -> null ;
208+ };
237209
238- return bidType ;
210+ final Bid bidWithMtype = mtype != null ? bid .toBuilder ().mtype (mtype ).build () : bid ;
211+
212+ return BidderBid .of (bidWithMtype , bidType , currency );
213+ } catch (PreBidException e ) {
214+ errors .add (BidderError .badServerResponse (e .getMessage ()));
215+ return null ;
216+ }
239217 }
240218}
0 commit comments