Skip to content

Commit 9cb55d8

Browse files
Merge pull request #71 from RADAR-base/release-0.3.2
Release 0.3.2
2 parents fb42fc4 + a3f38c0 commit 9cb55d8

File tree

13 files changed

+86
-39
lines changed

13 files changed

+86
-39
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ subprojects {
1111
apply plugin: 'java-library'
1212

1313
group = 'org.radarbase'
14-
version = '0.3.2-SNAPSHOT'
14+
version = '0.3.2'
1515

1616
sourceCompatibility = 1.8
1717
targetCompatibility = 1.8

docker-compose.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ services:
99
# Zookeeper Cluster #
1010
#---------------------------------------------------------------------------#
1111
zookeeper-1:
12-
image: confluentinc/cp-zookeeper:5.1.0
12+
image: confluentinc/cp-zookeeper:5.5.1
1313
environment:
1414
ZOOKEEPER_SERVER_ID: 1
1515
ZOOKEEPER_CLIENT_PORT: 2181
@@ -19,7 +19,7 @@ services:
1919
ZOOKEEPER_SERVERS: zookeeper-1:2888:3888;zookeeper-2:2888:3888;zookeeper-3:2888:3888
2020

2121
zookeeper-2:
22-
image: confluentinc/cp-zookeeper:5.1.0
22+
image: confluentinc/cp-zookeeper:5.5.1
2323
environment:
2424
ZOOKEEPER_SERVER_ID: 2
2525
ZOOKEEPER_CLIENT_PORT: 2181
@@ -29,7 +29,7 @@ services:
2929
ZOOKEEPER_SERVERS: zookeeper-1:2888:3888;zookeeper-2:2888:3888;zookeeper-3:2888:3888
3030

3131
zookeeper-3:
32-
image: confluentinc/cp-zookeeper:5.1.0
32+
image: confluentinc/cp-zookeeper:5.5.1
3333
environment:
3434
ZOOKEEPER_SERVER_ID: 3
3535
ZOOKEEPER_CLIENT_PORT: 2181
@@ -42,7 +42,7 @@ services:
4242
# Kafka Cluster #
4343
#---------------------------------------------------------------------------#
4444
kafka-1:
45-
image: confluentinc/cp-kafka:5.1.0
45+
image: confluentinc/cp-kafka:5.5.1
4646
depends_on:
4747
- zookeeper-1
4848
- zookeeper-2
@@ -61,7 +61,7 @@ services:
6161
KAFKA_CONFLUENT_SUPPORT_METRICS_ENABLE: "false"
6262

6363
kafka-2:
64-
image: confluentinc/cp-kafka:5.1.0
64+
image: confluentinc/cp-kafka:5.5.1
6565
depends_on:
6666
- zookeeper-1
6767
- zookeeper-2
@@ -80,7 +80,7 @@ services:
8080
KAFKA_CONFLUENT_SUPPORT_METRICS_ENABLE: "false"
8181

8282
kafka-3:
83-
image: confluentinc/cp-kafka:5.1.0
83+
image: confluentinc/cp-kafka:5.5.1
8484
depends_on:
8585
- zookeeper-1
8686
- zookeeper-2
@@ -102,7 +102,7 @@ services:
102102
# Schema Registry #
103103
#---------------------------------------------------------------------------#
104104
schema-registry-1:
105-
image: confluentinc/cp-schema-registry:5.1.0
105+
image: confluentinc/cp-schema-registry:5.5.1
106106
depends_on:
107107
- zookeeper-1
108108
- zookeeper-2
@@ -124,7 +124,7 @@ services:
124124
# REST proxy #
125125
#---------------------------------------------------------------------------#
126126
rest-proxy-1:
127-
image: confluentinc/cp-kafka-rest:5.1.0
127+
image: confluentinc/cp-kafka-rest:5.5.1
128128
depends_on:
129129
- zookeeper-1
130130
- zookeeper-2

kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/converter/FitbitAvroConverter.java

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,14 @@
2727
import java.util.Collection;
2828
import java.util.Collections;
2929
import java.util.HashMap;
30-
import java.util.Iterator;
3130
import java.util.Map;
32-
import java.util.Objects;
3331
import java.util.Optional;
34-
import java.util.OptionalDouble;
35-
import java.util.OptionalLong;
3632
import java.util.concurrent.TimeUnit;
3733
import java.util.stream.Collectors;
3834
import java.util.stream.Stream;
3935
import java.util.stream.StreamSupport;
40-
import okhttp3.Response;
41-
import okhttp3.ResponseBody;
36+
import okhttp3.Headers;
37+
import org.apache.avro.Schema.Field;
4238
import org.apache.avro.generic.IndexedRecord;
4339
import org.apache.kafka.connect.data.SchemaAndValue;
4440
import org.apache.kafka.connect.source.SourceRecord;
@@ -74,19 +70,18 @@ public FitbitAvroConverter(AvroData avroData) {
7470

7571
@Override
7672
public Collection<SourceRecord> convert(
77-
RestRequest restRequest, Response response) throws IOException {
78-
ResponseBody body = response.body();
79-
if (body == null) {
73+
RestRequest restRequest, Headers headers, byte[] data) throws IOException {
74+
if (data == null) {
8075
throw new IOException("Failed to read body");
8176
}
82-
JsonNode activities = JSON_READER.readTree(body.charStream());
77+
JsonNode activities = JSON_READER.readTree(data);
8378

8479
User user = ((FitbitRestRequest) restRequest).getUser();
8580
final SchemaAndValue key = user.getObservationKey(avroData);
8681
double timeReceived = System.currentTimeMillis() / 1000d;
8782

8883
return processRecords((FitbitRestRequest)restRequest, activities, timeReceived)
89-
.filter(Objects::nonNull)
84+
.filter(t -> validateRecord((FitbitRestRequest)restRequest, t))
9085
.map(t -> {
9186
SchemaAndValue avro = avroData.toConnectData(t.value.getSchema(), t.value);
9287
Map<String, ?> offset = Collections.singletonMap(
@@ -98,6 +93,22 @@ public Collection<SourceRecord> convert(
9893
.collect(Collectors.toList());
9994
}
10095

96+
private boolean validateRecord(FitbitRestRequest request, TopicData record) {
97+
if (record == null) {
98+
return false;
99+
}
100+
Instant endDate = request.getUser().getEndDate();
101+
if (endDate == null) {
102+
return true;
103+
}
104+
Field timeField = record.value.getSchema().getField("time");
105+
if (timeField != null) {
106+
long time = (long) (((Double)record.value.get(timeField.pos()) * 1000.0));
107+
return Instant.ofEpochMilli(time).isBefore(endDate);
108+
}
109+
return true;
110+
}
111+
101112
/** Process the JSON records generated by given request. */
102113
protected abstract Stream<TopicData> processRecords(
103114
FitbitRestRequest request,

kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/route/FitbitPollingRoute.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ protected Duration getLookbackTime() {
312312
*/
313313
protected Instant nextPoll(User user) {
314314
Instant offset = getOffset(user);
315-
if (offset.isAfter(user.getEndDate())) {
315+
if (offset.isAfter(user.getEndDate().minus(getEndDateThreshold()))) {
316316
return nearFuture();
317317
} else {
318318
Instant nextPoll = lastPollPerUser.getOrDefault(user.getId(), MIN_INSTANT)
@@ -321,6 +321,10 @@ protected Instant nextPoll(User user) {
321321
}
322322
}
323323

324+
private TemporalAmount getEndDateThreshold() {
325+
return Duration.ofHours(1);
326+
}
327+
324328
/**
325329
* Generate one date per day, using UTC time zone. The first date will have the time from the
326330
* given startDate. Following time stamps will start at 00:00. This will not up to the date of

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ public class LocalUser implements User {
4545
@JsonProperty("oauth2")
4646
private OAuth2UserCredentials oauth2Credentials = new OAuth2UserCredentials();
4747

48+
@JsonProperty("authorized")
49+
private Boolean isAuthorized;
50+
4851
@JsonIgnore
4952
private SchemaAndValue observationKey;
5053

@@ -95,6 +98,15 @@ public void setFitbitUserId(String id) {
9598
this.externalUserId = id;
9699
}
97100

101+
@Override
102+
public boolean isAuthorized() {
103+
if(isAuthorized == null) {
104+
return !oauth2Credentials.isAccessTokenExpired()
105+
|| oauth2Credentials.hasRefreshToken();
106+
}
107+
return isAuthorized;
108+
}
109+
98110
@Override
99111
public String getVersion() {
100112
return version;
@@ -115,6 +127,7 @@ public LocalUser copy() {
115127
copy.endDate = endDate;
116128
copy.sourceId = sourceId;
117129
copy.oauth2Credentials = oauth2Credentials;
130+
copy.isAuthorized = isAuthorized;
118131
return copy;
119132
}
120133

@@ -133,6 +146,7 @@ public String toString() {
133146
+ ", projectId='" + projectId + '\''
134147
+ ", userId='" + userId + '\''
135148
+ ", sourceId='" + sourceId + '\''
149+
+ ", isAuthorized='" + isAuthorized() + '\''
136150
+ '}';
137151
}
138152

@@ -152,7 +166,8 @@ public boolean equals(Object o) {
152166
&& Objects.equals(userId, localUser.userId)
153167
&& Objects.equals(sourceId, localUser.sourceId)
154168
&& Objects.equals(startDate, localUser.startDate)
155-
&& Objects.equals(endDate, localUser.endDate);
169+
&& Objects.equals(endDate, localUser.endDate)
170+
&& Objects.equals(isAuthorized(), localUser.isAuthorized());
156171
}
157172

158173
@Override

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ static SchemaAndValue computeObservationKey(AvroData avroData, User user) {
4545

4646
String getSourceId();
4747

48+
boolean isAuthorized();
49+
4850
default String getVersionedId() {
4951
String version = getVersion();
5052
if (version == null) {
@@ -60,6 +62,7 @@ default Boolean isComplete() {
6062
return getEndDate() != null
6163
&& getStartDate() != null
6264
&& getProjectId() != null
63-
&& getUserId() != null;
65+
&& getUserId() != null
66+
&& isAuthorized();
6467
}
6568
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ private void forceUpdateUsers() {
132132

133133
@Override
134134
public Stream<LocalUser> stream() {
135+
if (nextFetch.get().equals(MIN_INSTANT)) {
136+
applyPendingUpdates();
137+
}
135138
Stream<LockedUser> users = this.users.values().stream()
136139
.filter(lockedTest(u -> u.getOAuth2Credentials().hasRefreshToken()));
137140
if (!configuredUsers.isEmpty()) {

kafka-connect-fitbit-source/src/main/java/org/radarbase/connect/rest/fitbit/user/firebase/FirebaseUser.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@ public String getSourceId() {
7070
return fitbitAuthDetails.getSourceId();
7171
}
7272

73+
@Override
74+
public boolean isAuthorized() {
75+
return !fitbitAuthDetails.getOauth2Credentials().isAccessTokenExpired()
76+
|| fitbitAuthDetails.getOauth2Credentials().hasRefreshToken();
77+
}
78+
7379
public FirebaseUserDetails getFirebaseUserDetails() {
7480
return firebaseUserDetails;
7581
}

kafka-connect-rest-source/src/main/java/org/radarbase/connect/rest/converter/BytesPayloadConverter.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.Collection;
2424
import java.util.Collections;
2525
import java.util.Map;
26+
import okhttp3.Headers;
2627
import okhttp3.Response;
2728
import okhttp3.ResponseBody;
2829
import org.apache.kafka.connect.data.Schema;
@@ -36,15 +37,13 @@ public class BytesPayloadConverter implements PayloadToSourceRecordConverter {
3637

3738
// Just bytes for incoming messages
3839
@Override
39-
public Collection<SourceRecord> convert(RestRequest request, Response response) throws IOException {
40+
public Collection<SourceRecord> convert(RestRequest request, Headers headers, byte[] data) {
4041
Map<String, Long> sourceOffset = Collections.singletonMap(
4142
TIMESTAMP_OFFSET_KEY, currentTimeMillis());
42-
ResponseBody body = response.body();
43-
byte[] result = body != null ? body.bytes() : null;
44-
String topic = topicSelector.getTopic(request, result);
43+
String topic = topicSelector.getTopic(request, data);
4544
return Collections.singleton(
4645
new SourceRecord(request.getPartition(), sourceOffset,
47-
topic, Schema.BYTES_SCHEMA, result));
46+
topic, Schema.BYTES_SCHEMA, data));
4847
}
4948

5049
@Override

kafka-connect-rest-source/src/main/java/org/radarbase/connect/rest/converter/PayloadToSourceRecordConverter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
import java.time.Instant;
2323
import java.time.temporal.TemporalAmount;
2424
import java.util.Collection;
25-
import okhttp3.Response;
25+
import okhttp3.Headers;
2626
import org.apache.kafka.connect.source.SourceRecord;
2727
import org.radarbase.connect.rest.config.RestSourceTool;
2828
import org.radarbase.connect.rest.request.RestRequest;
@@ -33,7 +33,7 @@ public interface PayloadToSourceRecordConverter extends RestSourceTool {
3333
TemporalAmount NEAR_FUTURE = Duration.ofDays(31L);
3434

3535
Collection<SourceRecord> convert(
36-
RestRequest request, Response response) throws IOException;
36+
RestRequest request, Headers headers, byte[] data) throws IOException;
3737

3838
static Instant nearFuture() {
3939
return Instant.now().plus(NEAR_FUTURE);

0 commit comments

Comments
 (0)