Skip to content

Commit fc1cf1f

Browse files
committed
feat(core): replace hardcoded S3 and GCS emulator images with constants
- Introduced `DEFAULT_LOCALSTACK_S3_IMAGE` and `DEFAULT_FAKE_GCS_IMAGE` constants for centralizing default image configuration. - Updated `BigDataTestKit`, `BigDataContainerFactory`, Gradle plugin, and related test configurations to reference constants instead of hardcoded image strings. - Enhanced support for Floci S3 and GCS emulators with dynamic health endpoint selection and conditional configuration. - Updated documentation and examples to reflect emulator-specific changes and default configurations.
1 parent 6f03605 commit fc1cf1f

12 files changed

Lines changed: 86 additions & 54 deletions

File tree

autoconfigure/src/main/kotlin/org/openprojectx/bigdata/test/autoconfigure/BigDataTestProperties.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import org.openprojectx.bigdata.test.core.HiveMetastoreOptions
55
import org.openprojectx.bigdata.test.core.ClouderaHmsDatabaseType
66

77
import org.openprojectx.bigdata.test.core.ContainerLogMode
8+
import org.openprojectx.bigdata.test.core.DEFAULT_FAKE_GCS_IMAGE
9+
import org.openprojectx.bigdata.test.core.DEFAULT_LOCALSTACK_S3_IMAGE
810
import org.springframework.boot.context.properties.ConfigurationProperties
911

1012
@ConfigurationProperties("bigdata.test")
@@ -17,8 +19,8 @@ data class BigDataTestProperties(
1719
var hiveMetastore: HiveMetastore = HiveMetastore(),
1820
var clouderaHms: ClouderaHms = ClouderaHms(),
1921
var kafka: Kafka = Kafka(),
20-
var localstackS3: ObjectStore = ObjectStore(image = "localstack/localstack:4.14.0"),
21-
var fakeGcs: ObjectStore = ObjectStore(image = "fsouza/fake-gcs-server:1.54"),
22+
var localstackS3: ObjectStore = ObjectStore(image = DEFAULT_LOCALSTACK_S3_IMAGE),
23+
var fakeGcs: ObjectStore = ObjectStore(image = DEFAULT_FAKE_GCS_IMAGE),
2224
var containerLogs: ContainerLogs = ContainerLogs(),
2325
var containerLogLevels: Map<String, String> = emptyMap(),
2426
) {

core/src/main/kotlin/org/openprojectx/bigdata/test/core/BigDataService.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ enum class BigDataService(
5959
),
6060
),
6161
FAKE_GCS(
62-
defaultPorts = mapOf("http" to 4443, "https" to 443),
62+
defaultPorts = mapOf("http" to 4588, "https" to 443),
6363
endpointProperties = setOf("bigdata.test.gcs.endpoint", "google.cloud.storage.host"),
6464
),
6565
}

