From 1559173b26a4b59e2a11a2e36e0f5f21c7c6fd50 Mon Sep 17 00:00:00 2001
From: Oleksandr Zhevedenko <720803+Net-burst@users.noreply.github.com>
Date: Mon, 15 Jun 2026 10:12:03 -0400
Subject: [PATCH 1/6] Bump to Java 25 and Spring Boot 3.5
---
.github/workflows/codeql-analysis.yml | 2 +-
.github/workflows/pr-functional-tests.yml | 2 +-
.github/workflows/pr-java-ci.yml | 2 +-
Dockerfile | 2 +-
pom.xml | 89 +++++++------------
.../org/prebid/cache/PBCacheApplication.java | 3 -
.../builders/PrebidServerResponseBuilder.java | 40 +++++----
.../prebid/cache/handlers/ErrorHandler.java | 2 -
.../cache/handlers/cache/GetCacheHandler.java | 15 ++--
.../handlers/cache/PostCacheHandler.java | 7 +-
.../aerospike/AerospikeRepositoryImpl.java | 4 +-
...oduleCompositeRepositoryConfiguration.java | 14 ++-
.../translators/ThrowableTranslator.java | 4 +-
src/main/resources/application-aws.yml | 2 +-
src/main/resources/application.yml | 20 ++---
.../PrebidServerResponseBuilderTests.java | 3 -
.../cache/handlers/GetCacheHandlerTests.java | 26 +++---
.../handlers/GetStorageHandlerTests.java | 7 +-
.../cache/handlers/PostCacheHandlerTests.java | 23 +++--
.../handlers/PostStorageHandlerTests.java | 11 +--
.../cache/metrics/MetricsRecorderTest.java | 2 +
.../prebid/cache/functional/RedisCacheSpec.kt | 2 +-
.../prebid/cache/functional/StorageSpec.kt | 2 +-
.../testcontainers/ContainerDependencies.kt | 6 +-
src/test/resources/application.properties | 16 ++--
25 files changed, 132 insertions(+), 174 deletions(-)
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index b8d227a8..ce3d92a7 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -24,7 +24,7 @@ jobs:
uses: actions/setup-java@v3
with:
distribution: 'temurin'
- java-version: 21
+ java-version: 25
- name: Cache Maven packages
uses: actions/cache@v3
diff --git a/.github/workflows/pr-functional-tests.yml b/.github/workflows/pr-functional-tests.yml
index fb8f30af..3fb3b2fe 100644
--- a/.github/workflows/pr-functional-tests.yml
+++ b/.github/workflows/pr-functional-tests.yml
@@ -17,7 +17,7 @@ jobs:
strategy:
matrix:
- java: [ 21 ]
+ java: [ 25 ]
steps:
- uses: actions/checkout@v3
diff --git a/.github/workflows/pr-java-ci.yml b/.github/workflows/pr-java-ci.yml
index de6b7d56..9a1ab405 100644
--- a/.github/workflows/pr-java-ci.yml
+++ b/.github/workflows/pr-java-ci.yml
@@ -17,7 +17,7 @@ jobs:
strategy:
matrix:
- java: [ 21 ]
+ java: [ 25 ]
steps:
- uses: actions/checkout@v3
diff --git a/Dockerfile b/Dockerfile
index 8fbfc20c..e372bc43 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM amazoncorretto:21.0.6-al2023
+FROM amazoncorretto:25.0.3-al2023-headless
WORKDIR /app/prebid-cache
diff --git a/pom.xml b/pom.xml
index 53f202a3..c3424b72 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,19 +21,18 @@
org.springframework.boot
spring-boot-starter-parent
- 3.2.3
-
+ 3.5.15
+
+ 25
+ org.prebid.cache.PBCacheApplication
+
false
false
false
- src/main/resources
- org.prebid.cache.PBCacheApplication
- 5.9.2
-
0
manual
@@ -41,43 +40,35 @@
manual
yyyy-MM-dd HH:mm
- 21
UTF-8
UTF-8
3.2.1
- 3.2.0
- 3.2.5
- 3.11.0
+ 3.5.0
+ 3.5.6
+ 3.15.0
3.0.0-M5
- 0.1.4
- 3.2.3
- 6.5.1.RELEASE
2.10.1
- 32.0.0-jre
- 3.1.8
3.4.4
- 1.18.30
+ 1.18.46
4.2.17
- 3.0.0
0.10.2
9.0.5
2.17.0
3.5.1
-
3.3.1
- 3.3.0
- 10.12.1
- 0.8.12
+ 3.6.0
+ 13.5.0
+ 0.8.15
4.2.0
2.1.0
2.20.0
2.0.1.Final
- 5.8.0
- 1.9.22
- 1.8.0
- 1.20.0
+ 5.9.1
+ 2.4.0
+ 1.11.0
+ 1.21.4
5.15.0
2.3.13
2.16.1
@@ -123,18 +114,12 @@
io.lettuce
lettuce-core
- ${lettuce-core.version}
com.google.code.gson
gson
${gson.version}
-
- com.google.guava
- guava
- ${guava.version}
-
com.github.ben-manes.caffeine
caffeine
@@ -157,11 +142,6 @@
micrometer-registry-graphite
${micrometer.version}
-
- javax.el
- javax.el-api
- ${javax.el-api.version}
-
io.github.resilience4j
resilience4j-reactor
@@ -173,20 +153,12 @@
${resilience4j.version}
- org.springframework.boot
- spring-boot-starter-test
- test
+ org.apache.commons
+ commons-lang3
- org.junit.jupiter
- junit-jupiter-engine
- ${junit-jupiter.version}
- test
-
-
- org.junit.jupiter
- junit-jupiter-params
- ${junit-jupiter.version}
+ org.springframework.boot
+ spring-boot-starter-test
test
@@ -200,11 +172,6 @@
${wiremock.version}
test
-
- com.github.cjnygard
- rest-maven-plugin
- ${rest-maven-plugin.version}
-
org.reflections
reflections
@@ -300,7 +267,6 @@
${jackson-kotlin-module.version}
test
-
@@ -320,7 +286,6 @@
checkstyle.xml
- UTF-8
true
true
@@ -359,6 +324,9 @@
false
+
+ kotest
+
@@ -366,14 +334,19 @@
maven-compiler-plugin
${maven-compiler-plugin.version}
- ${java.version}
- ${java.version}
+ ${java.version}
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
org.springframework.boot
spring-boot-maven-plugin
- ${spring-boot-maven-plugin.version}
diff --git a/src/main/java/org/prebid/cache/PBCacheApplication.java b/src/main/java/org/prebid/cache/PBCacheApplication.java
index 5c319a37..219405db 100644
--- a/src/main/java/org/prebid/cache/PBCacheApplication.java
+++ b/src/main/java/org/prebid/cache/PBCacheApplication.java
@@ -1,7 +1,6 @@
package org.prebid.cache;
import org.prebid.cache.config.CorsConfig;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.reactive.config.CorsRegistry;
@@ -11,7 +10,6 @@
public class PBCacheApplication implements WebFluxConfigurer {
private final CorsConfig corsConfig;
- @Autowired
public PBCacheApplication(final CorsConfig corsConfig) {
this.corsConfig = corsConfig;
}
@@ -30,4 +28,3 @@ public void addCorsMappings(CorsRegistry registry) {
}
}
}
-
diff --git a/src/main/java/org/prebid/cache/builders/PrebidServerResponseBuilder.java b/src/main/java/org/prebid/cache/builders/PrebidServerResponseBuilder.java
index 8836e921..162282da 100644
--- a/src/main/java/org/prebid/cache/builders/PrebidServerResponseBuilder.java
+++ b/src/main/java/org/prebid/cache/builders/PrebidServerResponseBuilder.java
@@ -1,6 +1,5 @@
package org.prebid.cache.builders;
-import com.google.common.net.HttpHeaders;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.prebid.cache.model.ErrorResponse;
@@ -20,6 +19,9 @@
import java.util.List;
import java.util.function.Predicate;
+import static org.springframework.http.HttpHeaders.ACCEPT_ENCODING;
+import static org.springframework.http.HttpHeaders.CONNECTION;
+import static org.springframework.http.HttpHeaders.DATE;
import static org.springframework.web.reactive.function.BodyInserters.fromValue;
import static org.springframework.web.reactive.function.server.ServerResponse.status;
@@ -46,10 +48,10 @@ public Mono createResponseMono(final ServerRequest request,
private ServerResponse.BodyBuilder ok(final ServerRequest request, final MediaType mediaType) {
final String now = ZonedDateTime.now().format(DateTimeFormatter.RFC_1123_DATE_TIME);
ServerResponse.BodyBuilder builder = ServerResponse.ok()
- .contentType(mediaType)
- .header(HttpHeaders.DATE, now)
- .varyBy(HttpHeaders.ACCEPT_ENCODING)
- .cacheControl(CacheControl.noCache());
+ .contentType(mediaType)
+ .header(DATE, now)
+ .varyBy(ACCEPT_ENCODING)
+ .cacheControl(CacheControl.noCache());
applyHeaders(builder, request);
return builder;
}
@@ -60,13 +62,13 @@ public Mono error(final Mono monoError,
.flatMap(translation ->
addHeaders(status(translation.getHttpStatus()), request)
.body(Mono.just(
- ErrorResponse.builder()
- .error(translation.getHttpStatus().getReasonPhrase())
- .status(translation.getHttpStatus().value())
- .path(request.path())
- .message(translation.getErrorMessage())
- .timestamp(new Date())
- .build()),
+ ErrorResponse.builder()
+ .error(translation.getHttpStatus().getReasonPhrase())
+ .status(translation.getHttpStatus().value())
+ .path(request.path())
+ .message(translation.getErrorMessage())
+ .timestamp(new Date())
+ .build()),
ErrorResponse.class)
);
}
@@ -74,8 +76,8 @@ public Mono error(final Mono monoError,
private static ServerResponse.BodyBuilder addHeaders(final ServerResponse.BodyBuilder builder,
final ServerRequest request) {
ServerResponse.BodyBuilder headers =
- builder.header(HttpHeaders.DATE, ZonedDateTime.now().format(DateTimeFormatter.RFC_1123_DATE_TIME))
- .varyBy(HttpHeaders.ACCEPT_ENCODING)
+ builder.header(DATE, ZonedDateTime.now().format(DateTimeFormatter.RFC_1123_DATE_TIME))
+ .varyBy(ACCEPT_ENCODING)
.cacheControl(CacheControl.noCache());
return applyHeaders(headers, request);
@@ -84,20 +86,20 @@ private static ServerResponse.BodyBuilder addHeaders(final ServerResponse.BodyBu
private static ServerResponse.BodyBuilder applyHeaders(final ServerResponse.BodyBuilder builder,
final ServerRequest request) {
- final List connectionHeaders = request.headers().header(HttpHeaders.CONNECTION);
+ final List connectionHeaders = request.headers().header(CONNECTION);
if (hasConnectionValue(connectionHeaders, HEADER_CONNECTION_KEEPALIVE)) {
- builder.header(HttpHeaders.CONNECTION, HEADER_CONNECTION_KEEPALIVE);
+ builder.header(CONNECTION, HEADER_CONNECTION_KEEPALIVE);
}
if (hasConnectionValue(connectionHeaders, HEADER_CONNECTION_CLOSE)) {
- builder.header(HttpHeaders.CONNECTION, HEADER_CONNECTION_CLOSE);
+ builder.header(CONNECTION, HEADER_CONNECTION_CLOSE);
}
return builder;
}
private static boolean hasConnectionValue(List connectionHeaders, String value) {
return !connectionHeaders.isEmpty() && connectionHeaders.stream()
- .map(String::toLowerCase)
- .allMatch(Predicate.isEqual(value));
+ .map(String::toLowerCase)
+ .allMatch(Predicate.isEqual(value));
}
}
diff --git a/src/main/java/org/prebid/cache/handlers/ErrorHandler.java b/src/main/java/org/prebid/cache/handlers/ErrorHandler.java
index 46527198..3aaa0873 100644
--- a/src/main/java/org/prebid/cache/handlers/ErrorHandler.java
+++ b/src/main/java/org/prebid/cache/handlers/ErrorHandler.java
@@ -5,7 +5,6 @@
import org.prebid.cache.exceptions.BadRequestException;
import org.prebid.cache.exceptions.ResourceNotFoundException;
import org.prebid.cache.metrics.MetricsRecorder;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
@@ -19,7 +18,6 @@ public class ErrorHandler extends MetricsHandler {
private static final String INVALID_PARAMETERS = "Invalid Parameter(s): uuid not found or is empty.";
private static final String NO_ELEMENTS_FOUND = "No Elements Found.";
- @Autowired
public ErrorHandler(final MetricsRecorder metricsRecorder, final PrebidServerResponseBuilder builder) {
this.metricsRecorder = metricsRecorder;
this.builder = builder;
diff --git a/src/main/java/org/prebid/cache/handlers/cache/GetCacheHandler.java b/src/main/java/org/prebid/cache/handlers/cache/GetCacheHandler.java
index 78d603aa..35ecfeba 100644
--- a/src/main/java/org/prebid/cache/handlers/cache/GetCacheHandler.java
+++ b/src/main/java/org/prebid/cache/handlers/cache/GetCacheHandler.java
@@ -7,7 +7,6 @@
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.apache.http.client.utils.URIBuilder;
import org.prebid.cache.builders.PrebidServerResponseBuilder;
import org.prebid.cache.exceptions.UnsupportedMediaTypeException;
import org.prebid.cache.handlers.ErrorHandler;
@@ -20,7 +19,6 @@
import org.prebid.cache.repository.CacheConfig;
import org.prebid.cache.repository.ReactiveRepository;
import org.prebid.cache.routers.ApiConfig;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
@@ -30,6 +28,7 @@
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
+import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
import reactor.netty.http.client.HttpClient;
@@ -49,7 +48,6 @@ public class GetCacheHandler extends CacheHandler {
private final Map clientsCache;
private static final String UNSUPPORTED_MEDIATYPE = "Unsupported Media Type.";
- @Autowired
public GetCacheHandler(final ReactiveRepository repository,
final CacheConfig config,
final ApiConfig apiConfig,
@@ -108,10 +106,11 @@ private Mono fetch(final ServerRequest request,
private String resolveCacheUrl(final ServerRequest request) {
final var cacheHostParam = request.queryParam(CACHE_HOST_KEY).orElse(null);
if (StringUtils.isNotBlank(cacheHostParam)) {
- return new URIBuilder()
- .setHost(cacheHostParam)
- .setPath(apiConfig.getCachePath())
- .setScheme(config.getHostParamProtocol())
+ return UriComponentsBuilder.newInstance()
+ .host(cacheHostParam)
+ .path(apiConfig.getCachePath())
+ .scheme(config.getHostParamProtocol())
+ .build(false)
.toString();
}
@@ -181,7 +180,7 @@ private Mono processRequest(final ServerRequest request, final S
private Mono createServerResponse(final PayloadWrapper wrapper, final ServerRequest request) {
if (wrapper.getPayload().getType().equals(PayloadType.JSON.toString())) {
metricsRecorder.markMeterForTag(this.metricTagPrefix, MeasurementTag.JSON);
- return builder.createResponseMono(request, MediaType.APPLICATION_JSON_UTF8, wrapper);
+ return builder.createResponseMono(request, MediaType.APPLICATION_JSON, wrapper);
} else if (wrapper.getPayload().getType().equals(PayloadType.XML.toString())) {
metricsRecorder.markMeterForTag(this.metricTagPrefix, MeasurementTag.XML);
return builder.createResponseMono(request, MediaType.APPLICATION_XML, wrapper);
diff --git a/src/main/java/org/prebid/cache/handlers/cache/PostCacheHandler.java b/src/main/java/org/prebid/cache/handlers/cache/PostCacheHandler.java
index e027b143..21eecfe3 100644
--- a/src/main/java/org/prebid/cache/handlers/cache/PostCacheHandler.java
+++ b/src/main/java/org/prebid/cache/handlers/cache/PostCacheHandler.java
@@ -1,7 +1,6 @@
package org.prebid.cache.handlers.cache;
import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.common.collect.ImmutableMap;
import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.reactor.circuitbreaker.operator.CircuitBreakerOperator;
import io.netty.channel.ChannelOption;
@@ -26,7 +25,6 @@
import org.prebid.cache.repository.CacheConfig;
import org.prebid.cache.repository.ReactiveRepository;
import org.prebid.cache.routers.ApiConfig;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
@@ -63,13 +61,12 @@ public class PostCacheHandler extends CacheHandler {
private final ReactiveRepository repository;
private final CacheConfig config;
private final Function> payloadWrapperToMapTransformer = payload ->
- ImmutableMap.of(UUID_KEY, payload.getId());
+ Map.of(UUID_KEY, payload.getId());
private final Map webClients = new HashMap<>();
private final ObjectMapper objectMapper = new ObjectMapper();
private final CircuitBreaker circuitBreaker;
private final ApiConfig apiConfig;
- @Autowired
public PostCacheHandler(final ReactiveRepository repository,
final CacheConfig config,
final MetricsRecorder metricsRecorder,
@@ -145,7 +142,7 @@ public Mono save(final ServerRequest request) {
if (response.getResponses().isEmpty()) {
return ErrorHandler.createNoElementsFound();
} else {
- return builder.createResponseMono(request, MediaType.APPLICATION_JSON_UTF8, response);
+ return builder.createResponseMono(request, MediaType.APPLICATION_JSON, response);
}
});
diff --git a/src/main/java/org/prebid/cache/repository/aerospike/AerospikeRepositoryImpl.java b/src/main/java/org/prebid/cache/repository/aerospike/AerospikeRepositoryImpl.java
index 089649f8..660f3ba6 100644
--- a/src/main/java/org/prebid/cache/repository/aerospike/AerospikeRepositoryImpl.java
+++ b/src/main/java/org/prebid/cache/repository/aerospike/AerospikeRepositoryImpl.java
@@ -97,8 +97,8 @@ private Retry getRetryPolicy() {
return Retry.backoff(maxAttempts, minBackoff)
.maxBackoff(maxBackoff)
- .filter(e -> e instanceof AerospikeException
- && getRetryCodes().contains(((AerospikeException) e).getResultCode()))
+ .filter(e -> e instanceof AerospikeException ae
+ && getRetryCodes().contains(ae.getResultCode()))
.doAfterRetry(signal -> log.warn("Retrying context {}", signal.retryContextView()));
}
diff --git a/src/main/java/org/prebid/cache/repository/redis/module/storage/ModuleCompositeRepositoryConfiguration.java b/src/main/java/org/prebid/cache/repository/redis/module/storage/ModuleCompositeRepositoryConfiguration.java
index 0e26aa8f..b6302e24 100644
--- a/src/main/java/org/prebid/cache/repository/redis/module/storage/ModuleCompositeRepositoryConfiguration.java
+++ b/src/main/java/org/prebid/cache/repository/redis/module/storage/ModuleCompositeRepositoryConfiguration.java
@@ -14,6 +14,7 @@
import org.springframework.context.annotation.Configuration;
import java.util.Map;
+import java.util.Optional;
import java.util.stream.Collectors;
@Configuration
@@ -21,10 +22,15 @@ public class ModuleCompositeRepositoryConfiguration {
@Bean
ModuleCompositeRepository moduleCompositeRepository(ModuleCompositeRedisConfigurationProperties properties) {
- final Map> applicationToSource = properties.getRedis()
- .entrySet().stream()
- .map(entry -> Map.entry(entry.getKey(), getReactiveRepository(entry.getValue())))
- .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
+ final Map> applicationToSource =
+ Optional.ofNullable(properties.getRedis())
+ .map(redis ->
+ redis.entrySet()
+ .stream()
+ .collect(Collectors.toMap(
+ Map.Entry::getKey,
+ entry -> getReactiveRepository(entry.getValue()))))
+ .orElse(Map.of());
return new ModuleCompositeRepository(applicationToSource);
}
diff --git a/src/main/java/org/prebid/cache/translators/ThrowableTranslator.java b/src/main/java/org/prebid/cache/translators/ThrowableTranslator.java
index e6f021ab..48ea5c6f 100644
--- a/src/main/java/org/prebid/cache/translators/ThrowableTranslator.java
+++ b/src/main/java/org/prebid/cache/translators/ThrowableTranslator.java
@@ -28,8 +28,8 @@ private ThrowableTranslator(final Throwable throwable) {
}
private HttpStatus getStatus(final Throwable error) {
- if (error instanceof ErrorResponse) {
- return Optional.of((ErrorResponse) error)
+ if (error instanceof ErrorResponse response) {
+ return Optional.of(response)
.map(ErrorResponse::getStatusCode)
.map(HttpStatusCode::value)
.map(HttpStatus::resolve)
diff --git a/src/main/resources/application-aws.yml b/src/main/resources/application-aws.yml
index da26d750..c7ec5591 100644
--- a/src/main/resources/application-aws.yml
+++ b/src/main/resources/application-aws.yml
@@ -1,4 +1,4 @@
server.port: 5000
# redis
-spring.redis.host: ${SPRING_REDIS_HOST}
+spring.data.redis.host: ${SPRING_REDIS_HOST}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 1d13ca82..f60600ea 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -64,18 +64,18 @@ circuitbreaker:
# endpoint actuators
management.health.defaults.enabled: false
-management.endpoints.enabled-by-default: false
+management.endpoints.access.default: none
management.endpoints.web.base-path: /
management.health.diskspace.enabled: true
management.health.redis.enabled: false
management.endpoints.web.exposure.include: info, health, metrics, env, configprops
-management.endpoint.info.enabled: true
-management.endpoint.health.enabled: true
-management.endpoint.metrics.enabled: true
-management.endpoint.env.enabled: true
-management.endpoint.configprops.enabled: true
+management.endpoint.info.access: read-only
+management.endpoint.health.access: read-only
+management.endpoint.metrics.access: read-only
+management.endpoint.env.access: read-only
+management.endpoint.configprops.access: read-only
management.endpoint.health.show-details: always
-management.endpoint.shutdown.enabled: false
+management.endpoint.shutdown.access: none
management.endpoint.configprops.keys-to-sanitize: password,secret,key,token,.*credentials.*,vcap_services
management.endpoint.info.cache.time-to-live: 5s
management.endpoint.health.cache.time-to-live: 5s
@@ -146,8 +146,8 @@ logging.config: classpath:log4j2-qa.xml
---
# prod
spring.config.activate.on-profile: prod
-management.endpoint.metrics.enabled: false
-management.endpoint.env.enabled: false
-management.endpoint.configprops.enabled: false
+management.endpoint.metrics.access: none
+management.endpoint.env.access: none
+management.endpoint.configprops.access: none
logging.level.root: warn
logging.config: classpath:log4j2-prod.xml
diff --git a/src/test/java/org/prebid/cache/builders/PrebidServerResponseBuilderTests.java b/src/test/java/org/prebid/cache/builders/PrebidServerResponseBuilderTests.java
index a46b06dc..ede67558 100644
--- a/src/test/java/org/prebid/cache/builders/PrebidServerResponseBuilderTests.java
+++ b/src/test/java/org/prebid/cache/builders/PrebidServerResponseBuilderTests.java
@@ -2,7 +2,6 @@
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
import org.prebid.cache.exceptions.BadRequestException;
import org.prebid.cache.exceptions.RepositoryException;
import org.prebid.cache.exceptions.ResourceNotFoundException;
@@ -16,7 +15,6 @@
import org.springframework.http.MediaType;
import org.springframework.mock.web.reactive.function.server.MockServerRequest;
import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
@@ -31,7 +29,6 @@
import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8;
import static org.springframework.http.MediaType.APPLICATION_XML;
-@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes={PrebidServerResponseBuilder.class, ApiConfig.class})
@SpringBootTest
class PrebidServerResponseBuilderTests extends PayloadWrapperResponseTests {
diff --git a/src/test/java/org/prebid/cache/handlers/GetCacheHandlerTests.java b/src/test/java/org/prebid/cache/handlers/GetCacheHandlerTests.java
index c8e37bed..eb2b0191 100644
--- a/src/test/java/org/prebid/cache/handlers/GetCacheHandlerTests.java
+++ b/src/test/java/org/prebid/cache/handlers/GetCacheHandlerTests.java
@@ -5,7 +5,6 @@
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
import org.prebid.cache.builders.PrebidServerResponseBuilder;
import org.prebid.cache.config.CircuitBreakerPropertyConfiguration;
import org.prebid.cache.handlers.cache.GetCacheHandler;
@@ -19,13 +18,10 @@
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
-import org.springframework.http.MediaType;
import org.springframework.mock.web.reactive.function.server.MockServerRequest;
import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
import reactor.core.publisher.Signal;
@@ -44,8 +40,8 @@
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.BDDMockito.given;
import static org.springframework.http.HttpHeaders.CONTENT_TYPE;
+import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
-@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
GetCacheHandler.class,
PrebidServerResponseBuilder.class,
@@ -75,7 +71,7 @@ class GetCacheHandlerTests extends CacheHandlerTests {
@Autowired
PrebidServerResponseBuilder responseBuilder;
- @MockBean
+ @MockitoBean
ReactiveRepository repository;
@Value("${sampling.rate:2.0}")
@@ -132,12 +128,12 @@ void testVerifyFetch() {
@Test
void testVerifyFetchWithCacheHostParam() {
serverMock.stubFor(get(urlPathEqualTo("/cache"))
- .willReturn(aResponse().withHeader(HttpHeaders.CONTENT_TYPE, "application/json;charset=utf-8")
+ .willReturn(aResponse().withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE)
.withBody("{\"uuid\":\"2be04ba5-8f9b-4a1e-8100-d573c40312f8\"}")));
final var requestMono = MockServerRequest.builder()
.method(HttpMethod.GET)
- .header(CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)
+ .header(CONTENT_TYPE, APPLICATION_JSON_VALUE)
.queryParam("uuid", "a8db2208-d085-444c-9721-c1161d7f09ce")
.queryParam("ch", "localhost:8080")
.build();
@@ -153,7 +149,7 @@ void testVerifyFetchWithCacheHostParam() {
verify(getRequestedFor(urlPathEqualTo("/cache"))
.withQueryParam("uuid", equalTo("a8db2208-d085-444c-9721-c1161d7f09ce"))
- .withHeader(HttpHeaders.CONTENT_TYPE, equalToIgnoreCase(MediaType.APPLICATION_JSON_UTF8_VALUE))
+ .withHeader(CONTENT_TYPE, equalToIgnoreCase(APPLICATION_JSON_VALUE))
);
}
@@ -178,13 +174,13 @@ void testVerifyFailForNotFoundResourceWithCacheHostParam() {
void testVerifyFetchReturnsBadRequestWhenResponseStatusIsNotOk() {
serverMock.stubFor(get(urlPathEqualTo("/cache"))
- .willReturn(aResponse().withHeader(HttpHeaders.CONTENT_TYPE, "application/json;charset=utf-8")
+ .willReturn(aResponse().withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE)
.withStatus(201)
.withBody("{\"uuid\":\"2be04ba5-8f9b-4a1e-8100-d573c40312f8\"}")));
final var requestMono = MockServerRequest.builder()
.method(HttpMethod.GET)
- .header(CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)
+ .header(CONTENT_TYPE, APPLICATION_JSON_VALUE)
.queryParam("uuid", "a8db2208-d085-444c-9721-c1161d7f09ce")
.queryParam("ch", "localhost:8080")
.build();
@@ -200,7 +196,7 @@ void testVerifyFetchReturnsBadRequestWhenResponseStatusIsNotOk() {
verify(getRequestedFor(urlPathEqualTo("/cache"))
.withQueryParam("uuid", equalTo("a8db2208-d085-444c-9721-c1161d7f09ce"))
- .withHeader(HttpHeaders.CONTENT_TYPE, equalToIgnoreCase(MediaType.APPLICATION_JSON_UTF8_VALUE))
+ .withHeader(CONTENT_TYPE, equalToIgnoreCase(APPLICATION_JSON_VALUE))
);
}
@@ -208,7 +204,7 @@ void testVerifyFetchReturnsBadRequestWhenResponseStatusIsNotOk() {
void testVerifyFetchReturnsBadRequestWhenNoUuid() {
final var requestMono = MockServerRequest.builder()
.method(HttpMethod.GET)
- .header(CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)
+ .header(CONTENT_TYPE, APPLICATION_JSON_VALUE)
.build();
final var responseMono = handler.fetch(requestMono);
@@ -223,7 +219,7 @@ void testVerifyFetchReturnsBadRequestWhenNoUuid() {
void testVerifyFetchReturnsBadRequestWhenUuidIsEmpty() {
final var requestMono = MockServerRequest.builder()
.method(HttpMethod.GET)
- .header(CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)
+ .header(CONTENT_TYPE, APPLICATION_JSON_VALUE)
.queryParam("uuid", "")
.build();
diff --git a/src/test/java/org/prebid/cache/handlers/GetStorageHandlerTests.java b/src/test/java/org/prebid/cache/handlers/GetStorageHandlerTests.java
index ed6a1a6f..4d533bee 100644
--- a/src/test/java/org/prebid/cache/handlers/GetStorageHandlerTests.java
+++ b/src/test/java/org/prebid/cache/handlers/GetStorageHandlerTests.java
@@ -4,7 +4,6 @@
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
import org.prebid.cache.builders.PrebidServerResponseBuilder;
import org.prebid.cache.handlers.storage.GetStorageHandler;
import org.prebid.cache.model.Payload;
@@ -14,18 +13,16 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpMethod;
import org.springframework.mock.web.reactive.function.server.MockServerRequest;
import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.BDDMockito.given;
-@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
GetStorageHandler.class,
PrebidServerResponseBuilder.class,
@@ -41,7 +38,7 @@ public class GetStorageHandlerTests {
@Autowired
PrebidServerResponseBuilder responseBuilder;
- @MockBean
+ @MockitoBean
ModuleCompositeRepository moduleCompositeRepository;
GetStorageHandler handler;
diff --git a/src/test/java/org/prebid/cache/handlers/PostCacheHandlerTests.java b/src/test/java/org/prebid/cache/handlers/PostCacheHandlerTests.java
index 0503cb7e..f2dfdb52 100644
--- a/src/test/java/org/prebid/cache/handlers/PostCacheHandlerTests.java
+++ b/src/test/java/org/prebid/cache/handlers/PostCacheHandlerTests.java
@@ -6,7 +6,6 @@
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
import org.prebid.cache.builders.PrebidServerResponseBuilder;
import org.prebid.cache.config.CircuitBreakerPropertyConfiguration;
import org.prebid.cache.exceptions.DuplicateKeyException;
@@ -22,13 +21,12 @@
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.mock.web.reactive.function.server.MockServerRequest;
import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
@@ -49,7 +47,6 @@
import static org.prebid.cache.util.AwaitilityUtil.awaitAndVerify;
import static org.springframework.http.HttpHeaders.CONTENT_TYPE;
-@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
PostCacheHandler.class,
PrebidServerResponseBuilder.class,
@@ -75,13 +72,13 @@ class PostCacheHandlerTests extends CacheHandlerTests {
@Autowired
CircuitBreaker webClientCircuitBreaker;
- @MockBean
+ @MockitoBean
Supplier currentDateProvider;
- @MockBean
+ @MockitoBean
ReactiveRepository repository;
- @MockBean
+ @MockitoBean
ApiConfig apiConfig;
@Value("${sampling.rate:2.0}")
@@ -125,7 +122,7 @@ void testVerifySave() {
final Mono request = Mono.just(RequestObject.of(Collections.singletonList(PAYLOAD_TRANSFER)));
final MockServerRequest requestMono = MockServerRequest.builder()
.method(HttpMethod.POST)
- .header(CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)
+ .header(CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.body(request);
final Mono responseMono = handler.save(requestMono);
@@ -153,7 +150,7 @@ void testSecondaryCacheSuccess() {
final Mono request = Mono.just(RequestObject.of(Collections.singletonList(PAYLOAD_TRANSFER)));
final MockServerRequest requestMono = MockServerRequest.builder()
.method(HttpMethod.POST)
- .header(CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)
+ .header(CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.body(request);
final Mono responseMono = handler.save(requestMono);
@@ -195,7 +192,7 @@ void testExternalUUIDInvalid() {
final Mono request = Mono.just(RequestObject.of(Collections.singletonList(PAYLOAD_TRANSFER)));
final MockServerRequest requestMono = MockServerRequest.builder()
.method(HttpMethod.POST)
- .header(CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)
+ .header(CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.body(request);
final Mono responseMono = handler.save(requestMono);
@@ -235,7 +232,7 @@ void testUUIDDuplication() {
final Mono request = Mono.just(RequestObject.of(Collections.singletonList(PAYLOAD_TRANSFER)));
final MockServerRequest requestMono = MockServerRequest.builder()
.method(HttpMethod.POST)
- .header(CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)
+ .header(CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.body(request);
final Mono responseMono = handler.save(requestMono);
@@ -300,7 +297,7 @@ void testUuidAuthorizationWithoutValidApiKey() {
final var request = Mono.just(RequestObject.of(Collections.singletonList(PAYLOAD_TRANSFER)));
final var requestMono = MockServerRequest.builder()
.method(HttpMethod.POST)
- .header(CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)
+ .header(CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.body(request);
StepVerifier.create(handler.save(requestMono))
@@ -328,7 +325,7 @@ void testUuidAuthorizationWithValidApiKey() {
final var request = Mono.just(RequestObject.of(Collections.singletonList(PAYLOAD_TRANSFER)));
final var requestMono = MockServerRequest.builder()
.method(HttpMethod.POST)
- .header(CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)
+ .header(CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.header("x-pbc-api-key", "api-key")
.body(request);
diff --git a/src/test/java/org/prebid/cache/handlers/PostStorageHandlerTests.java b/src/test/java/org/prebid/cache/handlers/PostStorageHandlerTests.java
index 9c8428e2..d5fe562d 100644
--- a/src/test/java/org/prebid/cache/handlers/PostStorageHandlerTests.java
+++ b/src/test/java/org/prebid/cache/handlers/PostStorageHandlerTests.java
@@ -5,7 +5,6 @@
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
import org.prebid.cache.builders.PrebidServerResponseBuilder;
import org.prebid.cache.config.StorageConfig;
import org.prebid.cache.handlers.storage.PostStorageHandler;
@@ -17,11 +16,10 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpMethod;
import org.springframework.mock.web.reactive.function.server.MockServerRequest;
import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
@@ -31,7 +29,6 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
-@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
PrebidServerResponseBuilder.class,
ApiConfig.class
@@ -46,13 +43,13 @@ class PostStorageHandlerTests {
@Autowired
PrebidServerResponseBuilder responseBuilder;
- @MockBean
+ @MockitoBean
StorageConfig storageConfig;
- @MockBean
+ @MockitoBean
ModuleCompositeRepository moduleCompositeRepository;
- @MockBean
+ @MockitoBean
Validator validator;
PostStorageHandler handler;
diff --git a/src/test/java/org/prebid/cache/metrics/MetricsRecorderTest.java b/src/test/java/org/prebid/cache/metrics/MetricsRecorderTest.java
index 2f3eccd0..dc047640 100644
--- a/src/test/java/org/prebid/cache/metrics/MetricsRecorderTest.java
+++ b/src/test/java/org/prebid/cache/metrics/MetricsRecorderTest.java
@@ -5,8 +5,10 @@
import io.micrometer.core.instrument.simple.SimpleConfig;
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
+@Configuration
public class MetricsRecorderTest {
@Bean
diff --git a/src/test/kotlin/org/prebid/cache/functional/RedisCacheSpec.kt b/src/test/kotlin/org/prebid/cache/functional/RedisCacheSpec.kt
index d3d4401e..40fd66a5 100644
--- a/src/test/kotlin/org/prebid/cache/functional/RedisCacheSpec.kt
+++ b/src/test/kotlin/org/prebid/cache/functional/RedisCacheSpec.kt
@@ -50,7 +50,7 @@ class RedisCacheSpec : ShouldSpec({
// then: Internal Server Error exception is thrown
assertSoftly {
exception.statusCode shouldBe INTERNAL_SERVER_ERROR.value()
- exception.responseBody shouldContain "\"message\":\"ERR invalid expire time in setex\""
+ exception.responseBody shouldContain "\"message\":\"ERR invalid expire time in 'setex' command\""
}
// cleanup
diff --git a/src/test/kotlin/org/prebid/cache/functional/StorageSpec.kt b/src/test/kotlin/org/prebid/cache/functional/StorageSpec.kt
index 09600cae..7f43cbf2 100644
--- a/src/test/kotlin/org/prebid/cache/functional/StorageSpec.kt
+++ b/src/test/kotlin/org/prebid/cache/functional/StorageSpec.kt
@@ -297,7 +297,7 @@ class StorageSpec : ShouldSpec({
assertSoftly {
exception.statusCode shouldBe INTERNAL_SERVER_ERROR.value()
exception.responseBody shouldContain "\"path\":\"/storage\""
- exception.responseBody shouldContain "\"message\":\"ERR invalid expire time in setex"
+ exception.responseBody shouldContain "\"message\":\"ERR invalid expire time in 'setex' command\""
}
}
diff --git a/src/test/kotlin/org/prebid/cache/functional/testcontainers/ContainerDependencies.kt b/src/test/kotlin/org/prebid/cache/functional/testcontainers/ContainerDependencies.kt
index d4a4888a..8dc07c1a 100644
--- a/src/test/kotlin/org/prebid/cache/functional/testcontainers/ContainerDependencies.kt
+++ b/src/test/kotlin/org/prebid/cache/functional/testcontainers/ContainerDependencies.kt
@@ -11,9 +11,9 @@ import org.testcontainers.utility.DockerImageName
abstract class ContainerDependencies {
companion object {
- private const val redisImageName = "redis:6.2.6-alpine"
- private const val aerospikeImageName = "aerospike:ce-5.7.0.11"
- private const val apacheIgniteImageName = "apacheignite/ignite:2.16.0"
+ private const val redisImageName = "redis:8.8.0-alpine"
+ private const val aerospikeImageName = "aerospike:ce-8.1.2.2"
+ private const val apacheIgniteImageName = "apacheignite/ignite:2.18.0"
private const val prebidCacheImageName = "prebid-cache:latest"
private const val mockServerImageVersion = "mockserver/mockserver:5.15.0"
diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties
index a135060c..10e47bbc 100644
--- a/src/test/resources/application.properties
+++ b/src/test/resources/application.properties
@@ -31,21 +31,21 @@ logging.level.root=info
logging.config=classpath:log4j2-console.xml
# metrics
-management.metrics.export.graphite.enabled=false
+management.graphite.metrics.export.enabled=false
# endpoint actuators
management.health.defaults.enabled=false
-management.endpoints.enabled-by-default=false
+management.endpoints.access.default=none
management.endpoints.web.base-path=/
management.health.diskspace.enabled=true
management.endpoints.web.exposure.include=info, health, metrics, env, configprops
-management.endpoint.info.enabled=true
-management.endpoint.health.enabled=true
-management.endpoint.metrics.enabled=true
-management.endpoint.env.enabled=true
-management.endpoint.configprops.enabled=true
+management.endpoint.info.access=read-only
+management.endpoint.health.access=read-only
+management.endpoint.metrics.access=read-only
+management.endpoint.env.access=read-only
+management.endpoint.configprops.access=read-only
management.endpoint.health.show-details=always
-management.endpoint.shutdown.enabled=false
+management.endpoint.shutdown.access=none
management.endpoint.configprops.keys-to-sanitize=password,secret,key,token,.*credentials.*,vcap_services
management.endpoint.info.cache.time-to-live=5s
management.endpoint.health.cache.time-to-live=5s
From 65d2e705d05076c434649f2b2630618c775a240c Mon Sep 17 00:00:00 2001
From: Oleksandr Zhevedenko <720803+Net-burst@users.noreply.github.com>
Date: Mon, 15 Jun 2026 19:16:41 -0400
Subject: [PATCH 2/6] Update GitHub actions
---
.github/workflows/codeql-analysis.yml | 76 +++++++++++++----------
.github/workflows/pr-functional-tests.yml | 4 +-
.github/workflows/pr-java-ci.yml | 4 +-
3 files changed, 46 insertions(+), 38 deletions(-)
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index ce3d92a7..4b9f1f0a 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -1,48 +1,56 @@
-name: "CodeQL"
+name: CodeQL
on:
push:
- branches: [ "master" ]
+ branches: [ 'master' ]
pull_request:
- branches: [ "master" ]
+ branches: [ 'master' ]
+ schedule:
+ - cron: '0 3 * * 1'
+
+permissions:
+ security-events: write
+ packages: read
+ actions: read
+ contents: read
jobs:
analyze:
- name: Analyze
+ name: Analyze (${{ matrix.language }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
- language: [ 'java' ]
+ include:
+ - language: actions
+ build-mode: none
+ - language: java-kotlin
+ build-mode: manual
steps:
- - name: Checkout repository
- uses: actions/checkout@v4
-
- - name: Set up JDK
- uses: actions/setup-java@v3
- with:
- distribution: 'temurin'
- java-version: 25
-
- - name: Cache Maven packages
- uses: actions/cache@v3
- with:
- path: ~/.m2/repository
- key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
- restore-keys: |
- ${{ runner.os }}-maven-
-
- - name: Initialize CodeQL
- uses: github/codeql-action/init@v1
- with:
- languages: ${{ matrix.language }}
-
- - name: Build with Maven
- run: mvn -B package
-
- - name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v1
- with:
- category: "/language:${{ matrix.language }}"
+ - name: Checkout repository
+ uses: actions/checkout@v5
+
+ - name: Set up JDK
+ if: matrix.language == 'java-kotlin'
+ uses: actions/setup-java@v5
+ with:
+ distribution: 'temurin'
+ cache: 'maven'
+ java-version: 25
+
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v4
+ with:
+ languages: ${{ matrix.language }}
+ build-mode: ${{ matrix.build-mode }}
+
+ - name: Build with Maven
+ if: matrix.build-mode == 'manual'
+ run: mvn -B compile --file pom.xml
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v4
+ with:
+ category: '/language:${{ matrix.language }}'
diff --git a/.github/workflows/pr-functional-tests.yml b/.github/workflows/pr-functional-tests.yml
index 3fb3b2fe..3c95fb3a 100644
--- a/.github/workflows/pr-functional-tests.yml
+++ b/.github/workflows/pr-functional-tests.yml
@@ -20,10 +20,10 @@ jobs:
java: [ 25 ]
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v5
- name: Set up JDK
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v5
with:
distribution: 'temurin'
cache: 'maven'
diff --git a/.github/workflows/pr-java-ci.yml b/.github/workflows/pr-java-ci.yml
index 9a1ab405..75cb7f15 100644
--- a/.github/workflows/pr-java-ci.yml
+++ b/.github/workflows/pr-java-ci.yml
@@ -20,10 +20,10 @@ jobs:
java: [ 25 ]
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v5
- name: Set up JDK
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v5
with:
distribution: 'temurin'
cache: 'maven'
From a20d8bbb883a947c0ae885a76f74e7c40bf94c2b Mon Sep 17 00:00:00 2001
From: Oleksandr Zhevedenko <720803+Net-burst@users.noreply.github.com>
Date: Mon, 15 Jun 2026 19:47:42 -0400
Subject: [PATCH 3/6] Additional pom.xml cleanup
---
pom.xml | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/pom.xml b/pom.xml
index c3424b72..69b36ff8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -51,7 +51,6 @@
3.4.4
1.18.46
4.2.17
- 0.10.2
9.0.5
2.17.0
3.5.1
@@ -62,7 +61,6 @@
4.2.0
2.1.0
2.20.0
- 2.0.1.Final
5.9.1
@@ -111,10 +109,6 @@
org.springframework.boot
spring-boot-starter-data-redis
-
- io.lettuce
- lettuce-core
-
com.google.code.gson
gson
@@ -149,7 +143,7 @@
io.github.resilience4j
- resilience4j-spring-boot2
+ resilience4j-spring-boot3
${resilience4j.version}
@@ -172,12 +166,6 @@
${wiremock.version}
test
-
- org.reflections
- reflections
- ${reflections.version}
- test
-
com.aerospike
aerospike-client-jdk21
From af1c24c6a36c67f32bdcdda660e5ea23e684f160 Mon Sep 17 00:00:00 2001
From: Oleksandr Zhevedenko <720803+Net-burst@users.noreply.github.com>
Date: Tue, 16 Jun 2026 09:37:45 -0400
Subject: [PATCH 4/6] Fix remarks
---
...oduleCompositeRepositoryConfiguration.java | 21 ++++++++++---------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/src/main/java/org/prebid/cache/repository/redis/module/storage/ModuleCompositeRepositoryConfiguration.java b/src/main/java/org/prebid/cache/repository/redis/module/storage/ModuleCompositeRepositoryConfiguration.java
index b6302e24..ce8888d2 100644
--- a/src/main/java/org/prebid/cache/repository/redis/module/storage/ModuleCompositeRepositoryConfiguration.java
+++ b/src/main/java/org/prebid/cache/repository/redis/module/storage/ModuleCompositeRepositoryConfiguration.java
@@ -13,8 +13,8 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import java.util.Collections;
import java.util.Map;
-import java.util.Optional;
import java.util.stream.Collectors;
@Configuration
@@ -22,15 +22,16 @@ public class ModuleCompositeRepositoryConfiguration {
@Bean
ModuleCompositeRepository moduleCompositeRepository(ModuleCompositeRedisConfigurationProperties properties) {
- final Map> applicationToSource =
- Optional.ofNullable(properties.getRedis())
- .map(redis ->
- redis.entrySet()
- .stream()
- .collect(Collectors.toMap(
- Map.Entry::getKey,
- entry -> getReactiveRepository(entry.getValue()))))
- .orElse(Map.of());
+ final Map redisConfig = properties.getRedis();
+
+ if (redisConfig == null || redisConfig.isEmpty()) {
+ return new ModuleCompositeRepository(Collections.emptyMap());
+ }
+
+ final Map> applicationToSource = redisConfig.entrySet()
+ .stream()
+ .map(entry -> Map.entry(entry.getKey(), getReactiveRepository(entry.getValue())))
+ .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
return new ModuleCompositeRepository(applicationToSource);
}
From 58d0760113e170417c59a8efa03ad75556028b12 Mon Sep 17 00:00:00 2001
From: Oleksandr Zhevedenko <720803+Net-burst@users.noreply.github.com>
Date: Tue, 16 Jun 2026 10:16:36 -0400
Subject: [PATCH 5/6] Update README.md
---
README.md | 325 +++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 222 insertions(+), 103 deletions(-)
diff --git a/README.md b/README.md
index 705c94ba..d17c1894 100644
--- a/README.md
+++ b/README.md
@@ -1,22 +1,29 @@
### This is the Java version of Prebid Cache. See the Prebid Server [Feature List](https://docs.prebid.org/prebid-server/features/pbs-feature-idx.html) and [FAQ entry](https://docs.prebid.org/faq/prebid-server-faq.html#why-are-there-two-versions-of-prebid-server-are-they-kept-in-sync) to understand the differences between PBS-Java and [PBS-Go](https://github.com/prebid/prebid-cache).
# _Prebid Cache Java_
-Prebid Cache provides the caching service component for the Prebid Server project. Currently, the API supports both the GET and POST endpoints. Prebid Cache Java provides a Redis and Aerospike implementation for the cache. By default it uses Aerospike. How to switch between Redis And Aerospike described at Cache Configuration section. However, Prebid Cache is designed to support any cache implementation.
+
+Prebid Cache provides the caching service component for the Prebid Server project. Currently, the API supports both the
+GET and POST endpoints. Prebid Cache Java provides a Redis and Aerospike implementation for the cache. By default it
+uses Aerospike. How to switch between Redis And Aerospike described at Cache Configuration section. However, Prebid
+Cache is designed to support any cache implementation.
## Integration Guide
+
Project configuration is managed through the use of YAML configuration (see resources folder).
### _Requirements_
+
This section covers the mandatory pre-requisites needed to be able to run the application.
* Windows, Linux, AWS, GCP or macOS
-* JDK 8+
+* JDK 25 (the higher versions haven't been tested)
* Maven
* Git
* Redis (or a custom cache implementation)
* Aerospike
### _Quick Install_
+
This section describes how to download, install and run the application.
###### A. Using Maven on macOS (recommended installation method)
@@ -28,23 +35,32 @@ git clone https://github.com/prebid/prebid-cache-java.git
```
(2). Start Repo Locally:
-If you have installed [Redis](https://redis.io/docs/install/install-redis/) or [Aerospike](https://aerospike.com/docs/server/operations/install) or [Apache Ignite](https://ignite.apache.org/docs/latest/installation/deb-rpm) locally, you may start them both (or separately, depends on your needs) via bash:
+If you have installed [Redis](https://redis.io/docs/install/install-redis/)
+or [Aerospike](https://aerospike.com/docs/server/operations/install)
+or [Apache Ignite](https://ignite.apache.org/docs/latest/installation/deb-rpm) locally, you may start them both
+(or separately, depends on your needs) via bash:
+
```bash
sudo systemctl start redis
sudo systemctl start aerospike
sudo systemctl start apache-ignite
```
+
Alternatively, you may start DB as Docker image.
You should install [Docker Engine](https://docs.docker.com/engine/install/) if you don't have one.
(2.1) Redis via Docker
+
1. Pull [Redis docker image](https://hub.docker.com/_/redis) of an appropriate version
+
```bash
docker pull redis:
```
+
2. Run Redis container
- - the `` should correspond to the pulled image version
- - the `` should correspond to the `spring.redis.port` property values of the Prebid Cache
+ - the `` should correspond to the pulled image version
+ - the `` should correspond to the `spring.redis.port` property values of the Prebid Cache
+
```bash
docker run -d --name redis -p : redis:
@@ -53,14 +69,18 @@ docker run -d --name redis -p 6379:6379 redis:7.2.4
```
(2.2) Aerospike via Docker
+
1. Pull [Aerospike docker image](https://hub.docker.com/_/aerospike) of an appropriate version
+
```bash
docker pull aerospike:
```
+
2. Run Aerospike container (the following instruction is enough for the Community Edition only)
- - the `` should correspond to the pulled image version
- - the `` should correspond to the `spring.aerospike.port` property values of the Prebid Cache
- - the `` should correspond to the spring.aerospike.namespace property value of the Prebid Cache
+ - the `` should correspond to the pulled image version
+ - the `` should correspond to the `spring.aerospike.port` property values of the Prebid Cache
+ - the `` should correspond to the spring.aerospike.namespace property value of the Prebid Cache
+
```bash
docker run -d --name aerospike -e "NAMESPACE=" -p : aerospike:
@@ -69,15 +89,21 @@ docker run -d --name aerospike -e "NAMESPACE=prebid_cache" -p 3000:3000 aerospik
```
(2.3) Apache Ignite via Docker
-1. Pull [Apache Ignite docker image](https://ignite.apache.org/docs/latest/installation/installing-using-docker) of an appropriate version
+
+1. Pull [Apache Ignite docker image](https://ignite.apache.org/docs/latest/installation/installing-using-docker) of an
+ appropriate version
+
```bash
docker pull apacheignite/ignite:
```
+
2. Run Apache Ignite container
- the `` should correspond to the pulled image version
- - the `OPTION_LIBS=ignite-rest-http` corresponds to the library that enables REST API access to the server (i.e. to create a cache inside Apache Ignite)
- - the `-p 10800:10800` exposes the default port `10800` that will be a connection port for the Prebid Cache
+ - the `OPTION_LIBS=ignite-rest-http` corresponds to the library that enables REST API access to the server (i.e. to
+ create a cache inside Apache Ignite)
+ - the `-p 10800:10800` exposes the default port `10800` that will be a connection port for the Prebid Cache
- the host will be the `localhost`
+
```bash
docker run -d \
--name apache-ignite
@@ -85,12 +111,15 @@ docker run -d \
-p 8080:8080 -p 10800:10800 -p 11211:11211 -p 47100:47100 -p 47500:47500 \
apacheignite/ignite:
```
+
3. Create a cache via Rest Api
+
```bash
GET http://localhost:10800/ignite?cmd=getorcreate&cacheName=
```
(2.4) Make sure that the Aerospike, Redis and/or Apache Ignite is up and running
+
```bash
docker ps
```
@@ -113,8 +142,11 @@ mvn clean package
(4). Run Spring Boot JAR (_from project root_)
+Note: at least one storage backend must be configured to make the application start up successfully. For the local
+start-up the `local` profile has the Aerospike configured with default settings.
+
```bash
-java -jar target/prebid-cache.jar
+java -Dspring.profiles.active=manage,local -jar target/prebid-cache.jar
```
### _Spring Profiles_
@@ -124,6 +156,7 @@ This section shows examples of the various runtime environment configuration(s).
(1). Localhost with log4j and management endpoints enabled:
_VM Options:_
+
```bash
java -Dspring.profiles.active=manage,local -Dlog.dir=/app/prebid-cache-java/log/ -jar prebid-cache.jar
```
@@ -131,12 +164,14 @@ java -Dspring.profiles.active=manage,local -Dlog.dir=/app/prebid-cache-java/log/
(2). Production with log4j and management endpoints disabled:
_VM Options:_
+
```bash
java -Dspring.profiles.active=prod -Dlog.dir=/app/prebid-cache-java/log/ -jar prebid-cache.jar
```
_Note_
The `Apache Ignite` requires additional VM parameters to be added to support Java 17+
+
```bash
--add-opens=java.base/jdk.internal.access=ALL-UNNAMED
--add-opens=java.base/jdk.internal.misc=ALL-UNNAMED
@@ -165,15 +200,18 @@ The `Apache Ignite` requires additional VM parameters to be added to support Jav
```
### _Cache Configuration_
-Prebid cache uses Aerospike as a default cache implementation but also supports Redis and Apache Ignite. For switching from Aerospike
-to Redis replace next:
-_application.yml:_
+Enable **one and only one** backend in your application properties (Redis, Aerospike, or Apache Ignite). If none or more
+than one are configured, startup will fail.
+Prebid cache uses Aerospike as a default cache implementation.
+
+Pick exactly one of the following in the _application.yml:_
+
```yaml
spring.aerospike.host: value
```
-with
+or
```yaml
spring.redis.host: value
@@ -185,27 +223,52 @@ or
spring.ignite.host: value
```
-For configuring single redis node, please use next properties:
+For configuring Aerospike backend, you can start with the following local-profile default properties:
```yaml
spring:
- redis:
- host: host
- timeout: value
- port: value
+ aerospike:
+ port: 3000
+ host: localhost
+ cores: 4
+ password:
+ first_backoff: 300
+ max_backoff: 1000
+ max_retry: 3
+ namespace: "prebid_cache"
+ prevent_UUID_duplication: true
+ socket_timeout: 30000
+ total_timeout: 1000
+ connect_timeout: 0
+ min_conns_per_node: 0
+ max_conns_per_node: 100
+ read_policy: sequence
+```
+
+For configuring single Redis node, please use next properties:
+
+```yaml
+ spring:
+ redis:
+ host: host
+ timeout: value
+ port: value
```
-or
+For configuring Ignite backend, please use next properties:
+
```yaml
spring:
- ignite:
- host: host
- port: port
- cache-name: cacheName
+ ignite:
+ host: host
+ port: port
+ cache-name: cacheName
```
### Providing your own configuration
-It is possible to override the default YAML configuration by supplying a custom configuration. This is done using the `spring.config.additional-location` property.
+
+It is possible to override the default YAML configuration by supplying a custom configuration. This is done using the
+`spring.config.additional-location` property.
```bash
java -jar prebid-cache.jar --spring.config.additional-location=path-to-your-conf.yaml
@@ -215,76 +278,88 @@ java -jar prebid-cache.jar --spring.config.additional-location=path-to-your-conf
Redis cluster settings
_application-default.yml:_
+
```yaml
spring:
- redis:
- cluster:
- nodes:
- - host_1:port_1
- - host_2:port_2
- - host_3:port_3
- timeout: 300
+ redis:
+ cluster:
+ nodes:
+ - host_1:port_1
+ - host_2:port_2
+ - host_3:port_3
+ timeout: 300
```
+
Aerospike cluster settings
_application-default.yml:_
+
```yaml
spring.aerospike.host: aerospike_host_1:port,aerospike_host_2:port,aerospike_host_3:port
```
Apache Ignite cluster settings
_application-default.yml:_
+
```yaml
spring.ignite.host: ignite_host_1:port,ignite_host_2:port,ignite_host_3:port
```
### _Optional: Bring Your Own (BYO) Cache Implementation_
-Prebid Cache can support any cache implementation, although Redis is provided as default. Spring injects the cache repository bean instances during context initialization, or application startup. This section describes how to setup a custom cache repository.
+Prebid Cache can support any cache implementation, although Redis is provided as default. Spring injects the cache
+repository bean instances during context initialization, or application startup. This section describes how to setup a
+custom cache repository.
###### A. ReactiveRepository Interface
+
The custom cache implementation must contain a class that conforms to the _ReactiveRepository_ interface.
_CustomRepositoryImpl_:
-```java
-public class CustomRepositoryImpl implements ReactiveRepository
-{
- Mono save(final PayloadWrapper wrapper) {
- // You must implement save method
- }
- Mono findById(final String id) {
- // You must implement findById method
- }
+```java
+public class CustomRepositoryImpl implements ReactiveRepository {
+ Mono save(final PayloadWrapper wrapper) {
+ // You must implement save method
+ }
+
+ Mono findById(final String id) {
+ // You must implement findById method
+ }
}
```
###### B. Repository Configuration
-A configuration object should be passed into the constructor of your custom repository implementation. At minimum, this configuration object would contain the caching service _host_ and _port_ details.
- _CustomRepositoryImpl:_
+A configuration object should be passed into the constructor of your custom repository implementation. At minimum, this
+configuration object would contain the caching service _host_ and _port_ details.
+
+_CustomRepositoryImpl:_
+
```java
- public class CustomRepositoryImpl implements ReactiveRepository
- {
- private final CustomPropertyConfiguration config;
-
- @Autowired
- public CustomRepositoryImpl(final CustomPropertyConfiguration config) {
- this.config = config;
- }
- }
+ public class CustomRepositoryImpl implements ReactiveRepository {
+ private final CustomPropertyConfiguration config;
+
+ @Autowired
+ public CustomRepositoryImpl(final CustomPropertyConfiguration config) {
+ this.config = config;
+ }
+}
```
- Here is an example definition of a custom configuration property class. It is important to replace _'custom'_ with the correct cache implementation name (e.g. redis, memcached, aerospike, etc...). If Spring already provides a predefined configuration property prefix, please use that instead.
+Here is an example definition of a custom configuration property class. It is important to replace _'custom'_ with the
+correct cache implementation name (e.g. redis, memcached, aerospike, etc...). If Spring already provides a predefined
+configuration property prefix, please use that instead.
_CustomPropertyConfiguration_:
+
```java
+
@Data
@NoArgsConstructor
@AllArgsConstructor
@Configuration
-@ConfigurationProperties(prefix="spring.custom")
-public class CustomPropertyConfiguration
-{
+@ConfigurationProperties(prefix = "spring.custom")
+public class CustomPropertyConfiguration {
private String host;
private int port;
}
@@ -295,9 +370,11 @@ public class CustomPropertyConfiguration
Metrics are collected and exported using _Micrometer_.
For more information, see: https://micrometer.io
-###### A. Durations (timers) and Rates (meters)
+###### A. Durations (timers) and Rates (meters)
+
+Alongside the default application health metrics exported by the Spring Actuator, the metrics repository supports
+collection on these types:
-Alongside the default application health metrics exported by the Spring Actuator, the metrics repository supports collection on these types:
* _request and request duration_
* _json request_
* _xml request_
@@ -306,31 +383,35 @@ Alongside the default application health metrics exported by the Spring Actuator
* _invalid request error_
* _internal server error_
-
###### B. Micrometer YAML Configuration
-The full list of supported monitoring systems that Micrometer can export to can be found here: https://micrometer.io/docs
+The full list of supported monitoring systems that Micrometer can export to can be found
+here: https://micrometer.io/docs
Please keep in mind that for some of them, additional dependencies may be needed in pom.xml
_src/main/resources/repository.yml_:
+
```yaml
management:
- metrics:
- export:
- graphite:
- enabled: false
- host: http://graphite.yourdomain.com
- port: 2003
- tags-as-prefix:
- - prebid
+ metrics:
+ export:
+ graphite:
+ enabled: false
+ host: http://graphite.yourdomain.com
+ port: 2003
+ tags-as-prefix:
+ - prebid
```
### _Logging_
-Since logging is environment specific, log configuration and settings should be defined in the dev, qa, and prod profile sections of application.yml.
+
+Since logging is environment specific, log configuration and settings should be defined in the dev, qa, and prod profile
+sections of application.yml.
###### A. Dev Environment
_src/main/resources/application.yml_:
+
```yaml
# dev
spring.profiles: dev
@@ -339,6 +420,7 @@ logging.config: classpath:log4j2-dev.xml
```
_src/main/resources/log4j-dev.xml_:
+
```xml
@@ -366,7 +448,7 @@ _src/main/resources/log4j-dev.xml_:
${logPattern}
-
+
@@ -377,42 +459,51 @@ _src/main/resources/log4j-dev.xml_:
-
+
```
### _Circuit Breaker_
-To make prebid-cache more robust in face of network disruption or dependent services outage circuit breaker is available and should be configured at application.yml.
+
+To make prebid-cache more robust in face of network disruption or dependent services outage circuit breaker is available
+and should be configured at application.yml.
_src/main/resources/application.yml_:
+
```yaml
# dev
circuitbreaker:
- failure_rate_threshold: 50
- open_state_duration: 60000
- closed_state_calls_number: 5
- half_open_state_calls_number: 3
+ failure_rate_threshold: 50
+ open_state_duration: 60000
+ closed_state_calls_number: 5
+ half_open_state_calls_number: 3
```
+
where:
-* _failure_rate_threshold_ is the failure rate threshold in percentage above which the CircuitBreaker should trip open and start short-circuiting calls
+* _failure_rate_threshold_ is the failure rate threshold in percentage above which the CircuitBreaker should trip open
+ and start short-circuiting calls
-* _open_state_duration_ is the wait duration which specifies how long the CircuitBreaker should stay open, before it switches to half open
+* _open_state_duration_ is the wait duration which specifies how long the CircuitBreaker should stay open, before it
+ switches to half open
* _closed_state_calls_number_ is the size of the ring buffer when the CircuitBreaker is closed
* _half_open_state_calls_number_ is the size of the ring buffer when the CircuitBreaker is half open
-
### _Services (DevOps)_
-This section contains instructions on how to run the app as a service in various different ways. DevOps should find this section relevant and useful. By default, the packaged JAR is setup to be fully executable.
+
+This section contains instructions on how to run the app as a service in various different ways. DevOps should find this
+section relevant and useful. By default, the packaged JAR is setup to be fully executable.
###### A. Executable JAR
_pom.xml_:
+
```xml
+
org.springframework.boot
spring-boot-maven-plugin
@@ -423,15 +514,18 @@ _pom.xml_:
```
+
Note: A custom launch script is needed as a fix due to a Spring Boot issue (#12188):
https://github.com/spring-projects/spring-boot/issues/12188
-To launch the JAR from the command line (UNIX/Linux):
+To launch the JAR from the command line (UNIX/Linux):
+
```bash
./prebid-cache.jar
```
For security reasons, it is recommended to run the service as a non-root user:
+
```bash
sudo useradd prebid-cache
sudo passwd prebid-cache
@@ -442,6 +536,7 @@ sudo chmod 500 prebid-cache.jar
###### B. System V Init
Symbolic link JAR to init.d:
+
```bash
sudo ln -s /app/prebid-cache.jar /etc/init.d/prebid-cache
```
@@ -454,6 +549,7 @@ sudo service prebid-cache restart # restart service
```
Following these steps will allow for:
+
* Non-root users to run the service
* PID management (/var/run/)
* Console logs (/var/log/)
@@ -461,6 +557,7 @@ Following these steps will allow for:
###### C. Systemd
/etc/systemd/system/prebid-cache.service:
+
```text
[Unit]
Description=Prebid Cache Service
@@ -474,45 +571,55 @@ SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
```
+
Now you can manage this service with systemctl:
+
```bash
systemctl start prebid-cache.service # start service
systemctl stop prebid-cache.service # stop service
systemctl status prebid-cache.service # check status
```
+
For more details please refer to man pages for systemctl.
###### D. AWS - Amazon Web Services
+
This section describes how to run the app in an Elastic Beanstalk environment with ElastiCache.
##### Prepare Artifact:
(1). Go to the project root:
+
```bash
cd prebid-cache-java
```
(2). Update codebase :
+
```bash
git pull
```
(3). Rebuild sources with Maven
+
```bash
mvn clean gplus:execute package
```
(4). Create folder in work directory:
+
```bash
mkdir aws-prebid-cache
```
(5). Copy jar file from prebid-cache-java/target to created directory:
+
```bash
cp prebid-cache-java/target/prebid-cache.jar aws-prebid-cache
```
(6). Create Procfile in aws-prebid-cache directory:
+
```bash
sudo nano Procfile
@@ -520,9 +627,11 @@ web: java -Dspring.profiles.active=aws -jar prebid-cache.jar
```
(7). Zip aws-prebid-cache directory
+
```bash
zip -r eb-prebid-cache-new.zip eb-prebid-cache-new
```
+
Artifact is ready for deploy to Elastic Beanstalk.
For more information, see https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/java-se-platform.html.
@@ -548,41 +657,46 @@ For more information, see https://docs.aws.amazon.com/elasticbeanstalk/latest/dg
(10). Select subnet for EC2 instance and click next.
-(11). Press Launch button on review page for launching environment and application.
+(11). Press Launch button on review page for launching environment and application.
##### ElastiCache w/Redis:
-(1). After cluster configuration is complete, we will need to login, https://console.aws.amazon.com/elasticbeanstalk/.
+(1). After cluster configuration is complete, we will need to login, https://console.aws.amazon.com/elasticbeanstalk/.
(2). Go to the environment with application and press configuration.
(3). Choose software configuration and add SPRING_REDIS_HOST system property with host of the ElastiCache redis cluster.
-To learn more about how to create an Elastic Cache cluster and the configuration with Elastic Beanstalk, see https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/AWSHowTo.ElastiCache.html.
-
-
+To learn more about how to create an Elastic Cache cluster and the configuration with Elastic Beanstalk,
+see https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/AWSHowTo.ElastiCache.html.
### _Sample_
###### A. Request
+
```json
{
- "puts": [
- {
- "type": "json",
- "value": {
- "adm": "\n
\n\n\n
\n",
- "width": 300,
- "height": 250
- },
- "key" : "a8db2208-d085-444c-9721-c1161d7f09ce",
- "expiry" : 800
- },
- {"type" : "xml", "value":"\r\n \r\n <\/html>\r\n ]]>\r\n <\/creativeCode>\r\n<\/xml>"}
- ]
+ "puts": [
+ {
+ "type": "json",
+ "value": {
+ "adm": "\n
\n\n\n
\n",
+ "width": 300,
+ "height": 250
+ },
+ "key": "a8db2208-d085-444c-9721-c1161d7f09ce",
+ "expiry": 800
+ },
+ {
+ "type": "xml",
+ "value": "\r\n \r\n <\/html>\r\n ]]>\r\n <\/creativeCode>\r\n<\/xml>"
+ }
+ ]
}
```
+
###### B. Response
+
```json
{
"responses": [
@@ -597,21 +711,26 @@ To learn more about how to create an Elastic Cache cluster and the configuration
```
### _Staying Up-To-Date_ ###
+
For using the latest version of prebid cache, perform next steps:
(1). Go to the project root:
+
```bash
cd prebid-cache-java
```
(2). Update codebase:
+
```bash
git pull
```
(3). Rebuild sources with Maven
+
```bash
mvn clean gplus:execute package
```
-If there are any questions, issues, or concerns, please submit them to https://github.com/prebid/prebid-cache-java/issues/.
+If there are any questions, issues, or concerns, please submit them
+to https://github.com/prebid/prebid-cache-java/issues/.
From 77655260d7f75b915c23af0c869d76d9a48594f4 Mon Sep 17 00:00:00 2001
From: Oleksandr Zhevedenko <720803+Net-burst@users.noreply.github.com>
Date: Tue, 16 Jun 2026 10:28:37 -0400
Subject: [PATCH 6/6] Bump Aerospike and Ignite versions
---
pom.xml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pom.xml b/pom.xml
index 69b36ff8..873f9643 100644
--- a/pom.xml
+++ b/pom.xml
@@ -51,8 +51,8 @@
3.4.4
1.18.46
4.2.17
- 9.0.5
- 2.17.0
+ 9.3.0
+ 2.18.0
3.5.1
3.3.1
3.6.0