From 76c369dea1a3b7a7f36eaa9a90867c279012ba90 Mon Sep 17 00:00:00 2001 From: Pauline Date: Mon, 4 Mar 2024 17:07:04 +0000 Subject: [PATCH 01/15] Fix processing of sleep efficiency in FitbitSleepAvroConverter --- .../connect/rest/fitbit/converter/FitbitSleepAvroConverter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/converter/FitbitSleepAvroConverter.java b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/converter/FitbitSleepAvroConverter.java index c99e532a..89ea13f3 100644 --- a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/converter/FitbitSleepAvroConverter.java +++ b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/converter/FitbitSleepAvroConverter.java @@ -95,6 +95,7 @@ protected Stream processRecords( .flatMap(tryOrNull(s -> { Instant startTime = Instant.from(DATE_TIME_FORMAT.parse(s.get("startTime").asText())); boolean isStages = s.get("type") == null || s.get("type").asText().equals("stages"); + int efficiency = s.has("efficiency") ? s.get("efficiency").asInt() : null; // use an intermediate offset for all records but the last. Since the query time // depends only on the start time of a sleep stages group, this will reprocess the entire @@ -109,7 +110,6 @@ protected Stream processRecords( String dateTime = d.get("dateTime").asText(); int duration = d.get("seconds").asInt(); String level = d.get("level").asText(); - int efficiency = d.get("efficiency").asInt(); if (isStages) { sleep = new FitbitSleepStage( From 0c1da16f36d0084bf5ffea14978208a584791aeb Mon Sep 17 00:00:00 2001 From: Pauline Date: Tue, 5 Mar 2024 12:22:16 +0000 Subject: [PATCH 02/15] fix: hrv, breathing rate, and skin temp routes to limit to 30 days --- .../route/FitbitBreathingRateRoute.java | 21 +++++++++-------- ...tbitIntradayHeartRateVariabilityRoute.java | 23 ++++++++++--------- .../rest/fitbit/route/FitbitPollingRoute.java | 14 +++++++---- .../route/FitbitSkinTemperatureRoute.java | 21 +++++++++-------- 4 files changed, 43 insertions(+), 36 deletions(-) diff --git a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitBreathingRateRoute.java b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitBreathingRateRoute.java index b355ff19..56c85c24 100644 --- a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitBreathingRateRoute.java +++ b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitBreathingRateRoute.java @@ -23,16 +23,15 @@ import org.radarbase.connect.rest.fitbit.request.FitbitRestRequest; import org.radarbase.connect.rest.fitbit.user.User; import org.radarbase.connect.rest.fitbit.user.UserRepository; -import org.radarbase.connect.rest.fitbit.util.DateRange; -import java.time.ZonedDateTime; import java.util.stream.Stream; -import static java.time.ZoneOffset.UTC; import static java.time.temporal.ChronoUnit.SECONDS; +import java.time.Duration; public class FitbitBreathingRateRoute extends FitbitPollingRoute { private final FitbitBreathingRateAvroConverter converter; + protected static final Duration REQUEST_INTERVAL = Duration.ofDays(30); public FitbitBreathingRateRoute(FitbitRequestGenerator generator, UserRepository userRepository, AvroData avroData) { @@ -46,16 +45,18 @@ protected String getUrlFormat(String baseUrl) { } protected Stream createRequests(User user) { - ZonedDateTime startDate = this.getOffset(user).plus(ONE_SECOND) - .atZone(UTC) - .truncatedTo(SECONDS); - ZonedDateTime now = ZonedDateTime.now(UTC); - return Stream.of(newRequest(user, new DateRange(startDate, now), - user.getExternalUserId(), DATE_FORMAT.format(startDate), DATE_FORMAT.format(now))); + return startDateGenerator(getOffset(user).plus(ONE_SECOND).truncatedTo(SECONDS)) + .map(dateRange -> newRequest(user, dateRange, + user.getExternalUserId(), DATE_FORMAT.format(dateRange.start()))); + } + + @Override + Duration getDateRangeInterval() { + return REQUEST_INTERVAL; } @Override public FitbitBreathingRateAvroConverter converter() { return converter; } -} +} \ No newline at end of file diff --git a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitIntradayHeartRateVariabilityRoute.java b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitIntradayHeartRateVariabilityRoute.java index 1106a342..a1f4e3bc 100644 --- a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitIntradayHeartRateVariabilityRoute.java +++ b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitIntradayHeartRateVariabilityRoute.java @@ -18,22 +18,21 @@ package org.radarbase.connect.rest.fitbit.route; import io.confluent.connect.avro.AvroData; -import org.radarbase.connect.rest.fitbit.converter.FitbitIntradayHeartRateAvroConverter; import org.radarbase.connect.rest.fitbit.converter.FitbitIntradayHeartRateVariabilityAvroConverter; import org.radarbase.connect.rest.fitbit.request.FitbitRequestGenerator; import org.radarbase.connect.rest.fitbit.request.FitbitRestRequest; import org.radarbase.connect.rest.fitbit.user.User; import org.radarbase.connect.rest.fitbit.user.UserRepository; -import org.radarbase.connect.rest.fitbit.util.DateRange; -import java.time.ZonedDateTime; import java.util.stream.Stream; -import static java.time.ZoneOffset.UTC; import static java.time.temporal.ChronoUnit.SECONDS; +import java.time.Duration; + public class FitbitIntradayHeartRateVariabilityRoute extends FitbitPollingRoute { private final FitbitIntradayHeartRateVariabilityAvroConverter converter; + protected static final Duration REQUEST_INTERVAL = Duration.ofDays(30); public FitbitIntradayHeartRateVariabilityRoute(FitbitRequestGenerator generator, UserRepository userRepository, AvroData avroData) { @@ -47,16 +46,18 @@ protected String getUrlFormat(String baseUrl) { } protected Stream createRequests(User user) { - ZonedDateTime startDate = this.getOffset(user).plus(ONE_SECOND) - .atZone(UTC) - .truncatedTo(SECONDS); - ZonedDateTime now = ZonedDateTime.now(UTC); - return Stream.of(newRequest(user, new DateRange(startDate, now), - user.getExternalUserId(), DATE_FORMAT.format(startDate), DATE_FORMAT.format(now))); + return startDateGenerator(getOffset(user).plus(ONE_SECOND).truncatedTo(SECONDS)) + .map(dateRange -> newRequest(user, dateRange, + user.getExternalUserId(), DATE_FORMAT.format(dateRange.start()))); + } + + @Override + Duration getDateRangeInterval() { + return REQUEST_INTERVAL; } @Override public FitbitIntradayHeartRateVariabilityAvroConverter converter() { return converter; } -} +} \ No newline at end of file diff --git a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitPollingRoute.java b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitPollingRoute.java index 5f9905c8..8d8bb35d 100644 --- a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitPollingRoute.java +++ b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitPollingRoute.java @@ -326,7 +326,7 @@ private TemporalAmount getEndDateThreshold() { } /** - * Generate one date per day, using UTC time zone. The first date will have the time from the + * Generate one date per day (or specified rangeInterval), using UTC time zone. The first date will have the time from the * given startDate. Following time stamps will start at 00:00. This will not up to the date of * {@link #getLookbackTime()} (exclusive). */ @@ -345,12 +345,12 @@ Stream startDateGenerator(Instant startDate) { return Stream.empty(); } } else { - long numElements = DAYS.between(startDate, lookBack); + Duration rangeInterval = getDateRangeInterval(); Stream elements = Stream - .iterate(dateTime, t -> t.plus(ONE_DAY).truncatedTo(DAYS)) - .limit(numElements) - .map(s -> new DateRange(s, s.plus(ONE_DAY).truncatedTo(DAYS).minus(ONE_NANO))); + .iterate(dateTime, t -> t.plus(rangeInterval).truncatedTo(DAYS)) + .takeWhile(u -> u.isBefore(lookBackDateStart)) + .map(s -> new DateRange(s, s.plus(rangeInterval).truncatedTo(DAYS).minus(ONE_NANO))); // we're polling at exactly 00:00, should not poll the last date if (lookBackDateStart.equals(lookBackDate)) { @@ -362,4 +362,8 @@ Stream startDateGenerator(Instant startDate) { } } } + + Duration getDateRangeInterval() { + return ONE_DAY; + } } diff --git a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitSkinTemperatureRoute.java b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitSkinTemperatureRoute.java index 2fc921e1..9ac3676c 100644 --- a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitSkinTemperatureRoute.java +++ b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitSkinTemperatureRoute.java @@ -23,16 +23,15 @@ import org.radarbase.connect.rest.fitbit.request.FitbitRestRequest; import org.radarbase.connect.rest.fitbit.user.User; import org.radarbase.connect.rest.fitbit.user.UserRepository; -import org.radarbase.connect.rest.fitbit.util.DateRange; -import java.time.ZonedDateTime; import java.util.stream.Stream; -import static java.time.ZoneOffset.UTC; import static java.time.temporal.ChronoUnit.SECONDS; +import java.time.Duration; public class FitbitSkinTemperatureRoute extends FitbitPollingRoute { private final FitbitSkinTemperatureAvroConverter converter; + protected static final Duration REQUEST_INTERVAL = Duration.ofDays(30); public FitbitSkinTemperatureRoute(FitbitRequestGenerator generator, UserRepository userRepository, AvroData avroData) { @@ -46,16 +45,18 @@ protected String getUrlFormat(String baseUrl) { } protected Stream createRequests(User user) { - ZonedDateTime startDate = this.getOffset(user).plus(ONE_SECOND) - .atZone(UTC) - .truncatedTo(SECONDS); - ZonedDateTime now = ZonedDateTime.now(UTC); - return Stream.of(newRequest(user, new DateRange(startDate, now), - user.getExternalUserId(), DATE_FORMAT.format(startDate), DATE_FORMAT.format(now))); + return startDateGenerator(getOffset(user).plus(ONE_SECOND).truncatedTo(SECONDS)) + .map(dateRange -> newRequest(user, dateRange, + user.getExternalUserId(), DATE_FORMAT.format(dateRange.start()))); + } + + @Override + Duration getDateRangeInterval() { + return REQUEST_INTERVAL; } @Override public FitbitSkinTemperatureAvroConverter converter() { return converter; } -} +} \ No newline at end of file From ce7df98d6ce640a052821d338c3de1e8207f10f6 Mon Sep 17 00:00:00 2001 From: Pauline Date: Tue, 5 Mar 2024 14:10:57 +0000 Subject: [PATCH 03/15] Add Fitbit spo2 route and converter --- .../FitbitRestSourceConnectorConfig.java | 20 +++++ .../FitbitIntradaySpo2AvroConverter.java | 79 +++++++++++++++++++ .../fitbit/route/FitbitIntradaySpo2Route.java | 63 +++++++++++++++ 3 files changed, 162 insertions(+) create mode 100644 kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/converter/FitbitIntradaySpo2AvroConverter.java create mode 100644 kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitIntradaySpo2Route.java diff --git a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/FitbitRestSourceConnectorConfig.java b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/FitbitRestSourceConnectorConfig.java index ceafad5a..5d3f1f9b 100644 --- a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/FitbitRestSourceConnectorConfig.java +++ b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/FitbitRestSourceConnectorConfig.java @@ -106,6 +106,11 @@ public class FitbitRestSourceConnectorConfig extends RestSourceConnectorConfig { private static final String FITBIT_INTRADAY_HEART_RATE_VARIABILITY_TOPIC_DISPLAY = "Intraday heart rate variability topic"; private static final String FITBIT_INTRADAY_HEART_RATE_VARIABILITY_TOPIC_DEFAULT = "connect_fitbit_intraday_heart_rate_variability"; + private static final String FITBIT_INTRADAY_SPO2_TOPIC_CONFIG = "fitbit.intraday.spo2.topic"; + private static final String FITBIT_INTRADAY_SPO2_TOPIC_DOC = "Topic for Fitbit intraday intraday_spo2"; + private static final String FITBIT_INTRADAY_SPO2_TOPIC_DISPLAY = "Intraday spo2 topic"; + private static final String FITBIT_INTRADAY_SPO2_TOPIC_DEFAULT = "connect_fitbit_intraday_spo2"; + private static final String FITBIT_BREATHING_RATE_TOPIC_CONFIG = "fitbit.breathing.rate.topic"; private static final String FITBIT_BREATHING_RATE_TOPIC_DOC = "Topic for Fitbit breathing rate"; private static final String FITBIT_BREATHING_RATE_TOPIC_DISPLAY = "Breathing rate topic"; @@ -343,6 +348,17 @@ public String toString() { Width.SHORT, FITBIT_INTRADAY_HEART_RATE_VARIABILITY_TOPIC_DISPLAY) + .define(FITBIT_INTRADAY_SPO2_TOPIC_CONFIG, + Type.STRING, + FITBIT_INTRADAY_SPO2_TOPIC_DEFAULT, + nonControlChar, + Importance.LOW, + FITBIT_INTRADAY_SPO2_TOPIC_DOC, + group, + ++orderInGroup, + Width.SHORT, + FITBIT_INTRADAY_SPO2_TOPIC_DISPLAY) + .define(FITBIT_BREATHING_RATE_TOPIC_CONFIG, Type.STRING, FITBIT_BREATHING_RATE_TOPIC_DEFAULT, @@ -511,6 +527,10 @@ public String getFitbitIntradayHeartRateVariabilityTopic() { return getString(FITBIT_INTRADAY_HEART_RATE_VARIABILITY_TOPIC_CONFIG); } + public String getFitbitIntradaySpo2Topic() { + return getString(FITBIT_INTRADAY_SPO2_TOPIC_CONFIG); + } + public String getFitbitBreathingRateTopic() { return getString(FITBIT_BREATHING_RATE_TOPIC_CONFIG); } diff --git a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/converter/FitbitIntradaySpo2AvroConverter.java b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/converter/FitbitIntradaySpo2AvroConverter.java new file mode 100644 index 00000000..2f49aaca --- /dev/null +++ b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/converter/FitbitIntradaySpo2AvroConverter.java @@ -0,0 +1,79 @@ +/* + * Copyright 2018 The Hyve + * + * Licensed 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.radarbase.connect.rest.fitbit.converter; + +import com.fasterxml.jackson.databind.JsonNode; +import io.confluent.connect.avro.AvroData; +import org.radarbase.connect.rest.RestSourceConnectorConfig; +import org.radarbase.connect.rest.fitbit.FitbitRestSourceConnectorConfig; +import org.radarbase.connect.rest.fitbit.request.FitbitRestRequest; +import org.radarcns.connector.fitbit.FitbitIntradaySpo2; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZonedDateTime; +import java.util.stream.Stream; + +import static org.radarbase.connect.rest.util.ThrowingFunction.tryOrNull; + +public class FitbitIntradaySpo2AvroConverter extends FitbitAvroConverter { + private static final Logger logger = LoggerFactory.getLogger(FitbitIntradaySpo2AvroConverter.class); + private String spo2Topic; + + public FitbitIntradaySpo2AvroConverter(AvroData avroData) { + super(avroData); + } + + @Override + public void initialize(RestSourceConnectorConfig config) { + spo2Topic = ((FitbitRestSourceConnectorConfig) config).getFitbitIntradaySpo2Topic(); + logger.info("Using intraday spo2 topic {}", spo2Topic); + } + + @Override + protected Stream processRecords(FitbitRestRequest request, JsonNode root, double timeReceived) { + JsonNode spo2 = root; + if (spo2 == null || !spo2.isArray()) { + logger.warn("No Spo2 is provided for {}: {}", request, root); + return Stream.empty(); + } + ZonedDateTime startDate = request.getDateRange().end(); + + return iterableToStream(spo2) + .filter(m -> m != null && m.isObject()) + .map(m -> m.get("minutes")) + .filter(minutes -> minutes != null && minutes.isArray()) + .flatMap(FitbitAvroConverter::iterableToStream) + .map(tryOrNull(minuteData -> parseSpo2(minuteData, startDate, timeReceived), + (a, ex) -> logger.warn("Failed to convert spo2 from request {}, {}", request, a, ex))); + } + + private TopicData parseSpo2(JsonNode minuteData, ZonedDateTime startDate, double timeReceived) { + Instant time = startDate.with(LocalDateTime.parse(minuteData.get("minute").asText())).toInstant(); + Float value = (float) minuteData.get("value").asDouble(); + if (value == null) { + return null; + } + FitbitIntradaySpo2 fitbitSpo2 = new FitbitIntradaySpo2(time.toEpochMilli() / 1000d, + timeReceived, + (float) value); + return new TopicData(time, spo2Topic, fitbitSpo2); + } +} diff --git a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitIntradaySpo2Route.java b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitIntradaySpo2Route.java new file mode 100644 index 00000000..f7d3a3e2 --- /dev/null +++ b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitIntradaySpo2Route.java @@ -0,0 +1,63 @@ +/* + * Copyright 2018 The Hyve + * + * Licensed 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.radarbase.connect.rest.fitbit.route; + +import io.confluent.connect.avro.AvroData; +import org.radarbase.connect.rest.fitbit.converter.FitbitIntradaySpo2AvroConverter; +import org.radarbase.connect.rest.fitbit.request.FitbitRequestGenerator; +import org.radarbase.connect.rest.fitbit.request.FitbitRestRequest; +import org.radarbase.connect.rest.fitbit.user.User; +import org.radarbase.connect.rest.fitbit.user.UserRepository; + +import java.util.stream.Stream; + +import static java.time.temporal.ChronoUnit.SECONDS; +import java.time.Duration; + + +public class FitbitIntradaySpo2Route extends FitbitPollingRoute { + private final FitbitIntradaySpo2AvroConverter converter; + protected static final Duration REQUEST_INTERVAL = Duration.ofDays(30); + + public FitbitIntradaySpo2Route(FitbitRequestGenerator generator, + UserRepository userRepository, AvroData avroData) { + super(generator, userRepository, "intraday_spo2"); + this.converter = new FitbitIntradaySpo2AvroConverter(avroData); + } + + @Override + protected String getUrlFormat(String baseUrl) { + return baseUrl + "/1/user/%s/spo2/date/%s/%s/all.json"; + } + + protected Stream createRequests(User user) { + return startDateGenerator(getOffset(user).plus(ONE_SECOND).truncatedTo(SECONDS)) + .map(dateRange -> newRequest(user, dateRange, + user.getExternalUserId(), DATE_FORMAT.format(dateRange.start()))); + } + + @Override + Duration getDateRangeInterval() { + return REQUEST_INTERVAL; + } + + @Override + public FitbitIntradaySpo2AvroConverter converter() { + return converter; + } +} \ No newline at end of file From 8e2949d12459c8c355a5a06d510a4f1453e7dc2d Mon Sep 17 00:00:00 2001 From: Pauline Date: Tue, 5 Mar 2024 15:10:59 +0000 Subject: [PATCH 04/15] Update route range interval and add docs --- .../connect/rest/fitbit/route/FitbitBreathingRateRoute.java | 4 ++-- .../fitbit/route/FitbitIntradayHeartRateVariabilityRoute.java | 4 ++-- .../connect/rest/fitbit/route/FitbitPollingRoute.java | 1 + .../connect/rest/fitbit/route/FitbitSkinTemperatureRoute.java | 4 ++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitBreathingRateRoute.java b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitBreathingRateRoute.java index 56c85c24..1ed5bbc5 100644 --- a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitBreathingRateRoute.java +++ b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitBreathingRateRoute.java @@ -31,7 +31,6 @@ public class FitbitBreathingRateRoute extends FitbitPollingRoute { private final FitbitBreathingRateAvroConverter converter; - protected static final Duration REQUEST_INTERVAL = Duration.ofDays(30); public FitbitBreathingRateRoute(FitbitRequestGenerator generator, UserRepository userRepository, AvroData avroData) { @@ -50,9 +49,10 @@ protected Stream createRequests(User user) { user.getExternalUserId(), DATE_FORMAT.format(dateRange.start()))); } + /** Limit range to 30 days as documented here: https://dev.fitbit.com/build/reference/web-api/intraday/get-br-intraday-by-interval/ */ @Override Duration getDateRangeInterval() { - return REQUEST_INTERVAL; + return THIRTY_DAYS; } @Override diff --git a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitIntradayHeartRateVariabilityRoute.java b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitIntradayHeartRateVariabilityRoute.java index a1f4e3bc..2b5958b9 100644 --- a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitIntradayHeartRateVariabilityRoute.java +++ b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitIntradayHeartRateVariabilityRoute.java @@ -32,7 +32,6 @@ public class FitbitIntradayHeartRateVariabilityRoute extends FitbitPollingRoute { private final FitbitIntradayHeartRateVariabilityAvroConverter converter; - protected static final Duration REQUEST_INTERVAL = Duration.ofDays(30); public FitbitIntradayHeartRateVariabilityRoute(FitbitRequestGenerator generator, UserRepository userRepository, AvroData avroData) { @@ -51,9 +50,10 @@ protected Stream createRequests(User user) { user.getExternalUserId(), DATE_FORMAT.format(dateRange.start()))); } + /** Limit range to 30 days as documented here: https://dev.fitbit.com/build/reference/web-api/intraday/get-hrv-intraday-by-interval/ */ @Override Duration getDateRangeInterval() { - return REQUEST_INTERVAL; + return THIRTY_DAYS; } @Override diff --git a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitPollingRoute.java b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitPollingRoute.java index 8d8bb35d..53e17b97 100644 --- a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitPollingRoute.java +++ b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitPollingRoute.java @@ -95,6 +95,7 @@ public abstract class FitbitPollingRoute implements PollingRequestRoute { protected static final Duration LOOKBACK_TIME = Duration.ofDays(1); // 1 day protected static final long HISTORICAL_TIME_DAYS = 14L; protected static final Duration ONE_DAY = DAYS.getDuration(); + protected static final Duration THIRTY_DAYS = Duration.ofDays(30); protected static final Duration ONE_NANO = NANOS.getDuration(); protected static final TemporalAmount ONE_SECOND = SECONDS.getDuration(); protected static final TemporalAmount ONE_MINUTE = MINUTES.getDuration(); diff --git a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitSkinTemperatureRoute.java b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitSkinTemperatureRoute.java index 9ac3676c..31362c94 100644 --- a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitSkinTemperatureRoute.java +++ b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitSkinTemperatureRoute.java @@ -31,7 +31,6 @@ public class FitbitSkinTemperatureRoute extends FitbitPollingRoute { private final FitbitSkinTemperatureAvroConverter converter; - protected static final Duration REQUEST_INTERVAL = Duration.ofDays(30); public FitbitSkinTemperatureRoute(FitbitRequestGenerator generator, UserRepository userRepository, AvroData avroData) { @@ -50,9 +49,10 @@ protected Stream createRequests(User user) { user.getExternalUserId(), DATE_FORMAT.format(dateRange.start()))); } + /** Limit range to 30 days as documented here: https://dev.fitbit.com/build/reference/web-api/temperature/get-temperature-skin-summary-by-interval */ @Override Duration getDateRangeInterval() { - return REQUEST_INTERVAL; + return THIRTY_DAYS; } @Override From 6d0fdb43e97ce2b29b01ab907d9cd8da3fb3473b Mon Sep 17 00:00:00 2001 From: Pauline Date: Tue, 5 Mar 2024 15:20:21 +0000 Subject: [PATCH 05/15] Update Spo2 route --- .../connect/rest/fitbit/route/FitbitIntradaySpo2Route.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitIntradaySpo2Route.java b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitIntradaySpo2Route.java index f7d3a3e2..d5844c17 100644 --- a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitIntradaySpo2Route.java +++ b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitIntradaySpo2Route.java @@ -32,7 +32,6 @@ public class FitbitIntradaySpo2Route extends FitbitPollingRoute { private final FitbitIntradaySpo2AvroConverter converter; - protected static final Duration REQUEST_INTERVAL = Duration.ofDays(30); public FitbitIntradaySpo2Route(FitbitRequestGenerator generator, UserRepository userRepository, AvroData avroData) { @@ -51,9 +50,10 @@ protected Stream createRequests(User user) { user.getExternalUserId(), DATE_FORMAT.format(dateRange.start()))); } + /** Limit range to 30 days as documented here: https://dev.fitbit.com/build/reference/web-api/intraday/get-spo2-intraday-by-interval/ */ @Override Duration getDateRangeInterval() { - return REQUEST_INTERVAL; + return THIRTY_DAYS; } @Override From 4a082dd233c243e5a33cb79c073e595385350beb Mon Sep 17 00:00:00 2001 From: Pauline Date: Thu, 7 Mar 2024 12:34:11 +0000 Subject: [PATCH 06/15] Fix hrv rmssd key --- .../FitbitIntradayHeartRateVariabilityAvroConverter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/converter/FitbitIntradayHeartRateVariabilityAvroConverter.java b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/converter/FitbitIntradayHeartRateVariabilityAvroConverter.java index 58c10b37..5e22ec5b 100644 --- a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/converter/FitbitIntradayHeartRateVariabilityAvroConverter.java +++ b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/converter/FitbitIntradayHeartRateVariabilityAvroConverter.java @@ -73,7 +73,7 @@ private TopicData parseHrv(JsonNode minuteData, ZonedDateTime startDate, double } FitbitIntradayHeartRateVariability fitbitHrv = new FitbitIntradayHeartRateVariability(time.toEpochMilli() / 1000d, timeReceived, - (float) value.get("dailyRmssd").asDouble(), + (float) value.get("rmssd").asDouble(), (float) value.get("coverage").asDouble(), (float) value.get("hf").asDouble(), (float) value.get("lf").asDouble()); From 9ed954a2f330c53cc3cf7b83d8b87175e591ddf2 Mon Sep 17 00:00:00 2001 From: Pauline Date: Thu, 7 Mar 2024 12:34:28 +0000 Subject: [PATCH 07/15] Add back end date to request param --- .../connect/rest/fitbit/route/FitbitBreathingRateRoute.java | 2 +- .../fitbit/route/FitbitIntradayHeartRateVariabilityRoute.java | 2 +- .../connect/rest/fitbit/route/FitbitSkinTemperatureRoute.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitBreathingRateRoute.java b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitBreathingRateRoute.java index 1ed5bbc5..1a8d6b99 100644 --- a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitBreathingRateRoute.java +++ b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitBreathingRateRoute.java @@ -46,7 +46,7 @@ protected String getUrlFormat(String baseUrl) { protected Stream createRequests(User user) { return startDateGenerator(getOffset(user).plus(ONE_SECOND).truncatedTo(SECONDS)) .map(dateRange -> newRequest(user, dateRange, - user.getExternalUserId(), DATE_FORMAT.format(dateRange.start()))); + user.getExternalUserId(), DATE_FORMAT.format(dateRange.start()), DATE_FORMAT.format(dateRange.end()))); } /** Limit range to 30 days as documented here: https://dev.fitbit.com/build/reference/web-api/intraday/get-br-intraday-by-interval/ */ diff --git a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitIntradayHeartRateVariabilityRoute.java b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitIntradayHeartRateVariabilityRoute.java index 2b5958b9..7610bd77 100644 --- a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitIntradayHeartRateVariabilityRoute.java +++ b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitIntradayHeartRateVariabilityRoute.java @@ -47,7 +47,7 @@ protected String getUrlFormat(String baseUrl) { protected Stream createRequests(User user) { return startDateGenerator(getOffset(user).plus(ONE_SECOND).truncatedTo(SECONDS)) .map(dateRange -> newRequest(user, dateRange, - user.getExternalUserId(), DATE_FORMAT.format(dateRange.start()))); + user.getExternalUserId(), DATE_FORMAT.format(dateRange.start()), DATE_FORMAT.format(dateRange.end()))); } /** Limit range to 30 days as documented here: https://dev.fitbit.com/build/reference/web-api/intraday/get-hrv-intraday-by-interval/ */ diff --git a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitSkinTemperatureRoute.java b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitSkinTemperatureRoute.java index 31362c94..78fb91c0 100644 --- a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitSkinTemperatureRoute.java +++ b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitSkinTemperatureRoute.java @@ -46,7 +46,7 @@ protected String getUrlFormat(String baseUrl) { protected Stream createRequests(User user) { return startDateGenerator(getOffset(user).plus(ONE_SECOND).truncatedTo(SECONDS)) .map(dateRange -> newRequest(user, dateRange, - user.getExternalUserId(), DATE_FORMAT.format(dateRange.start()))); + user.getExternalUserId(), DATE_FORMAT.format(dateRange.start()), DATE_FORMAT.format(dateRange.end()))); } /** Limit range to 30 days as documented here: https://dev.fitbit.com/build/reference/web-api/temperature/get-temperature-skin-summary-by-interval */ From 835101d580b5ee090dda4eeed871ec4a1851d2bf Mon Sep 17 00:00:00 2001 From: Pauline Date: Thu, 7 Mar 2024 12:50:20 +0000 Subject: [PATCH 08/15] Update creating of requests in spo2 route --- .../connect/rest/fitbit/route/FitbitIntradaySpo2Route.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitIntradaySpo2Route.java b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitIntradaySpo2Route.java index d5844c17..75b2c171 100644 --- a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitIntradaySpo2Route.java +++ b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitIntradaySpo2Route.java @@ -47,7 +47,7 @@ protected String getUrlFormat(String baseUrl) { protected Stream createRequests(User user) { return startDateGenerator(getOffset(user).plus(ONE_SECOND).truncatedTo(SECONDS)) .map(dateRange -> newRequest(user, dateRange, - user.getExternalUserId(), DATE_FORMAT.format(dateRange.start()))); + user.getExternalUserId(), DATE_FORMAT.format(dateRange.start()), DATE_FORMAT.format(dateRange.end()))); } /** Limit range to 30 days as documented here: https://dev.fitbit.com/build/reference/web-api/intraday/get-spo2-intraday-by-interval/ */ From 50aca296f632bdb4910f4cded0f8498e0409b139 Mon Sep 17 00:00:00 2001 From: Peyman Mohtashami Date: Thu, 21 Mar 2024 13:16:15 +0100 Subject: [PATCH 09/15] Fix breathing and skin temperature convertors --- buildSrc/src/main/kotlin/Versions.kt | 2 +- .../FitbitBreathingRateAvroConverter.java | 15 ++++++--------- .../FitbitSkinTemperatureAvroConverter.java | 13 +++++-------- .../fitbit/route/FitbitSkinTemperatureRoute.java | 4 ++-- 4 files changed, 14 insertions(+), 20 deletions(-) diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index 8766a71e..f47e49e7 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -22,7 +22,7 @@ object Versions { const val okhttp = "4.11.0" const val firebaseAdmin = "9.1.0" - const val radarSchemas = "0.8.7-SNAPSHOT" + const val radarSchemas = "0.8.6" const val ktor = "2.3.5" const val junit = "5.9.3" diff --git a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/converter/FitbitBreathingRateAvroConverter.java b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/converter/FitbitBreathingRateAvroConverter.java index 7a0e9604..8595749f 100644 --- a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/converter/FitbitBreathingRateAvroConverter.java +++ b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/converter/FitbitBreathingRateAvroConverter.java @@ -26,9 +26,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZonedDateTime; +import java.time.*; import java.util.stream.Stream; import static org.radarbase.connect.rest.util.ThrowingFunction.tryOrNull; @@ -58,23 +56,22 @@ protected Stream processRecords(FitbitRestRequest request, JsonNode r return iterableToStream(br) .filter(m -> m != null && m.isObject()) - .flatMap(FitbitAvroConverter::iterableToStream) .map(tryOrNull(m -> parseBr(m, startDate, timeReceived), (a, ex) -> logger.warn("Failed to convert breathing rate from request {}, {}", request, a, ex))); } private TopicData parseBr(JsonNode data, ZonedDateTime startDate, double timeReceived) { - Instant time = startDate.with(LocalDateTime.parse(data.get("dateTime").asText())).toInstant(); + Instant time = LocalDate.parse(data.get("dateTime").asText()).atStartOfDay(ZoneOffset.UTC).toInstant(); JsonNode value = data.get("value"); if (value == null || !value.isObject()) { return null; } FitbitBreathingRate fitbitBr = new FitbitBreathingRate(time.toEpochMilli() / 1000d, timeReceived, - (float) value.get("deepSleepBrSummary").get("breathingRate").asDouble(), - (float) value.get("remSleepBrSummary").get("breathingRate").asDouble(), - (float) value.get("fullSleepBrSummary").get("breathingRate").asDouble(), - (float) value.get("lightSleepBrSummary").get("breathingRate").asDouble()); + (float) value.get("deepSleepSummary").get("breathingRate").asDouble(), + (float) value.get("remSleepSummary").get("breathingRate").asDouble(), + (float) value.get("fullSleepSummary").get("breathingRate").asDouble(), + (float) value.get("lightSleepSummary").get("breathingRate").asDouble()); return new TopicData(time, breathingRateTopic, fitbitBr); } } diff --git a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/converter/FitbitSkinTemperatureAvroConverter.java b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/converter/FitbitSkinTemperatureAvroConverter.java index 14ab9370..680d6b91 100644 --- a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/converter/FitbitSkinTemperatureAvroConverter.java +++ b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/converter/FitbitSkinTemperatureAvroConverter.java @@ -26,9 +26,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZonedDateTime; +import java.time.*; import java.util.HashMap; import java.util.Map; import java.util.stream.Stream; @@ -68,24 +66,23 @@ protected Stream processRecords(FitbitRestRequest request, JsonNode r return iterableToStream(tempSkin) .filter(m -> m != null && m.isObject()) - .flatMap(FitbitAvroConverter::iterableToStream) .map(tryOrNull(m -> parseTempSkin(m, startDate, timeReceived), (a, ex) -> logger.warn("Failed to convert skin temperature from request {}, {}", request, a, ex))); } private TopicData parseTempSkin(JsonNode data, ZonedDateTime startDate, double timeReceived) { - Instant time = startDate.with(LocalDateTime.parse(data.get("dateTime").asText())).toInstant(); + Instant time = LocalDate.parse(data.get("dateTime").asText()).atStartOfDay(ZoneOffset.UTC).toInstant(); JsonNode value = data.get("value"); if (value == null || !value.isObject()) { return null; } - String logType = data.get("level").asText(); - FitbitSkinTemperature fitbitHrv = new FitbitSkinTemperature( + String logType = data.get("logType").asText(); + FitbitSkinTemperature fitbitSkinTemperature = new FitbitSkinTemperature( time.toEpochMilli() / 1000d, timeReceived, (float) value.get("nightlyRelative").asDouble(), LOG_TYPE_MAP.getOrDefault(logType, FitbitSkinTemperatureLogType.UNKNOWN) ); - return new TopicData(time, skinTemperatureTopic, fitbitHrv); + return new TopicData(time, skinTemperatureTopic, fitbitSkinTemperature); } } diff --git a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitSkinTemperatureRoute.java b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitSkinTemperatureRoute.java index 78fb91c0..e808a855 100644 --- a/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitSkinTemperatureRoute.java +++ b/kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitSkinTemperatureRoute.java @@ -40,7 +40,7 @@ public FitbitSkinTemperatureRoute(FitbitRequestGenerator generator, @Override protected String getUrlFormat(String baseUrl) { - return baseUrl + "/1/user/%s/temp/skin/date/%s/%s/.json"; + return baseUrl + "/1/user/%s/temp/skin/date/%s/%s.json"; } protected Stream createRequests(User user) { @@ -59,4 +59,4 @@ Duration getDateRangeInterval() { public FitbitSkinTemperatureAvroConverter converter() { return converter; } -} \ No newline at end of file +} From 65b753f9779d60ea17834029e252087a3ed9f029 Mon Sep 17 00:00:00 2001 From: Pauline Conde Date: Wed, 17 Apr 2024 16:31:10 +0100 Subject: [PATCH 10/15] Bump radar-schemas to version 0.8.7-hotfix --- buildSrc/src/main/kotlin/Versions.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index f47e49e7..abb652ff 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -22,7 +22,7 @@ object Versions { const val okhttp = "4.11.0" const val firebaseAdmin = "9.1.0" - const val radarSchemas = "0.8.6" + const val radarSchemas = "0.8.7-hotfix" const val ktor = "2.3.5" const val junit = "5.9.3" From c7450fd3f64d7b5935047b84610b4d94797b5ea1 Mon Sep 17 00:00:00 2001 From: Pauline Date: Wed, 17 Apr 2024 16:52:14 +0100 Subject: [PATCH 11/15] Bump deps to latest versions and bump java to 17 --- buildSrc/build.gradle.kts | 2 +- buildSrc/src/main/kotlin/Versions.kt | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 8a695a47..dfbb6e6f 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - kotlin("jvm") version "1.9.10" + kotlin("jvm") version "1.9.22" } repositories { diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index abb652ff..0109e945 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -2,24 +2,24 @@ object Versions { const val project = "0.4.2-SNAPSHOT" - const val java = 11 + const val java = 17 const val kotlin = "1.9.10" const val wrapper = "8.4" - const val radarCommons = "1.1.1" - const val confluent = "7.5.0" + const val radarCommons = "1.1.2" + const val confluent = "7.6.0" const val kafka = "$confluent-ce" - const val avro = "1.11.0" + const val avro = "1.11.3" const val managementPortal = "2.0.0" // From image - const val jackson = "2.14.2" + const val jackson = "2.16.1" const val log4j2 = "2.20.0" const val slf4j = "2.0.9" - const val okhttp = "4.11.0" + const val okhttp = "4.12.0" const val firebaseAdmin = "9.1.0" const val radarSchemas = "0.8.7-hotfix" @@ -29,5 +29,5 @@ object Versions { const val wiremock = "2.27.2" const val mockito = "5.3.1" - const val kotlinVersion = "1.8.21" + const val kotlinVersion = "1.9.10" } From 1677b54b257a2ec7e8edba02db0258511bdb2a84 Mon Sep 17 00:00:00 2001 From: Pauline Date: Wed, 17 Apr 2024 16:52:55 +0100 Subject: [PATCH 12/15] Update Dockerfile and GA workflows to use java 17 --- .github/workflows/main.yml | 2 +- .github/workflows/oura.yml | 2 +- .github/workflows/release-fitbit.yml | 2 +- .github/workflows/release-oura.yml | 2 +- README.md | 2 +- kafka-connect-fitbit-source/Dockerfile | 2 +- kafka-connect-oura-source/Dockerfile | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 81fa3ecb..c77ab544 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -25,7 +25,7 @@ jobs: - uses: actions/setup-java@v3 with: distribution: temurin - java-version: 11 + java-version: 17 - name: Setup Gradle uses: gradle/gradle-build-action@v2 diff --git a/.github/workflows/oura.yml b/.github/workflows/oura.yml index f4b5095f..2d268be0 100644 --- a/.github/workflows/oura.yml +++ b/.github/workflows/oura.yml @@ -25,7 +25,7 @@ jobs: - uses: actions/setup-java@v3 with: distribution: temurin - java-version: 11 + java-version: 17 - name: Setup Gradle uses: gradle/gradle-build-action@v2 diff --git a/.github/workflows/release-fitbit.yml b/.github/workflows/release-fitbit.yml index e7e5997d..87432a10 100644 --- a/.github/workflows/release-fitbit.yml +++ b/.github/workflows/release-fitbit.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/setup-java@v3 with: distribution: temurin - java-version: 11 + java-version: 17 - name: Gradle cache uses: actions/cache@v3 diff --git a/.github/workflows/release-oura.yml b/.github/workflows/release-oura.yml index 28897ae7..7c0e8182 100644 --- a/.github/workflows/release-oura.yml +++ b/.github/workflows/release-oura.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/setup-java@v3 with: distribution: temurin - java-version: 11 + java-version: 17 - name: Gradle cache uses: actions/cache@v3 diff --git a/README.md b/README.md index b186e677..1119ef89 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Fitbit in particular. The documentation of the Kafka Connect REST source still n ### Installation This repository relies on a recent version of docker and docker-compose as well as an installation -of Java 11 or later. +of Java 17 or later. ### Usage diff --git a/kafka-connect-fitbit-source/Dockerfile b/kafka-connect-fitbit-source/Dockerfile index 19f3a503..d4c7ff01 100644 --- a/kafka-connect-fitbit-source/Dockerfile +++ b/kafka-connect-fitbit-source/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=$BUILDPLATFORM gradle:8.4-jdk11 as builder +FROM --platform=$BUILDPLATFORM gradle:8.4-jdk17 as builder RUN mkdir /code WORKDIR /code diff --git a/kafka-connect-oura-source/Dockerfile b/kafka-connect-oura-source/Dockerfile index 2daec601..41972797 100644 --- a/kafka-connect-oura-source/Dockerfile +++ b/kafka-connect-oura-source/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=$BUILDPLATFORM gradle:8.4-jdk11 as builder +FROM --platform=$BUILDPLATFORM gradle:8.4-jdk17 as builder RUN mkdir /code WORKDIR /code From 6988b063d5d8a345d5ee5d55fe23440dcee00b96 Mon Sep 17 00:00:00 2001 From: Pauline Date: Wed, 17 Apr 2024 17:12:44 +0100 Subject: [PATCH 13/15] Bump project version --- buildSrc/src/main/kotlin/Versions.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index a6be703c..c2463f20 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -1,6 +1,6 @@ @Suppress("ConstPropertyName", "MemberVisibilityCanBePrivate") object Versions { - const val project = "0.5.1" + const val project = "0.5.2" const val java = 17 const val kotlin = "1.9.10" From 4712d0fd6a28b67f9224716b078ebad5f1fe972a Mon Sep 17 00:00:00 2001 From: Bastiaan Date: Thu, 18 Apr 2024 15:11:11 +0200 Subject: [PATCH 14/15] Create codeql.yml --- .github/workflows/codeql.yml | 89 ++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 00000000..ce888345 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,89 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ "main", "dev" ] + pull_request: + branches: [ "main", "dev" ] + schedule: + - cron: '24 21 * * 0' + +jobs: + analyze: + name: Analyze + # Runner size impacts CodeQL analysis time. To learn more, please see: + # - https://gh.io/recommended-hardware-resources-for-running-codeql + # - https://gh.io/supported-runners-and-hardware-resources + # - https://gh.io/using-larger-runners + # Consider using larger runners for possible analysis time improvements. + runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} + timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} + permissions: + # required for all workflows + security-events: write + + # only required for workflows in private repositories + actions: read + contents: read + + strategy: + fail-fast: false + matrix: + language: [ 'java-kotlin' ] + # CodeQL supports [ 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' ] + # Use only 'java-kotlin' to analyze code written in Java, Kotlin or both + # Use only 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' # See 'Supported distributions' for available options + java-version: '17' + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v3 + + # ℹī¸ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{matrix.language}}" From 0d52c919a78046d2dae387fd2b66c73829f73559 Mon Sep 17 00:00:00 2001 From: Pauline Date: Thu, 18 Apr 2024 16:00:40 +0100 Subject: [PATCH 15/15] Update codeql workflow branch to master --- .github/workflows/codeql.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index ce888345..ba50633a 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -13,9 +13,9 @@ name: "CodeQL" on: push: - branches: [ "main", "dev" ] + branches: [ "master", "dev" ] pull_request: - branches: [ "main", "dev" ] + branches: [ "master", "dev" ] schedule: - cron: '24 21 * * 0'