Skip to content

Commit 1329f6c

Browse files
committed
Implementation of AntoxaAntoxic review (round 2)
1 parent bc8cd58 commit 1329f6c

2 files changed

Lines changed: 127 additions & 154 deletions

File tree

src/main/java/org/prebid/server/bidder/sparteo/SparteoBidder.java

Lines changed: 60 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import org.prebid.server.bidder.model.BidderError;
1818
import org.prebid.server.bidder.model.HttpRequest;
1919
import org.prebid.server.bidder.model.Result;
20+
import org.prebid.server.exception.PreBidException;
2021
import org.prebid.server.json.DecodeException;
2122
import org.prebid.server.json.JacksonMapper;
2223
import org.prebid.server.proto.openrtb.ext.request.ExtPublisher;
@@ -31,6 +32,7 @@
3132
import java.util.Collections;
3233
import java.util.List;
3334
import java.util.Objects;
35+
import java.util.Optional;
3436

3537
public 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

Comments
 (0)