parameters = null;
+ byte[] contents = new byte[] {1, 2, 3, 4, 5, 6, 7};
+ final Resource blob = new ByteArrayResource(contents);
+
+ TileLayer tileLayer = mock(TileLayer.class);
+ when(tileLayer.getId()).thenReturn(layerName);
+ when(layers.getTileLayer(eq(layerName))).thenReturn(tileLayer);
+
+ TileObject tile =
+ TileObject.createCompleteTileObject(
+ layerName, xyz, gridSetId, format, parameters, blob);
+ store.put(tile);
+
+ TileObject query =
+ TileObject.createQueryTileObject(layerName, xyz, gridSetId, format, parameters);
+
+ // can't really test get, see https://github.com/Azure/Azurite/issues/217
+ if (true) return;
+ assertThat(store.get(query)).isTrue();
+ assertThat(query.getBlob()).isNotNull();
+ byte[] readContents = IOUtils.toByteArray(query.getBlob().getInputStream());
+ assertThat(readContents).isEqualTo(contents);
+ }
+}
diff --git a/src/gwc/backends/src/test/java/org/geoserver/cloud/gwc/config/blobstore/AzuriteContainer.java b/src/gwc/backends/src/test/java/org/geoserver/cloud/gwc/config/blobstore/AzuriteContainer.java
new file mode 100644
index 000000000..80ed13b26
--- /dev/null
+++ b/src/gwc/backends/src/test/java/org/geoserver/cloud/gwc/config/blobstore/AzuriteContainer.java
@@ -0,0 +1,50 @@
+package org.geoserver.cloud.gwc.config.blobstore;
+
+import lombok.Getter;
+import lombok.NonNull;
+
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.wait.strategy.Wait;
+import org.testcontainers.junit.jupiter.Testcontainers;
+import org.testcontainers.utility.DockerImageName;
+
+/**
+ * {@link Testcontainers} container for AWS Azurite blobstore test environment.
+ *
+ * Runs the Azurite
+ * emulator for local Azure Storage development with testcontainers.
+ *
+ *
Azurite accepts the same well-known account and key used by the legacy Azure Storage Emulator.
+ *
+ *
+ * - Account name: {@code devstoreaccount1}
+ *
- Account key: {@code
+ * Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==}
+ *
+ */
+public class AzuriteContainer extends GenericContainer {
+
+ private static final @NonNull DockerImageName IMAGE_NAME =
+ DockerImageName.parse("mcr.microsoft.com/azure-storage/azurite:latest");
+
+ public final @Getter String accountName = "devstoreaccount1";
+ public final @Getter String accountKey =
+ "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";
+
+ private final int blobsPort = 10_000;
+
+ public AzuriteContainer() {
+ super(IMAGE_NAME);
+ super.setWaitStrategy(Wait.forListeningPort());
+ super.addExposedPort(blobsPort);
+ }
+
+ public int getBlobsPort() {
+ return super.getMappedPort(blobsPort);
+ }
+
+ public String getBlobsUrl() {
+ return "http://localhost:%d/%s".formatted(getBlobsPort(), getAccountName());
+ }
+}
diff --git a/src/gwc/backends/src/test/resources/logback-test.xml b/src/gwc/backends/src/test/resources/logback-test.xml
new file mode 100644
index 000000000..84b8339d1
--- /dev/null
+++ b/src/gwc/backends/src/test/resources/logback-test.xml
@@ -0,0 +1,16 @@
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger [%X{instance-id}] %msg%n
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/pom.xml b/src/pom.xml
index 9cd43b3a4..8bf26f9da 100644
--- a/src/pom.xml
+++ b/src/pom.xml
@@ -28,10 +28,8 @@
2.23-CLOUD
29-SNAPSHOT
1.0.2
-
-
+
4.1.41.Final
1.18.30
1.4.2.Final
@@ -904,6 +902,7 @@
true
false
+ --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.text=ALL-UNNAMED --add-opens=java.desktop/java.awt.font=ALL-UNNAMED --add-opens=java.desktop/sun.awt.image=ALL-UNNAMED --add-opens=java.naming/com.sun.jndi.ldap=ALL-UNNAMED
@@ -1113,57 +1112,57 @@
io.netty
netty-buffer
- 4.1.94.Final
+ ${netty.version}
io.netty
netty-codec
- 4.1.94.Final
+ ${netty.version}
io.netty
netty-codec-http
- 4.1.94.Final
+ ${netty.version}
io.netty
netty-codec-http2
- 4.1.94.Final
+ ${netty.version}
io.netty
netty-codec-socks
- 4.1.94.Final
+ ${netty.version}
io.netty
netty-common
- 4.1.94.Final
+ ${netty.version}
io.netty
netty-handler
- 4.1.94.Final
+ ${netty.version}
io.netty
netty-handler-proxy
- 4.1.94.Final
+ ${netty.version}
io.netty
netty-resolver
- 4.1.94.Final
+ ${netty.version}
io.netty
netty-transport
- 4.1.94.Final
+ ${netty.version}
io.netty
netty-transport-native-unix-common
- 4.1.94.Final
+ ${netty.version}