Skip to content
Merged
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 @@ -11,8 +11,8 @@

public class Cache {

private static final String APP_CODE = "prebid-Java";
private static final String APPLICATION = "optable-targeting";
private static final String APPLICATION = "prebid-Java";
private static final String APP_CODE = "optable-targeting";

private final PbcStorageService cacheService;
private final JacksonMapper mapper;
Expand Down
61 changes: 51 additions & 10 deletions src/main/java/org/prebid/server/cache/BasicPbcStorageService.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@
import org.prebid.server.exception.PreBidException;
import org.prebid.server.json.DecodeException;
import org.prebid.server.json.JacksonMapper;
import org.prebid.server.metric.MetricName;
import org.prebid.server.metric.Metrics;
import org.prebid.server.util.HttpUtil;
import org.prebid.server.vertx.httpclient.HttpClient;

import java.net.URL;
import java.time.Clock;
import java.util.Objects;

public class BasicPbcStorageService implements PbcStorageService {
Expand All @@ -27,18 +30,24 @@ public class BasicPbcStorageService implements PbcStorageService {
private final String apiKey;
private final int callTimeoutMs;
private final JacksonMapper mapper;
private final Clock clock;
private final Metrics metrics;

public BasicPbcStorageService(HttpClient httpClient,
URL endpointUrl,
String apiKey,
int callTimeoutMs,
JacksonMapper mapper) {
JacksonMapper mapper,
Clock clock,
Metrics metrics) {

this.httpClient = Objects.requireNonNull(httpClient);
this.endpointUrl = Objects.requireNonNull(endpointUrl);
this.apiKey = Objects.requireNonNull(apiKey);
this.callTimeoutMs = callTimeoutMs;
this.mapper = Objects.requireNonNull(mapper);
this.clock = Objects.requireNonNull(clock);
this.metrics = Objects.requireNonNull(metrics);
}

@Override
Expand All @@ -55,20 +64,28 @@ public Future<Void> storeEntry(String key,
return Future.failedFuture(e);
}

final String valueToStore = prepareValueForStoring(value, type);
final ModuleCacheRequest moduleCacheRequest =
ModuleCacheRequest.of(
constructEntryKey(key, appCode),
type,
prepareValueForStoring(value, type),
valueToStore,
application,
ttlseconds);

updateCreativeMetrics(valueToStore, type, ttlseconds, appCode);

final long startTime = clock.millis();
return httpClient.post(
endpointUrl.toString(),
securedCallHeaders(),
mapper.encodeToString(moduleCacheRequest),
callTimeoutMs)
.compose(response -> processStoreResponse(response.getStatusCode(), response.getBody()));
.compose(response -> processStoreResponse(
response.getStatusCode(),
response.getBody(),
startTime,
appCode));

}

Expand Down Expand Up @@ -99,6 +116,19 @@ private static void validateStoreData(String key,
}
}

private void updateCreativeMetrics(String value, StorageDataType type, Integer ttlseconds, String appCode) {
final MetricName metricName = switch (type) {
case XML -> MetricName.xml;
case JSON -> MetricName.json;
case TEXT -> MetricName.text;
};

metrics.updateModuleStorageCacheEntrySize(appCode, value.length(), metricName);
if (ttlseconds != null) {
metrics.updateModuleStorageCacheEntryTtl(appCode, ttlseconds, metricName);
}
}

private static String prepareValueForStoring(String value, StorageDataType type) {
return type == StorageDataType.TEXT
? new String(Base64.encodeBase64(value.getBytes()))
Expand All @@ -114,31 +144,35 @@ private String constructEntryKey(String key, String moduleCode) {
return MODULE_KEY_PREFIX + MODULE_KEY_DELIMETER + moduleCode + MODULE_KEY_DELIMETER + key;
}

private Future<Void> processStoreResponse(int statusCode, String responseBody) {
private Future<Void> processStoreResponse(int statusCode, String responseBody, long startTime, String appCode) {
if (statusCode != 204) {
metrics.updateModuleStorageCacheWriteRequestTime(appCode, clock.millis() - startTime, MetricName.err);
throw new PreBidException("HTTP status code: '%s', body: '%s' "
.formatted(statusCode, responseBody));
}

metrics.updateModuleStorageCacheWriteRequestTime(appCode, clock.millis() - startTime, MetricName.ok);
return Future.succeededFuture();
}

@Override
public Future<ModuleCacheResponse> retrieveEntry(String key,
String appCode,
String application) {

public Future<ModuleCacheResponse> retrieveEntry(String key, String appCode, String application) {
try {
validateRetrieveData(key, application, appCode);
} catch (PreBidException e) {
return Future.failedFuture(e);
}

final long startTime = clock.millis();
return httpClient.get(
getRetrieveEndpoint(key, appCode, application),
securedCallHeaders(),
callTimeoutMs)
.map(response -> toModuleCacheResponse(response.getStatusCode(), response.getBody()));
.map(response -> toModuleCacheResponse(
response.getStatusCode(),
response.getBody(),
startTime,
appCode));

}

Expand All @@ -165,11 +199,18 @@ private String getRetrieveEndpoint(String key,
+ "&a=" + application;
}

private ModuleCacheResponse toModuleCacheResponse(int statusCode, String responseBody) {
private ModuleCacheResponse toModuleCacheResponse(int statusCode,
String responseBody,
long startTime,
String application) {

if (statusCode != 200) {
metrics.updateModuleStorageCacheReadRequestTime(application, clock.millis() - startTime, MetricName.err);
throw new PreBidException("HTTP status code " + statusCode);
}

metrics.updateModuleStorageCacheReadRequestTime(application, clock.millis() - startTime, MetricName.ok);

final ModuleCacheResponse moduleCacheResponse;
try {
moduleCacheResponse = mapper.decodeValue(responseBody, ModuleCacheResponse.class);
Expand Down
26 changes: 16 additions & 10 deletions src/main/java/org/prebid/server/cache/CoreCacheService.java
Original file line number Diff line number Diff line change
Expand Up @@ -208,13 +208,6 @@ private BidCacheResponse processVtrackWriteCacheResponse(int statusCode,
return bidCacheResponse;
}

private <T> Future<T> failVtrackCacheWriteResponse(Throwable exception, String accountId, long startTime) {
if (exception instanceof PreBidException) {
metrics.updateVtrackCacheWriteRequestTime(accountId, clock.millis() - startTime, MetricName.err);
}
return failResponse(exception);
}

public Future<BidCacheResponse> cachePutObjects(List<BidPutObject> bidPutObjects,
Boolean isEventsEnabled,
Set<String> biddersAllowingVastUpdate,
Expand Down Expand Up @@ -671,7 +664,7 @@ public Future<HttpClientResponse> getCachedObject(String key, String ch, Timeout
final long startTime = clock.millis();
return httpClient.get(url, cacheHeaders, remainingTimeout)
.map(response -> processVtrackReadResponse(response, startTime))
.recover(CoreCacheService::failResponse);
.recover(exception -> failVtrackCacheReadResponse(exception, startTime));
}

private HttpClientResponse processVtrackReadResponse(HttpClientResponse response, long startTime) {
Expand All @@ -683,16 +676,29 @@ private HttpClientResponse processVtrackReadResponse(HttpClientResponse response
return response;
}

metrics.updateVtrackCacheReadRequestTime(clock.millis() - startTime, MetricName.err);

try {
final CacheErrorResponse errorResponse = mapper.decodeValue(body, CacheErrorResponse.class);
metrics.updateVtrackCacheReadRequestTime(clock.millis() - startTime, MetricName.err);
return HttpClientResponse.of(statusCode, response.getHeaders(), errorResponse.getMessage());
} catch (DecodeException e) {
throw new PreBidException("Cannot parse response: " + body, e);
}
}

private <T> Future<T> failVtrackCacheWriteResponse(Throwable exception, String accountId, long startTime) {
if (exception instanceof PreBidException) {
metrics.updateVtrackCacheWriteRequestTime(accountId, clock.millis() - startTime, MetricName.err);
}
return failResponse(exception);
}

private <T> Future<T> failVtrackCacheReadResponse(Throwable exception, long startTime) {
if (exception instanceof PreBidException) {
metrics.updateVtrackCacheReadRequestTime(clock.millis() - startTime, MetricName.err);
}
return failResponse(exception);
}

private static <T> Future<T> failResponse(Throwable exception) {
logger.warn("Error occurred while interacting with cache service: {}", exception.getMessage());
logger.debug("Error occurred while interacting with cache service", exception);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
package org.prebid.server.metric;

import com.codahale.metrics.MetricRegistry;
import org.prebid.server.metric.model.CacheCreativeType;

import java.util.Objects;
import java.util.function.Function;

public class CacheCreativeSizeMetrics extends UpdatableMetrics {

CacheCreativeSizeMetrics(MetricRegistry metricRegistry, CounterType counterType, String prefix) {
CacheCreativeSizeMetrics(MetricRegistry metricRegistry,
CounterType counterType,
String prefix,
CacheCreativeType type) {

super(Objects.requireNonNull(metricRegistry), Objects.requireNonNull(counterType),
nameCreator(Objects.requireNonNull(prefix)));
nameCreator(Objects.requireNonNull(prefix), Objects.requireNonNull(type)));
}

private static Function<MetricName, String> nameCreator(String prefix) {
return metricName -> "%s.creative_size.%s".formatted(prefix, metricName);
private static Function<MetricName, String> nameCreator(String prefix, CacheCreativeType type) {
return metricName -> "%s.%s_size.%s".formatted(prefix, type.getType(), metricName);
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
package org.prebid.server.metric;

import com.codahale.metrics.MetricRegistry;
import org.prebid.server.metric.model.CacheCreativeType;

import java.util.Objects;
import java.util.function.Function;

public class CacheCreativeTtlMetrics extends UpdatableMetrics {

CacheCreativeTtlMetrics(MetricRegistry metricRegistry, CounterType counterType, String prefix) {
CacheCreativeTtlMetrics(MetricRegistry metricRegistry,
CounterType counterType,
String prefix,
CacheCreativeType type) {

super(Objects.requireNonNull(metricRegistry),
Objects.requireNonNull(counterType),
nameCreator(Objects.requireNonNull(prefix)));
nameCreator(Objects.requireNonNull(prefix), Objects.requireNonNull(type)));
}

private static Function<MetricName, String> nameCreator(String prefix) {
return metricName -> "%s.creative_ttl.%s".formatted(prefix, metricName);
private static Function<MetricName, String> nameCreator(String prefix, CacheCreativeType type) {
return metricName -> "%s.%s_ttl.%s".formatted(prefix, type.getType(), metricName);
}
}
27 changes: 23 additions & 4 deletions src/main/java/org/prebid/server/metric/CacheMetrics.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package org.prebid.server.metric;

import com.codahale.metrics.MetricRegistry;
import org.prebid.server.metric.model.CacheCreativeType;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;

Expand All @@ -14,6 +17,8 @@ class CacheMetrics extends UpdatableMetrics {
private final CacheCreativeSizeMetrics cacheCreativeSizeMetrics;
private final CacheCreativeTtlMetrics cacheCreativeTtlMetrics;
private final CacheVtrackMetrics cacheVtrackMetrics;
private final Map<String, CacheModuleStorageMetrics> cacheModuleStorageMetrics;
private final Function<String, CacheModuleStorageMetrics> cacheModuleStorageMetricsCreator;

CacheMetrics(MetricRegistry metricRegistry, CounterType counterType) {
super(
Expand All @@ -22,9 +27,14 @@ class CacheMetrics extends UpdatableMetrics {
nameCreator(createPrefix()));

requestsMetrics = new RequestMetrics(metricRegistry, counterType, createPrefix());
cacheCreativeSizeMetrics = new CacheCreativeSizeMetrics(metricRegistry, counterType, createPrefix());
cacheCreativeTtlMetrics = new CacheCreativeTtlMetrics(metricRegistry, counterType, createPrefix());
cacheCreativeSizeMetrics = new CacheCreativeSizeMetrics(
metricRegistry, counterType, createPrefix(), CacheCreativeType.CREATIVE);
cacheCreativeTtlMetrics = new CacheCreativeTtlMetrics(
metricRegistry, counterType, createPrefix(), CacheCreativeType.CREATIVE);
cacheVtrackMetrics = new CacheVtrackMetrics(metricRegistry, counterType, createPrefix());
cacheModuleStorageMetrics = new HashMap<>();
cacheModuleStorageMetricsCreator = moduleCode ->
new CacheModuleStorageMetrics(metricRegistry, counterType, createPrefix(), moduleCode);
}

CacheMetrics(MetricRegistry metricRegistry, CounterType counterType, String prefix) {
Expand All @@ -34,9 +44,14 @@ class CacheMetrics extends UpdatableMetrics {
nameCreator(createPrefix(Objects.requireNonNull(prefix))));

requestsMetrics = new RequestMetrics(metricRegistry, counterType, createPrefix(prefix));
cacheCreativeSizeMetrics = new CacheCreativeSizeMetrics(metricRegistry, counterType, createPrefix(prefix));
cacheCreativeTtlMetrics = new CacheCreativeTtlMetrics(metricRegistry, counterType, createPrefix(prefix));
cacheCreativeSizeMetrics = new CacheCreativeSizeMetrics(
metricRegistry, counterType, createPrefix(prefix), CacheCreativeType.CREATIVE);
cacheCreativeTtlMetrics = new CacheCreativeTtlMetrics(
metricRegistry, counterType, createPrefix(prefix), CacheCreativeType.CREATIVE);
cacheVtrackMetrics = new CacheVtrackMetrics(metricRegistry, counterType, createPrefix(prefix));
cacheModuleStorageMetrics = new HashMap<>();
cacheModuleStorageMetricsCreator = moduleCode ->
new CacheModuleStorageMetrics(metricRegistry, counterType, createPrefix(), moduleCode);
}

private static String createPrefix(String prefix) {
Expand Down Expand Up @@ -66,4 +81,8 @@ CacheCreativeTtlMetrics creativeTtl() {
CacheVtrackMetrics vtrack() {
return cacheVtrackMetrics;
}

CacheModuleStorageMetrics moduleStorage(String moduleCode) {
return cacheModuleStorageMetrics.computeIfAbsent(moduleCode, cacheModuleStorageMetricsCreator);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.prebid.server.metric;

import com.codahale.metrics.MetricRegistry;
import org.prebid.server.metric.model.CacheCreativeType;

import java.util.Objects;
import java.util.function.Function;

class CacheModuleStorageMetrics extends UpdatableMetrics {

private final CacheReadMetrics readMetrics;
private final CacheWriteMetrics writeMetrics;
private final CacheCreativeSizeMetrics entrySizeMetrics;
private final CacheCreativeTtlMetrics entryTtlMetrics;

CacheModuleStorageMetrics(MetricRegistry metricRegistry, CounterType counterType, String prefix, String module) {
super(
Objects.requireNonNull(metricRegistry),
Objects.requireNonNull(counterType),
nameCreator(createPrefix(Objects.requireNonNull(prefix), Objects.requireNonNull(module))));

readMetrics = new CacheReadMetrics(metricRegistry, counterType, createPrefix(prefix, module));
writeMetrics = new CacheWriteMetrics(metricRegistry, counterType, createPrefix(prefix, module));
entrySizeMetrics = new CacheCreativeSizeMetrics(
metricRegistry, counterType, createPrefix(prefix, module), CacheCreativeType.ENTRY);
entryTtlMetrics = new CacheCreativeTtlMetrics(
metricRegistry, counterType, createPrefix(prefix, module), CacheCreativeType.ENTRY);
}

private static Function<MetricName, String> nameCreator(String prefix) {
return metricName -> "%s.%s".formatted(prefix, metricName);
}

private static String createPrefix(String prefix, String moduleCode) {
return "%s.module_storage.%s".formatted(prefix, moduleCode);
}

CacheReadMetrics read() {
return readMetrics;
}

CacheWriteMetrics write() {
return writeMetrics;
}

CacheCreativeSizeMetrics entrySize() {
return entrySizeMetrics;
}

CacheCreativeTtlMetrics entryTtl() {
return entryTtlMetrics;
}

}
Loading
Loading