Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public class NextMillenniumBidder implements Bidder<BidRequest> {
new TypeReference<>() {
};

private static final String NM_ADAPTER_VERSION = "v1.0.0";
private static final String NM_ADAPTER_VERSION = "v1.0.1";

private final String endpointUrl;
private final JacksonMapper mapper;
Expand Down Expand Up @@ -108,8 +108,8 @@ private BidRequest updateBidRequest(BidRequest bidRequest, ExtImpNextMillennium
.orElse(null);

return bidRequest.toBuilder()
.imp(modifyFirstImp(bidRequest.getImp(), soredRequestId))
.ext(createExtRequest(soredRequestId, extRequestPrebidServer))
.imp(modifyFirstImp(bidRequest.getImp(), soredRequestId, extImp))
.ext(createExtRequest(soredRequestId, extRequestPrebidServer, extImp))
.build();
}

Expand Down Expand Up @@ -150,13 +150,14 @@ private static String formatSize(Integer w, Integer h) {
: null;
}

private List<Imp> modifyFirstImp(List<Imp> imps, String storedRequestId) {
private List<Imp> modifyFirstImp(List<Imp> imps, String storedRequestId, ExtImpNextMillennium extImp) {
final ExtRequestPrebid extRequestPrebid = ExtRequestPrebid.builder()
.storedrequest(ExtStoredRequest.of(storedRequestId))
.build();

final NextMillenniumExt nextMillenniumExt = NextMillenniumExt.of(
NextMillenniumExtBidder.of(nmmFlags, null, null));
NextMillenniumExtBidder.of(
nmmFlags, extImp.getAdSlots(), extImp.getAllowedAds(), null, null));
Comment on lines +159 to +160
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand the changes in Go correctly adslots and allowedads shouldn't be added to the imp.ext

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and please, create a separate static constructor of with the only nmmFlags parameter

Copy link
Collaborator Author

@przemkaczmarek przemkaczmarek Oct 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

according to the json's samples:

"mockBidRequest": {
    "id": "testid",
    "imp": [
      {
        "id": "123654",
        "banner": {
          "w": 320,
          "h": 250
        },
        "ext": {
          "bidder": {
            "group_id": "7819",
            "allowedAds":["allowed_ad_1, allowed_ad_2"]
          }
        }
      }
    ],
    "app": {
      "domain": "www.example.com"
    }
  },

  "httpCalls": [
    {
      "expectedRequest": {
        "uri": "https://pbs.nextmillmedia.com/openrtb2/auction",
        "body":{
          "id": "testid",
          "app": {
            "domain": "www.example.com"
          },
          "ext": {
            "nextMillennium": {
              "allowedAds":["allowed_ad_1, allowed_ad_2"],
              "nm_version":"v1.0.1"
            },
            ```
            ----------------------------------------------------------
            ```
            type nmExtNMM struct {
	NmmFlags       []string `json:"nmmFlags,omitempty"`
	AdSlots        []string `json:"adSlots,omitempty"`
	AllowedAds     []string `json:"allowedAds,omitempty"`
	ServerVersion  string   `json:"server_version,omitempty"`
	AdapterVersion string   `json:"nm_version,omitempty"`
}

AdSlots and AllowedAds are parts of nmmExt:


final ExtRequest extRequest = ExtRequest.of(extRequestPrebid);
mapper.fillExtension(extRequest, nextMillenniumExt);
Expand All @@ -169,14 +170,18 @@ private List<Imp> modifyFirstImp(List<Imp> imps, String storedRequestId) {
return modifiedImps;
}

private ExtRequest createExtRequest(String storedRequestId, ExtRequestPrebidServer extRequestPrebidServer) {
private ExtRequest createExtRequest(String storedRequestId,
ExtRequestPrebidServer extRequestPrebidServer,
ExtImpNextMillennium extImp) {
final ExtRequestPrebid extRequestPrebid = ExtRequestPrebid.builder()
.storedrequest(ExtStoredRequest.of(storedRequestId))
.server(extRequestPrebidServer)
.build();

final NextMillenniumExt nextMillenniumExt = NextMillenniumExt.of(
NextMillenniumExtBidder.of(nmmFlags, NM_ADAPTER_VERSION, versionProvider.getNameVersionRecord()));
NextMillenniumExtBidder.of(
nmmFlags, extImp.getAdSlots(), extImp.getAllowedAds(), NM_ADAPTER_VERSION,
versionProvider.getNameVersionRecord()));
Comment on lines +183 to +184
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please chop the whole parameter list down


final ExtRequest extRequest = ExtRequest.of(extRequestPrebid);
mapper.fillExtension(extRequest, nextMillenniumExt);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ public class NextMillenniumExtBidder {
@JsonProperty("nmmFlags")
List<String> nmmFlags;

@JsonProperty("adSlots")
List<String> adSlots;

@JsonProperty("allowedAds")
List<String> allowedAds;

String nmVersion;

String serverVersion;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
package org.prebid.server.proto.openrtb.ext.request.nextmillennium;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Value;

import java.util.List;

@Value(staticConstructor = "of")
public class ExtImpNextMillennium {

String placementId;

String groupId;

@JsonProperty("adSlots")
List<String> adSlots;

@JsonProperty("allowedAds")
List<String> allowedAds;
}
15 changes: 15 additions & 0 deletions src/main/resources/static/bidder-params/nextmillennium.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,21 @@
"type": "string",
"minLength": 1,
"description": "An id used to identify NextMillennium placement group"
},
"adSlots": {
"type": "array",
"minItems": 1,
"description": "IDs which identifies the ad slots",
"items": {
"type": "string"
}
},
"allowedAds": {
"type": "array",
"description": "List of allowed ads",
"items": {
"type": "string"
}
}
},
"anyOf": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import org.prebid.server.bidder.model.HttpRequest;
import org.prebid.server.bidder.model.HttpResponse;
import org.prebid.server.bidder.model.Result;
import org.prebid.server.bidder.nextmillennium.proto.NextMillenniumExt;
import org.prebid.server.bidder.nextmillennium.proto.NextMillenniumExtBidder;
import org.prebid.server.proto.openrtb.ext.ExtPrebid;
import org.prebid.server.proto.openrtb.ext.request.ExtRequest;
import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebid;
Expand Down Expand Up @@ -78,8 +80,8 @@ public void makeHttpRequestsShouldUseBidRequestIdForAllRequests() {
// given
final BidRequest bidRequest = givenBidRequest(
request -> request.id("id"),
givenImpWithExt(identity(), ExtImpNextMillennium.of(null, null)),
givenImpWithExt(identity(), ExtImpNextMillennium.of(null, null)));
givenImpWithExt(identity(), ExtImpNextMillennium.of(null, null, null, null)),
givenImpWithExt(identity(), ExtImpNextMillennium.of(null, null, null, null)));

// when
final Result<List<HttpRequest<BidRequest>>> result = target.makeHttpRequests(bidRequest);
Expand All @@ -97,8 +99,8 @@ public void makeHttpRequestsShouldUseBidRequestTestForAllRequests() {
// given
final BidRequest bidRequest = givenBidRequest(
request -> request.test(1),
givenImpWithExt(identity(), ExtImpNextMillennium.of(null, null)),
givenImpWithExt(identity(), ExtImpNextMillennium.of(null, null)));
givenImpWithExt(identity(), ExtImpNextMillennium.of(null, null, null, null)),
givenImpWithExt(identity(), ExtImpNextMillennium.of(null, null, null, null)));

// when
final Result<List<HttpRequest<BidRequest>>> result = target.makeHttpRequests(bidRequest);
Expand All @@ -116,8 +118,8 @@ public void makeHttpRequestsShouldUseImpExtBidderPlacementIdForStoredRequestId()
// given
final BidRequest bidRequest = givenBidRequest(
identity(),
givenImpWithExt(identity(), ExtImpNextMillennium.of("placement1", null)),
givenImpWithExt(identity(), ExtImpNextMillennium.of("placement2", null)));
givenImpWithExt(identity(), givenExtImpWithPlacementId("placement1")),
givenImpWithExt(identity(), givenExtImpWithPlacementId("placement2")));

// when
final Result<List<HttpRequest<BidRequest>>> result = target.makeHttpRequests(bidRequest);
Expand All @@ -138,8 +140,8 @@ public void makeHttpRequestsShouldUseImpExtBidderGroupIdForStoredRequestId() {
// given
final BidRequest bidRequest = givenBidRequest(
identity(),
givenImpWithExt(identity(), ExtImpNextMillennium.of(null, "group1")),
givenImpWithExt(identity(), ExtImpNextMillennium.of(null, "group2")));
givenImpWithExt(identity(), givenExtImpWithGroupId("group1")),
givenImpWithExt(identity(), givenExtImpWithGroupId("group2")));

// when
final Result<List<HttpRequest<BidRequest>>> result = target.makeHttpRequests(bidRequest);
Expand Down Expand Up @@ -168,10 +170,10 @@ public void makeHttpRequestsShouldUseFirstImpBannerFirstFormatForStoredRequestId
.w(5)
.h(6)
.build()),
ExtImpNextMillennium.of(null, "group1")),
givenExtImpWithGroupId("group1")),
givenImpWithExt(
imp -> imp.banner(Banner.builder().w(7).h(8).build()),
ExtImpNextMillennium.of(null, "group2")));
givenExtImpWithGroupId("group2")));

// when
final Result<List<HttpRequest<BidRequest>>> result = target.makeHttpRequests(bidRequest);
Expand All @@ -187,19 +189,61 @@ public void makeHttpRequestsShouldUseFirstImpBannerFirstFormatForStoredRequestId
.containsExactly("ggroup1;1x2;", "ggroup2;1x2;");
}

@Test
public void makeHttpRequestsShouldIncludeAdSlotsAndAllowedAdsInRequestAndImpExt() {
// given
final List<String> adSlots = List.of("slot1", "slot2");
final List<String> allowedAds = List.of("ad1", "ad2");

final ExtImpNextMillennium extImp = ExtImpNextMillennium.of("placement123", null, adSlots, allowedAds);

final BidRequest bidRequest = givenBidRequest(
identity(),
givenImpWithExt(identity(), extImp));

// when
final Result<List<HttpRequest<BidRequest>>> result = target.makeHttpRequests(bidRequest);

// then
assertThat(result.getErrors()).isEmpty();
assertThat(result.getValue()).hasSize(1);

final BidRequest actualRequest = result.getValue().getFirst().getPayload();

final NextMillenniumExtBidder requestExt = jacksonMapper.mapper()
.convertValue(
jacksonMapper.mapper().convertValue(actualRequest
.getExt(), NextMillenniumExt.class).getNextMillennium(),
NextMillenniumExtBidder.class);

final NextMillenniumExtBidder impExt = jacksonMapper.mapper()
.convertValue(
jacksonMapper.mapper().convertValue(actualRequest
.getImp().getFirst().getExt(), NextMillenniumExt.class).getNextMillennium(),
NextMillenniumExtBidder.class);

assertThat(requestExt)
.extracting(NextMillenniumExtBidder::getAdSlots, NextMillenniumExtBidder::getAllowedAds)
.containsExactly(adSlots, allowedAds);

assertThat(impExt)
.extracting(NextMillenniumExtBidder::getAdSlots, NextMillenniumExtBidder::getAllowedAds)
.containsExactly(adSlots, allowedAds);
}

