diff --git a/examples/spring/pom.xml b/examples/spring/pom.xml new file mode 100644 index 00000000..ff1134b9 --- /dev/null +++ b/examples/spring/pom.xml @@ -0,0 +1,123 @@ + + + 4.0.0 + + com.influxdb.v3.spring + spring-example + 1.0-SNAPSHOT + spring-example + + + UTF-8 + 17 + 6.2.11 + org.influxdb.v3.Application + + + + + org.springframework + spring-context + ${spring.version} + + + org.springframework + spring-core + ${spring.version} + + + org.springframework + spring-aspects + ${spring.version} + + + org.springframework.retry + spring-retry + 2.0.12 + + + com.influxdb + influxdb3-java + 1.6.0-SNAPSHOT + + + ch.qos.logback + logback-classic + 1.5.20 + + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + + + java + + + + + ${exec.main} + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.10.1 + + 11 + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.2.1 + + true + ../../checkstyle.xml + true + false + + src/main/java + + + + + verify + + checkstyle + + + + + + + diff --git a/examples/spring/src/main/java/org/influxdb/v3/Application.java b/examples/spring/src/main/java/org/influxdb/v3/Application.java new file mode 100644 index 00000000..e16654e7 --- /dev/null +++ b/examples/spring/src/main/java/org/influxdb/v3/Application.java @@ -0,0 +1,109 @@ +/* + * The MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.influxdb.v3; + +import java.time.Duration; +import java.util.stream.Stream; +import javax.annotation.Nonnull; + +import org.influxdb.v3.config.AppConfig; +import org.influxdb.v3.reading.EnvReading; +import org.influxdb.v3.sensor.SensorCollection; +import org.influxdb.v3.service.PersistService; +import org.influxdb.v3.service.ReadingsService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.stereotype.Component; + +import com.influxdb.v3.client.PointValues; + +@Component +public final class Application { + + private Application() { } + + static Logger logger = LoggerFactory.getLogger(Application.class); + + public static void main(final String[] args) { + try (var ctx = new AnnotationConfigApplicationContext(AppConfig.class)) { + ctx.registerShutdownHook(); + + SensorCollection sensors = ctx.getBean(SensorCollection.class); + PersistService persistService = ctx.getBean(PersistService.class); + persistService.persistDataRandom(sensors, 1, Duration.ofMinutes(5)); + + ReadingsService readingsService = ctx.getBean(ReadingsService.class); + logger.info("==== [ Get as Point Values ] ===="); + /* + Be sure to use streams in try-with-resources blocks, failure to do so + may not close the underlying Arrow FlightStream properly, and + a memory leak can result. + */ + try (Stream stream = readingsService.getAllReadingsAsPV()) { + logPVStream(stream); + } + logger.info("==== [ Get as Mapped EnvReadings ] ===="); + try (Stream stream = readingsService.getAllReadings()) { + logEnvReadingStream(stream); + } + logger.info("==== [ Get as Object Array ] ===="); + try (Stream stream = readingsService.getAllReadingsAsObj()) { + logObjArrayStream(stream); + } + } + } + + public static void logPVStream(final @Nonnull Stream pvs) { + StringBuilder pvResults = new StringBuilder(); + pvs.forEach(pv -> { + pvResults.append(String.format("%s, ", pv.getTimestamp())); + pvResults.append(String.format("name: %s, ", pv.getTag(("name")))); + pvResults.append(String.format("model: %s, ", pv.getTag(("model")))); + pvResults.append(String.format("id: %s, ", pv.getTag(("id")))); + pvResults.append(String.format("temp: %3.2f ", pv.getFloatField(("temp")))); + pvResults.append(String.format("press: %3.2f ", pv.getFloatField(("press")))); + pvResults.append(String.format("humid: %3.2f ", pv.getFloatField(("humid")))); + pvResults.append("\n"); + }); + logger.info("PointValueResults:\n{}\n", pvResults); + } + + public static void logObjArrayStream(final @Nonnull Stream oas) { + StringBuilder results = new StringBuilder(); + oas.forEach(o -> { + for (int i = 0; i < o.length; i++) { + results.append(String.format("%s, ", o[i])); + } + results.append("\n"); + }); + logger.info("ObjectArrayStream results:\n{}\n", results); + } + + public static void logEnvReadingStream(final @Nonnull Stream evs) { + StringBuilder result = new StringBuilder(); + evs.forEach(point -> { + result.append(String.format("%s\n", point.toString())); + }); + logger.info(result.toString()); + } +} \ No newline at end of file diff --git a/examples/spring/src/main/java/org/influxdb/v3/config/AppConfig.java b/examples/spring/src/main/java/org/influxdb/v3/config/AppConfig.java new file mode 100644 index 00000000..b08d1073 --- /dev/null +++ b/examples/spring/src/main/java/org/influxdb/v3/config/AppConfig.java @@ -0,0 +1,101 @@ +/* + * The MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.influxdb.v3.config; + +import java.net.ConnectException; +import java.util.List; + +import org.apache.arrow.flight.FlightRuntimeException; +import org.influxdb.v3.sensor.Sensor; +import org.influxdb.v3.sensor.SensorCollection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.retry.annotation.EnableRetry; +import org.springframework.retry.support.RetryTemplate; + +import com.influxdb.v3.client.InfluxDBApiException; +import com.influxdb.v3.client.InfluxDBClient; + +@Configuration +@EnableRetry +@ComponentScan(basePackages = "org.influxdb.v3") +@PropertySource("classpath:application.properties") +public class AppConfig { + + Logger logger = LoggerFactory.getLogger(AppConfig.class); + + static List sensors = List.of(new Sensor("Able", "R2D2", "123"), + new Sensor("Baker", "C3PO", "456"), + new Sensor("Charlie", "Robbie", "789"), + new Sensor("Delta", "R2D2", "abc"), + new Sensor("Easy", "C3PO", "def") + ); + + @Value("${influxdb.url}") + private String influxDBUrl; + + @Value("${influxdb.token}") + private String influxDBToken; + + @Value("${influxdb.database}") + private String influxDBDatabase; + + @Bean(name = {"internalSensors"}) + public SensorCollection sensorCollectionInit() { + logger.debug("sensorCollection"); + return new SensorCollection(sensors); + } + + @Bean + public InfluxDBClient influxDBClient() { + logger.debug("influxDBClientBaseInit with " + influxDBUrl); + return InfluxDBClient.getInstance(influxDBUrl, influxDBToken.toCharArray(), influxDBDatabase); + } + + @Bean + @Qualifier("writesTemplate") + public RetryTemplate retryTemplateWrites() { + return RetryTemplate.builder() + .maxAttempts(5) + .exponentialBackoff(100, 2, 10000) + .retryOn(List.of(InfluxDBApiException.class, ConnectException.class)) + .traversingCauses() + .build(); + } + + @Bean + @Qualifier("readsTemplate") + public RetryTemplate retryTemplateReads() { + return RetryTemplate.builder() + .maxAttempts(3) + .exponentialBackoff(100, 2, 10000) + .retryOn(List.of(InfluxDBApiException.class, FlightRuntimeException.class, ConnectException.class)) + .traversingCauses() + .build(); + } +} diff --git a/examples/spring/src/main/java/org/influxdb/v3/reading/EnvReading.java b/examples/spring/src/main/java/org/influxdb/v3/reading/EnvReading.java new file mode 100644 index 00000000..bda41507 --- /dev/null +++ b/examples/spring/src/main/java/org/influxdb/v3/reading/EnvReading.java @@ -0,0 +1,78 @@ +/* + * The MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.influxdb.v3.reading; + +import java.time.Instant; +import javax.annotation.Nonnull; + +import org.influxdb.v3.sensor.Sensor; + +import com.influxdb.v3.client.Point; + +public class EnvReading { + + Sensor sensor; + double temperature; + double humidity; + double pressure; + Instant timestamp; + + public EnvReading(final @Nonnull Sensor sensor, + final double temperature, + final double humidity, + final double pressure) { + this.sensor = sensor; + this.temperature = temperature; + this.humidity = humidity; + this.pressure = pressure; + } + + public EnvReading(final @Nonnull Sensor sensor, + final double temperature, + final double humidity, + final double pressure, + final @Nonnull Instant timestamp) { + this.sensor = sensor; + this.temperature = temperature; + this.humidity = humidity; + this.pressure = pressure; + this.timestamp = timestamp; + } + + public Point toPoint(final String measurement, final @Nonnull Instant timestamp) { + if (this.timestamp == null) { + this.timestamp = timestamp; + } + return new Point(measurement) + .setTags(this.sensor.toTags()) + .setFloatField("temp", this.temperature) + .setFloatField("humid", this.humidity) + .setFloatField("press", this.pressure) + .setTimestamp(timestamp); + } + + @Override + public String toString() { + return String.format("sensor[%s] temp: %f3.3, humid: %f3.3, press: %f3.3, time: %s", + sensor, temperature, humidity, pressure, timestamp); + } +} diff --git a/examples/spring/src/main/java/org/influxdb/v3/reading/RandomEnvReading.java b/examples/spring/src/main/java/org/influxdb/v3/reading/RandomEnvReading.java new file mode 100644 index 00000000..6ee9f71c --- /dev/null +++ b/examples/spring/src/main/java/org/influxdb/v3/reading/RandomEnvReading.java @@ -0,0 +1,39 @@ +/* + * The MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.influxdb.v3.reading; + +import javax.annotation.Nonnull; + +import org.influxdb.v3.sensor.Sensor; + +public final class RandomEnvReading { + + private RandomEnvReading() { } + + public static EnvReading genReading(final @Nonnull Sensor sensor) { + return new EnvReading(sensor, + (Math.random() * 40.0) + (Math.random() * 40.0) - 20.0, + (Math.random() * 60) + (Math.random() * 40), + Math.random() * 8.0 + 26.0 + ); + } +} diff --git a/examples/spring/src/main/java/org/influxdb/v3/sensor/Sensor.java b/examples/spring/src/main/java/org/influxdb/v3/sensor/Sensor.java new file mode 100644 index 00000000..63443cb5 --- /dev/null +++ b/examples/spring/src/main/java/org/influxdb/v3/sensor/Sensor.java @@ -0,0 +1,48 @@ +/* + * The MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.influxdb.v3.sensor; + +import java.util.Map; + +public class Sensor { + + String name; + String model; + String id; + + public Sensor(final String name, + final String model, + final String id) { + this.name = name; + this.model = model; + this.id = id; + } + + public Map toTags() { + return Map.of("name", name, "model", model, "id", id); + } + + @Override + public String toString() { + return String.format("name: %s, model: %s, id: %s", name, model, id); + } +} diff --git a/examples/spring/src/main/java/org/influxdb/v3/sensor/SensorCollection.java b/examples/spring/src/main/java/org/influxdb/v3/sensor/SensorCollection.java new file mode 100644 index 00000000..13851d6b --- /dev/null +++ b/examples/spring/src/main/java/org/influxdb/v3/sensor/SensorCollection.java @@ -0,0 +1,45 @@ +/* + * The MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.influxdb.v3.sensor; + +import java.util.List; +import javax.annotation.Nonnull; + +import org.springframework.beans.factory.annotation.Autowired; + +public class SensorCollection { + + List sensors; + + @Autowired + public SensorCollection(final @Nonnull List sensors) { + this.sensors = sensors; + } + + public List getSensors() { + return sensors; + } + + public void setSensors(final @Nonnull List sensors) { + this.sensors = sensors; + } +} diff --git a/examples/spring/src/main/java/org/influxdb/v3/service/PersistService.java b/examples/spring/src/main/java/org/influxdb/v3/service/PersistService.java new file mode 100644 index 00000000..41474117 --- /dev/null +++ b/examples/spring/src/main/java/org/influxdb/v3/service/PersistService.java @@ -0,0 +1,84 @@ +/* + * The MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.influxdb.v3.service; + +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +import org.influxdb.v3.reading.RandomEnvReading; +import org.influxdb.v3.sensor.Sensor; +import org.influxdb.v3.sensor.SensorCollection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.retry.support.RetryTemplate; +import org.springframework.stereotype.Service; + +import com.influxdb.v3.client.InfluxDBClient; +import com.influxdb.v3.client.Point; + +@Service +public class PersistService { + + Logger logger = LoggerFactory.getLogger(PersistService.class); + + InfluxDBClient influxDBClientBase; + + @Value("${influxdb.measurement}") + String measurement; + + RetryTemplate retryTemplate; + + @Autowired + public PersistService(final InfluxDBClient influxDBClient, + final @Qualifier("writesTemplate")RetryTemplate retryTemplateWrites) { + this.influxDBClientBase = influxDBClient; + this.retryTemplate = retryTemplateWrites; + } + + public void persistDataRandom(final SensorCollection sensors, final int count, final Duration interval) { + + this.retryTemplate.execute(context -> { + logger.info("persistDataRandom " + count + " sensor sets at interval: " + interval); + logger.info("context {}", context); + Instant current = Instant.now().minus(Duration.ofMillis(count * interval.toMillis())); + Instant end = Instant.now(); + int currentCount = 0; + while (currentCount < count) { + List points = new ArrayList<>(); + for (Sensor sensor : sensors.getSensors()) { + Point reading = RandomEnvReading.genReading(sensor).toPoint(measurement, current); + points.add(reading); + logger.info("reading {}", reading.toLineProtocol()); + } + influxDBClientBase.writePoints(points); + current = current.plus(interval); + currentCount++; + } + return null; + }); + } +} diff --git a/examples/spring/src/main/java/org/influxdb/v3/service/ReadingsService.java b/examples/spring/src/main/java/org/influxdb/v3/service/ReadingsService.java new file mode 100644 index 00000000..51fb362a --- /dev/null +++ b/examples/spring/src/main/java/org/influxdb/v3/service/ReadingsService.java @@ -0,0 +1,100 @@ +/* + * The MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.influxdb.v3.service; + +import java.time.Instant; +import java.util.stream.Stream; +import javax.annotation.Nonnull; + +import org.influxdb.v3.reading.EnvReading; +import org.influxdb.v3.sensor.Sensor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.retry.support.RetryTemplate; +import org.springframework.stereotype.Service; + +import com.influxdb.v3.client.InfluxDBClient; +import com.influxdb.v3.client.PointValues; + +@Service +public class ReadingsService { + + Logger logger = LoggerFactory.getLogger(ReadingsService.class); + + @Value("${readings.query1}") + String query1; + + InfluxDBClient influxDBClientBase; + + RetryTemplate retryTemplate; + + @Autowired + public ReadingsService(final InfluxDBClient influxDBClient, + final @Qualifier("readsTemplate") RetryTemplate retryTemplateReads) { + logger.debug("instantiating ReadingsService"); + this.influxDBClientBase = influxDBClient; + this.retryTemplate = retryTemplateReads; + } + + public Stream getAllReadings() { + System.out.println("DEBUG query1 " + query1); + return this.retryTemplate.execute(context -> { + logger.info("getting all readings"); + logger.info("RetryContext {}", context); + return buildEnvReadings(influxDBClientBase.queryPoints(query1)); + }); + } + + public Stream getAllReadingsAsPV() { + return this.retryTemplate.execute(context -> { + logger.info("getting all readings as PointValues"); + logger.info("RetryContext {}", context); + return influxDBClientBase.queryPoints(query1); + }); + } + + public Stream getAllReadingsAsObj() { + return this.retryTemplate.execute(context -> { + logger.info("getting all readings as Object"); + logger.info("RetryContext {}", context); + return influxDBClientBase.query(query1); + }); + } + + Stream buildEnvReadings(final Stream pointValuesStream) { + return pointValuesStream.map(e -> { + double temp = e.getFloatField("temp") == null ? 0 : e.getFloatField("temp"); + double humid = e.getFloatField("humid") == null ? 0 : e.getFloatField("humid"); + double press = e.getFloatField("press") == null ? 0 : e.getFloatField("press"); + Number timestamp = e.getTimestamp() == null ? 0 : e.getTimestamp(); + return new EnvReading(new Sensor(e.getTag("name"), e.getTag("model"), e.getTag("id")), + temp, humid, press, parseTimestamp(timestamp)); + }); + } + + private static Instant parseTimestamp(final @Nonnull Number timestamp) { + return Instant.ofEpochMilli(timestamp.longValue() / 1_000_000); + } +} diff --git a/examples/spring/src/main/resources/application.properties b/examples/spring/src/main/resources/application.properties new file mode 100644 index 00000000..91e09a78 --- /dev/null +++ b/examples/spring/src/main/resources/application.properties @@ -0,0 +1,5 @@ +influxdb.url=http://localhost:8181/ +influxdb.token=my-token +influxdb.database=my-db +influxdb.measurement=springsensor +readings.query1=SELECT * FROM "${influxdb.measurement}" ORDER BY time DESC diff --git a/examples/spring/src/main/resources/logback.xml b/examples/spring/src/main/resources/logback.xml new file mode 100644 index 00000000..9f1204ad --- /dev/null +++ b/examples/spring/src/main/resources/logback.xml @@ -0,0 +1,18 @@ + + + + + + + + + %d{HH:mm:ss.SSS} %blue(%-5level) %magenta(%logger{36}) - %msg %n + + + + + + + + + diff --git a/pom.xml b/pom.xml index 70be09cb..bf950bc7 100644 --- a/pom.xml +++ b/pom.xml @@ -417,7 +417,7 @@ **/target/**, **/*.jar, **/.git/**, **/.*, **/*.png, **/*.iml, **/*.bolt, .idea/**, **/*nightly*/**, **/.m2/**, LICENSE, **/*.md, **/.github/**, license_header.txt, release.properties/, **/pom.xml.releaseBackup, **/pom.xml.tag, **/semantic.yml, - .circleci/config.yml, **/*.pem + .circleci/config.yml, **/*.pem, **/resources/*.properties, **/resources/*.xml