Skip to content

Commit f300e59

Browse files
authored
ClickHouseIO - Improve user agent (#37815)
* product name is deprecated, changing to client name * create a share method + append external client name * add unittests and rename original test file to IT * reuse the same properties * add user agent logic to the generated documentation * fix query log targeted column * add integration test to verify user agent is correct * make sure integration tests are included * move IT out of test task
1 parent 621354f commit f300e59

File tree

5 files changed

+581
-464
lines changed

5 files changed

+581
-464
lines changed

.github/workflows/beam_PreCommit_Java_Clickhouse_IO_Direct.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,13 @@ jobs:
9292
arguments: |
9393
-PdisableSpotlessCheck=true \
9494
-PdisableCheckStyle=true \
95+
- name: run Clickhouse IO IT script
96+
uses: ./.github/actions/gradle-command-self-hosted-action
97+
with:
98+
gradle-command: :sdks:java:io:clickhouse:integrationTest
99+
arguments: |
100+
-PdisableSpotlessCheck=true \
101+
-PdisableCheckStyle=true \
95102
- name: Archive JUnit Test Results
96103
uses: actions/upload-artifact@v4
97104
if: ${{ !success() }}

sdks/java/io/clickhouse/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ applyJavaNature(
2929
// javacc generated code produces lint warnings
3030
disableLintWarnings: ['dep-ann'],
3131
)
32+
provideIntegrationTestingDependencies()
33+
enableJavaPerformanceTesting()
3234

3335
description = "Apache Beam :: SDKs :: Java :: IO :: ClickHouse"
3436
ext.summary = "IO to write to ClickHouse (https://clickhouse.com)."

sdks/java/io/clickhouse/src/main/java/org/apache/beam/sdk/io/clickhouse/ClickHouseIO.java

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,18 @@
107107
* href="https://clickhouse.com/docs/guides/developer/deduplication">Deduplication strategies
108108
* documentation</a>
109109
*
110+
* <h4>User agent</h4>
111+
*
112+
* <p>The connector automatically sets the ClickHouse client name to {@code Apache Beam/<version>},
113+
* which is visible in {@code system.query_log.client_name}. If you set the {@code client_name}
114+
* connection property, it is appended after the Beam identifier, for example:
115+
*
116+
* <pre>{@code
117+
* Properties props = new Properties();
118+
* props.setProperty("client_name", "MyApp/1.0");
119+
* // Results in: "Apache Beam/<version> MyApp/1.0"
120+
* }</pre>
121+
*
110122
* <h4>Mapping between Beam and ClickHouse types</h4>
111123
*
112124
* <table summary="Type mapping">
@@ -244,21 +256,19 @@ public abstract static class Write<T> extends PTransform<PCollection<T>, PDone>
244256

245257
@Override
246258
public PDone expand(PCollection<T> input) {
259+
260+
Properties properties = properties();
261+
set(properties, "client_name", buildClientName(properties));
262+
247263
TableSchema tableSchema = tableSchema();
248264
if (tableSchema == null) {
249-
tableSchema = getTableSchema(clickHouseUrl(), database(), table(), properties());
265+
tableSchema = getTableSchema(clickHouseUrl(), database(), table(), properties);
250266
}
251267

252-
String sdkVersion = ReleaseInfo.getReleaseInfo().getSdkVersion();
253-
String userAgent = String.format("Apache Beam/%s", sdkVersion);
254-
255-
Properties properties = properties();
256-
257268
set(properties, "max_insert_block_size", maxInsertBlockSize());
258269
set(properties, "insert_quorum", insertQuorum());
259270
set(properties, "insert_distributed_sync", insertDistributedSync());
260271
set(properties, "insert_deduplication", insertDeduplicate());
261-
set(properties, "product_name", userAgent);
262272

263273
WriteFn<T> fn =
264274
new AutoValue_ClickHouseIO_WriteFn.Builder<T>()
@@ -526,8 +536,7 @@ public void setup() throws Exception {
526536
.setPassword(password)
527537
.setDefaultDatabase(database())
528538
.setOptions(options)
529-
.setClientName(
530-
String.format("Apache Beam/%s", ReleaseInfo.getReleaseInfo().getSdkVersion()));
539+
.setClientName(properties().getProperty("client_name"));
531540

532541
// Add optional compression if specified in properties
533542
String compress = properties().getProperty("compress", "false");
@@ -725,8 +734,7 @@ public static TableSchema getTableSchema(
725734
.setUsername(user)
726735
.setPassword(password)
727736
.setDefaultDatabase(database)
728-
.setClientName(
729-
String.format("Apache Beam/%s", ReleaseInfo.getReleaseInfo().getSdkVersion()));
737+
.setClientName(buildClientName(properties));
730738

731739
try (Client client = clientBuilder.build()) {
732740
String query = "DESCRIBE TABLE " + quoteIdentifier(table);
@@ -766,6 +774,17 @@ public static TableSchema getTableSchema(
766774
}
767775
}
768776

777+
@VisibleForTesting
778+
static String buildClientName(Properties properties) {
779+
String beamAgent =
780+
String.format("Apache Beam/%s", ReleaseInfo.getReleaseInfo().getSdkVersion());
781+
String existingClientName = properties.getProperty("client_name");
782+
if (!Strings.isNullOrEmpty(existingClientName)) {
783+
return beamAgent + " " + existingClientName;
784+
}
785+
return beamAgent;
786+
}
787+
769788
static String quoteIdentifier(String identifier) {
770789
String backslash = "\\\\";
771790
String quote = "\"";

0 commit comments

Comments
 (0)