core/src/main/kotlin/org/openprojectx/bigdata/test/core/BigDataTestKit.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class BigDataTestKit private constructor(
5858
private var hiveMetastore = HiveMetastoreOptions()
5959
private var kafka = KafkaOptions()
6060
private var localStackS3 = ObjectStoreOptions()
61-
private var fakeGcs = ObjectStoreOptions(image = "fsouza/fake-gcs-server:1.54")
61+
private var fakeGcs = ObjectStoreOptions(image = DEFAULT_FAKE_GCS_IMAGE)
6262
private var portBindings = PortBindingOptions()
6363
private var containerLogs = ContainerLogOptions()
6464
private var containerCustomizations = emptyMap<BigDataService, ContainerCustomizationOptions>()
@@ -92,7 +92,7 @@ class BigDataTestKit private constructor(
9292
fun withLocalStackS3(options: ObjectStoreOptions = ObjectStoreOptions(enabled = true)): Builder =
9393
apply { localStackS3 = options.copy(enabled = true) }
9494

95-
fun withFakeGcs(options: ObjectStoreOptions = ObjectStoreOptions(enabled = true, image = "fsouza/fake-gcs-server:1.54")): Builder =
95+
fun withFakeGcs(options: ObjectStoreOptions = ObjectStoreOptions(enabled = true, image = DEFAULT_FAKE_GCS_IMAGE)): Builder =
9696
apply { fakeGcs = options.copy(enabled = true) }
9797

9898
fun withPortBindings(options: PortBindingOptions): Builder =

core/src/main/kotlin/org/openprojectx/bigdata/test/core/BigDataTestKitOptions.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@ package org.openprojectx.bigdata.test.core
22

33
import org.testcontainers.containers.GenericContainer
44

5+
const val DEFAULT_LOCALSTACK_S3_IMAGE = "floci/floci:latest"
6+
const val DEFAULT_FAKE_GCS_IMAGE = "floci/floci-gcp:latest"
7+
58
data class BigDataTestKitOptions(
69
val kerberos: KerberosOptions = KerberosOptions(),
710
val tls: TlsOptions = TlsOptions(),
811
val hdfs: HdfsOptions = HdfsOptions(),
912
val hiveMetastore: HiveMetastoreOptions = HiveMetastoreOptions(),
1013
val kafka: KafkaOptions = KafkaOptions(),
1114
val localStackS3: ObjectStoreOptions = ObjectStoreOptions(),
12-
val fakeGcs: ObjectStoreOptions = ObjectStoreOptions(image = "fsouza/fake-gcs-server:1.54"),
15+
val fakeGcs: ObjectStoreOptions = ObjectStoreOptions(image = DEFAULT_FAKE_GCS_IMAGE),
1316
val portBindings: PortBindingOptions = PortBindingOptions(),
1417
val containerLogs: ContainerLogOptions = ContainerLogOptions(),
1518
val containerCustomizations: Map<BigDataService, ContainerCustomizationOptions> = emptyMap(),
@@ -148,7 +151,7 @@ data class KafkaOptions(
148151

149152
data class ObjectStoreOptions(
150153
val enabled: Boolean = false,
151-
val image: String = "localstack/localstack:4.14.0",
154+
val image: String = DEFAULT_LOCALSTACK_S3_IMAGE,
152155
val tls: HttpTlsOptions = HttpTlsOptions(),
153156
)
154157

core/src/main/kotlin/org/openprojectx/bigdata/test/core/container/BigDataContainerFactory.kt

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -710,12 +710,19 @@ internal class BigDataContainerFactory(
710710

711711
private fun localStackS3(): BigDataServiceContainer {
712712
val objectStore = options.localStackS3
713+
val isFloci = objectStore.image.substringBefore(":") == "floci/floci"
713714
val container = GenericBigDataContainer(objectStore.image)
714715
.withNetwork(network)
715716
.withNetworkAliases("localstack")
716717
.withServicePort(4566, options.portBindings.hostPort(4566, options.portBindings.localStackS3))
717-
.withEnv("SERVICES", "s3")
718-
.waitingFor(Wait.forHttp("/_localstack/health").forStatusCode(200).withStartupTimeout(Duration.ofMinutes(3)))
718+
.waitingFor(
719+
Wait.forHttp(if (isFloci) "/_floci/health" else "/_localstack/health")
720+
.forStatusCode(200)
721+
.withStartupTimeout(Duration.ofMinutes(3)),
722+
)
723+
if (!isFloci) {
724+
container.withEnv("SERVICES", "s3")
725+
}
719726

720727
return BigDataServiceContainer(
721728
BigDataService.LOCALSTACK_S3,
@@ -746,12 +753,20 @@ internal class BigDataContainerFactory(
746753

747754
private fun fakeGcs(): BigDataServiceContainer {
748755
val objectStore = options.fakeGcs
756+
val servicePort = fakeGcsServicePort()
757+
val isFlociGcp = isFlociGcp()
749758
val container = GenericBigDataContainer(objectStore.image)
750759
.withNetwork(network)
751760
.withNetworkAliases("fake-gcs")
752-
.withServicePort(4443, options.portBindings.hostPort(4443, options.portBindings.fakeGcs))
753-
.withCommand("-scheme", "http", "-port", "4443")
754-
.waitingFor(Wait.forHttp("/storage/v1/b").forStatusCode(200).withStartupTimeout(Duration.ofMinutes(2)))
761+
.withServicePort(servicePort, options.portBindings.hostPort(servicePort, options.portBindings.fakeGcs))
762+
.waitingFor(
763+
Wait.forHttp(if (isFlociGcp) "/_floci-gcp/health" else "/storage/v1/b")
764+
.forStatusCode(200)
765+
.withStartupTimeout(Duration.ofMinutes(2)),
766+
)
767+
if (!isFlociGcp) {
768+
container.withCommand("-scheme", "http", "-port", servicePort.toString())
769+
}
755770

756771
return BigDataServiceContainer(
757772
BigDataService.FAKE_GCS,
@@ -761,14 +776,14 @@ internal class BigDataContainerFactory(
761776
name = "fake-gcs",
762777
tls = objectStore.tls,
763778
backendHost = "fake-gcs",
764-
backendPort = 4443,
779+
backendPort = servicePort,
765780
hostPort = tlsHostPort(options.portBindings.fakeGcsTls),
766781
)
767-
val endpoint = tlsEndpoint.url ?: "http://${container.host}:${container.getMappedPort(4443)}"
782+
val endpoint = tlsEndpoint.url ?: "http://${container.host}:${container.getMappedPort(servicePort)}"
768783
BigDataEndpoint(
769784
service = BigDataService.FAKE_GCS,
770785
host = tlsEndpoint.host ?: container.host,
771-
ports = mapOf("http" to container.getMappedPort(4443)) + tlsEndpoint.port("https"),
786+
ports = mapOf("http" to container.getMappedPort(servicePort)) + tlsEndpoint.port("https"),
772787
properties = mapOf(
773788
"bigdata.test.gcs.endpoint" to endpoint,
774789
"google.cloud.storage.host" to endpoint,
@@ -777,6 +792,12 @@ internal class BigDataContainerFactory(
777792
}
778793
}
779794

795+
private fun isFlociGcp(): Boolean =
796+
options.fakeGcs.image.substringBefore(":") == "floci/floci-gcp"
797+
798+
private fun fakeGcsServicePort(): Int =
799+
if (isFlociGcp()) 4588 else 4443
800+
780801

781802
private fun hiveMetastoreObjectStoreConfiguration(): Map<String, String> =
782803
buildMap {
@@ -796,10 +817,11 @@ internal class BigDataContainerFactory(
796817
put("fs.s3a.change.detection.mode", "none")
797818
}
798819
if (options.fakeGcs.enabled) {
820+
val fakeGcsEndpoint = "http://fake-gcs:${fakeGcsServicePort()}"
799821
put("fs.gs.impl", "com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystem")
800822
put("fs.AbstractFileSystem.gs.impl", "com.google.cloud.hadoop.fs.gcs.GoogleHadoopFS")
801823
put("fs.gs.project.id", "bigdata-test")
802-
put("fs.gs.storage.root.url", "http://fake-gcs:4443/")
824+
put("fs.gs.storage.root.url", "$fakeGcsEndpoint/")
803825
put("fs.gs.storage.service.path", "storage/v1/")
804826
put("fs.gs.client.type", "HTTP_API_CLIENT")
805827
put("fs.gs.auth.type", "UNAUTHENTICATED")
@@ -842,12 +864,13 @@ internal class BigDataContainerFactory(
842864
.withEnv("S3_SSL_ENABLED", "false")
843865
}
844866
if (options.fakeGcs.enabled) {
867+
val fakeGcsEndpoint = "http://fake-gcs:${fakeGcsServicePort()}"
845868
container
846869
.withEnv("GCS_FILE_SYSTEM_IMPL", "com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystem")
847870
.withEnv("GCS_ABSTRACT_FILE_SYSTEM_IMPL", "com.google.cloud.hadoop.fs.gcs.GoogleHadoopFS")
848871
.withEnv("GCS_AUTH_TYPE", "UNAUTHENTICATED")
849872
.withEnv("GCS_PROJECT_ID", "bigdata-test")
850-
.withEnv("GCS_STORAGE_ROOT_URL", "http://fake-gcs:4443")
873+
.withEnv("GCS_STORAGE_ROOT_URL", fakeGcsEndpoint)
851874
.withEnv("GCS_STORAGE_SERVICE_PATH", "/storage/v1/")
852875
.withEnv("GCS_CREATE_ITEMS_CONFLICT_CHECK_ENABLED", "false")
853876
.withEnv("GCS_CLIENT_UPLOAD_TYPE", "WRITE_TO_DISK_THEN_UPLOAD")
@@ -1204,11 +1227,11 @@ internal class BigDataContainerFactory(
12041227
elif command -v aws >/dev/null 2>&1; then
12051228
AWS_ACCESS_KEY_ID=test AWS_SECRET_ACCESS_KEY=test aws --endpoint-url=http://localhost:4566 s3 ls >/dev/null
12061229
else
1207-
${httpContainerProbe("http://localhost:4566/_localstack/health")}
1230+
${httpContainerProbe("http://localhost:4566/_floci/health")} || ${httpContainerProbe("http://localhost:4566/_localstack/health")}
12081231
fi
12091232
""".trimIndent()
12101233
BigDataService.FAKE_GCS ->
1211-
httpContainerProbe("http://localhost:4443/storage/v1/b")
1234+
"${httpContainerProbe("http://localhost:4588/_floci-gcp/health")} || ${httpContainerProbe("http://localhost:4443/storage/v1/b")}"
12121235
}
12131236

12141237
private fun httpContainerProbe(url: String): String =

doc/user-guide.adoc

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ The project currently provides containers and test integration for:
1616
* Kafka
1717
* Schema Registry
1818
* Kafka UI
19-
* LocalStack S3
20-
* fake-gcs-server
19+
* Floci S3-compatible AWS emulator
20+
* Floci GCP-compatible GCS emulator
2121
* Kerberos KDC and service principals
2222

2323
The project is split so lightweight users can depend on `core` or `junit5` without pulling Spark, Hadoop client utilities, or storage SDKs. Heavier setup such as JCEKS creation, Kafka Avro seeding, and Spark SQL preparation lives in the `extensions` module.
@@ -213,10 +213,10 @@ The JUnit extension starts the kit before all tests in the class and closes it a
213213
|Configures Kafka UI for Kerberos/SASL Kafka access.
214214

215215
|`localStackS3`
216-
|Starts LocalStack with S3 enabled.
216+
|Starts Floci S3-compatible AWS emulation.
217217

218218
|`fakeGcs`
219-
|Starts fake-gcs-server.
219+
|Starts Floci GCP-compatible GCS emulation.
220220
|===
221221

222222
=== Service Image Configuration
@@ -236,8 +236,8 @@ clouderaHmsMariadb = "ghcr.io/openprojectx/cloudera-hms:0.1.74-mariadb"
236236
kafka = "apache/kafka:4.1.2"
237237
schemaRegistry = "confluentinc/cp-schema-registry:7.8.0"
238238
kafkaUi = "ghcr.io/kafbat/kafka-ui:latest"
239-
localStackS3 = "localstack/localstack:4.14.0"
240-
fakeGcs = "fsouza/fake-gcs-server:1.54"
239+
localStackS3 = "floci/floci:latest"
240+
fakeGcs = "floci/floci-gcp:latest"
241241
----
242242

243243
Kafka and the open-source HMS database sidecar use typed Testcontainers classes instead of plain generic containers. When you override those images, `bigdata-test` marks the configured Kafka image as a compatible substitute for `apache/kafka`, PostgreSQL as a compatible substitute for `postgres`, and MySQL as a compatible substitute for `mysql`, so private mirrors or rebuilt images can still pass Testcontainers image checks.
@@ -521,11 +521,11 @@ Current CLI probes:
521521
|Kafka UI
522522
|Uses `wget` or `curl` against `/`.
523523

524-
|LocalStack S3
524+
|Floci S3-compatible AWS emulator
525525
|Uses `awslocal s3 ls` when available, then falls back to `aws --endpoint-url`, then HTTP health.
526526

527-
|fake-gcs-server
528-
|Uses `wget` or `curl` against `/storage/v1/b`.
527+
|Floci GCP-compatible GCS emulator
528+
|Uses `wget` or `curl` against the configured HTTP health endpoint.
529529
|===
530530

531531
CLI probes validate the container's own environment. For host-side behavior, such as Windows HDFS clients connecting through mapped ports, use a host/JVM smoke test as well because an in-container `hdfs dfs` command cannot prove host network reachability.
@@ -834,7 +834,7 @@ To bind each enabled service to the same localhost port it uses inside the conta
834834
class MySameHostPortTest
835835
----
836836

837-
This maps common service ports directly, for example HDFS `8020`, `9866`, and `9870`, Hive Metastore `9083`, Kafka `9092`, Schema Registry `8085`, LocalStack `4566`, and fake GCS `4443`. Explicit per-service port fields still take priority over `sameHostPorts`.
837+
This maps common service ports directly, for example HDFS `8020`, `9866`, and `9870`, Hive Metastore `9083`, Kafka `9092`, Schema Registry `8085`, Floci S3 `4566`, and Floci GCS `4588`. Explicit per-service port fields still take priority over `sameHostPorts`.
838838

839839
TLS gateway ports are not affected by `sameHostPorts`, because every gateway listens on container port `443`. Configure the per-service TLS port fields explicitly if a stable HTTPS host port is needed.
840840

@@ -913,22 +913,22 @@ Available fixed host-port config:
913913
|`kafkaUiTls`
914914
|`443` on the HAProxy gateway
915915

916-
|LocalStack S3 HTTP
916+
|Floci S3 HTTP
917917
|`localStackS3`
918918
|`localStackS3Port`
919919
|`4566`
920920

921-
|LocalStack S3 TLS gateway
921+
|Floci S3 TLS gateway
922922
|`localStackS3Tls`
923923
|`localStackS3Tls`
924924
|`443` on the HAProxy gateway
925925

926-
|fake-gcs-server HTTP
926+
|Floci GCS HTTP
927927
|`fakeGcs`
928928
|`fakeGcsPort`
929-
|`4443`
929+
|`4588` by default, or `4443` when overriding the image to `fsouza/fake-gcs-server`
930930

931-
|fake-gcs-server TLS gateway
931+
|Floci GCS TLS gateway
932932
|`fakeGcsTls`
933933
|`fakeGcsTls`
934934
|`443` on the HAProxy gateway
@@ -1003,7 +1003,7 @@ Each started service exposes a `BigDataEndpoint` with named ports and connection
10031003

10041004
|`BigDataService.FAKE_GCS`
10051005
|`http`, `https`
1006-
|`4443`, `443`
1006+
|`4588`, `443`
10071007
|`bigdata.test.gcs.endpoint`, `google.cloud.storage.host`
10081008
|===
10091009

@@ -1348,7 +1348,7 @@ Outputs:
13481348

13491349
=== S3 JCEKS Extension
13501350

1351-
The `s3Jceks` extension creates a Hadoop credential provider file in HDFS and stores LocalStack S3 credentials in it.
1351+
The `s3Jceks` extension creates a Hadoop credential provider file in HDFS and stores the S3 emulator credentials in it.
13521352
It builds its Hadoop client configuration from the active HDFS endpoint properties, including `fs.defaultFS`, `dfs.client.use.datanode.hostname`, `dfs.datanode.hostname`, and any HDFS TLS properties exposed by the test kit.
13531353

13541354
[source,toml]
@@ -1421,8 +1421,8 @@ When `useKitEndpoints = true`, the default, the extension wires known endpoint p
14211421

14221422
* Hive Metastore URI and HMS TLS properties
14231423
* HDFS default filesystem and DataNode hostname setting
1424-
* LocalStack S3 endpoint and test credentials
1425-
* fake-gcs-server endpoint using unauthenticated GCS connector settings
1424+
* S3 emulator endpoint and test credentials
1425+
* GCS emulator endpoint using unauthenticated GCS connector settings
14261426
* Kerberos client `krb5.conf`, principal, and keytab properties when Kerberos is enabled
14271427

14281428
Explicit `configs` are applied after endpoint defaults and therefore override generated Spark config.
@@ -1572,7 +1572,7 @@ This asks HMS to validate table metadata and location using HMS server-side Hado
15721572

15731573
=== HMS Server-Side S3A
15741574

1575-
When Hive Metastore starts with LocalStack S3 enabled, `bigdata-test` injects HMS-side S3A configuration:
1575+
When Hive Metastore starts with the S3 emulator enabled, `bigdata-test` injects HMS-side S3A configuration:
15761576

15771577
* `fs.s3a.endpoint=http://localstack:4566`
15781578
* `fs.s3a.endpoint.region=us-east-1`
@@ -1583,7 +1583,7 @@ When Hive Metastore starts with LocalStack S3 enabled, `bigdata-test` injects HM
15831583
* `fs.s3a.connection.ssl.enabled=false`
15841584
* `fs.s3a.change.detection.mode=none`
15851585

1586-
This allows Hive external table DDL with `s3a://` locations to validate against the internal LocalStack endpoint. The Spark example includes this path and verifies the HMS table location through `HiveMetaStoreClient`.
1586+
This allows Hive external table DDL with `s3a://` locations to validate against the internal S3 emulator endpoint. The Spark example includes this path and verifies the HMS table location through `HiveMetaStoreClient`.
15871587

15881588
=== HMS Server-Side HDFS
15891589

@@ -1597,12 +1597,12 @@ This lets HMS resolve `hdfs://` warehouse and table locations from inside the Do
15971597

15981598
=== HMS Server-Side GCS
15991599

1600-
When Hive Metastore starts with fake GCS enabled, `bigdata-test` injects HMS-side GCS configuration based on the Google Cloud Storage connector configuration model:
1600+
When Hive Metastore starts with the GCS emulator enabled, `bigdata-test` injects HMS-side GCS configuration based on the Google Cloud Storage connector configuration model:
16011601

16021602
* `fs.gs.impl=com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystem`
16031603
* `fs.AbstractFileSystem.gs.impl=com.google.cloud.hadoop.fs.gcs.GoogleHadoopFS`
16041604
* `fs.gs.project.id=bigdata-test`
1605-
* `fs.gs.storage.root.url=http://fake-gcs:4443/`
1605+
* `fs.gs.storage.root.url=http://fake-gcs:4588/`
16061606
* `fs.gs.storage.service.path=storage/v1/`
16071607
* `fs.gs.client.type=HTTP_API_CLIENT`
16081608
* `fs.gs.auth.type=UNAUTHENTICATED`
@@ -2078,7 +2078,7 @@ The Spring example is a normal Spring Boot web application. Its default configur
20782078
GRADLE_USER_HOME=/data/.gradle ./gradlew :example:spring:check
20792079
----
20802080

2081-
The local developer profile is fully configuration driven. The app source does not call `BigDataTestKit`; `application-local.yaml` starts Kerberos, HDFS, and LocalStack S3 and enables the REST API.
2081+
The local developer profile is fully configuration driven. The app source does not call `BigDataTestKit`; `application-local.yaml` starts Kerberos, HDFS, and the S3 emulator and enables the REST API.
20822082

20832083
The local profile also enables HDFS and Kerberos container logs on stdout:
20842084

@@ -2137,7 +2137,7 @@ curl -sS -X DELETE http://localhost:8080/api/s3/objects/demo.txt
21372137

21382138
=== Spark Example
21392139

2140-
The Spark example lives under `example/spark`. It starts HDFS, Hive Metastore, Kafka, Schema Registry, LocalStack S3, and fake GCS.
2140+
The Spark example lives under `example/spark`. It starts HDFS, Hive Metastore, Kafka, Schema Registry, Floci S3, and Floci GCS.
21412141

21422142
The example uses `hiveMetastore = true` with the Hive 3 open-source HMS image. This keeps Spark 3.x on a compatible HMS protocol while still exercising server-side S3A and GCS configuration. Use `clouderaHms = true` when the embedded-Postgres Cloudera HMS image is the target under test.
21432143

@@ -2284,7 +2284,7 @@ This Hadoop message can appear in test output when Hadoop checks for native util
22842284

22852285
=== S3 Hive External Table Fails with Credential Errors
22862286

2287-
If a Hive external table on `s3a://` fails with an AWS credential error, check whether HMS was started with LocalStack S3 enabled and whether custom `HiveMetastoreOptions.extraConfiguration` overrides the S3A settings.
2287+
If a Hive external table on `s3a://` fails with an AWS credential error, check whether HMS was started with the S3 emulator enabled and whether custom `HiveMetastoreOptions.extraConfiguration` overrides the S3A settings.
22882288

22892289
The important distinction is where the path is resolved:
22902290

example/junit/src/test/kotlin/org/openprojectx/bigdata/test/example/junit/LocalStackS3TlsExampleTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class LocalStackS3TlsExampleTest {
2020
val client = HttpClient.newHttpClient()
2121

2222
val response = client.send(
23-
HttpRequest.newBuilder(URI.create("$url/_localstack/health")).GET().build(),
23+
HttpRequest.newBuilder(URI.create("$url/_floci/health")).GET().build(),
2424
HttpResponse.BodyHandlers.ofString(),
2525
)
2626

0 commit comments

Comments
 (0)