-
Notifications
You must be signed in to change notification settings - Fork 224
Kobler: New adapter ported from Go #3684
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 15 commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
8ea1419
Kobler: New adapter (#3667)
przemkaczmarek 3e4f05e
fix clean code
przemkaczmarek 858b5df
Merge branch 'master' into Kobler-New-Adapter-(#3667)
przemkaczmarek c3e11ce
fix bugs
przemkaczmarek 5ca450c
fix bugs
przemkaczmarek 7293b44
fix bugs
przemkaczmarek ac1eb72
fix comments
przemkaczmarek 9287f80
fix checkstyle
przemkaczmarek 857a308
fix yaml
przemkaczmarek c385084
fix comments
przemkaczmarek 3078b30
fix checkstyle
przemkaczmarek d64f134
fix comments
przemkaczmarek 68770b0
fix checkstyle
przemkaczmarek 4982cf4
fix comments
przemkaczmarek 3521a00
fix comments
przemkaczmarek 5ee2283
fix comments
przemkaczmarek a8b9c4b
fix tests
przemkaczmarek 0ea93c2
fix comments
przemkaczmarek 1ffdb23
fix comments
przemkaczmarek 733c5bc
fix comments
przemkaczmarek 0bcb6cf
fix comments
przemkaczmarek File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
178 changes: 178 additions & 0 deletions
178
src/main/java/org/prebid/server/bidder/kobler/KoblerBidder.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,178 @@ | ||
| package org.prebid.server.bidder.kobler; | ||
|
|
||
| import com.fasterxml.jackson.core.JsonProcessingException; | ||
| import com.fasterxml.jackson.core.type.TypeReference; | ||
| import com.fasterxml.jackson.databind.node.ObjectNode; | ||
| import com.iab.openrtb.request.BidRequest; | ||
| import com.iab.openrtb.request.Imp; | ||
| import com.iab.openrtb.response.Bid; | ||
| import com.iab.openrtb.response.BidResponse; | ||
| import com.iab.openrtb.response.SeatBid; | ||
| import org.apache.commons.collections4.CollectionUtils; | ||
| import org.prebid.server.bidder.Bidder; | ||
| import org.prebid.server.bidder.model.BidderBid; | ||
| import org.prebid.server.bidder.model.BidderCall; | ||
| import org.prebid.server.bidder.model.BidderError; | ||
| import org.prebid.server.bidder.model.HttpRequest; | ||
| import org.prebid.server.bidder.model.Price; | ||
| import org.prebid.server.bidder.model.Result; | ||
| import org.prebid.server.currency.CurrencyConversionService; | ||
| import org.prebid.server.exception.PreBidException; | ||
| import org.prebid.server.json.DecodeException; | ||
| import org.prebid.server.json.JacksonMapper; | ||
| import org.prebid.server.proto.openrtb.ext.ExtPrebid; | ||
| import org.prebid.server.proto.openrtb.ext.request.kobler.ExtImpKobler; | ||
| import org.prebid.server.proto.openrtb.ext.response.BidType; | ||
| import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebid; | ||
| import org.prebid.server.util.BidderUtil; | ||
| import org.prebid.server.util.HttpUtil; | ||
|
|
||
| import java.math.BigDecimal; | ||
| import java.util.ArrayList; | ||
| import java.util.Collection; | ||
| import java.util.Collections; | ||
| import java.util.List; | ||
| import java.util.Objects; | ||
| import java.util.Optional; | ||
|
|
||
| public class KoblerBidder implements Bidder<BidRequest> { | ||
|
|
||
| private static final TypeReference<ExtPrebid<?, ExtImpKobler>> KOBLER_EXT_TYPE_REFERENCE = | ||
| new TypeReference<>() { | ||
| }; | ||
| private static final String EXT_PREBID = "prebid"; | ||
| private static final String DEFAULT_BID_CURRENCY = "USD"; | ||
| private static final String DEV_ENDPOINT = "https://bid-service.dev.essrtb.com/bid/prebid_server_rtb_call"; | ||
CTMBNara marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| private final String endpointUrl; | ||
| private final CurrencyConversionService currencyConversionService; | ||
| private final JacksonMapper mapper; | ||
|
|
||
| public KoblerBidder(String endpointUrl, | ||
| CurrencyConversionService currencyConversionService, | ||
| JacksonMapper mapper) { | ||
|
|
||
| this.endpointUrl = HttpUtil.validateUrl(endpointUrl); | ||
| this.currencyConversionService = Objects.requireNonNull(currencyConversionService); | ||
| this.mapper = Objects.requireNonNull(mapper); | ||
| } | ||
|
|
||
| @Override | ||
| public Result<List<HttpRequest<BidRequest>>> makeHttpRequests(BidRequest bidRequest) { | ||
| final List<BidderError> errors = new ArrayList<>(); | ||
| boolean testMode = false; | ||
| final List<Imp> modifiedImps = new ArrayList<>(); | ||
|
|
||
| final List<String> currencies = new ArrayList<>(bidRequest.getCur()); | ||
| if (!currencies.contains(DEFAULT_BID_CURRENCY)) { | ||
| currencies.add(DEFAULT_BID_CURRENCY); | ||
| } | ||
CTMBNara marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| final List<Imp> imps = bidRequest.getImp(); | ||
| if (!imps.isEmpty()) { | ||
| try { | ||
| testMode = parseImpExt(imps.getFirst()).getTest(); | ||
| } catch (PreBidException e) { | ||
| errors.add(BidderError.badInput(e.getMessage())); | ||
| return Result.withErrors(errors); | ||
| } | ||
| } | ||
CTMBNara marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| for (Imp imp : imps) { | ||
| try { | ||
| modifiedImps.add(modifyImp(bidRequest, imp)); | ||
| } catch (PreBidException e) { | ||
| errors.add(BidderError.badInput(e.getMessage())); | ||
przemkaczmarek marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return Result.withErrors(errors); | ||
| } | ||
| } | ||
|
|
||
| final BidRequest modifiedRequest = bidRequest.toBuilder() | ||
| .cur(currencies) | ||
| .imp(modifiedImps) | ||
| .build(); | ||
|
|
||
| final String endpoint = testMode ? DEV_ENDPOINT : endpointUrl; | ||
|
|
||
| final HttpRequest<BidRequest> httpRequest = BidderUtil.defaultRequest(modifiedRequest, endpoint, mapper); | ||
| return Result.of(Collections.singletonList(httpRequest), errors); | ||
| } | ||
|
|
||
| private Imp modifyImp(BidRequest bidRequest, Imp imp) { | ||
| final Price resolvedBidFloor = resolveBidFloor(imp, bidRequest); | ||
|
|
||
| return imp.toBuilder() | ||
| .bidfloor(resolvedBidFloor.getValue()) | ||
| .bidfloorcur(resolvedBidFloor.getCurrency()) | ||
| .build(); | ||
| } | ||
|
|
||
| private Price resolveBidFloor(Imp imp, BidRequest bidRequest) { | ||
| final Price initialBidFloorPrice = Price.of(imp.getBidfloorcur(), imp.getBidfloor()); | ||
| return BidderUtil.shouldConvertBidFloor(initialBidFloorPrice, DEFAULT_BID_CURRENCY) | ||
| ? convertBidFloor(initialBidFloorPrice, bidRequest) | ||
| : initialBidFloorPrice; | ||
| } | ||
|
|
||
| private Price convertBidFloor(Price bidFloorPrice, BidRequest bidRequest) { | ||
| final BigDecimal convertedPrice = currencyConversionService.convertCurrency( | ||
| bidFloorPrice.getValue(), | ||
| bidRequest, | ||
| bidFloorPrice.getCurrency(), | ||
| DEFAULT_BID_CURRENCY); | ||
|
|
||
| return Price.of(DEFAULT_BID_CURRENCY, convertedPrice); | ||
| } | ||
|
|
||
| private ExtImpKobler parseImpExt(Imp imp) { | ||
| try { | ||
| return mapper.mapper().convertValue(imp.getExt(), KOBLER_EXT_TYPE_REFERENCE).getBidder(); | ||
| } catch (IllegalArgumentException e) { | ||
| throw new PreBidException(e.getMessage()); | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public Result<List<BidderBid>> makeBids(BidderCall<BidRequest> httpCall, BidRequest bidRequest) { | ||
| try { | ||
| final BidResponse bidResponse = mapper.decodeValue(httpCall.getResponse().getBody(), BidResponse.class); | ||
| return Result.withValues(extractBids(bidResponse)); | ||
| } catch (DecodeException e) { | ||
| return Result.withError(BidderError.badServerResponse(e.getMessage())); | ||
| } | ||
| } | ||
|
|
||
| private List<BidderBid> extractBids(BidResponse bidResponse) { | ||
| if (bidResponse == null || CollectionUtils.isEmpty(bidResponse.getSeatbid())) { | ||
| return Collections.emptyList(); | ||
| } | ||
| return bidsFromResponse(bidResponse); | ||
| } | ||
|
|
||
| private List<BidderBid> bidsFromResponse(BidResponse bidResponse) { | ||
| return bidResponse.getSeatbid().stream() | ||
| .filter(Objects::nonNull) | ||
| .map(SeatBid::getBid) | ||
| .filter(Objects::nonNull) | ||
| .flatMap(Collection::stream) | ||
| .map(bid -> BidderBid.of(bid, getBidType(bid), bidResponse.getCur())) | ||
przemkaczmarek marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| .toList(); | ||
| } | ||
|
|
||
| private BidType getBidType(Bid bid) { | ||
| return Optional.ofNullable(bid.getExt()) | ||
| .map(ext -> ext.get(EXT_PREBID)) | ||
| .map(ObjectNode.class::cast) | ||
CTMBNara marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| .map(this::parseExtBidPrebid) | ||
| .map(ExtBidPrebid::getType) | ||
| .orElse(BidType.banner); | ||
| } | ||
|
|
||
| private ExtBidPrebid parseExtBidPrebid(ObjectNode prebid) { | ||
| try { | ||
| return mapper.mapper().treeToValue(prebid, ExtBidPrebid.class); | ||
| } catch (JsonProcessingException e) { | ||
| return null; | ||
| } | ||
| } | ||
| } | ||
11 changes: 11 additions & 0 deletions
11
src/main/java/org/prebid/server/proto/openrtb/ext/request/kobler/ExtImpKobler.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| package org.prebid.server.proto.openrtb.ext.request.kobler; | ||
|
|
||
| import com.fasterxml.jackson.annotation.JsonProperty; | ||
| import lombok.Value; | ||
|
|
||
| @Value(staticConstructor = "of") | ||
| public class ExtImpKobler { | ||
|
|
||
| @JsonProperty("test") | ||
CTMBNara marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Boolean test; | ||
| } | ||
43 changes: 43 additions & 0 deletions
43
src/main/java/org/prebid/server/spring/config/bidder/KoblerConfiguration.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| package org.prebid.server.spring.config.bidder; | ||
|
|
||
| import org.prebid.server.bidder.BidderDeps; | ||
| import org.prebid.server.bidder.kobler.KoblerBidder; | ||
| import org.prebid.server.currency.CurrencyConversionService; | ||
| import org.prebid.server.json.JacksonMapper; | ||
| import org.prebid.server.spring.config.bidder.model.BidderConfigurationProperties; | ||
| import org.prebid.server.spring.config.bidder.util.BidderDepsAssembler; | ||
| import org.prebid.server.spring.config.bidder.util.UsersyncerCreator; | ||
| import org.prebid.server.spring.env.YamlPropertySourceFactory; | ||
| import org.springframework.beans.factory.annotation.Value; | ||
| import org.springframework.boot.context.properties.ConfigurationProperties; | ||
| import org.springframework.context.annotation.Bean; | ||
| import org.springframework.context.annotation.Configuration; | ||
| import org.springframework.context.annotation.PropertySource; | ||
|
|
||
| import jakarta.validation.constraints.NotBlank; | ||
|
|
||
| @Configuration | ||
| @PropertySource(value = "classpath:/bidder-config/kobler.yaml", factory = YamlPropertySourceFactory.class) | ||
| public class KoblerConfiguration { | ||
|
|
||
| private static final String BIDDER_NAME = "kobler"; | ||
|
|
||
| @Bean("koblerConfigurationProperties") | ||
| @ConfigurationProperties("adapters.kobler") | ||
| BidderConfigurationProperties configurationProperties() { | ||
| return new BidderConfigurationProperties(); | ||
| } | ||
|
|
||
| @Bean | ||
| BidderDeps koblerBidderDeps(BidderConfigurationProperties koblerConfigurationProperties, | ||
| CurrencyConversionService currencyConversionService, | ||
| @NotBlank @Value("${external-url}") String externalUrl, | ||
| JacksonMapper mapper) { | ||
|
|
||
| return BidderDepsAssembler.forBidder(BIDDER_NAME) | ||
| .withConfig(koblerConfigurationProperties) | ||
| .usersyncerCreator(UsersyncerCreator.create(externalUrl)) | ||
| .bidderCreator(config -> new KoblerBidder(config.getEndpoint(), currencyConversionService, mapper)) | ||
| .assemble(); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| adapters: | ||
| kobler: | ||
| endpoint: "https://bid.essrtb.com/bid/prebid_server_rtb_call" | ||
przemkaczmarek marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| endpoint-compression: gzip | ||
| geoscope: | ||
| - NOR | ||
| - SWE | ||
| - DNK | ||
| meta-info: | ||
| maintainer-email: [email protected] | ||
| site-media-types: | ||
| - banner | ||
| vendor-id: 0 | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| { | ||
| "$schema": "http://json-schema.org/draft-04/schema#", | ||
| "title": "Kobler Adapter Params", | ||
| "description": "A schema which validates params accepted by the Kobler adapter", | ||
| "type": "object", | ||
|
|
||
| "properties": { | ||
| "test": { | ||
| "type": "boolean", | ||
| "description": "Whether the request is for testing only. When multiple ad units are submitted together, it is enough to set this parameter on the first one." | ||
| } | ||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.