-
Notifications
You must be signed in to change notification settings - Fork 187
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement x-prebid headers support (#1301)
- Loading branch information
1 parent
9d107a7
commit 62acfde
Showing
6 changed files
with
222 additions
and
116 deletions.
There are no files selected for viewing
87 changes: 87 additions & 0 deletions
87
src/main/java/org/prebid/server/bidder/HttpBidderRequestEnricher.java
This file contains 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,87 @@ | ||
package org.prebid.server.bidder; | ||
|
||
import com.iab.openrtb.request.App; | ||
import com.iab.openrtb.request.BidRequest; | ||
import io.vertx.core.MultiMap; | ||
import org.apache.commons.lang3.StringUtils; | ||
import org.prebid.server.proto.openrtb.ext.request.ExtApp; | ||
import org.prebid.server.proto.openrtb.ext.request.ExtAppPrebid; | ||
import org.prebid.server.proto.openrtb.ext.request.ExtRequest; | ||
import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebid; | ||
import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebidChannel; | ||
import org.prebid.server.util.HttpUtil; | ||
|
||
import java.util.Collections; | ||
import java.util.Objects; | ||
import java.util.Set; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.Stream; | ||
|
||
public class HttpBidderRequestEnricher { | ||
|
||
private static final Set<CharSequence> HEADERS_TO_COPY = Collections.singleton(HttpUtil.SEC_GPC_HEADER.toString()); | ||
|
||
private final String pbsRecord; | ||
|
||
public HttpBidderRequestEnricher(String pbsVersion) { | ||
pbsRecord = createNameVersionRecord("pbs-java", Objects.requireNonNull(pbsVersion)); | ||
} | ||
|
||
MultiMap enrichHeaders(MultiMap bidderRequestHeaders, MultiMap originalRequestHeaders, BidRequest bidRequest) { | ||
// some bidders has headers on class level, so we create copy to not affect them | ||
final MultiMap bidderRequestHeadersCopy = copyMultiMap(bidderRequestHeaders); | ||
|
||
addOriginalRequestHeaders(originalRequestHeaders, bidderRequestHeadersCopy); | ||
addXPrebidHeader(bidderRequestHeadersCopy, bidRequest); | ||
|
||
return bidderRequestHeadersCopy; | ||
} | ||
|
||
private static MultiMap copyMultiMap(MultiMap source) { | ||
final MultiMap copiedMultiMap = MultiMap.caseInsensitiveMultiMap(); | ||
if (source != null && !source.isEmpty()) { | ||
source.forEach(entry -> copiedMultiMap.add(entry.getKey(), entry.getValue())); | ||
} | ||
return copiedMultiMap; | ||
} | ||
|
||
private static void addOriginalRequestHeaders(MultiMap originalHeaders, MultiMap bidderHeaders) { | ||
originalHeaders.entries().stream() | ||
.filter(entry -> HEADERS_TO_COPY.contains(entry.getKey()) | ||
&& !bidderHeaders.contains(entry.getKey())) | ||
.forEach(entry -> bidderHeaders.add(entry.getKey(), entry.getValue())); | ||
} | ||
|
||
private void addXPrebidHeader(MultiMap headers, BidRequest bidRequest) { | ||
final String channelRecord = resolveChannelVersionRecord(bidRequest.getExt()); | ||
final String sdkRecord = resolveSdkVersionRecord(bidRequest.getApp()); | ||
final String value = Stream.of(channelRecord, sdkRecord, pbsRecord) | ||
.filter(Objects::nonNull) | ||
.collect(Collectors.joining(",")); | ||
HttpUtil.addHeaderIfValueIsNotEmpty(headers, HttpUtil.X_PREBID_HEADER, value); | ||
} | ||
|
||
private static String resolveChannelVersionRecord(ExtRequest extRequest) { | ||
final ExtRequestPrebid extPrebid = extRequest != null ? extRequest.getPrebid() : null; | ||
final ExtRequestPrebidChannel channel = extPrebid != null ? extPrebid.getChannel() : null; | ||
final String channelName = channel != null ? channel.getName() : null; | ||
final String channelVersion = channel != null ? channel.getVersion() : null; | ||
|
||
return createNameVersionRecord(channelName, channelVersion); | ||
} | ||
|
||
private static String resolveSdkVersionRecord(App app) { | ||
final ExtApp extApp = app != null ? app.getExt() : null; | ||
final ExtAppPrebid extPrebid = extApp != null ? extApp.getPrebid() : null; | ||
final String sdkSource = extPrebid != null ? extPrebid.getSource() : null; | ||
final String sdkVersion = extPrebid != null ? extPrebid.getVersion() : null; | ||
|
||
return createNameVersionRecord(sdkSource, sdkVersion); | ||
} | ||
|
||
private static String createNameVersionRecord(String name, String version) { | ||
return StringUtils.isNotEmpty(name) && StringUtils.isNotEmpty(version) | ||
? String.format("%s/%s", name, version) | ||
: null; | ||
} | ||
} |
This file contains 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
This file contains 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
This file contains 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
103 changes: 103 additions & 0 deletions
103
src/test/java/org/prebid/server/bidder/HttpBidderRequestEnricherTest.java
This file contains 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,103 @@ | ||
package org.prebid.server.bidder; | ||
|
||
import com.iab.openrtb.request.App; | ||
import com.iab.openrtb.request.BidRequest; | ||
import io.vertx.core.MultiMap; | ||
import io.vertx.core.http.CaseInsensitiveHeaders; | ||
import org.junit.Before; | ||
import org.junit.Test; | ||
import org.prebid.server.proto.openrtb.ext.request.ExtApp; | ||
import org.prebid.server.proto.openrtb.ext.request.ExtAppPrebid; | ||
import org.prebid.server.proto.openrtb.ext.request.ExtRequest; | ||
import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebid; | ||
import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebidChannel; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
public class HttpBidderRequestEnricherTest { | ||
|
||
private HttpBidderRequestEnricher requestEnricher; | ||
|
||
@Before | ||
public void setUp() { | ||
|
||
requestEnricher = new HttpBidderRequestEnricher("1.00"); | ||
} | ||
|
||
@Test | ||
public void shouldSendPopulatedPostRequest() { | ||
// given | ||
final MultiMap headers = new CaseInsensitiveHeaders(); | ||
headers.add("header1", "value1"); | ||
headers.add("header2", "value2"); | ||
|
||
// when | ||
final MultiMap resultHeaders = | ||
requestEnricher.enrichHeaders(headers, new CaseInsensitiveHeaders(), BidRequest.builder().build()); | ||
|
||
// then | ||
final MultiMap expectedHeaders = new CaseInsensitiveHeaders(); | ||
expectedHeaders.addAll(headers); | ||
expectedHeaders.add("x-prebid", "pbs-java/1.00"); | ||
assertThat(resultHeaders).hasSize(3); | ||
assertThat(isEqualsMultiMaps(resultHeaders, expectedHeaders)).isTrue(); | ||
} | ||
|
||
@Test | ||
public void shouldAddSecGpcHeaderFromOriginalRequest() { | ||
// given | ||
final MultiMap originalHeaders = new CaseInsensitiveHeaders().add("Sec-GPC", "1"); | ||
|
||
// when | ||
final MultiMap resultHeaders = | ||
requestEnricher.enrichHeaders(new CaseInsensitiveHeaders(), | ||
originalHeaders, BidRequest.builder().build()); | ||
|
||
// then | ||
assertThat(resultHeaders.contains("Sec-GPC")).isTrue(); | ||
assertThat(resultHeaders.get("Sec-GPC")).isEqualTo("1"); | ||
} | ||
|
||
@Test | ||
public void shouldNotOverrideHeadersFromBidRequest() { | ||
// given | ||
final MultiMap originalHeaders = new CaseInsensitiveHeaders().add("Sec-GPC", "1"); | ||
final MultiMap bidderRequestHeaders = new CaseInsensitiveHeaders().add("Sec-GPC", "0"); | ||
|
||
// when | ||
final MultiMap resultHeaders = requestEnricher.enrichHeaders(bidderRequestHeaders, | ||
originalHeaders, BidRequest.builder().build()); | ||
|
||
// then | ||
assertThat(resultHeaders.contains("Sec-GPC")).isTrue(); | ||
assertThat(resultHeaders.getAll("Sec-GPC")).hasSize(1); | ||
assertThat(resultHeaders.get("Sec-GPC")).isEqualTo("0"); | ||
} | ||
|
||
@Test | ||
public void shouldCreateXPrebidHeaderForOutgoingRequest() { | ||
// given | ||
final BidRequest bidRequest = BidRequest.builder() | ||
.ext(ExtRequest.of(ExtRequestPrebid.builder() | ||
.channel(ExtRequestPrebidChannel.of("pbjs", "4.39")) | ||
.build())) | ||
.app(App.builder() | ||
.ext(ExtApp.of(ExtAppPrebid.of("prebid-mobile", "1.2.3"), null)) | ||
.build()) | ||
.build(); | ||
|
||
// when | ||
final MultiMap resultHeaders = requestEnricher.enrichHeaders(new CaseInsensitiveHeaders(), | ||
new CaseInsensitiveHeaders(), bidRequest); | ||
|
||
// then | ||
final MultiMap expectedHeaders = new CaseInsensitiveHeaders(); | ||
expectedHeaders.add("x-prebid", "pbjs/4.39,prebid-mobile/1.2.3,pbs-java/1.00"); | ||
assertThat(isEqualsMultiMaps(resultHeaders, expectedHeaders)).isTrue(); | ||
} | ||
|
||
private static boolean isEqualsMultiMaps(MultiMap left, MultiMap right) { | ||
return left.size() == right.size() && left.entries().stream() | ||
.allMatch(entry -> right.contains(entry.getKey(), entry.getValue(), true)); | ||
} | ||
} |
Oops, something went wrong.