@Test
public void makeHttpRequestsShouldUseFirstImpBannerSizeForStoredRequestIds() {
// given
final BidRequest bidRequest = givenBidRequest(
identity(),
givenImpWithExt(
imp -> imp.banner(Banner.builder().w(7).h(8).build()),
ExtImpNextMillennium.of(null, "group1")),
givenExtImpWithGroupId("group1")),
givenImpWithExt(
imp -> imp.banner(Banner.builder()
.format(singletonList(Format.builder().w(1).h(2).build()))
.build()),
ExtImpNextMillennium.of(null, "group2")));
givenExtImpWithGroupId("group2")));

// when
final Result<List<HttpRequest<BidRequest>>> result = target.makeHttpRequests(bidRequest);
Expand All @@ -220,8 +264,8 @@ public void makeHttpRequestsShouldUseAppDomainForStoredRequestId() {
// given
final BidRequest bidRequest = givenBidRequest(
request -> request.app(App.builder().domain("appDomain").build()),
givenImpWithExt(identity(), ExtImpNextMillennium.of(null, "group1")),
givenImpWithExt(identity(), ExtImpNextMillennium.of(null, "group2")));
givenImpWithExt(identity(), givenExtImpWithGroupId("group1")),
givenImpWithExt(identity(), givenExtImpWithGroupId("group2")));

