Skip to content

Commit 6e29fd5

Browse files
authored
Merge pull request #142 from RADAR-base/release-0.5.3
Release 0.5.3
2 parents 361ae2b + 27e5a19 commit 6e29fd5

File tree

11 files changed

+104
-53
lines changed

11 files changed

+104
-53
lines changed

.github/workflows/snyk.yaml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Snyk test
2+
3+
on:
4+
- pull_request
5+
6+
jobs:
7+
security:
8+
runs-on: ubuntu-latest
9+
10+
steps:
11+
- uses: actions/checkout@v3
12+
- uses: snyk/actions/setup@master
13+
with:
14+
snyk-version: v1.1032.0
15+
16+
- uses: actions/setup-java@v3
17+
with:
18+
distribution: temurin
19+
java-version: 17
20+
21+
- name: Setup Gradle
22+
uses: gradle/gradle-build-action@v2
23+
24+
- name: Run Snyk to check for vulnerabilities
25+
env:
26+
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
27+
run: >
28+
snyk test
29+
--all-projects
30+
--configuration-matching="^runtimeClasspath$"
31+
--fail-on=upgradable
32+
--org=radar-base
33+
--policy-path=.snyk
34+
--severity-threshold=high
Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,31 @@
11
@Suppress("ConstPropertyName", "MemberVisibilityCanBePrivate")
22
object Versions {
3-
const val project = "0.5.2"
3+
const val project = "0.5.3"
44

55
const val java = 17
6-
const val kotlin = "1.9.10"
6+
const val kotlin = "1.9.22"
77
const val wrapper = "8.4"
88

99
const val radarCommons = "1.1.2"
10-
const val confluent = "7.6.0"
10+
const val confluent = "7.7.0"
1111
const val kafka = "$confluent-ce"
12-
const val avro = "1.11.3"
12+
const val avro = "1.12.0"
1313

1414
const val managementPortal = "2.0.0"
1515

1616
// From image
17-
const val jackson = "2.16.1"
17+
const val jackson = "2.17.0"
1818

19-
const val log4j2 = "2.20.0"
20-
const val slf4j = "2.0.9"
19+
const val log4j2 = "2.23.1"
20+
const val slf4j = "2.0.13"
2121

2222
const val okhttp = "4.12.0"
2323

24-
const val firebaseAdmin = "9.1.0"
24+
const val firebaseAdmin = "9.2.0"
2525
const val radarSchemas = "0.8.7-hotfix"
26-
const val ktor = "2.3.5"
26+
const val ktor = "2.3.10"
2727

28-
const val junit = "5.9.3"
29-
const val wiremock = "2.27.2"
30-
const val mockito = "5.3.1"
31-
32-
const val kotlinVersion = "1.9.10"
28+
const val junit = "5.10.2"
29+
const val wiremock = "3.0.1"
30+
const val mockito = "5.11.0"
3331
}

kafka-connect-fitbit-source/Dockerfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ RUN gradle jar
3434

3535
FROM confluentinc/cp-kafka-connect-base:7.5.0
3636

37+
USER root
38+
39+
RUN yum remove -y zulu11-ca-jdk-headless && yum remove -y zulu11-ca-jre-headless
40+
RUN yum install -y zulu17-ca-jdk-headless && yum install -y zulu17-ca-jre-headless
41+
42+
USER appuser
43+
3744
MAINTAINER Joris Borgdorff <[email protected]>
3845

3946
LABEL description="Kafka REST API Source connector"

kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/user/ServiceUserRepository.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,10 @@ class ServiceUserRepository : UserRepository {
240240
): T = withContext(Dispatchers.IO) {
241241
val response = client.request(builder)
242242
val contentLength = response.contentLength()
243-
val hasBody = contentLength != null && contentLength > 0
243+
// if Transfer-Encoding: chunked, then the request has data but contentLength will be null.
244+
val transferEncoding = response.headers["Transfer-Encoding"]
245+
val hasBody = (contentLength != null && contentLength > 0) ||
246+
(transferEncoding != null && transferEncoding.contains("chunked"))
244247
if (response.status == HttpStatusCode.NotFound) {
245248
throw NoSuchElementException("URL " + response.request.url + " does not exist")
246249
} else if (!response.status.isSuccess() || !hasBody) {

kafka-connect-oura-source/Dockerfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ RUN gradle jar
3434

3535
FROM confluentinc/cp-kafka-connect-base:7.5.0
3636

37+
USER root
38+
39+
RUN yum remove -y zulu11-ca-jdk-headless && yum remove -y zulu11-ca-jre-headless
40+
RUN yum install -y zulu17-ca-jdk-headless && yum install -y zulu17-ca-jre-headless
41+
42+
USER appuser
43+
3744
MAINTAINER Pauline Conde <[email protected]>
3845

3946
LABEL description="Kafka Oura REST API Source connector"

kafka-connect-oura-source/src/main/java/org/radarbase/connect/rest/oura/OuraSourceTask.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ public class OuraSourceTask extends SourceTask {
6363
private AvroData avroData = new AvroData(20);
6464
private KafkaOffsetManager offsetManager;
6565
String TIMESTAMP_OFFSET_KEY = "timestamp";
66+
long TIMEOUT = 60000L;
6667

6768
public void initialize(OuraRestSourceConnectorConfig config, OffsetStorageReader offsetStorageReader) {
6869
OuraRestSourceConnectorConfig ouraConfig = (OuraRestSourceConnectorConfig) config;
@@ -144,6 +145,8 @@ public List<SourceRecord> poll() throws InterruptedException {
144145
List<SourceRecord> sourceRecords = Collections.emptyList();
145146

146147
do {
148+
Thread.sleep(TIMEOUT);
149+
147150
Map<String, String> configs = context.configs();
148151
Iterator<? extends RestRequest> requestIterator = this.requests()
149152
.iterator();

kafka-connect-oura-source/src/main/java/org/radarbase/connect/rest/oura/offset/KafkaOffsetManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public void initialize(List<Map<String, Object>> partitions) {
3636
.filter(e -> e.getValue() != null && e.getValue().containsKey(TIMESTAMP_OFFSET_KEY))
3737
.collect(Collectors.toMap(
3838
e -> (String) e.getKey().get("user") + "-" + e.getKey().get("route"),
39-
e -> Instant.ofEpochMilli(((Number) e.getValue().get(TIMESTAMP_OFFSET_KEY)).longValue())));
39+
e -> Instant.ofEpochSecond(((Number) e.getValue().get(TIMESTAMP_OFFSET_KEY)).longValue())));
4040
} else {
4141
logger.warn("Offset storage reader is null, will resume from an empty state.");
4242
}

kafka-connect-rest-source/src/test/java/org/radarbase/connect/rest/RestTaskTest.java

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,11 @@
1717

1818
package org.radarbase.connect.rest;
1919

20-
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
21-
import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
22-
import static com.github.tomakehurst.wiremock.client.WireMock.matching;
23-
import static com.github.tomakehurst.wiremock.client.WireMock.post;
24-
import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
25-
import static com.github.tomakehurst.wiremock.client.WireMock.resetAllRequests;
26-
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
27-
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
28-
import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
29-
import static com.github.tomakehurst.wiremock.client.WireMock.verify;
30-
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
31-
import static org.junit.jupiter.api.Assertions.assertEquals;
32-
3320
import com.github.tomakehurst.wiremock.WireMockServer;
3421
import com.github.tomakehurst.wiremock.client.VerificationException;
3522
import com.github.tomakehurst.wiremock.client.WireMock;
3623
import com.github.tomakehurst.wiremock.verification.LoggedRequest;
3724
import com.github.tomakehurst.wiremock.verification.NearMiss;
38-
import java.util.HashMap;
39-
import java.util.List;
40-
import java.util.Map;
4125
import org.apache.kafka.connect.source.SourceRecord;
4226
import org.apache.kafka.connect.source.SourceTaskContext;
4327
import org.apache.kafka.connect.storage.OffsetStorageReader;
@@ -56,6 +40,23 @@
5640
import org.radarbase.connect.rest.single.SingleRestSourceConnector;
5741
import org.radarbase.connect.rest.single.SingleRestSourceConnectorConfig;
5842

43+
import java.util.HashMap;
44+
import java.util.List;
45+
import java.util.Map;
46+
47+
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
48+
import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
49+
import static com.github.tomakehurst.wiremock.client.WireMock.matching;
50+
import static com.github.tomakehurst.wiremock.client.WireMock.post;
51+
import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
52+
import static com.github.tomakehurst.wiremock.client.WireMock.resetAllRequests;
53+
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
54+
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
55+
import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
56+
import static com.github.tomakehurst.wiremock.client.WireMock.verify;
57+
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
58+
import static org.junit.jupiter.api.Assertions.assertEquals;
59+
5960
@ExtendWith(WireMockRule.class)
6061
public class RestTaskTest {
6162

@@ -167,7 +168,7 @@ public void afterEach(ExtensionContext context) {
167168
}
168169
}
169170

170-
private void checkForUnmatchedRequests() {
171+
public void checkForUnmatchedRequests() {
171172
List<LoggedRequest> unmatchedRequests = findAllUnmatchedRequests();
172173
if (!unmatchedRequests.isEmpty()) {
173174
List<NearMiss> nearMisses = findNearMissesForAllUnmatchedRequests();

oura-library/src/main/kotlin/org/radarbase/oura/request/OuraRequestGenerator.kt

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,9 @@ constructor(
8989
logger.info("Offsets found in persistence: " + offsetTime.toString())
9090
offsetTime.coerceAtLeast(startDate)
9191
}
92-
val endDate = if (user.endDate >= Instant.now()) Instant.now() else user.endDate
93-
if (Duration.between(startOffset, endDate).toDays() <= ONE_DAY) {
94-
logger.info("Interval between dates is too short. Backing off..")
95-
userNextRequest[user.versionedId] = Instant.now().plus(USER_BACK_OFF_TIME)
92+
val endDate = user.endDate?.coerceAtMost(Instant.now()) ?: Instant.now()
93+
if (Duration.between(startOffset, endDate) <= ONE_DAY) {
94+
logger.info("Interval between dates is too short. Not requesting..")
9695
return emptySequence()
9796
}
9897
val endTime = (startOffset + defaultQueryRange).coerceAtMost(endDate)
@@ -130,26 +129,24 @@ constructor(
130129
ouraOffsetManager.updateOffsets(
131130
request.route,
132131
request.user,
133-
Instant.ofEpochSecond(offset).plus(Duration.ofMillis(500)),
132+
Instant.ofEpochSecond(offset).plus(ONE_DAY),
134133
)
135-
val currentNextRequestTime = userNextRequest[request.user.versionedId]
136134
val nextRequestTime = Instant.now().plus(SUCCESS_BACK_OFF_TIME)
137135
userNextRequest[request.user.versionedId] =
138-
currentNextRequestTime?.let {
139-
if (currentNextRequestTime > nextRequestTime) {
140-
currentNextRequestTime
141-
} else {
142-
nextRequestTime
143-
}
144-
}
145-
?: nextRequestTime
136+
userNextRequest[request.user.versionedId]?.let {
137+
if (it > nextRequestTime) it else nextRequestTime
138+
} ?: nextRequestTime
146139
} else {
147140
if (request.startDate.plus(TIME_AFTER_REQUEST).isBefore(Instant.now())) {
141+
logger.info("No records found, updating offsets to end date..")
148142
ouraOffsetManager.updateOffsets(
149143
request.route,
150144
request.user,
151145
request.endDate,
152146
)
147+
userNextRequest[request.user.versionedId] = Instant.now().plus(BACK_OFF_TIME)
148+
} else {
149+
userNextRequest[request.user.versionedId] = Instant.now().plus(BACK_OFF_TIME)
153150
}
154151
}
155152
return records
@@ -240,10 +237,10 @@ constructor(
240237
companion object {
241238
private val logger = LoggerFactory.getLogger(OuraRequestGenerator::class.java)
242239
private val BACK_OFF_TIME = Duration.ofMinutes(10L)
243-
private val ONE_DAY = 1L
240+
private val ONE_DAY = Duration.ofDays(1L)
244241
private val TIME_AFTER_REQUEST = Duration.ofDays(30)
245-
private val USER_BACK_OFF_TIME = Duration.ofMinutes(2L)
246-
private val SUCCESS_BACK_OFF_TIME = Duration.ofSeconds(3L)
242+
private val USER_BACK_OFF_TIME = Duration.ofHours(12L)
243+
private val SUCCESS_BACK_OFF_TIME = Duration.ofMinutes(1L)
247244
private val USER_MAX_REQUESTS = 20
248245
val JSON_FACTORY = JsonFactory()
249246
val JSON_READER = ObjectMapper(JSON_FACTORY).registerModule(JavaTimeModule()).reader()

oura-library/src/main/kotlin/org/radarbase/oura/user/OuraUser.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@ data class OuraUser(
1616
@JsonProperty("externalId") override val externalId: String?,
1717
@JsonProperty("isAuthorized") override val isAuthorized: Boolean,
1818
@JsonProperty("startDate") override val startDate: Instant,
19-
@JsonProperty("endDate") override val endDate: Instant,
19+
@JsonProperty("endDate") override val endDate: Instant? = null,
2020
@JsonProperty("version") override val version: String? = null,
2121
@JsonProperty("serviceUserId") override val serviceUserId: String? = null,
2222
) : User {
2323
override val observationKey: ObservationKey = ObservationKey(projectId, userId, sourceId)
2424
override val versionedId: String = "$id${version?.let { "#$it" } ?: ""}"
2525

26-
fun isComplete() = isAuthorized && startDate.isBefore(endDate) && serviceUserId != null
26+
fun isComplete() =
27+
isAuthorized && (endDate == null || startDate.isBefore(endDate)) && serviceUserId != null
2728
}

0 commit comments

Comments
 (0)