diff --git a/docs/config-app.md b/docs/config-app.md index 327878d6a8f..4bd9f0e793b 100644 --- a/docs/config-app.md +++ b/docs/config-app.md @@ -55,6 +55,7 @@ There are several typical keys: - `adapters..endpoint` - the url for submitting bids. - `adapters..usersync-url` - the url for synchronizing UIDs cookie. - `adapters..pbs-enforces-gdpr` - indicates if pbs server provides gdpr support for bidder or bidder will handle it itself. +- `adapters..deprecated-names` - comma separated deprecated names of bidder. But feel free to add additional bidder's specific options. diff --git a/src/main/java/org/prebid/server/auction/ExchangeService.java b/src/main/java/org/prebid/server/auction/ExchangeService.java index a40466fc31e..b67374dd0ba 100644 --- a/src/main/java/org/prebid/server/auction/ExchangeService.java +++ b/src/main/java/org/prebid/server/auction/ExchangeService.java @@ -246,8 +246,7 @@ private static Map> currencyRates(ExtRequestTarg * NOTE: the return list will only contain entries for bidders that both have the extension field in at least one * {@link Imp}, and are known to {@link BidderCatalog} or aliases from {@link BidRequest}.ext.prebid.aliases. */ - private Future> extractBidderRequests(BidRequest bidRequest, - UidsCookie uidsCookie, + private Future> extractBidderRequests(BidRequest bidRequest, UidsCookie uidsCookie, Map aliases, Timeout timeout) { // sanity check: discard imps without extension @@ -1065,15 +1064,19 @@ private CacheAsset toCacheAsset(String cacheId) { * Creates {@link ExtBidResponse} populated with response time, errors and debug info (if requested) from all * bidders */ - private static ExtBidResponse toExtBidResponse(List results, BidRequest bidRequest) { + private ExtBidResponse toExtBidResponse(List results, BidRequest bidRequest) { final Map> httpCalls = Objects.equals(bidRequest.getTest(), 1) ? results.stream().collect( Collectors.toMap(BidderResponse::getBidder, r -> ListUtils.emptyIfNull(r.getSeatBid().getHttpCalls()))) : null; final ExtResponseDebug extResponseDebug = httpCalls != null ? ExtResponseDebug.of(httpCalls, bidRequest) : null; - final Map> errors = results.stream() - .collect(Collectors.toMap(BidderResponse::getBidder, r -> messages(r.getSeatBid().getErrors()))); + final Map> errors = new HashMap<>(); + for (BidderResponse bidderResponse : results) { + errors.put(bidderResponse.getBidder(), messages(bidderResponse.getSeatBid().getErrors())); + } + + errors.putAll(extractDeprecatedBiddersErrors(bidRequest)); final Map responseTimeMillis = results.stream() .collect(Collectors.toMap(BidderResponse::getBidder, BidderResponse::getResponseTime)); @@ -1081,6 +1084,16 @@ private static ExtBidResponse toExtBidResponse(List results, Bid return ExtBidResponse.of(extResponseDebug, errors, responseTimeMillis, null); } + private Map> extractDeprecatedBiddersErrors(BidRequest bidRequest) { + return bidRequest.getImp().stream() + .filter(imp -> imp.getExt() != null) + .flatMap(imp -> asStream(imp.getExt().fieldNames())) + .distinct() + .filter(bidderCatalog::isDeprecatedName) + .collect(Collectors.toMap(Function.identity(), + bidder -> Collections.singletonList(bidderCatalog.errorForDeprecatedName(bidder)))); + } + private static List messages(List errors) { return CollectionUtils.emptyIfNull(errors).stream().map(BidderError::getMessage).collect(Collectors.toList()); } diff --git a/src/main/java/org/prebid/server/bidder/BidderCatalog.java b/src/main/java/org/prebid/server/bidder/BidderCatalog.java index ce49c241a50..febc1e2dc24 100644 --- a/src/main/java/org/prebid/server/bidder/BidderCatalog.java +++ b/src/main/java/org/prebid/server/bidder/BidderCatalog.java @@ -1,5 +1,6 @@ package org.prebid.server.bidder; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -13,11 +14,20 @@ */ public class BidderCatalog { + private static final String ERROR_MESSAGE_TEMPLATE_FOR_DEPRECATED = "%s has been deprecated and is no " + + "longer available. Use %s instead."; + private final Map bidderDepsMap; + private final Map deprecatedNameToError = new HashMap<>(); + public BidderCatalog(List bidderDeps) { bidderDepsMap = Objects.requireNonNull(bidderDeps).stream() .collect(Collectors.toMap(BidderDeps::getName, Function.identity())); + + bidderDeps.forEach(deps -> + deprecatedNameToError.putAll(createErrorsForDeprecatedNames(deps.getDeprecatedNames(), + deps.getName()))); } /** @@ -34,6 +44,19 @@ public boolean isValidName(String name) { return bidderDepsMap.containsKey(name); } + public boolean isDeprecatedName(String name) { + return deprecatedNameToError.containsKey(name); + } + + public String errorForDeprecatedName(String name) { + return deprecatedNameToError.get(name); + } + + private Map createErrorsForDeprecatedNames(List deprecatedNames, String name) { + return deprecatedNames.stream().collect(Collectors.toMap(deprecatedName -> deprecatedName, + deprecatedName -> String.format(ERROR_MESSAGE_TEMPLATE_FOR_DEPRECATED, deprecatedName, name))); + } + /** * Tells if given bidder is enabled and ready for auction. */ diff --git a/src/main/java/org/prebid/server/bidder/BidderDeps.java b/src/main/java/org/prebid/server/bidder/BidderDeps.java index 3d2c06bf085..b970735500b 100644 --- a/src/main/java/org/prebid/server/bidder/BidderDeps.java +++ b/src/main/java/org/prebid/server/bidder/BidderDeps.java @@ -3,6 +3,8 @@ import lombok.AllArgsConstructor; import lombok.Value; +import java.util.List; + /** * Gathers all dependencies for bidder. */ @@ -18,6 +20,8 @@ public class BidderDeps { */ String name; + List deprecatedNames; + /** * Bidder's meta information is used in {@link org.prebid.server.handler.info.BidderDetailsHandler} handler */ diff --git a/src/main/java/org/prebid/server/spring/config/bidder/AdformConfiguration.java b/src/main/java/org/prebid/server/spring/config/bidder/AdformConfiguration.java index d6b85ac53f6..d505c6d193c 100644 --- a/src/main/java/org/prebid/server/spring/config/bidder/AdformConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/bidder/AdformConfiguration.java @@ -17,6 +17,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.util.List; + @Configuration public class AdformConfiguration extends BidderConfiguration { @@ -37,6 +39,9 @@ public class AdformConfiguration extends BidderConfiguration { @Value("${external-url}") private String externalUrl; + @Value("${adapters.adform.deprecated-names}") + private List deprecatedNames; + @Bean BidderDeps adformBidderDeps(HttpClient httpClient, HttpAdapterConnector httpAdapterConnector) { return bidderDeps(httpClient, httpAdapterConnector); @@ -47,6 +52,11 @@ protected String bidderName() { return BIDDER_NAME; } + @Override + protected List deprecatedNames() { + return deprecatedNames; + } + @Override protected MetaInfo createMetaInfo() { return new AdformMetaInfo(enabled, pbsEnforcesGdpr); diff --git a/src/main/java/org/prebid/server/spring/config/bidder/AdkernelAdnConfiguration.java b/src/main/java/org/prebid/server/spring/config/bidder/AdkernelAdnConfiguration.java index 9524d66222c..0c905a1f870 100644 --- a/src/main/java/org/prebid/server/spring/config/bidder/AdkernelAdnConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/bidder/AdkernelAdnConfiguration.java @@ -16,6 +16,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.util.List; + @Configuration public class AdkernelAdnConfiguration extends BidderConfiguration { @@ -36,6 +38,9 @@ public class AdkernelAdnConfiguration extends BidderConfiguration { @Value("${external-url}") private String externalUrl; + @Value("${adapters.adkerneladn.deprecated-names}") + private List deprecatedNames; + @Bean BidderDeps adkernelAdnBidderDeps(HttpClient httpClient, HttpAdapterConnector httpAdapterConnector) { return bidderDeps(httpClient, httpAdapterConnector); @@ -46,6 +51,11 @@ protected String bidderName() { return BIDDER_NAME; } + @Override + protected List deprecatedNames() { + return deprecatedNames; + } + @Override protected MetaInfo createMetaInfo() { return new AdkernelAdnMetaInfo(enabled, pbsEnforcesGdpr); diff --git a/src/main/java/org/prebid/server/spring/config/bidder/AdtelligentConfiguration.java b/src/main/java/org/prebid/server/spring/config/bidder/AdtelligentConfiguration.java index dc916a35525..e0fe3faccb6 100644 --- a/src/main/java/org/prebid/server/spring/config/bidder/AdtelligentConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/bidder/AdtelligentConfiguration.java @@ -16,6 +16,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.util.List; + @Configuration public class AdtelligentConfiguration extends BidderConfiguration { @@ -36,11 +38,19 @@ public class AdtelligentConfiguration extends BidderConfiguration { @Value("${external-url}") private String externalUrl; + @Value("${adapters.adtelligent.deprecated-names}") + private List deprecatedNames; + @Override protected String bidderName() { return BIDDER_NAME; } + @Override + protected List deprecatedNames() { + return deprecatedNames; + } + @Bean BidderDeps adtelligentBidderDeps(HttpClient httpClient, HttpAdapterConnector httpAdapterConnector) { return bidderDeps(httpClient, httpAdapterConnector); diff --git a/src/main/java/org/prebid/server/spring/config/bidder/AppnexusConfiguration.java b/src/main/java/org/prebid/server/spring/config/bidder/AppnexusConfiguration.java index daf72f89832..54b8c4e623d 100644 --- a/src/main/java/org/prebid/server/spring/config/bidder/AppnexusConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/bidder/AppnexusConfiguration.java @@ -17,6 +17,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.util.List; + @Configuration public class AppnexusConfiguration extends BidderConfiguration { @@ -37,6 +39,9 @@ public class AppnexusConfiguration extends BidderConfiguration { @Value("${external-url}") private String externalUrl; + @Value("${adapters.appnexus.deprecated-names}") + private List deprecatedNames; + @Bean BidderDeps appnexusBidderDeps(HttpClient httpClient, HttpAdapterConnector httpAdapterConnector) { return bidderDeps(httpClient, httpAdapterConnector); @@ -47,6 +52,11 @@ protected String bidderName() { return BIDDER_NAME; } + @Override + protected List deprecatedNames() { + return deprecatedNames; + } + @Override protected MetaInfo createMetaInfo() { return new AppnexusMetaInfo(enabled, pbsEnforcesGdpr); diff --git a/src/main/java/org/prebid/server/spring/config/bidder/BeachfrontConfiguration.java b/src/main/java/org/prebid/server/spring/config/bidder/BeachfrontConfiguration.java index 425c1f423e2..b1488ab5bb2 100644 --- a/src/main/java/org/prebid/server/spring/config/bidder/BeachfrontConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/bidder/BeachfrontConfiguration.java @@ -16,6 +16,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.util.List; + @Configuration public class BeachfrontConfiguration extends BidderConfiguration { @@ -39,6 +41,9 @@ public class BeachfrontConfiguration extends BidderConfiguration { @Value("${adapters.beachfront.pbs-enforces-gdpr}") private boolean pbsEnforcesGdpr; + @Value("${adapters.beachfront.deprecated-names}") + private List deprecatedNames; + @Bean BidderDeps beachfrontBidderDeps(HttpClient httpClient, HttpAdapterConnector httpAdapterConnector) { return bidderDeps(httpClient, httpAdapterConnector); @@ -49,6 +54,11 @@ protected String bidderName() { return BIDDER_NAME; } + @Override + protected List deprecatedNames() { + return deprecatedNames; + } + @Override protected MetaInfo createMetaInfo() { return new BeachfrontMetaInfo(enabled, pbsEnforcesGdpr); diff --git a/src/main/java/org/prebid/server/spring/config/bidder/BidderConfiguration.java b/src/main/java/org/prebid/server/spring/config/bidder/BidderConfiguration.java index e5059bda47c..f5de7def303 100644 --- a/src/main/java/org/prebid/server/spring/config/bidder/BidderConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/bidder/BidderConfiguration.java @@ -11,6 +11,8 @@ import org.prebid.server.bidder.Usersyncer; import org.prebid.server.vertx.http.HttpClient; +import java.util.List; + public abstract class BidderConfiguration { private static final String ERROR_MESSAGE_TEMPLATE_FOR_DISABLED = "%s is not configured properly on this " @@ -33,11 +35,13 @@ protected BidderDeps bidderDeps(HttpClient httpClient, HttpAdapterConnector http final BidderRequester bidderRequester = createBidderRequester(httpClient, bidder, adapter, usersyncer, httpAdapterConnector); - return BidderDeps.of(bidderName, metaInfo, usersyncer, bidder, adapter, bidderRequester); + return BidderDeps.of(bidderName, deprecatedNames(), metaInfo, usersyncer, bidder, adapter, bidderRequester); } protected abstract String bidderName(); + protected abstract List deprecatedNames(); + protected abstract MetaInfo createMetaInfo(); protected abstract Usersyncer createUsersyncer(); diff --git a/src/main/java/org/prebid/server/spring/config/bidder/BrightrollConfiguration.java b/src/main/java/org/prebid/server/spring/config/bidder/BrightrollConfiguration.java index ad5ee4b9f93..0e537a31495 100644 --- a/src/main/java/org/prebid/server/spring/config/bidder/BrightrollConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/bidder/BrightrollConfiguration.java @@ -16,6 +16,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.util.List; + @Configuration public class BrightrollConfiguration extends BidderConfiguration { @@ -36,6 +38,9 @@ public class BrightrollConfiguration extends BidderConfiguration { @Value("${external-url}") private String externalUrl; + @Value("${adapters.brightroll.deprecated-names}") + private List deprecatedNames; + @Bean BidderDeps brightrollBidderDeps(HttpClient httpClient, HttpAdapterConnector httpAdapterConnector) { return bidderDeps(httpClient, httpAdapterConnector); @@ -46,6 +51,11 @@ protected String bidderName() { return BIDDER_NAME; } + @Override + protected List deprecatedNames() { + return deprecatedNames; + } + @Override protected MetaInfo createMetaInfo() { return new BrightrollMetaInfo(enabled, pbsEnforcesGdpr); diff --git a/src/main/java/org/prebid/server/spring/config/bidder/ConversantConfiguration.java b/src/main/java/org/prebid/server/spring/config/bidder/ConversantConfiguration.java index e0e0826cf20..ef22f28fa4d 100644 --- a/src/main/java/org/prebid/server/spring/config/bidder/ConversantConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/bidder/ConversantConfiguration.java @@ -17,6 +17,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.util.List; + @Configuration public class ConversantConfiguration extends BidderConfiguration { @@ -37,6 +39,9 @@ public class ConversantConfiguration extends BidderConfiguration { @Value("${external-url}") private String externalUrl; + @Value("${adapters.conversant.deprecated-names}") + private List deprecatedNames; + @Bean BidderDeps conversantBidderDeps(HttpClient httpClient, HttpAdapterConnector httpAdapterConnector) { return bidderDeps(httpClient, httpAdapterConnector); @@ -47,6 +52,11 @@ protected String bidderName() { return BIDDER_NAME; } + @Override + protected List deprecatedNames() { + return deprecatedNames; + } + @Override protected MetaInfo createMetaInfo() { return new ConversantMetaInfo(enabled, pbsEnforcesGdpr); diff --git a/src/main/java/org/prebid/server/spring/config/bidder/EplanningConfiguration.java b/src/main/java/org/prebid/server/spring/config/bidder/EplanningConfiguration.java index 4ca73b842fb..28b4063d0c4 100644 --- a/src/main/java/org/prebid/server/spring/config/bidder/EplanningConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/bidder/EplanningConfiguration.java @@ -16,6 +16,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.util.List; + @Configuration public class EplanningConfiguration extends BidderConfiguration { @@ -36,11 +38,19 @@ public class EplanningConfiguration extends BidderConfiguration { @Value("${external-url}") private String externalUrl; + @Value("${adapters.eplanning.deprecated-names}") + private List deprecatedNames; + @Override protected String bidderName() { return BIDDER_NAME; } + @Override + protected List deprecatedNames() { + return deprecatedNames; + } + @Bean BidderDeps eplanningBidderDeps(HttpClient httpClient, HttpAdapterConnector httpAdapterConnector) { return bidderDeps(httpClient, httpAdapterConnector); diff --git a/src/main/java/org/prebid/server/spring/config/bidder/FacebookConfiguration.java b/src/main/java/org/prebid/server/spring/config/bidder/FacebookConfiguration.java index ceb0f08fec4..9a8c42bd70f 100644 --- a/src/main/java/org/prebid/server/spring/config/bidder/FacebookConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/bidder/FacebookConfiguration.java @@ -18,6 +18,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.util.List; + @Configuration public class FacebookConfiguration extends BidderConfiguration { @@ -41,6 +43,9 @@ public class FacebookConfiguration extends BidderConfiguration { @Value("${adapters.facebook.platformId:#{null}}") private String platformId; + @Value("${adapters.facebook.deprecated-names}") + private List deprecatedNames; + @Bean BidderDeps facebookBidderDeps(HttpClient httpClient, HttpAdapterConnector httpAdapterConnector) { if (enabled && (usersyncUrl == null || platformId == null)) { @@ -56,6 +61,11 @@ protected String bidderName() { return BIDDER_NAME; } + @Override + protected List deprecatedNames() { + return deprecatedNames; + } + @Override protected MetaInfo createMetaInfo() { return new FacebookMetaInfo(enabled, pbsEnforcesGdpr); diff --git a/src/main/java/org/prebid/server/spring/config/bidder/IxConfiguration.java b/src/main/java/org/prebid/server/spring/config/bidder/IxConfiguration.java index c38a1bfd16c..def29f431a7 100644 --- a/src/main/java/org/prebid/server/spring/config/bidder/IxConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/bidder/IxConfiguration.java @@ -17,6 +17,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.util.List; + @Configuration public class IxConfiguration extends BidderConfiguration { @@ -34,6 +36,9 @@ public class IxConfiguration extends BidderConfiguration { @Value("${adapters.ix.pbs-enforces-gdpr}") private boolean pbsEnforcesGdpr; + @Value("${adapters.ix.deprecated-names}") + private List deprecatedNames; + @Bean BidderDeps ixBidderDeps(HttpClient httpClient, HttpAdapterConnector httpAdapterConnector) { if (enabled && endpoint == null) { @@ -49,6 +54,11 @@ protected String bidderName() { return BIDDER_NAME; } + @Override + protected List deprecatedNames() { + return deprecatedNames; + } + @Override protected MetaInfo createMetaInfo() { return new IxMetaInfo(enabled, pbsEnforcesGdpr); diff --git a/src/main/java/org/prebid/server/spring/config/bidder/LifestreetConfiguration.java b/src/main/java/org/prebid/server/spring/config/bidder/LifestreetConfiguration.java index be441ffbd13..e720dc8e7bc 100644 --- a/src/main/java/org/prebid/server/spring/config/bidder/LifestreetConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/bidder/LifestreetConfiguration.java @@ -17,6 +17,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.util.List; + @Configuration public class LifestreetConfiguration extends BidderConfiguration { @@ -37,6 +39,9 @@ public class LifestreetConfiguration extends BidderConfiguration { @Value("${external-url}") private String externalUrl; + @Value("${adapters.lifestreet.deprecated-names}") + private List deprecatedNames; + @Bean BidderDeps lifestreetBidderDeps(HttpClient httpClient, HttpAdapterConnector httpAdapterConnector) { return bidderDeps(httpClient, httpAdapterConnector); @@ -47,6 +52,11 @@ protected String bidderName() { return BIDDER_NAME; } + @Override + protected List deprecatedNames() { + return deprecatedNames; + } + @Override protected MetaInfo createMetaInfo() { return new LifestreetMetaInfo(enabled, pbsEnforcesGdpr); diff --git a/src/main/java/org/prebid/server/spring/config/bidder/OpenxConfiguration.java b/src/main/java/org/prebid/server/spring/config/bidder/OpenxConfiguration.java index ca3bfc380c4..0f62c99ba0e 100644 --- a/src/main/java/org/prebid/server/spring/config/bidder/OpenxConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/bidder/OpenxConfiguration.java @@ -16,6 +16,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.util.List; + @Configuration public class OpenxConfiguration extends BidderConfiguration { @@ -36,6 +38,9 @@ public class OpenxConfiguration extends BidderConfiguration { @Value("${external-url}") private String externalUrl; + @Value("${adapters.openx.deprecated-names}") + private List deprecatedNames; + @Bean BidderDeps openxBidderDeps(HttpClient httpClient, HttpAdapterConnector httpAdapterConnector) { return bidderDeps(httpClient, httpAdapterConnector); @@ -46,6 +51,11 @@ protected String bidderName() { return BIDDER_NAME; } + @Override + protected List deprecatedNames() { + return deprecatedNames; + } + @Override protected MetaInfo createMetaInfo() { return new OpenxMetaInfo(enabled, pbsEnforcesGdpr); diff --git a/src/main/java/org/prebid/server/spring/config/bidder/PubmaticConfiguration.java b/src/main/java/org/prebid/server/spring/config/bidder/PubmaticConfiguration.java index 1d2cc1da34b..40d5926d25a 100644 --- a/src/main/java/org/prebid/server/spring/config/bidder/PubmaticConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/bidder/PubmaticConfiguration.java @@ -17,6 +17,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.util.List; + @Configuration public class PubmaticConfiguration extends BidderConfiguration { @@ -37,6 +39,9 @@ public class PubmaticConfiguration extends BidderConfiguration { @Value("${external-url}") private String externalUrl; + @Value("${adapters.pubmatic.deprecated-names}") + private List deprecatedNames; + @Bean BidderDeps pubmaticBidderDeps(HttpClient httpClient, HttpAdapterConnector httpAdapterConnector) { return bidderDeps(httpClient, httpAdapterConnector); @@ -47,6 +52,11 @@ protected String bidderName() { return BIDDER_NAME; } + @Override + protected List deprecatedNames() { + return deprecatedNames; + } + @Override protected MetaInfo createMetaInfo() { return new PubmaticMetaInfo(enabled, pbsEnforcesGdpr); diff --git a/src/main/java/org/prebid/server/spring/config/bidder/PulsepointConfiguration.java b/src/main/java/org/prebid/server/spring/config/bidder/PulsepointConfiguration.java index 09d76fe1b6e..892d24f67e7 100644 --- a/src/main/java/org/prebid/server/spring/config/bidder/PulsepointConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/bidder/PulsepointConfiguration.java @@ -17,6 +17,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.util.List; + @Configuration public class PulsepointConfiguration extends BidderConfiguration { @@ -37,6 +39,9 @@ public class PulsepointConfiguration extends BidderConfiguration { @Value("${external-url}") private String externalUrl; + @Value("${adapters.pulsepoint.deprecated-names}") + private List deprecatedNames; + @Bean BidderDeps pulsepointBidderDeps(HttpClient httpClient, HttpAdapterConnector httpAdapterConnector) { return bidderDeps(httpClient, httpAdapterConnector); @@ -47,6 +52,11 @@ protected String bidderName() { return BIDDER_NAME; } + @Override + protected List deprecatedNames() { + return deprecatedNames; + } + @Override protected MetaInfo createMetaInfo() { return new PulsepointMetaInfo(enabled, pbsEnforcesGdpr); diff --git a/src/main/java/org/prebid/server/spring/config/bidder/RubiconConfiguration.java b/src/main/java/org/prebid/server/spring/config/bidder/RubiconConfiguration.java index 4ca05555136..231730ff60b 100644 --- a/src/main/java/org/prebid/server/spring/config/bidder/RubiconConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/bidder/RubiconConfiguration.java @@ -17,6 +17,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.util.List; + @Configuration public class RubiconConfiguration extends BidderConfiguration { @@ -40,6 +42,9 @@ public class RubiconConfiguration extends BidderConfiguration { @Value("${adapters.rubicon.XAPI.Password}") private String password; + @Value("${adapters.rubicon.deprecated-names}") + private List deprecatedNames; + @Bean BidderDeps rubiconBidderDeps(HttpClient httpClient, HttpAdapterConnector httpAdapterConnector) { return bidderDeps(httpClient, httpAdapterConnector); @@ -50,6 +55,11 @@ public String bidderName() { return BIDDER_NAME; } + @Override + protected List deprecatedNames() { + return deprecatedNames; + } + @Override public MetaInfo createMetaInfo() { return new RubiconMetaInfo(enabled, pbsEnforcesGdpr); diff --git a/src/main/java/org/prebid/server/spring/config/bidder/SomoaudienceConfiguration.java b/src/main/java/org/prebid/server/spring/config/bidder/SomoaudienceConfiguration.java index e8a4041faa7..4ff33abebc7 100644 --- a/src/main/java/org/prebid/server/spring/config/bidder/SomoaudienceConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/bidder/SomoaudienceConfiguration.java @@ -16,6 +16,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.util.List; + @Configuration public class SomoaudienceConfiguration extends BidderConfiguration { @@ -36,6 +38,9 @@ public class SomoaudienceConfiguration extends BidderConfiguration { @Value("${external-url}") private String externalUrl; + @Value("${adapters.somoaudience.deprecated-names}") + private List deprecatedNames; + @Bean BidderDeps somoaudienceBidderDeps(HttpClient httpClient, HttpAdapterConnector httpAdapterConnector) { return bidderDeps(httpClient, httpAdapterConnector); @@ -46,6 +51,11 @@ protected String bidderName() { return BIDDER_NAME; } + @Override + protected List deprecatedNames() { + return deprecatedNames; + } + @Override protected MetaInfo createMetaInfo() { return new SomoaudienceMetaInfo(enabled, pbsEnforcesGdpr); diff --git a/src/main/java/org/prebid/server/spring/config/bidder/SovrnConfiguration.java b/src/main/java/org/prebid/server/spring/config/bidder/SovrnConfiguration.java index 5c135dc6ee3..b093fad77b0 100644 --- a/src/main/java/org/prebid/server/spring/config/bidder/SovrnConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/bidder/SovrnConfiguration.java @@ -17,6 +17,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.util.List; + @Configuration public class SovrnConfiguration extends BidderConfiguration { @@ -37,6 +39,9 @@ public class SovrnConfiguration extends BidderConfiguration { @Value("${external-url}") private String externalUrl; + @Value("${adapters.sovrn.deprecated-names}") + private List deprecatedNames; + @Bean BidderDeps sovrnBidderDeps(HttpClient httpClient, HttpAdapterConnector httpAdapterConnector) { return bidderDeps(httpClient, httpAdapterConnector); @@ -47,6 +52,11 @@ protected String bidderName() { return BIDDER_NAME; } + @Override + protected List deprecatedNames() { + return deprecatedNames; + } + @Override protected MetaInfo createMetaInfo() { return new SovrnMetaInfo(enabled, pbsEnforcesGdpr); diff --git a/src/main/java/org/prebid/server/validation/RequestValidator.java b/src/main/java/org/prebid/server/validation/RequestValidator.java index 601bd4abc5e..55a9d533cd1 100644 --- a/src/main/java/org/prebid/server/validation/RequestValidator.java +++ b/src/main/java/org/prebid/server/validation/RequestValidator.java @@ -547,7 +547,7 @@ private void validateImpBidderExtName(int impIndex, Map.Entry throw new ValidationException("request.imp[%d].ext.%s failed validation.\n%s", impIndex, bidderName, messages.stream().collect(Collectors.joining("\n"))); } - } else { + } else if (!bidderCatalog.isDeprecatedName(bidderName)) { throw new ValidationException( "request.imp[%d].ext contains unknown bidder: %s", impIndex, bidderName); } diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 92270f4941c..58ec9812b9c 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -38,21 +38,25 @@ adapters: endpoint: http://adx.adform.net/adx usersync-url: //cm.adform.net/cookie?redirect_url= pbs-enforces-gdpr: true + deprecated-names: adkerneladn: enabled: false endpoint: http://tag.adkernel.com/rtbpub?account= usersync-url: https://tag.adkernel.com/syncr?gdpr={{gdpr}}&gdpr_consent={{gdpr_consent}}&r= pbs-enforces-gdpr: true + deprecated-names: adtelligent: enabled: false endpoint: http://hb.adtelligent.com/auction usersync-url: //sync.adtelligent.com/csync?t=p&ep=0&redir= pbs-enforces-gdpr: true + deprecated-names: appnexus: enabled: false endpoint: http://ib.adnxs.com/openrtb2 usersync-url: //ib.adnxs.com/getuid? pbs-enforces-gdpr: true + deprecated-names: beachfront: enabled: false banner-endpoint: https://display.bfmio.com/prebid_display @@ -60,26 +64,31 @@ adapters: usersync-url: //sync.bfmio.com/syncb?pid= platform-id: 142 pbs-enforces-gdpr: true + deprecated-names: brightroll: enabled: false endpoint: http://east-bid.ybp.yahoo.com/bid/appnexuspbs usersync-url: http://east-bid.ybp.yahoo.com/sync/appnexuspbs?gdpr={{gdpr}}&euconsent={{gdpr_consent}}&url= pbs-enforces-gdpr: true + deprecated-names: conversant: enabled: false endpoint: http://api.hb.ad.cpe.dotomi.com/s2s/header/24 usersync-url: //prebid-match.dotomi.com/prebid/match?rurl= pbs-enforces-gdpr: true + deprecated-names: eplanning: enabled: false endpoint: http://ads.us.e-planning.net/dsp/obr/1 usersync-url: http://sync.e-planning.net/um?uid pbs-enforces-gdpr: true + deprecated-names: facebook: enabled: false endpoint: https://an.facebook.com/placementbid.ortb nonSecureEndpoint: http://an.facebook.com/placementbid.ortb pbs-enforces-gdpr: true + deprecated-names: ix: enabled: false endpoint: http://appnexus-us-east.lb.indexww.com/transbidder?p=184932 @@ -91,36 +100,43 @@ adapters: endpoint: https://prebid.s2s.lfstmedia.com/adrequest usersync-url: //ads.lfstmedia.com/idsync/137062?synced=1&ttl=1s&rurl= pbs-enforces-gdpr: true + deprecated-names: openx: enabled: false endpoint: http://rtb.openx.net/prebid usersync-url: https://rtb.openx.net/sync/prebid?r= pbs-enforces-gdpr: true + deprecated-names: pubmatic: enabled: false endpoint: http://hbopenbid.pubmatic.com/translator?source=prebid-server usersync-url: //ads.pubmatic.com/AdServer/js/user_sync.html?predirect= pbs-enforces-gdpr: true + deprecated-names: pulsepoint: enabled: false endpoint: http://bid.contextweb.com/header/s/ortb/prebid-s2s usersync-url: //bh.contextweb.com/rtset?pid=561205&ev=1&rurl= pbs-enforces-gdpr: true + deprecated-names: rubicon: enabled: false endpoint: http://exapi-us-east.rubiconproject.com/a/api/exchange.json usersync-url: https://pixel.rubiconproject.com/exchange/sync.php?p=prebid&gdpr={{gdpr}}&gdpr_consent={{gdpr_consent}} pbs-enforces-gdpr: true + deprecated-names: somoaudience: enabled: false endpoint: http://publisher-east.mobileadtrading.com/rtb/bid usersync-url: //publisher-east.mobileadtrading.com/usersync?ru= pbs-enforces-gdpr: true + deprecated-names: sovrn: enabled: false endpoint: http://ap.lijit.com/rtb/bid?src=prebid_server usersync-url: //ap.lijit.com/pixel? pbs-enforces-gdpr: true + deprecated-names: metrics: metricType: flushingCounter accounts: diff --git a/src/test/java/org/prebid/server/auction/ExchangeServiceTest.java b/src/test/java/org/prebid/server/auction/ExchangeServiceTest.java index 090af977de3..53b09d54d25 100644 --- a/src/test/java/org/prebid/server/auction/ExchangeServiceTest.java +++ b/src/test/java/org/prebid/server/auction/ExchangeServiceTest.java @@ -80,6 +80,7 @@ import java.time.Clock; import java.time.Instant; import java.time.ZoneId; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -202,11 +203,31 @@ public void shouldTolerateImpWithUnknownBidderInExtension() { // then verify(bidderCatalog).isValidName(eq("invalid")); - verifyNoMoreInteractions(bidderCatalog); + verify(bidderCatalog).isDeprecatedName(eq("invalid")); verifyZeroInteractions(bidderRequester); assertThat(bidResponse).isNotNull(); } + @Test + public void shouldProcessRequestAndAddErrorAboutDeprecatedBidder() { + //given + final String invalidBidderName = "invalid"; + + given(bidderCatalog.isValidName(invalidBidderName)).willReturn(false); + given(bidderCatalog.isDeprecatedName(invalidBidderName)).willReturn(true); + given(bidderCatalog.errorForDeprecatedName(invalidBidderName)).willReturn("invalid has been deprecated and is no longer available. Use valid instead."); + + final BidRequest bidRequest = givenBidRequest(givenSingleImp(singletonMap(invalidBidderName, 0))); + + //when + final BidResponse bidResponse = exchangeService.holdAuction(bidRequest, uidsCookie, timeout, metricsContext).result(); + + //then + assertThat(bidResponse.getExt()).isEqualTo(mapper.valueToTree(ExtBidResponse.of(null, + Collections.singletonMap(invalidBidderName, Collections.singletonList("invalid has been deprecated and is no longer available. Use valid instead.")), + new HashMap<>(), null))); + } + @Test public void shouldTolerateMissingPrebidImpExtension() { // given diff --git a/src/test/java/org/prebid/server/bidder/BidderCatalogTest.java b/src/test/java/org/prebid/server/bidder/BidderCatalogTest.java index 412247a596a..d6a45b41145 100644 --- a/src/test/java/org/prebid/server/bidder/BidderCatalogTest.java +++ b/src/test/java/org/prebid/server/bidder/BidderCatalogTest.java @@ -6,7 +6,10 @@ import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; +import java.util.Collections; + import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; @@ -34,7 +37,7 @@ public class BidderCatalogTest { @Test public void isValidNameShouldReturnTrueForKnownBidder() { // given - bidderDeps = BidderDeps.of(BIDDER, null, null, null, null, null); + bidderDeps = BidderDeps.of(BIDDER, emptyList(), null, null, null, null, null); bidderCatalog = new BidderCatalog(singletonList(bidderDeps)); // when and then @@ -53,7 +56,7 @@ public void isValidNameShouldReturnFalseForUnknownBidder() { @Test public void metaInfoByNameShouldReturnMetaInfoForKnownBidder() { // given - bidderDeps = BidderDeps.of(BIDDER, metaInfo, null, null, null, null); + bidderDeps = BidderDeps.of(BIDDER, emptyList(), metaInfo, null, null, null, null); bidderCatalog = new BidderCatalog(singletonList(bidderDeps)); // when and then @@ -72,7 +75,7 @@ public void metaInfoByNameShouldReturnNullForUnknownBidder() { @Test public void usersyncerByNameShouldReturnUsersyncerForKnownBidder() { // given - bidderDeps = BidderDeps.of(BIDDER, null, usersyncer, null, null, null); + bidderDeps = BidderDeps.of(BIDDER, emptyList(), null, usersyncer, null, null, null); bidderCatalog = new BidderCatalog(singletonList(bidderDeps)); // when and then @@ -91,7 +94,7 @@ public void usersyncerByNameShouldReturnNullForUnknownBidder() { @Test public void bidderByNameShouldReturnBidderForKnownBidder() { // given - bidderDeps = BidderDeps.of(BIDDER, null, null, bidder, null, null); + bidderDeps = BidderDeps.of(BIDDER, emptyList(), null, null, bidder, null, null); bidderCatalog = new BidderCatalog(singletonList(bidderDeps)); // when and then @@ -110,7 +113,7 @@ public void bidderByNameShouldReturnNullForUnknownBidder() { @Test public void adapterByNameShouldReturnAdapterForKnownBidder() { // given - bidderDeps = BidderDeps.of(BIDDER, null, null, null, adapter, null); + bidderDeps = BidderDeps.of(BIDDER, emptyList(),null, null, null, adapter, null); bidderCatalog = new BidderCatalog(singletonList(bidderDeps)); // when and then @@ -129,7 +132,7 @@ public void adapterByNameShouldReturnNullForUnknownBidder() { @Test public void bidderRequesterByNameShouldReturnBidderRequesterForKnownBidder() { // given - bidderDeps = BidderDeps.of(BIDDER, null, null, null, null, bidderRequester); + bidderDeps = BidderDeps.of(BIDDER, emptyList(),null, null, null, null, bidderRequester); bidderCatalog = new BidderCatalog(singletonList(bidderDeps)); // when and then @@ -148,7 +151,7 @@ public void bidderRequesterByNameShouldReturnNullForUnknownBidder() { @Test public void isValidAdapterNameShouldReturnTrueIfNameIsValidAndAdapterIsDefined() { // given - bidderDeps = BidderDeps.of(BIDDER, null, null, null, adapter, null); + bidderDeps = BidderDeps.of(BIDDER, emptyList(),null, null, null, adapter, null); bidderCatalog = new BidderCatalog(singletonList(bidderDeps)); // when and then assertThat(bidderCatalog.isValidAdapterName(BIDDER)).isTrue(); @@ -157,7 +160,7 @@ public void isValidAdapterNameShouldReturnTrueIfNameIsValidAndAdapterIsDefined() @Test public void isValidAdapterNameShouldReturnFalseIfNameIsInvalid() { // given - bidderDeps = BidderDeps.of("invalid", null, null, null, adapter, null); + bidderDeps = BidderDeps.of("invalid", emptyList(),null, null, null, adapter, null); bidderCatalog = new BidderCatalog(singletonList(bidderDeps)); // when and then assertThat(bidderCatalog.isValidAdapterName(BIDDER)).isFalse(); @@ -166,7 +169,7 @@ public void isValidAdapterNameShouldReturnFalseIfNameIsInvalid() { @Test public void isValidAdapterNameShouldReturnFalseIfAdapterIsNotDefined() { // given - bidderDeps = BidderDeps.of(BIDDER, null, null, null, null, null); + bidderDeps = BidderDeps.of(BIDDER, emptyList(),null, null, null, null, null); bidderCatalog = new BidderCatalog(singletonList(bidderDeps)); // when and then assertThat(bidderCatalog.isValidAdapterName(BIDDER)).isFalse();