// when
final Result<List<HttpRequest<BidRequest>>> result = target.makeHttpRequests(bidRequest);
Expand All @@ -242,8 +286,8 @@ public void makeHttpRequestsShouldUseSiteDomainForStoredRequestId() {
// given
final BidRequest bidRequest = givenBidRequest(
request -> request.site(Site.builder().domain("siteDomain").build()),
givenImpWithExt(identity(), ExtImpNextMillennium.of("placement1", "group1")),
givenImpWithExt(identity(), ExtImpNextMillennium.of("placement2", "group2")));
givenImpWithExt(identity(), givenExtImpWithPlacementIdAndGroupId("placement1", "group1")),
givenImpWithExt(identity(), givenExtImpWithPlacementIdAndGroupId("placement2", "group2")));

// when
final Result<List<HttpRequest<BidRequest>>> result = target.makeHttpRequests(bidRequest);
Expand Down Expand Up @@ -294,7 +338,7 @@ public void makeHttpRequestsImpExtComparison() {
.h(90)
.build()))
.build()),
ExtImpNextMillennium.of(placementId, null));
ExtImpNextMillennium.of(placementId, null, null, null));

final ExtRequest extRequest = ExtRequest.of(ExtRequestPrebid.builder()
.schains(emptyList())
Expand Down Expand Up @@ -346,7 +390,7 @@ public void makeHttpRequestsImpShouldBeIdenticalExceptExt() {
.tagid("custom_imp_tagid")
.secure(1)
.banner(banner),
ExtImpNextMillennium.of(placementId, null));
ExtImpNextMillennium.of(placementId, null, null, null));

final BidRequest bidRequest = givenBidRequest(b -> b
.id("c868fd0b-960c-4f49-a8d6-2b3e938b41f2")
Expand Down Expand Up @@ -386,7 +430,7 @@ public void makeHttpRequestsBidRequestShouldBeIdenticalExceptImpExt() {
.tagid("custom_imp_tagid")
.secure(1)
.banner(banner),
ExtImpNextMillennium.of(placementId, null));
ExtImpNextMillennium.of(placementId, null, null, null));

final ExtRequest extRequest = ExtRequest.of(ExtRequestPrebid.builder()
.schains(emptyList())
Expand Down Expand Up @@ -432,7 +476,7 @@ public void makeHttpRequestsShouldPreserveExtPrebidServer() {
.id("test-request")
.imp(singletonList(givenImpWithExt(
imp -> imp.banner(Banner.builder().w(300).h(250).build()),
ExtImpNextMillennium.of("placement_id", null))))
ExtImpNextMillennium.of("placement_id", null, null, null))))
.ext(extRequest)
.build();

Expand Down Expand Up @@ -603,4 +647,16 @@ private static Imp givenImpWithExt(UnaryOperator<Imp.ImpBuilder> impCustomizer,
return givenImp(impCustomizer.andThen(imp -> imp.ext(mapper.valueToTree(
ExtPrebid.of(null, extImpNextMillennium))))::apply);
}

private static ExtImpNextMillennium givenExtImpWithGroupId(String groupId) {
return ExtImpNextMillennium.of(null, groupId, null, null);
}

private static ExtImpNextMillennium givenExtImpWithPlacementId(String placementId) {
return ExtImpNextMillennium.of(placementId, null, null, null);
}

private static ExtImpNextMillennium givenExtImpWithPlacementIdAndGroupId(String placementId, String groupId) {
return ExtImpNextMillennium.of(placementId, groupId, null, null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
},
"ext": {
"nextmillennium" : {
"placement_id": "placement_id"
"placement_id": "placement_id",
"adSlots": ["slot-1", "slot-2"],
"allowedAds": ["banner", "native"]
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
"secure": 1,
"ext": {
"nextMillennium" : {
"nmmFlags" : [ "1" ]
"nmmFlags" : [ "1" ],
"adSlots": ["slot-1", "slot-2"],
"allowedAds": ["banner", "native"]
},
"prebid": {
"storedrequest": {
Expand Down Expand Up @@ -61,7 +63,9 @@
},
"nextMillennium": {
"nmmFlags": [ "1" ],
"nm_version": "v1.0.0",
"adSlots": ["slot-1", "slot-2"],
"allowedAds": ["banner", "native"],
"nm_version": "v1.0.1",
"server_version": "${json-unit.any-string}"
}
}
Expand Down
Loading