Skip to content

Commit c91eea7

Browse files
author
softcoder594
committed
optable-targeting: Split API endpoint configuration into host-level and account-level settings
1 parent b669837 commit c91eea7

10 files changed

Lines changed: 73 additions & 28 deletions

File tree

extra/modules/optable-targeting/sample-requests/data.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
"source": "pubcid.org",
6565
"uids": [
6666
{
67-
"id": "f9528392fd38786082c7fd01cd2aa5a60d2c3a2788789b1f9de4574a7c9dabae",
67+
"id": "test",
6868
"atype": 1
6969
}
7070
]

extra/modules/optable-targeting/src/main/java/org/prebid/server/hooks/modules/optable/targeting/model/config/OptableTargetingProperties.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ public final class OptableTargetingProperties {
1717
@JsonProperty("api-key")
1818
String apiKey;
1919

20+
@JsonProperty("user-id")
21+
String userId;
22+
23+
String origin;
24+
2025
@JsonProperty("ppid-mapping")
2126
Map<String, String> ppidMapping;
2227

extra/modules/optable-targeting/src/main/java/org/prebid/server/hooks/modules/optable/targeting/v1/core/Cache.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@ public Cache(PbcStorageService cacheService,
2929
public Future<TargetingResult> get(String query) {
3030
return cacheService.retrieveEntry(query, APP_CODE, APPLICATION)
3131
.map(ModuleCacheResponse::getValue)
32-
.map(optableResponseMapper::parse)
32+
.map(it -> it != null ? optableResponseMapper.parse(it) : null)
3333
.otherwise(it -> null);
3434
}
3535

3636
public Future<Void> put(String query, TargetingResult value, int ttlSeconds) {
37+
if (value == null) return Future.succeededFuture();
38+
3739
return cacheService.storeEntry(
3840
query,
3941
optableResponseMapper.toJsonString(value),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package org.prebid.server.hooks.modules.optable.targeting.v1.core;
2+
3+
public class EndpointResolver {
4+
5+
private static final String ACCOUNT_ID = "{ACCOUNT_ID}";
6+
7+
private static final String ORIGIN = "{ORIGIN}";
8+
9+
private EndpointResolver() {
10+
}
11+
12+
public static String resolve(String endpointTemplate, String accountId, String origin) {
13+
return endpointTemplate.replace(ACCOUNT_ID, accountId)
14+
.replace(ORIGIN, origin);
15+
}
16+
}

extra/modules/optable-targeting/src/main/java/org/prebid/server/hooks/modules/optable/targeting/v1/core/OptableTargeting.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,33 +43,39 @@ public Future<TargetingResult> getTargeting(OptableTargetingProperties propertie
4343
? getOrFetchTargetingResults(
4444
properties.getCache(),
4545
properties.getApiKey(),
46+
properties.getUserId(),
47+
properties.getOrigin(),
4648
query,
4749
attributes.getIps(), timeout)
4850
: apiClient.getTargeting(
4951
properties.getApiKey(),
52+
properties.getUserId(),
53+
properties.getOrigin(),
5054
query,
5155
attributes.getIps(),
5256
timeout))
5357
.orElse(Future.failedFuture("Can't get targeting"));
5458
}
5559

5660
private Future<TargetingResult> getOrFetchTargetingResults(CacheProperties cacheProperties, String apiKey,
61+
String accountId, String origin,
5762
String query, List<String> ips, long timeout) {
5863

59-
final String key = URLEncoder.encode(query, StandardCharsets.UTF_8);
64+
final String key = accountId + ":" +URLEncoder.encode(query, StandardCharsets.UTF_8);
6065

6166
return cache.get(key)
6267
.recover(err -> Future.succeededFuture(null))
6368
.compose(entry -> entry != null
6469
? Future.succeededFuture(entry)
65-
: fetchAndCacheResult(cacheProperties.getTtlseconds(), apiKey, query, ips, timeout));
70+
: fetchAndCacheResult(accountId, origin, cacheProperties.getTtlseconds(), apiKey,
71+
query, ips, timeout));
6672

6773
}
6874

69-
private Future<TargetingResult> fetchAndCacheResult(int ttlSeconds, String apiKey, String query,
70-
List<String> ips, long timeout) {
75+
private Future<TargetingResult> fetchAndCacheResult(String accountId, String origin, int ttlSeconds, String apiKey,
76+
String query, List<String> ips, long timeout) {
7177

72-
return apiClient.getTargeting(apiKey, query, ips, timeout)
73-
.compose(result -> cache.put(query, result, ttlSeconds).map(result));
78+
return apiClient.getTargeting(apiKey, accountId, origin, query, ips, timeout)
79+
.compose(result -> cache.put(accountId + ":" + query, result, ttlSeconds).map(result));
7480
}
7581
}

extra/modules/optable-targeting/src/main/java/org/prebid/server/hooks/modules/optable/targeting/v1/net/APIClient.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import org.prebid.server.hooks.modules.optable.targeting.model.net.OptableCall;
1414
import org.prebid.server.hooks.modules.optable.targeting.model.net.OptableError;
1515
import org.prebid.server.hooks.modules.optable.targeting.model.openrtb.TargetingResult;
16+
import org.prebid.server.hooks.modules.optable.targeting.v1.core.EndpointResolver;
1617
import org.prebid.server.log.ConditionalLogger;
1718
import org.prebid.server.log.Logger;
1819
import org.prebid.server.log.LoggerFactory;
@@ -50,7 +51,9 @@ public APIClient(String endpoint,
5051
this.responseMapper = Objects.requireNonNull(responseMapper);
5152
}
5253

53-
public Future<TargetingResult> getTargeting(String apiKey, String query, List<String> ips, long timeout) {
54+
public Future<TargetingResult> getTargeting(String apiKey, String accountId, String origin,
55+
String query, List<String> ips, long timeout) {
56+
5457
final MultiMap headers = HeadersMultiMap.headers()
5558
.add(HttpUtil.ACCEPT_HEADER, "application/json");
5659

@@ -65,7 +68,7 @@ public Future<TargetingResult> getTargeting(String apiKey, String query, List<St
6568
}
6669

6770
final HttpRequest request = HttpRequest.builder()
68-
.uri(endpoint)
71+
.uri(EndpointResolver.resolve(endpoint, accountId, origin))
6972
.query(query)
7073
.headers(headers)
7174
.build();
@@ -103,7 +106,7 @@ private Future<TargetingResult> logParsingError(Throwable exception, HttpRequest
103106
private Future<HttpClientResponse> createRequest(HttpRequest httpRequest, long remainingTimeout) {
104107
try {
105108
return httpClient.request(HttpMethod.GET,
106-
httpRequest.getUri() + "?id=" + httpRequest.getQuery(),
109+
httpRequest.getUri() + "&id=" + httpRequest.getQuery(),
107110
httpRequest.getHeaders(),
108111
(String) null,
109112
remainingTimeout);

extra/modules/optable-targeting/src/test/java/org/prebid/server/hooks/modules/optable/targeting/v1/core/OptableTargetingTest.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public void shouldReturnTargetingResultsAndNotUseCache() {
6363
final BidRequest bidRequest = givenBidRequest();
6464
properties = givenOptableTargetingProperties(false);
6565
when(idsMapper.toIds(any(), any())).thenReturn(List.of(Id.of(Id.ID5, "id")));
66-
when(apiClient.getTargeting(any(), any(), any(), anyLong()))
66+
when(apiClient.getTargeting(any(), any(), any(), any(), any(), anyLong()))
6767
.thenReturn(Future.succeededFuture(givenTargetingResult()));
6868

6969
// when
@@ -78,7 +78,7 @@ public void shouldReturnTargetingResultsAndNotUseCache() {
7878
.returns("id", it -> it.getData().getFirst().getId())
7979
.returns("id", it -> it.getData().getFirst().getSegment().getFirst().getId());
8080
verify(cache, times(0)).get(any());
81-
verify(apiClient, times(1)).getTargeting(any(), any(), any(), anyLong());
81+
verify(apiClient, times(1)).getTargeting(any(), any(), any(), any(), any(), anyLong());
8282
verify(cache, times(0)).put(any(), eq(targetingResult.result()), anyInt());
8383
}
8484

@@ -89,7 +89,7 @@ public void shouldCallAPIAndAddTargetingResultsToCache() {
8989
when(cache.put(any(), any(), anyInt())).thenReturn(Future.succeededFuture());
9090
final BidRequest bidRequest = givenBidRequest();
9191
when(idsMapper.toIds(any(), any())).thenReturn(List.of(Id.of(Id.ID5, "id")));
92-
when(apiClient.getTargeting(any(), any(), any(), anyLong()))
92+
when(apiClient.getTargeting(any(), any(), any(), any(), any(), anyLong()))
9393
.thenReturn(Future.succeededFuture(givenTargetingResult()));
9494

9595
// when
@@ -113,7 +113,7 @@ public void shouldCallAPIAndAddTargetingResultsToCacheWhenCacheReturnsFailure()
113113
when(cache.put(any(), any(), anyInt())).thenReturn(Future.succeededFuture());
114114
final BidRequest bidRequest = givenBidRequest();
115115
when(idsMapper.toIds(any(), any())).thenReturn(List.of(Id.of(Id.ID5, "id")));
116-
when(apiClient.getTargeting(any(), any(), any(), anyLong()))
116+
when(apiClient.getTargeting(any(), any(), any(), any(), any(), anyLong()))
117117
.thenReturn(Future.succeededFuture(givenTargetingResult()));
118118

119119
// when
@@ -127,7 +127,7 @@ public void shouldCallAPIAndAddTargetingResultsToCacheWhenCacheReturnsFailure()
127127
.returns("id", it -> it.getEids().getFirst().getUids().getFirst().getId())
128128
.returns("id", it -> it.getData().getFirst().getId())
129129
.returns("id", it -> it.getData().getFirst().getSegment().getFirst().getId());
130-
verify(apiClient, times(1)).getTargeting(any(), any(), any(), anyLong());
130+
verify(apiClient, times(1)).getTargeting(any(), any(), any(), any(), any(), anyLong());
131131
verify(cache).put(any(), eq(targetingResult.result()), anyInt());
132132
}
133133

@@ -150,7 +150,7 @@ public void shouldUseCachedResult() {
150150
.returns("id", it -> it.getData().getFirst().getId())
151151
.returns("id", it -> it.getData().getFirst().getSegment().getFirst().getId());
152152
verify(cache, times(1)).get(any());
153-
verify(apiClient, times(0)).getTargeting(any(), any(), any(), anyLong());
153+
verify(apiClient, times(0)).getTargeting(any(), any(), any(), any(), any(), anyLong());
154154
verify(cache, times(0)).put(any(), eq(targetingResult.result()), anyInt());
155155
}
156156

@@ -175,7 +175,7 @@ public void shouldNotFailWhenApiClientIsFailed() {
175175
properties = givenOptableTargetingProperties(false);
176176
final BidRequest bidRequest = givenBidRequest();
177177
when(idsMapper.toIds(any(), any())).thenReturn(List.of(Id.of(Id.ID5, "id")));
178-
when(apiClient.getTargeting(any(), any(), any(), anyLong())).thenReturn(null);
178+
when(apiClient.getTargeting(any(), any(), any(), any(), any(), anyLong())).thenReturn(null);
179179

180180
// when
181181
final Future<TargetingResult> targetingResult = target.getTargeting(properties, bidRequest,
@@ -191,7 +191,8 @@ public void shouldNotFailWhenApiClientReturnsFailFuture() {
191191
final BidRequest bidRequest = givenBidRequest();
192192
properties = givenOptableTargetingProperties(false);
193193
when(idsMapper.toIds(any(), any())).thenReturn(List.of(Id.of(Id.ID5, "id")));
194-
when(apiClient.getTargeting(any(), any(), any(), anyLong())).thenReturn(Future.failedFuture("File"));
194+
when(apiClient.getTargeting(any(), any(), any(), any(), any(), anyLong()))
195+
.thenReturn(Future.failedFuture("File"));
195196

196197
// when
197198
final Future<TargetingResult> targetingResult = target.getTargeting(properties, bidRequest,

extra/modules/optable-targeting/src/test/java/org/prebid/server/hooks/modules/optable/targeting/v1/net/APIClientTest.java

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ public void shouldReturnTargetingResult() {
6161
.thenReturn(Future.succeededFuture(givenSuccessHttpResponse("targeting_response.json")));
6262

6363
// when
64-
final Future<TargetingResult> result = target.getTargeting("key", "query", List.of("8.8.8.8"), 1000);
64+
final Future<TargetingResult> result = target.getTargeting("key", "accountId", "origin",
65+
"query", List.of("8.8.8.8"), 1000);
6566

6667
// then
6768
assertThat(result.result()).isNotNull();
@@ -78,7 +79,8 @@ public void shouldReturnNullWhenEndpointRespondsWithError() {
7879
.thenReturn(Future.succeededFuture(givenFailHttpResponse("error_response.json")));
7980

8081
// when
81-
final Future<TargetingResult> result = target.getTargeting("key", "query", List.of("8.8.8.8"), 1000);
82+
final Future<TargetingResult> result = target.getTargeting("key", "accountId", "origin",
83+
"query", List.of("8.8.8.8"), 1000);
8284

8385
// then
8486
assertThat(result.result()).isNull();
@@ -91,7 +93,8 @@ public void shouldNotFailWhenEndpointRespondsWithWrongData() {
9193
.thenReturn(Future.succeededFuture(givenSuccessHttpResponse("plain_text_response.json")));
9294

9395
// when
94-
final Future<TargetingResult> result = target.getTargeting("key", "query", List.of("8.8.8.8"), 1000);
96+
final Future<TargetingResult> result = target.getTargeting("key", "accountId", "origin",
97+
"query", List.of("8.8.8.8"), 1000);
9598

9699
// then
97100
assertThat(result.result()).isNull();
@@ -104,7 +107,8 @@ public void shouldNotFailWhenHttpClientIsCrashed() {
104107
.thenThrow(new NullPointerException());
105108

106109
// when
107-
final Future<TargetingResult> result = target.getTargeting("key", "query", List.of("8.8.8.8"), 1000);
110+
final Future<TargetingResult> result = target.getTargeting("key", "accountId", "origin",
111+
"query", List.of("8.8.8.8"), 1000);
108112

109113
// then
110114
assertThat(result.result()).isNull();
@@ -118,7 +122,8 @@ public void shouldNotFailWhenInternalErrorOccurs() {
118122
"plain_text_response.json")));
119123

120124
// when
121-
final Future<TargetingResult> result = target.getTargeting("key", "query", List.of("8.8.8.8"), 1000);
125+
final Future<TargetingResult> result = target.getTargeting("key", "accountId", "origin",
126+
"query", List.of("8.8.8.8"), 1000);
122127

123128
// then
124129
assertThat(result.result()).isNull();
@@ -137,7 +142,8 @@ public void shouldUseAuthorizationHeaderIfApiKeyIsPresent() {
137142
"plain_text_response.json")));
138143

139144
// when
140-
final Future<TargetingResult> result = target.getTargeting("key", "query", List.of("8.8.8.8"), 1000);
145+
final Future<TargetingResult> result = target.getTargeting("key", "accountId", "origin",
146+
"query", List.of("8.8.8.8"), 1000);
141147

142148
// then
143149
final ArgumentCaptor<MultiMap> headersCaptor = ArgumentCaptor.forClass(MultiMap.class);
@@ -156,7 +162,8 @@ public void shouldNotUseAuthorizationHeaderIfApiKeyIsAbsent() {
156162
"plain_text_response.json")));
157163

158164
// when
159-
final Future<TargetingResult> result = target.getTargeting(null, "query", List.of("8.8.8.8"), 1000);
165+
final Future<TargetingResult> result = target.getTargeting(null, "accountId", "origin",
166+
"query", List.of("8.8.8.8"), 1000);
160167

161168
// then
162169
final ArgumentCaptor<MultiMap> headersCaptor = ArgumentCaptor.forClass(MultiMap.class);
@@ -177,6 +184,8 @@ public void shouldPassThroughIpAddresses() {
177184
// when
178185
final Future<TargetingResult> result = target.getTargeting(
179186
"key",
187+
"accountId",
188+
"origin",
180189
"query",
181190
List.of("8.8.8.8", "2001:4860:4860::8888"),
182191
1000);
@@ -197,7 +206,8 @@ public void shouldNotPassThroughIpAddressWhenNotSpecified() {
197206
"plain_text_response.json")));
198207

199208
// when
200-
final Future<TargetingResult> result = target.getTargeting("key", "query", null, 1000);
209+
final Future<TargetingResult> result = target.getTargeting("key", "accountId", "origin",
210+
"query", null, 1000);
201211

202212
// then
203213
final ArgumentCaptor<MultiMap> headersCaptor = ArgumentCaptor.forClass(MultiMap.class);

sample/configs/prebid-config-with-optable.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,4 @@ hooks:
5050
enabled: true
5151
modules:
5252
optable-targeting:
53-
api-endpoint: endpoint
53+
api-endpoint: https://na.edge.optable.co/v2/targeting?t={ACCOUNT_ID}&o={ORIGIN}

sample/configs/sample-app-settings-optable.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ accounts:
1919
modules:
2020
optable-targeting:
2121
api-key: key
22+
user-id: optable
23+
origin: web-sdk-demo
2224
ppid-mapping: { "pubcid.org": "c" }
2325
adserver-targeting: true
2426
cache:

0 commit comments

Comments
 (0)