From 7dd7e4b59849492310fc42a1a437fdc71d9c04b3 Mon Sep 17 00:00:00 2001 From: karel rehor Date: Wed, 18 Dec 2024 17:15:20 +0100 Subject: [PATCH 1/5] docs: (WIP) updates onboarding steps for the influxdb3-java client. --- .../components/steps/java/ExecuteQuerySql.tsx | 116 +++++++++++++++--- .../steps/java/InitializeClientSql.tsx | 4 +- .../steps/java/InstallDependenciesSql.tsx | 10 +- .../components/steps/java/WriteDataSql.tsx | 92 +++++++++----- 4 files changed, 170 insertions(+), 52 deletions(-) diff --git a/src/homepageExperience/components/steps/java/ExecuteQuerySql.tsx b/src/homepageExperience/components/steps/java/ExecuteQuerySql.tsx index be91f98c1f..6d2b352310 100644 --- a/src/homepageExperience/components/steps/java/ExecuteQuerySql.tsx +++ b/src/homepageExperience/components/steps/java/ExecuteQuerySql.tsx @@ -19,29 +19,97 @@ FROM 'census' WHERE time >= now() - interval '1 hour' AND ('bees' IS NOT NULL OR 'ants' IS NOT NULL) order by time asc` - const query = `String sql = "SELECT * " + - "FROM 'census' " + - "WHERE time >= now() - interval '1 hour' " + - "AND ('bees' IS NOT NULL OR 'ants' IS NOT NULL) order by time asc"; + const query = ` String sql = "SELECT * " + + "FROM 'census' " + + "WHERE time >= now() - interval '5 minutes' " + + "AND ('$species1' IS NOT NULL OR '$species2' IS NOT NULL) order by time asc"; -System.out.printf("| %-5s | %-5s | %-8s | %-30s |%n", "ants", "bees", "location", "time"); -try (Stream stream = client.query(sql, new QueryOptions("${bucket}", QueryType.SQL))) { - stream.forEach(row -> System.out.printf("| %-5s | %-5s | %-8s | %-30s |%n", row[0], row[1], row[2], row[3])); -} + System.out.printf("| %-5s | %-5s | %-8s | %-30s |%n", "ants", "bees", "location", "time"); + + try (Stream ps = client.queryPoints(sql, + Map.of( + "species1", "bees", + "species2", "ants"), // Set Query Parameters + new QueryOptions("${bucket}", QueryType.SQL))) { // Set Query Options + ps.forEach(pv -> + System.out.printf("| %-5s | %-5s | %-8s | %-30s |%n", + IntOrDefault(pv, "ants", 0), + IntOrDefault(pv,"bees", 0), + pv.getTag("location"), + InstantTime(pv, Instant.ofEpochSecond(0)))); + } ` const queryPreview = `| ants | bees | location | time | -| null | 23 | Klamath | 2023-06-02T10:21:21.083529279 | -| 30 | null | Portland | 2023-06-02T10:21:22.276295461 | -| null | 28 | Klamath | 2023-06-02T10:21:23.462901032 | -| 32 | null | Portland | 2023-06-02T10:21:24.608998154 | -| null | 29 | Klamath | 2023-06-02T10:21:25.762346305 | -| 40 | null | Portland | 2023-06-02T10:21:26.901005154 | +| 0 | 23 | Klamath | 2024-12-18T15:58:07.275779579Z | +| 30 | 0 | Portland | 2024-12-18T15:58:08.275779579Z | +| 0 | 28 | Klamath | 2024-12-18T15:58:09.275779579Z | +| 32 | 0 | Portland | 2024-12-18T15:58:10.275779579Z | +| 0 | 29 | Klamath | 2024-12-18T15:58:11.275779579Z | +| 40 | 0 | Portland | 2024-12-18T15:58:12.275779579Z | +` + + const staticHelpers = ` private static long IntOrDefault(final PointValues pointValues, + final String key, + final long defaultValue){ + Long result = pointValues.getIntegerField(key); + return result == null ? defaultValue : result; + } + + private static Instant InstantTime(final PointValues pointValues, + final Instant replacement){ + Number raw = pointValues.getTimestamp(); + if(raw == null) { + if (replacement == null){ + return Instant.ofEpochSecond(0); + } + return replacement; + } + long stamp = raw.longValue(); + long sec = stamp / 1000000000; + long nanos = stamp % 1000000000; + return Instant.ofEpochSecond(sec, nanos); + } ` return ( <>

Execute a SQL Query

+

The query transport makes use of Apache Arrow Flight to + shorten processing time. When executing queries Arrow needs + access to internal JVM resources. This means setting the + following JVM argument: --add-opens=java.base/java.nio=ALL-UNNAMED

+

Java

+

With straightforward Java this can be done with an + environment variable:

+ +

Maven

+

This argument can also be added to MAVEN_OPTS:

+ +

Gradle

+

With gradle this can be added to the build file, e.g. in build.gradle.kts:

+ +

Now let's query the data we wrote into the database with SQL. Here is what our query looks like on its own: @@ -56,12 +124,26 @@ try (Stream stream = client.query(sql, new QueryOptions("${bucket}", Q In this query, we are looking for data points within the last 1 hour with a "census" measurement and either "bees" or "ants" fields.

+

The client API will pass through null values for mismatched or missing + tags, fields and timestamps. In anticipation of this possibility copy the + following static helper methods to the bottom of + the InfluxClientExample class.

+

- Let's use that SQL query in our Java code to show us the - results of what we have written. + Now let's use the model SQL query in our Java code + to show us the results of what we have written. Furthermore, let's use the SQL query + parameters feature of the client library to make query calls more + dynamic.

- Add the following code to the WriteQueryExample class: + The following code replaces the fixed values of "bees" and "ants" + with the parameters $species1 and $species2. + Add it to the InfluxClientExample class after the + write code added in the previous step:

diff --git a/src/homepageExperience/components/steps/java/InitializeClientSql.tsx b/src/homepageExperience/components/steps/java/InitializeClientSql.tsx index b6850341eb..98515047c6 100644 --- a/src/homepageExperience/components/steps/java/InitializeClientSql.tsx +++ b/src/homepageExperience/components/steps/java/InitializeClientSql.tsx @@ -20,12 +20,12 @@ import java.time.Instant; import java.util.stream.Stream; import com.influxdb.v3.client.InfluxDBClient; +import com.influxdb.v3.client.Point; import com.influxdb.v3.client.query.QueryOptions; import com.influxdb.v3.client.query.QueryType; -import com.influxdb.v3.client.write.Point; import com.influxdb.v3.client.write.WriteOptions; -public final class WriteQueryExample { +public final class InfluxClientExample { public static void main(final String[] args) throws Exception { String hostUrl = "${url}"; diff --git a/src/homepageExperience/components/steps/java/InstallDependenciesSql.tsx b/src/homepageExperience/components/steps/java/InstallDependenciesSql.tsx index 2bfc5857cd..2eaac9c664 100644 --- a/src/homepageExperience/components/steps/java/InstallDependenciesSql.tsx +++ b/src/homepageExperience/components/steps/java/InstallDependenciesSql.tsx @@ -10,12 +10,12 @@ export const InstallDependenciesSql: FC = () => { } const mavenDependency = ` - com.influxdb - influxdb3-java - 0.2.0 -` + com.influxdb + influxdb3-java + 1.0.0 + ` const gradleDependency = `dependencies { - implementation "com.influxdb:influxdb3-java:0.2.0" + implementation("com.influxdb:influxdb3-java:1.0.0") }` return ( <> diff --git a/src/homepageExperience/components/steps/java/WriteDataSql.tsx b/src/homepageExperience/components/steps/java/WriteDataSql.tsx index 29b4b062dc..09b5b7aee4 100644 --- a/src/homepageExperience/components/steps/java/WriteDataSql.tsx +++ b/src/homepageExperience/components/steps/java/WriteDataSql.tsx @@ -49,36 +49,57 @@ export const WriteDataSqlComponent = (props: OwnProps) => { onSelectBucket(bucket.name) }, [bucket, onSelectBucket]) - const codeSnippet = `String database = "${bucket.name}"; + const internalClass = ` static class CensusRecord { + String location; + String species; + int count; -Point[] points = new Point[] { - Point.measurement("census") - .addTag("location", "Klamath") - .addField("bees", 23), - Point.measurement("census") - .addTag("location", "Portland") - .addField("ants", 30), - Point.measurement("census") - .addTag("location", "Klamath") - .addField("bees", 28), - Point.measurement("census") - .addTag("location", "Portland") - .addField("ants", 32), - Point.measurement("census") - .addTag("location", "Klamath") - .addField("bees", 29), - Point.measurement("census") - .addTag("location", "Portland") - .addField("ants", 40) -}; + public CensusRecord(String location, String species, int count) { + this.location = location; + this.species = species; + this.count = count; + } -for (Point point : points) { - client.writePoint(point, new WriteOptions.Builder().database(database).build()); - - Thread.sleep(1000); // separate points by 1 second -} + public String getLocation() { + return location; + } + + public String getSpecies() { + return species; + } + + public int getCount() { + return count; + } + }` + + const dataPrep = `String database = "${bucket.name}" + + List records = Arrays.asList( + new CensusRecord("Klamath", "bees", 23), + new CensusRecord("Portland", "ants", 30), + new CensusRecord("Klamath", "bees", 28), + new CensusRecord("Portland", "ants", 32), + new CensusRecord("Klamath", "bees", 29), + new CensusRecord("Portland", "ants", 40) + ); + + List points = new ArrayList<>(); + + Instant stamp = Instant.now().minusSeconds(records.size()); + + for (CensusRecord record : records) { + points.add(Point.measurement("census") + .setTag("location", record.getLocation()) + .setIntegerField(record.getSpecies(), record.getCount()) + .setTimestamp(stamp) + ); + stamp = stamp.plusSeconds(1); + }` -System.out.println("Complete. Return to the InfluxDB UI."); + const codeSnippet = ` client.writePoints(points, new WriteOptions.Builder().database(database).build()); + + System.out.println("Complete. Return to the InfluxDB UI."); ` return ( @@ -238,8 +259,23 @@ System.out.println("Complete. Return to the InfluxDB UI."); These concepts are important in building your time-series schema. Now, let's write this data into our bucket.

+

First, add the following internal class to the + InfluxClientExample above the main method:

+ +

Then, copy the following data preparation statements, into + the main method above the try(InfluxDBClient ...) block:

+

- Add the following code to the WriteQueryExample class: + Finally, add the following + code within the try(InfluxDBClient ...) block:

Date: Mon, 6 Jan 2025 16:42:57 +0100 Subject: [PATCH 2/5] chore: dry run onboarding java. Add missing semi-colon. Minor edit. --- .../components/steps/java/ExecuteQuerySql.tsx | 2 +- src/homepageExperience/components/steps/java/WriteDataSql.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/homepageExperience/components/steps/java/ExecuteQuerySql.tsx b/src/homepageExperience/components/steps/java/ExecuteQuerySql.tsx index 6d2b352310..5cefdb3b73 100644 --- a/src/homepageExperience/components/steps/java/ExecuteQuerySql.tsx +++ b/src/homepageExperience/components/steps/java/ExecuteQuerySql.tsx @@ -126,7 +126,7 @@ application {

The client API will pass through null values for mismatched or missing tags, fields and timestamps. In anticipation of this possibility copy the - following static helper methods to the bottom of + following static helper methods to the bottom of the InfluxClientExample class.

{ } }` - const dataPrep = `String database = "${bucket.name}" + const dataPrep = ` String database = "${bucket.name}"; List records = Arrays.asList( new CensusRecord("Klamath", "bees", 23), From 098de94f89476c62c39751cb9a250667249a9f4e Mon Sep 17 00:00:00 2001 From: karel rehor Date: Mon, 6 Jan 2025 16:58:58 +0100 Subject: [PATCH 3/5] chore: run prettier:fix --- .../components/steps/java/ExecuteQuerySql.tsx | 56 +++++++++++-------- .../components/steps/java/WriteDataSql.tsx | 24 +++++--- 2 files changed, 48 insertions(+), 32 deletions(-) diff --git a/src/homepageExperience/components/steps/java/ExecuteQuerySql.tsx b/src/homepageExperience/components/steps/java/ExecuteQuerySql.tsx index 5cefdb3b73..f3464a3ec5 100644 --- a/src/homepageExperience/components/steps/java/ExecuteQuerySql.tsx +++ b/src/homepageExperience/components/steps/java/ExecuteQuerySql.tsx @@ -75,21 +75,26 @@ AND ('bees' IS NOT NULL OR 'ants' IS NOT NULL) order by time asc` return ( <>

Execute a SQL Query

-

The query transport makes use of Apache Arrow Flight to - shorten processing time. When executing queries Arrow needs - access to internal JVM resources. This means setting the - following JVM argument: --add-opens=java.base/java.nio=ALL-UNNAMED

+

+ The query transport makes use of Apache Arrow Flight to shorten + processing time. When executing queries Arrow needs access to internal + JVM resources. This means setting the following JVM argument:{' '} + --add-opens=java.base/java.nio=ALL-UNNAMED +

Java

-

With straightforward Java this can be done with an - environment variable:

+

+ With straightforward Java this can be done with an environment variable: +

Maven

-

This argument can also be added to MAVEN_OPTS:

+

+ This argument can also be added to MAVEN_OPTS: +

Gradle

-

With gradle this can be added to the build file, e.g. in build.gradle.kts:

+

+ With gradle this can be added to the build file, e.g. in{' '} + build.gradle.kts: +

-

The client API will pass through null values for mismatched or missing - tags, fields and timestamps. In anticipation of this possibility copy the - following static helper methods to the bottom of - the InfluxClientExample class.

+

+ The client API will pass through null values for mismatched or missing + tags, fields and timestamps. In anticipation of this possibility copy + the following static helper methods to the bottom of the{' '} + InfluxClientExample class. +

- Now let's use the model SQL query in our Java code - to show us the results of what we have written. Furthermore, let's use the SQL query - parameters feature of the client library to make query calls more + Now let's use the model SQL query in our Java code to show + us the results of what we have written. Furthermore, let's use the SQL + query parameters feature of the client library to make query calls more dynamic.

- The following code replaces the fixed values of "bees" and "ants" - with the parameters $species1 and $species2. - Add it to the InfluxClientExample class after the - write code added in the previous step: + The following code replaces the fixed values of "bees" and "ants" with + the parameters $species1 and $species2. Add it + to the InfluxClientExample class after the write + code added in the previous step:

diff --git a/src/homepageExperience/components/steps/java/WriteDataSql.tsx b/src/homepageExperience/components/steps/java/WriteDataSql.tsx index cbe34728f1..65fb142ed7 100644 --- a/src/homepageExperience/components/steps/java/WriteDataSql.tsx +++ b/src/homepageExperience/components/steps/java/WriteDataSql.tsx @@ -259,23 +259,29 @@ export const WriteDataSqlComponent = (props: OwnProps) => { These concepts are important in building your time-series schema. Now, let's write this data into our bucket.

-

First, add the following internal class to the - InfluxClientExample above the main method:

+

+ First, add the following internal class to the + InfluxClientExample above the main{' '} + method: +

-

Then, copy the following data preparation statements, into - the main method above the try(InfluxDBClient ...) block:

+

+ Then, copy the following data preparation statements, into the{' '} + main method above the{' '} + try(InfluxDBClient ...) block: +

- Finally, add the following - code within the try(InfluxDBClient ...) block: + Finally, add the following code within the{' '} + try(InfluxDBClient ...) block:

Date: Wed, 8 Jan 2025 10:28:26 +0100 Subject: [PATCH 4/5] docs: update wording of query requirements for Arrow. --- .../components/steps/java/ExecuteQuerySql.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/homepageExperience/components/steps/java/ExecuteQuerySql.tsx b/src/homepageExperience/components/steps/java/ExecuteQuerySql.tsx index f3464a3ec5..47ff74736b 100644 --- a/src/homepageExperience/components/steps/java/ExecuteQuerySql.tsx +++ b/src/homepageExperience/components/steps/java/ExecuteQuerySql.tsx @@ -78,12 +78,12 @@ AND ('bees' IS NOT NULL OR 'ants' IS NOT NULL) order by time asc`

The query transport makes use of Apache Arrow Flight to shorten processing time. When executing queries Arrow needs access to internal - JVM resources. This means setting the following JVM argument:{' '} + JVM resources. This requires setting the following JVM argument:{' '} --add-opens=java.base/java.nio=ALL-UNNAMED

Java

- With straightforward Java this can be done with an environment variable: + This can be done with an environment variable:

Date: Wed, 8 Jan 2025 10:40:52 +0100 Subject: [PATCH 5/5] chore: rerun linter --- .../components/steps/java/ExecuteQuerySql.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/homepageExperience/components/steps/java/ExecuteQuerySql.tsx b/src/homepageExperience/components/steps/java/ExecuteQuerySql.tsx index 47ff74736b..40ede60b22 100644 --- a/src/homepageExperience/components/steps/java/ExecuteQuerySql.tsx +++ b/src/homepageExperience/components/steps/java/ExecuteQuerySql.tsx @@ -82,9 +82,7 @@ AND ('bees' IS NOT NULL OR 'ants' IS NOT NULL) order by time asc` --add-opens=java.base/java.nio=ALL-UNNAMED

Java

-

- This can be done with an environment variable: -

+

This can be done with an environment variable: