From 46927ccba9ade30d48d39837c45b76486f74940d Mon Sep 17 00:00:00 2001 From: OmCheeLin <19563671928@163.com> Date: Thu, 7 Aug 2025 09:58:08 +0800 Subject: [PATCH 01/16] login --- .../banyandb/v1/client/BanyanDBClient.java | 14 ++- .../banyandb/v1/client/Options.java | 8 ++ .../v1/client/auth/AuthInterceptor.java | 58 ++++++++++++ .../banyandb/v1/client/BanyanDBAuthTest.java | 88 +++++++++++++++++++ src/test/resources/config.yaml | 20 +++++ 5 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/apache/skywalking/banyandb/v1/client/auth/AuthInterceptor.java create mode 100644 src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java create mode 100644 src/test/resources/config.yaml diff --git a/src/main/java/org/apache/skywalking/banyandb/v1/client/BanyanDBClient.java b/src/main/java/org/apache/skywalking/banyandb/v1/client/BanyanDBClient.java index 50a9079c..f6f70876 100644 --- a/src/main/java/org/apache/skywalking/banyandb/v1/client/BanyanDBClient.java +++ b/src/main/java/org/apache/skywalking/banyandb/v1/client/BanyanDBClient.java @@ -23,6 +23,7 @@ import com.google.common.base.Strings; import com.google.protobuf.Timestamp; import io.grpc.Channel; +import io.grpc.ClientInterceptors; import io.grpc.ManagedChannel; import io.grpc.Status; import io.grpc.stub.StreamObserver; @@ -51,6 +52,7 @@ import org.apache.skywalking.banyandb.measure.v1.MeasureServiceGrpc; import org.apache.skywalking.banyandb.stream.v1.BanyandbStream; import org.apache.skywalking.banyandb.stream.v1.StreamServiceGrpc; +import org.apache.skywalking.banyandb.v1.client.auth.AuthInterceptor; import org.apache.skywalking.banyandb.v1.client.grpc.HandleExceptionsWith; import org.apache.skywalking.banyandb.v1.client.grpc.channel.ChannelManager; import org.apache.skywalking.banyandb.v1.client.grpc.channel.DefaultChannelFactory; @@ -183,8 +185,18 @@ public void connect() throws IOException { for (int i = 0; i < this.targets.length; i++) { addresses[i] = URI.create("//" + this.targets[i]); } - this.channel = ChannelManager.create(this.options.buildChannelManagerSettings(), + Channel rawChannel = ChannelManager.create(this.options.buildChannelManagerSettings(), new DefaultChannelFactory(addresses, this.options)); + Channel interceptedChannel = rawChannel; + // register auth interceptor + String username = options.getUsername(); + String password = options.getPassword(); + if (!"".equals(username) && !"".equals(password)) { + interceptedChannel = ClientInterceptors.intercept(rawChannel, + new AuthInterceptor(options.getUsername(), options.getPassword())); + } + // Ensure this.channel is assigned only once. + this.channel = interceptedChannel; streamServiceBlockingStub = StreamServiceGrpc.newBlockingStub(this.channel); measureServiceBlockingStub = MeasureServiceGrpc.newBlockingStub(this.channel); streamServiceStub = StreamServiceGrpc.newStub(this.channel); diff --git a/src/main/java/org/apache/skywalking/banyandb/v1/client/Options.java b/src/main/java/org/apache/skywalking/banyandb/v1/client/Options.java index e22959c4..9be150a2 100644 --- a/src/main/java/org/apache/skywalking/banyandb/v1/client/Options.java +++ b/src/main/java/org/apache/skywalking/banyandb/v1/client/Options.java @@ -63,6 +63,14 @@ public class Options { * SSL: Cert Key Path, BanyanDB server not support mTLS yet */ private String sslKeyPath = ""; + /** + * Basic Auth: username of BanyanDB server + */ + private String username = ""; + /** + * Basic Auth: password of BanyanDB server + */ + private String password = ""; public Options() { } diff --git a/src/main/java/org/apache/skywalking/banyandb/v1/client/auth/AuthInterceptor.java b/src/main/java/org/apache/skywalking/banyandb/v1/client/auth/AuthInterceptor.java new file mode 100644 index 00000000..52d0d742 --- /dev/null +++ b/src/main/java/org/apache/skywalking/banyandb/v1/client/auth/AuthInterceptor.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.banyandb.v1.client.auth; + +import io.grpc.CallOptions; +import io.grpc.Channel; +import io.grpc.ClientCall; +import io.grpc.ClientInterceptor; +import io.grpc.ForwardingClientCall; +import io.grpc.Metadata; +import io.grpc.MethodDescriptor; + +public class AuthInterceptor implements ClientInterceptor { + private final String username; + private final String password; + + public AuthInterceptor(String username, String password) { + this.username = username; + this.password = password; + } + + @Override + public ClientCall interceptCall( + MethodDescriptor method, + CallOptions callOptions, + Channel next) { + + return new ForwardingClientCall.SimpleForwardingClientCall( + next.newCall(method, callOptions)) { + @Override + public void start(Listener responseListener, Metadata headers) { + Metadata.Key usernameKey = Metadata.Key.of("username", Metadata.ASCII_STRING_MARSHALLER); + Metadata.Key passwordKey = Metadata.Key.of("password", Metadata.ASCII_STRING_MARSHALLER); + + headers.put(usernameKey, username); + headers.put(passwordKey, password); + + super.start(responseListener, headers); + } + }; + } +} \ No newline at end of file diff --git a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java new file mode 100644 index 00000000..118fd4a5 --- /dev/null +++ b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.banyandb.v1.client; + +import lombok.extern.slf4j.Slf4j; +import org.apache.skywalking.banyandb.common.v1.BanyandbCommon; +import org.apache.skywalking.banyandb.v1.client.grpc.exception.BanyanDBException; +import org.apache.skywalking.banyandb.v1.client.grpc.exception.UnauthenticatedException; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.utility.DockerImageName; +import org.testcontainers.utility.MountableFile; + +import java.io.IOException; +import java.util.List; + +import static org.junit.Assert.assertThrows; + +@Slf4j +public class BanyanDBAuthTest { + private static final String REGISTRY = "ghcr.io"; + private static final String IMAGE_NAME = "apache/skywalking-banyandb"; + private static final String TAG = "42ec9df7457868926eb80157b36355d94fcd6bba"; + + private static final String IMAGE = REGISTRY + "/" + IMAGE_NAME + ":" + TAG; + + protected static final int GRPC_PORT = 17912; + protected static final int HTTP_PORT = 17913; + + @Rule + public GenericContainer banyanDB = new GenericContainer<>(DockerImageName.parse(IMAGE)) + .withCopyFileToContainer( + MountableFile.forClasspathResource("config.yaml"), + "/tmp/bydb_server_config.yaml" + ) + .withCommand("standalone", + "--auth-config-file", "/tmp/bydb_server_config.yaml", + "--enable-health-auth", "true" + ) + .withExposedPorts(GRPC_PORT, HTTP_PORT) + .waitingFor(Wait.forLogMessage(".*\"message\":\"Listening to\".*", 1)); + + @Test + public void testAuthWithCorrect() throws BanyanDBException, IOException { + BanyanDBClient client = createClient("admin", "123456"); + client.connect(); + // list all groups + List groupList = client.findGroups(); + Assert.assertEquals(1, groupList.size()); + Assert.assertEquals("_monitoring", groupList.get(0).getMetadata().getName()); + client.close(); + } + + @Test + public void testAuthWithWrong() throws IOException { + BanyanDBClient client = createClient("admin", "123456" + "wrong"); + client.connect(); + assertThrows(UnauthenticatedException.class, client::getAPIVersion); + client.close(); + } + + private BanyanDBClient createClient(String username, String password) { + Options options = new Options(); + options.setUsername(username); + options.setPassword(password); + String url = String.format("%s:%d", banyanDB.getHost(), banyanDB.getMappedPort(GRPC_PORT)); + return new BanyanDBClient(new String[]{url}, options); + } +} \ No newline at end of file diff --git a/src/test/resources/config.yaml b/src/test/resources/config.yaml new file mode 100644 index 00000000..286d88a2 --- /dev/null +++ b/src/test/resources/config.yaml @@ -0,0 +1,20 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +users: + - username: admin + password: 123456 + - username: test + password: 123456 \ No newline at end of file From 541e3b998a29204279fd99fe4625edc16b4337f2 Mon Sep 17 00:00:00 2001 From: OmCheeLin <19563671928@163.com> Date: Thu, 7 Aug 2025 10:13:42 +0800 Subject: [PATCH 02/16] fix --- .../skywalking/banyandb/v1/client/BanyanDBAuthTest.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java index 118fd4a5..ceaa1371 100644 --- a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java +++ b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java @@ -18,7 +18,6 @@ package org.apache.skywalking.banyandb.v1.client; -import lombok.extern.slf4j.Slf4j; import org.apache.skywalking.banyandb.common.v1.BanyandbCommon; import org.apache.skywalking.banyandb.v1.client.grpc.exception.BanyanDBException; import org.apache.skywalking.banyandb.v1.client.grpc.exception.UnauthenticatedException; @@ -35,7 +34,6 @@ import static org.junit.Assert.assertThrows; -@Slf4j public class BanyanDBAuthTest { private static final String REGISTRY = "ghcr.io"; private static final String IMAGE_NAME = "apache/skywalking-banyandb"; @@ -56,8 +54,8 @@ public class BanyanDBAuthTest { "--auth-config-file", "/tmp/bydb_server_config.yaml", "--enable-health-auth", "true" ) - .withExposedPorts(GRPC_PORT, HTTP_PORT) - .waitingFor(Wait.forLogMessage(".*\"message\":\"Listening to\".*", 1)); + .withExposedPorts(GRPC_PORT, HTTP_PORT); + // TODO .waitingFor(Wait.forLogMessage(".*\"message\":\"Listening to\".*", 1)); @Test public void testAuthWithCorrect() throws BanyanDBException, IOException { From 6b6427de60bba1d6b1e23edaeebfe79ed4bbac4c Mon Sep 17 00:00:00 2001 From: OmCheeLin <19563671928@163.com> Date: Thu, 7 Aug 2025 10:18:30 +0800 Subject: [PATCH 03/16] update --- .../apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java index ceaa1371..06218236 100644 --- a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java +++ b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java @@ -25,7 +25,6 @@ import org.junit.Rule; import org.junit.Test; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.utility.DockerImageName; import org.testcontainers.utility.MountableFile; From 44df37bc46f83abef972fb32da765499e5de1740 Mon Sep 17 00:00:00 2001 From: OmCheeLin <19563671928@163.com> Date: Thu, 7 Aug 2025 10:36:00 +0800 Subject: [PATCH 04/16] add wait --- .../banyandb/v1/client/BanyanDBAuthTest.java | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java index 06218236..c0ecdcb9 100644 --- a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java +++ b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java @@ -25,12 +25,17 @@ import org.junit.Rule; import org.junit.Test; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.utility.DockerImageName; import org.testcontainers.utility.MountableFile; import java.io.IOException; +import java.time.Duration; +import java.util.Base64; import java.util.List; +import java.util.concurrent.TimeUnit; +import static org.awaitility.Awaitility.await; import static org.junit.Assert.assertThrows; public class BanyanDBAuthTest { @@ -39,6 +44,7 @@ public class BanyanDBAuthTest { private static final String TAG = "42ec9df7457868926eb80157b36355d94fcd6bba"; private static final String IMAGE = REGISTRY + "/" + IMAGE_NAME + ":" + TAG; + private static final String AUTH = Base64.getEncoder().encodeToString("admin:123456".getBytes()); protected static final int GRPC_PORT = 17912; protected static final int HTTP_PORT = 17913; @@ -53,17 +59,23 @@ public class BanyanDBAuthTest { "--auth-config-file", "/tmp/bydb_server_config.yaml", "--enable-health-auth", "true" ) - .withExposedPorts(GRPC_PORT, HTTP_PORT); - // TODO .waitingFor(Wait.forLogMessage(".*\"message\":\"Listening to\".*", 1)); + .withExposedPorts(GRPC_PORT, HTTP_PORT) + .waitingFor(Wait.forHttp("/api/healthz") + .forPort(HTTP_PORT) + .withHeader("Authorization", "Basic " + AUTH) + .forStatusCode(200) + .withStartupTimeout(Duration.ofSeconds(30))); @Test public void testAuthWithCorrect() throws BanyanDBException, IOException { BanyanDBClient client = createClient("admin", "123456"); client.connect(); - // list all groups - List groupList = client.findGroups(); - Assert.assertEquals(1, groupList.size()); - Assert.assertEquals("_monitoring", groupList.get(0).getMetadata().getName()); + await().atMost(10, TimeUnit.SECONDS).untilAsserted(() -> { + // list all groups + List groupList = client.findGroups(); + Assert.assertEquals(1, groupList.size()); + Assert.assertEquals("_monitoring", groupList.get(0).getMetadata().getName()); + }); client.close(); } @@ -71,7 +83,9 @@ public void testAuthWithCorrect() throws BanyanDBException, IOException { public void testAuthWithWrong() throws IOException { BanyanDBClient client = createClient("admin", "123456" + "wrong"); client.connect(); - assertThrows(UnauthenticatedException.class, client::getAPIVersion); + await().atMost(10, TimeUnit.SECONDS).untilAsserted(() -> { + assertThrows(UnauthenticatedException.class, client::getAPIVersion); + }); client.close(); } From 5f6b6db046b457f60b6af9463c74c639fae1878e Mon Sep 17 00:00:00 2001 From: OmCheeLin <19563671928@163.com> Date: Thu, 7 Aug 2025 10:44:12 +0800 Subject: [PATCH 05/16] fix --- .../skywalking/banyandb/v1/client/BanyanDBAuthTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java index c0ecdcb9..c24363d0 100644 --- a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java +++ b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java @@ -64,10 +64,10 @@ public class BanyanDBAuthTest { .forPort(HTTP_PORT) .withHeader("Authorization", "Basic " + AUTH) .forStatusCode(200) - .withStartupTimeout(Duration.ofSeconds(30))); + .withStartupTimeout(Duration.ofSeconds(1000))); @Test - public void testAuthWithCorrect() throws BanyanDBException, IOException { + public void testAuthWithCorrect() throws IOException { BanyanDBClient client = createClient("admin", "123456"); client.connect(); await().atMost(10, TimeUnit.SECONDS).untilAsserted(() -> { From 49c31838d647f35880a82770ef2e2b97fdf2960b Mon Sep 17 00:00:00 2001 From: OmCheeLin <19563671928@163.com> Date: Thu, 7 Aug 2025 10:46:52 +0800 Subject: [PATCH 06/16] fix --- .../apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java index c24363d0..e93f9692 100644 --- a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java +++ b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java @@ -19,7 +19,6 @@ package org.apache.skywalking.banyandb.v1.client; import org.apache.skywalking.banyandb.common.v1.BanyandbCommon; -import org.apache.skywalking.banyandb.v1.client.grpc.exception.BanyanDBException; import org.apache.skywalking.banyandb.v1.client.grpc.exception.UnauthenticatedException; import org.junit.Assert; import org.junit.Rule; From d6ce7b4a0df172a5b218cc4ef5d12e08bdd368d1 Mon Sep 17 00:00:00 2001 From: OmCheeLin <19563671928@163.com> Date: Thu, 7 Aug 2025 14:41:17 +0800 Subject: [PATCH 07/16] fix --- .../skywalking/banyandb/v1/client/BanyanDBAuthTest.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java index e93f9692..9ce1ed58 100644 --- a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java +++ b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java @@ -56,14 +56,10 @@ public class BanyanDBAuthTest { ) .withCommand("standalone", "--auth-config-file", "/tmp/bydb_server_config.yaml", - "--enable-health-auth", "true" + "--enable-health-auth", "false" ) .withExposedPorts(GRPC_PORT, HTTP_PORT) - .waitingFor(Wait.forHttp("/api/healthz") - .forPort(HTTP_PORT) - .withHeader("Authorization", "Basic " + AUTH) - .forStatusCode(200) - .withStartupTimeout(Duration.ofSeconds(1000))); + .waitingFor(Wait.forHttp("/api/healthz").forPort(HTTP_PORT)); @Test public void testAuthWithCorrect() throws IOException { From a803a00eb49a225643b5f201cda801a7b5b8ac5d Mon Sep 17 00:00:00 2001 From: OmCheeLin <19563671928@163.com> Date: Thu, 7 Aug 2025 14:43:12 +0800 Subject: [PATCH 08/16] fix --- .../apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java index 9ce1ed58..f506a142 100644 --- a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java +++ b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java @@ -29,7 +29,6 @@ import org.testcontainers.utility.MountableFile; import java.io.IOException; -import java.time.Duration; import java.util.Base64; import java.util.List; import java.util.concurrent.TimeUnit; From 0260ccbcfd90f425b761a0e66b8b64d0c961d920 Mon Sep 17 00:00:00 2001 From: OmCheeLin <19563671928@163.com> Date: Thu, 7 Aug 2025 14:43:47 +0800 Subject: [PATCH 09/16] lint --- .../apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java index f506a142..3d43aea0 100644 --- a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java +++ b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java @@ -29,7 +29,6 @@ import org.testcontainers.utility.MountableFile; import java.io.IOException; -import java.util.Base64; import java.util.List; import java.util.concurrent.TimeUnit; @@ -42,7 +41,6 @@ public class BanyanDBAuthTest { private static final String TAG = "42ec9df7457868926eb80157b36355d94fcd6bba"; private static final String IMAGE = REGISTRY + "/" + IMAGE_NAME + ":" + TAG; - private static final String AUTH = Base64.getEncoder().encodeToString("admin:123456".getBytes()); protected static final int GRPC_PORT = 17912; protected static final int HTTP_PORT = 17913; From 6c38eb06f36001091570bdba8958f5dc99cb9d21 Mon Sep 17 00:00:00 2001 From: OmCheeLin <19563671928@163.com> Date: Thu, 7 Aug 2025 14:51:12 +0800 Subject: [PATCH 10/16] lint --- .../skywalking/banyandb/v1/client/BanyanDBAuthTest.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java index 3d43aea0..5081f1ad 100644 --- a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java +++ b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java @@ -51,9 +51,10 @@ public class BanyanDBAuthTest { MountableFile.forClasspathResource("config.yaml"), "/tmp/bydb_server_config.yaml" ) - .withCommand("standalone", - "--auth-config-file", "/tmp/bydb_server_config.yaml", - "--enable-health-auth", "false" + .withCommand("sh", "-c", + "chmod 600 /tmp/bydb_server_config.yaml && exec standalone " + + "--auth-config-file /tmp/bydb_server_config.yaml " + + "--enable-health-auth false" ) .withExposedPorts(GRPC_PORT, HTTP_PORT) .waitingFor(Wait.forHttp("/api/healthz").forPort(HTTP_PORT)); From 1c52d3c8923c883172ee2488cc8348b505f90756 Mon Sep 17 00:00:00 2001 From: OmCheeLin <19563671928@163.com> Date: Thu, 7 Aug 2025 15:01:33 +0800 Subject: [PATCH 11/16] fix --- .../banyandb/v1/client/BanyanDBAuthTest.java | 39 +++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java index 5081f1ad..75a71510 100644 --- a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java +++ b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java @@ -29,6 +29,10 @@ import org.testcontainers.utility.MountableFile; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.attribute.PosixFilePermissions; import java.util.List; import java.util.concurrent.TimeUnit; @@ -46,18 +50,29 @@ public class BanyanDBAuthTest { protected static final int HTTP_PORT = 17913; @Rule - public GenericContainer banyanDB = new GenericContainer<>(DockerImageName.parse(IMAGE)) - .withCopyFileToContainer( - MountableFile.forClasspathResource("config.yaml"), - "/tmp/bydb_server_config.yaml" - ) - .withCommand("sh", "-c", - "chmod 600 /tmp/bydb_server_config.yaml && exec standalone " + - "--auth-config-file /tmp/bydb_server_config.yaml " + - "--enable-health-auth false" - ) - .withExposedPorts(GRPC_PORT, HTTP_PORT) - .waitingFor(Wait.forHttp("/api/healthz").forPort(HTTP_PORT)); + public GenericContainer banyanDB; + + public BanyanDBAuthTest() throws Exception { + // Step 1: prepare config file with 0600 permissions + Path tempConfigPath = Files.createTempFile("bydb_server_config", ".yaml"); + Files.write(tempConfigPath, Files.readAllBytes( + Paths.get(getClass().getClassLoader().getResource("config.yaml").toURI())) + ); + Files.setPosixFilePermissions(tempConfigPath, PosixFilePermissions.fromString("rw-------")); + + // Step 2: create container + banyanDB = new GenericContainer<>(DockerImageName.parse(IMAGE)) + .withCopyFileToContainer( + MountableFile.forHostPath(tempConfigPath), + "/tmp/bydb_server_config.yaml" + ) + .withCommand("standalone", + "--auth-config-file", "/tmp/bydb_server_config.yaml", + "--enable-health-auth", "false" + ) + .withExposedPorts(GRPC_PORT, HTTP_PORT) + .waitingFor(Wait.forHttp("/api/healthz").forPort(HTTP_PORT)); + } @Test public void testAuthWithCorrect() throws IOException { From 942274a0e864cd31e6b6099c9096a8451fc45100 Mon Sep 17 00:00:00 2001 From: OmCheeLin <19563671928@163.com> Date: Thu, 7 Aug 2025 15:11:46 +0800 Subject: [PATCH 12/16] fix --- .../skywalking/banyandb/v1/client/BanyanDBAuthTest.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java index 75a71510..cd0a67f8 100644 --- a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java +++ b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java @@ -66,10 +66,7 @@ public BanyanDBAuthTest() throws Exception { MountableFile.forHostPath(tempConfigPath), "/tmp/bydb_server_config.yaml" ) - .withCommand("standalone", - "--auth-config-file", "/tmp/bydb_server_config.yaml", - "--enable-health-auth", "false" - ) + .withCommand("standalone", "--auth-config-file", "/tmp/bydb_server_config.yaml") .withExposedPorts(GRPC_PORT, HTTP_PORT) .waitingFor(Wait.forHttp("/api/healthz").forPort(HTTP_PORT)); } From 267b0bf94fd1855b502b9f2a16c05e2a8a998783 Mon Sep 17 00:00:00 2001 From: OmCheeLin <19563671928@163.com> Date: Thu, 7 Aug 2025 15:24:26 +0800 Subject: [PATCH 13/16] fix --- .../skywalking/banyandb/v1/client/BanyanDBAuthTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java index cd0a67f8..01dec9c4 100644 --- a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java +++ b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java @@ -76,10 +76,11 @@ public void testAuthWithCorrect() throws IOException { BanyanDBClient client = createClient("admin", "123456"); client.connect(); await().atMost(10, TimeUnit.SECONDS).untilAsserted(() -> { + // get api version + client.getAPIVersion(); // list all groups List groupList = client.findGroups(); - Assert.assertEquals(1, groupList.size()); - Assert.assertEquals("_monitoring", groupList.get(0).getMetadata().getName()); + Assert.assertEquals(0, groupList.size()); }); client.close(); } From b377f2875228315ca82033d28bde196f04bd9716 Mon Sep 17 00:00:00 2001 From: OmCheeLin <19563671928@163.com> Date: Thu, 7 Aug 2025 15:33:18 +0800 Subject: [PATCH 14/16] modify --- .../banyandb/v1/client/BanyanDBAuthTest.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java index 01dec9c4..ccba393e 100644 --- a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java +++ b/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java @@ -33,6 +33,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.PosixFilePermissions; +import java.util.Base64; import java.util.List; import java.util.concurrent.TimeUnit; @@ -66,9 +67,15 @@ public BanyanDBAuthTest() throws Exception { MountableFile.forHostPath(tempConfigPath), "/tmp/bydb_server_config.yaml" ) - .withCommand("standalone", "--auth-config-file", "/tmp/bydb_server_config.yaml") + .withCommand("standalone", + "--auth-config-file", "/tmp/bydb_server_config.yaml", + "--enable-health-auth", "true" + ) .withExposedPorts(GRPC_PORT, HTTP_PORT) - .waitingFor(Wait.forHttp("/api/healthz").forPort(HTTP_PORT)); + .waitingFor(Wait.forHttp("/api/healthz") + .withHeader("Authorization", + "Basic " + Base64.getEncoder().encodeToString("admin:123456".getBytes())) + .forPort(HTTP_PORT)); } @Test From 74248d8d744c405cffef1aa2c1d6fc44898c97f2 Mon Sep 17 00:00:00 2001 From: OmCheeLin <19563671928@163.com> Date: Mon, 11 Aug 2025 12:05:59 +0800 Subject: [PATCH 15/16] optimize --- .../banyandb/v1/client/BanyanDBClient.java | 2 +- .../banyandb/v1/client/auth/AuthInterceptor.java | 12 +++++++----- ...anyanDBAuthTest.java => ITBanyanDBAuthTest.java} | 13 ++++--------- 3 files changed, 12 insertions(+), 15 deletions(-) rename src/test/java/org/apache/skywalking/banyandb/v1/client/{BanyanDBAuthTest.java => ITBanyanDBAuthTest.java} (90%) diff --git a/src/main/java/org/apache/skywalking/banyandb/v1/client/BanyanDBClient.java b/src/main/java/org/apache/skywalking/banyandb/v1/client/BanyanDBClient.java index f6f70876..7d3ddd03 100644 --- a/src/main/java/org/apache/skywalking/banyandb/v1/client/BanyanDBClient.java +++ b/src/main/java/org/apache/skywalking/banyandb/v1/client/BanyanDBClient.java @@ -193,7 +193,7 @@ public void connect() throws IOException { String password = options.getPassword(); if (!"".equals(username) && !"".equals(password)) { interceptedChannel = ClientInterceptors.intercept(rawChannel, - new AuthInterceptor(options.getUsername(), options.getPassword())); + new AuthInterceptor(username, password)); } // Ensure this.channel is assigned only once. this.channel = interceptedChannel; diff --git a/src/main/java/org/apache/skywalking/banyandb/v1/client/auth/AuthInterceptor.java b/src/main/java/org/apache/skywalking/banyandb/v1/client/auth/AuthInterceptor.java index 52d0d742..85b31902 100644 --- a/src/main/java/org/apache/skywalking/banyandb/v1/client/auth/AuthInterceptor.java +++ b/src/main/java/org/apache/skywalking/banyandb/v1/client/auth/AuthInterceptor.java @@ -30,6 +30,11 @@ public class AuthInterceptor implements ClientInterceptor { private final String username; private final String password; + private static final Metadata.Key USERNAME_KEY = + Metadata.Key.of("username", Metadata.ASCII_STRING_MARSHALLER); + private static final Metadata.Key PASSWORD_KEY = + Metadata.Key.of("password", Metadata.ASCII_STRING_MARSHALLER); + public AuthInterceptor(String username, String password) { this.username = username; this.password = password; @@ -45,11 +50,8 @@ public ClientCall interceptCall( next.newCall(method, callOptions)) { @Override public void start(Listener responseListener, Metadata headers) { - Metadata.Key usernameKey = Metadata.Key.of("username", Metadata.ASCII_STRING_MARSHALLER); - Metadata.Key passwordKey = Metadata.Key.of("password", Metadata.ASCII_STRING_MARSHALLER); - - headers.put(usernameKey, username); - headers.put(passwordKey, password); + headers.put(USERNAME_KEY, username); + headers.put(PASSWORD_KEY, password); super.start(responseListener, headers); } diff --git a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java b/src/test/java/org/apache/skywalking/banyandb/v1/client/ITBanyanDBAuthTest.java similarity index 90% rename from src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java rename to src/test/java/org/apache/skywalking/banyandb/v1/client/ITBanyanDBAuthTest.java index ccba393e..73c59d84 100644 --- a/src/test/java/org/apache/skywalking/banyandb/v1/client/BanyanDBAuthTest.java +++ b/src/test/java/org/apache/skywalking/banyandb/v1/client/ITBanyanDBAuthTest.java @@ -33,14 +33,13 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.PosixFilePermissions; -import java.util.Base64; import java.util.List; import java.util.concurrent.TimeUnit; import static org.awaitility.Awaitility.await; import static org.junit.Assert.assertThrows; -public class BanyanDBAuthTest { +public class ITBanyanDBAuthTest { private static final String REGISTRY = "ghcr.io"; private static final String IMAGE_NAME = "apache/skywalking-banyandb"; private static final String TAG = "42ec9df7457868926eb80157b36355d94fcd6bba"; @@ -53,7 +52,7 @@ public class BanyanDBAuthTest { @Rule public GenericContainer banyanDB; - public BanyanDBAuthTest() throws Exception { + public ITBanyanDBAuthTest() throws Exception { // Step 1: prepare config file with 0600 permissions Path tempConfigPath = Files.createTempFile("bydb_server_config", ".yaml"); Files.write(tempConfigPath, Files.readAllBytes( @@ -68,14 +67,10 @@ public BanyanDBAuthTest() throws Exception { "/tmp/bydb_server_config.yaml" ) .withCommand("standalone", - "--auth-config-file", "/tmp/bydb_server_config.yaml", - "--enable-health-auth", "true" + "--auth-config-file", "/tmp/bydb_server_config.yaml" ) .withExposedPorts(GRPC_PORT, HTTP_PORT) - .waitingFor(Wait.forHttp("/api/healthz") - .withHeader("Authorization", - "Basic " + Base64.getEncoder().encodeToString("admin:123456".getBytes())) - .forPort(HTTP_PORT)); + .waitingFor(Wait.forHttp("/api/healthz").forPort(HTTP_PORT)); } @Test From b36cfb5096ca3caa6f08d2f1e4de93c9139fd365 Mon Sep 17 00:00:00 2001 From: OmCheeLin <19563671928@163.com> Date: Tue, 12 Aug 2025 10:44:05 +0800 Subject: [PATCH 16/16] update doc --- CHANGES.md | 1 + README.md | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index d5f8c495..c5cb6fe4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,7 @@ Release Notes. * Bump up the API to support sharding_key. * Bump up the API to support version 0.9. * Support stage query on TopN. +* Support auth with username and password. 0.8.0 ------------------ diff --git a/README.md b/README.md index af6c62ad..b8161b98 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,10 @@ options are listed below, | forceReconnectionThreshold | Threshold of force gRPC reconnection if network issue is encountered | 1 | | forceTLS | Force use TLS for gRPC | false | | sslTrustCAPath | SSL: Trusted CA Path | | +| sslCertChainPath | SSL: Cert Chain Path, BanyanDB server not support mTLS yet | | +| sslKeyPath | SSL: Cert Key Path, BanyanDB server not support mTLS yet | | +| username | Basic Auth: username of BanyanDB server | | +| password | Basic Auth: password of BanyanDB server | | ## Schema Management