44import com .fasterxml .jackson .core .type .TypeReference ;
55import com .fasterxml .jackson .databind .JsonNode ;
66import com .fasterxml .jackson .databind .node .ObjectNode ;
7+ import com .iab .openrtb .request .App ;
78import com .iab .openrtb .request .BidRequest ;
89import com .iab .openrtb .request .Imp ;
910import com .iab .openrtb .request .Publisher ;
3839
3940public class SparteoBidder implements Bidder <BidRequest > {
4041
42+ private static final String NETWORK_ID_MACRO = "{{NetworkId}}" ;
43+ private static final String DOMAIN_MACRO = "{{Domain}}" ;
44+ private static final String BUNDLE_QUERY_MACRO = "{{BundleQuery}}" ;
45+
4146 private static final TypeReference <ExtPrebid <?, ExtImpSparteo >> TYPE_REFERENCE =
4247 new TypeReference <>() { };
4348
4449 private final String endpointUrl ;
4550 private final JacksonMapper mapper ;
4651
4752 public SparteoBidder (String endpointUrl , JacksonMapper mapper ) {
48- this .endpointUrl = HttpUtil .validateUrl (Objects .requireNonNull (endpointUrl ));
53+ this .endpointUrl = HttpUtil .validateUrlSyntax (Objects .requireNonNull (endpointUrl ));
4954 this .mapper = Objects .requireNonNull (mapper );
5055 }
5156
5257 @ Override
5358 public Result <List <HttpRequest <BidRequest >>> makeHttpRequests (BidRequest request ) {
5459 final List <BidderError > errors = new ArrayList <>();
5560 final List <Imp > modifiedImps = new ArrayList <>();
56- String siteNetworkId = null ;
61+ String networkId = null ;
5762
5863 for (Imp imp : request .getImp ()) {
59- if (siteNetworkId == null ) {
64+ if (networkId == null ) {
6065 try {
61- siteNetworkId = parseExtImp (imp ).getNetworkId ();
66+ networkId = parseExtImp (imp ).getNetworkId ();
6267 } catch (PreBidException e ) {
6368 errors .add (BidderError .badInput (
6469 "ignoring imp id=%s, error processing ext: %s" .formatted (
6570 imp .getId (), e .getMessage ())));
6671 }
6772 }
68-
6973 final ObjectNode modifiedExt = modifyImpExt (imp );
7074 modifiedImps .add (imp .toBuilder ().ext (modifiedExt ).build ());
7175 }
@@ -74,12 +78,21 @@ public Result<List<HttpRequest<BidRequest>>> makeHttpRequests(BidRequest request
7478 return Result .withErrors (errors );
7579 }
7680
77- final BidRequest outgoingRequest = request .toBuilder ()
78- .imp (modifiedImps )
79- .site (modifySite (request .getSite (), siteNetworkId , mapper ))
80- .build ();
81+ final BidRequest .BidRequestBuilder builder = request .toBuilder ().imp (modifiedImps );
82+
83+ final Site site = request .getSite ();
84+ final App app = request .getApp ();
85+
86+ if (site != null ) {
87+ builder .site (modifySite (site , networkId , mapper ));
88+ } else if (app != null ) {
89+ builder .app (modifyApp (app , networkId , mapper ));
90+ }
8191
82- final HttpRequest <BidRequest > call = BidderUtil .defaultRequest (outgoingRequest , endpointUrl , mapper );
92+ final BidRequest outgoingRequest = builder .build ();
93+
94+ final String finalEndpointUrl = replaceMacros (site , app , networkId );
95+ final HttpRequest <BidRequest > call = BidderUtil .defaultRequest (outgoingRequest , finalEndpointUrl , mapper );
8396
8497 return Result .of (Collections .singletonList (call ), errors );
8598 }
@@ -92,23 +105,24 @@ private ExtImpSparteo parseExtImp(Imp imp) {
92105 }
93106 }
94107
95- private static ObjectNode modifyImpExt (Imp imp ) {
108+ private ObjectNode modifyImpExt (Imp imp ) {
96109 final ObjectNode modifiedImpExt = imp .getExt ().deepCopy ();
97110 final ObjectNode sparteoNode = modifiedImpExt .putObject ("sparteo" );
98111 final JsonNode bidderJsonNode = modifiedImpExt .remove ("bidder" );
99112 sparteoNode .set ("params" , bidderJsonNode );
100-
101113 return modifiedImpExt ;
102114 }
103115
104- private Site modifySite (Site site , String siteNetworkId , JacksonMapper mapper ) {
105- if (site == null || site . getPublisher () == null || siteNetworkId == null ) {
116+ private Site modifySite (Site site , String networkId , JacksonMapper mapper ) {
117+ if (site == null ) {
106118 return site ;
107119 }
108120
109- final Publisher originalPublisher = site .getPublisher ();
110- final ExtPublisher originalExt = originalPublisher .getExt ();
121+ final Publisher originalPublisher = site .getPublisher () != null
122+ ? site .getPublisher ()
123+ : Publisher .builder ().build ();
111124
125+ final ExtPublisher originalExt = originalPublisher .getExt ();
112126 final ExtPublisher modifiedExt = originalExt != null
113127 ? ExtPublisher .of (originalExt .getPrebid ())
114128 : ExtPublisher .empty ();
@@ -117,25 +131,90 @@ private Site modifySite(Site site, String siteNetworkId, JacksonMapper mapper) {
117131 mapper .fillExtension (modifiedExt , originalExt );
118132 }
119133
120- final JsonNode paramsProperty = modifiedExt . getProperty ( "params" );
121- final ObjectNode paramsNode ;
134+ final ObjectNode paramsNode = ensureParamsNode ( modifiedExt );
135+ paramsNode . put ( "networkId" , networkId ) ;
122136
123- if (paramsProperty != null && paramsProperty .isObject ()) {
124- paramsNode = (ObjectNode ) paramsProperty ;
125- } else {
126- paramsNode = mapper .mapper ().createObjectNode ();
127- modifiedExt .addProperty ("params" , paramsNode );
137+ final Publisher modifiedPublisher = originalPublisher .toBuilder ()
138+ .ext (modifiedExt )
139+ .build ();
140+
141+ return site .toBuilder ().publisher (modifiedPublisher ).build ();
142+ }
143+
144+ private App modifyApp (App app , String networkId , JacksonMapper mapper ) {
145+ if (app == null ) {
146+ return app ;
147+ }
148+
149+ final Publisher originalPublisher = app .getPublisher () != null
150+ ? app .getPublisher ()
151+ : Publisher .builder ().build ();
152+
153+ final ExtPublisher originalExt = originalPublisher .getExt ();
154+ final ExtPublisher modifiedExt = originalExt != null
155+ ? ExtPublisher .of (originalExt .getPrebid ())
156+ : ExtPublisher .empty ();
157+
158+ if (originalExt != null ) {
159+ mapper .fillExtension (modifiedExt , originalExt );
128160 }
129161
130- paramsNode .put ("networkId" , siteNetworkId );
162+ final ObjectNode paramsNode = ensureParamsNode (modifiedExt );
163+ paramsNode .put ("networkId" , networkId );
131164
132165 final Publisher modifiedPublisher = originalPublisher .toBuilder ()
133166 .ext (modifiedExt )
134167 .build ();
135168
136- return site .toBuilder ()
137- .publisher (modifiedPublisher )
138- .build ();
169+ return app .toBuilder ().publisher (modifiedPublisher ).build ();
170+ }
171+
172+ private ObjectNode ensureParamsNode (ExtPublisher extPublisher ) {
173+ final JsonNode paramsProperty = extPublisher .getProperty ("params" );
174+ if (paramsProperty != null && paramsProperty .isObject ()) {
175+ return (ObjectNode ) paramsProperty ;
176+ }
177+ final ObjectNode paramsNode = mapper .mapper ().createObjectNode ();
178+ extPublisher .addProperty ("params" , paramsNode );
179+ return paramsNode ;
180+ }
181+
182+ private String replaceMacros (Site site , App app , String networkId ) {
183+ final String domain = resolveDomain (site , app );
184+ final String bundle = Optional .ofNullable (app ).map (App ::getBundle ).orElse (null );
185+ return resolveEndpoint (domain , networkId , bundle );
186+ }
187+
188+ private String resolveDomain (Site site , App app ) {
189+ if (site != null ) {
190+ final String siteDomain = site .getDomain ();
191+ if (siteDomain != null && !siteDomain .isEmpty ()) {
192+ return siteDomain ;
193+ }
194+ final Publisher pub = site .getPublisher ();
195+ if (pub != null && pub .getDomain () != null && !pub .getDomain ().isEmpty ()) {
196+ return pub .getDomain ();
197+ }
198+ }
199+ if (app != null && app .getDomain () != null && !app .getDomain ().isEmpty ()) {
200+ return app .getDomain ();
201+ }
202+ return null ;
203+ }
204+
205+ private String resolveEndpoint (String domain , String networkId , String bundle ) {
206+ String uri = endpointUrl .replace (NETWORK_ID_MACRO , HttpUtil .encodeUrl (networkId ));
207+
208+ if (domain != null && !domain .isEmpty ()) {
209+ uri = uri .replace (DOMAIN_MACRO , HttpUtil .encodeUrl (domain ));
210+ }
211+
212+ final String bundleQuery = (bundle != null && !bundle .isEmpty ())
213+ ? "&bundle=" + HttpUtil .encodeUrl (bundle )
214+ : "" ;
215+ uri = uri .replace (BUNDLE_QUERY_MACRO , bundleQuery );
216+
217+ return uri ;
139218 }
140219
141220 @ Override
0 commit comments