Skip to content

Commit 7c8cccb

Browse files
authored
Merge pull request #60 from RADAR-base/release-0.3.1
Release 0.3.1
2 parents 743ebeb + 99fc03c commit 7c8cccb

File tree

16 files changed

+189
-47
lines changed

16 files changed

+189
-47
lines changed

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ COPY ./kafka-connect-fitbit-source/src/ /code/kafka-connect-fitbit-source/src
4040

4141
RUN ./gradlew jar
4242

43-
FROM confluentinc/cp-kafka-connect-base:5.1.0
43+
FROM confluentinc/cp-kafka-connect-base:5.5.0
4444

4545
MAINTAINER Joris Borgdorff <[email protected]>
4646

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ your Fitbit App client ID and client secret. The following tables shows the poss
6363
<tr>
6464
<td>fitbit.user.repository.url</td></td><td>URL for webservice containing user credentials. Only used if a webservice-based user repository is configured.</td></td><td>string</td></td><td>""</td></td><td></td></td><td>low</td></td></tr>
6565
<tr>
66+
<td>fitbit.user.repository.client.id</td></td><td>Client ID for connecting to the service repository.</td></td><td>string</td></td><td>""</td></td><td></td></td><td>medium</td></td></tr>
67+
<tr>
68+
<td>fitbit.user.repository.client.secret</td></td><td>Client secret for connecting to the service repository.</td></td><td>string</td></td><td>""</td></td><td></td></td><td>medium</td></td></tr>
69+
<tr>
70+
<td>fitbit.user.repository.oauth2.token.url</td></td><td>OAuth 2.0 token url for retrieving client credentials.</td></td><td>string</td></td><td>""</td></td><td></td></td><td>medium</td></td></tr>
71+
<tr>
6672
<td>fitbit.intraday.steps.topic</td></td><td>Topic for Fitbit intraday steps</td></td><td>string</td></td><td>connect_fitbit_intraday_steps</td></td><td>non-empty string without control characters</td></td><td>low</td></td></tr>
6773
<tr>
6874
<td>fitbit.intraday.heart.rate.topic</td></td><td>Topic for Fitbit intraday heart_rate</td></td><td>string</td></td><td>connect_fitbit_intraday_heart_rate</td></td><td>non-empty string without control characters</td></td><td>low</td></td></tr>
@@ -76,8 +82,26 @@ your Fitbit App client ID and client secret. The following tables shows the poss
7682
<td>fitbit.activity.log.topic</td></td><td>Topic for Fitbit activity log.</td></td><td>string</td></td><td>connect_fitbit_activity_log</td></td><td>non-empty string without control characters</td></td><td>low</td></td></tr>
7783
<tr>
7884
<td>fitbit.intraday.calories.topic</td></td><td>Topic for Fitbit intraday calories</td></td><td>string</td></td><td>connect_fitbit_intraday_calories</td></td><td>non-empty string without control characters</td></td><td>low</td></td></tr>
85+
<tr>
86+
<td>fitbit.user.firebase.collection.fitbit.name</td></td><td>Firestore Collection for retrieving Fitbit Auth details. Only used when a Firebase based user repository is used.</td></td><td>string</td></td><td>fitbit</td></td><td></td></td><td>low</td></td></tr>
87+
<tr>
88+
<td>fitbit.user.firebase.collection.user.name</td></td><td>Firestore Collection for retrieving User details. Only used when a Firebase based user repository is used.</td></td><td>string</td></td><td>users</td></td><td></td></td><td>low</td></td></tr>
7989
</tbody></table>
8090

91+
If the ManagementPortal is used to authenticate against the user repository, please add an OAuth client to ManagementPortal with the following properties:
92+
93+
```
94+
Client ID: fitbit.user.repository.client.id
95+
Client Secret: fitbit.user.repository.client.secret
96+
Scope: SUBJECT.READ
97+
Resources: res_restAuthorizer
98+
Grant types: client_credentials
99+
Access Token validity: 600
100+
Refresh Token validity: 0
101+
```
102+
103+
Finally set the `fitbit.user.repository.oauth.token.url` to `http://managementportal-app:8080/managementportal/oauth/token`.
104+
81105
Now you can run a full Kafka stack using
82106

83107
```shell

build.gradle

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@ description = 'kafka-connect-rest-source'
22

33
subprojects {
44
ext {
5-
kafkaVersion = '2.2.0-cp2'
6-
confluentVersion = '5.2.1'
7-
jacksonVersion = '2.9.9'
5+
kafkaVersion = '2.5.0'
6+
confluentVersion = '5.5.0'
7+
jacksonVersion = '2.11.0'
88
}
99

1010
apply plugin: 'java'
1111
apply plugin: 'java-library'
1212

1313
group = 'org.radarbase'
14-
version = '0.3.0'
14+
version = '0.3.1'
1515

1616
sourceCompatibility = 1.8
1717
targetCompatibility = 1.8
@@ -21,12 +21,13 @@ subprojects {
2121
maven { url "https://packages.confluent.io/maven/" }
2222
maven { url "https://repo.maven.apache.org/maven2" }
2323
jcenter()
24+
maven { url "https://dl.bintray.com/radar-cns/org.radarcns" }
2425
maven { url 'https://oss.jfrog.org/artifactory/oss-snapshot-local/' }
2526
}
2627
}
2728

2829
wrapper {
29-
gradleVersion '5.4.1'
30+
gradleVersion '6.4.1'
3031
}
3132

3233
evaluationDependsOnChildren()

docker/kafka-wait

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,11 @@ max_timeout=32
1818
tries=10
1919
timeout=1
2020
while true; do
21-
ZOOKEEPER_CHECK=$(zookeeper-shell ${CONNECT_ZOOKEEPER_CONNECT} <<< "ls /brokers/ids" | tail -2 | head -1)
21+
ZOOKEEPER_CHECK=$(zookeeper-shell ${CONNECT_ZOOKEEPER_CONNECT} <<< "ls /brokers/ids" | tail -n 1)
2222
echo "Zookeeper response: ${ZOOKEEPER_CHECK}"
23-
# ZOOKEEPER_CHECK="${ZOOKEEPER_CHECK##*$'\n'}"
2423
ZOOKEEPER_CHECK="$(echo -e "${ZOOKEEPER_CHECK}" | tr -d '[:space:]' | tr -d '[' | tr -d ']')"
2524

26-
IFS=',' read -r -a array <<< ${ZOOKEEPER_CHECK}
25+
IFS=',' read -r -a array <<< "${ZOOKEEPER_CHECK}"
2726
LENGTH=${#array[@]}
2827
if [ "$LENGTH" -eq "$KAFKA_BROKERS" ]; then
2928
echo "Kafka brokers available."

gradle/wrapper/gradle-wrapper.jar

3.22 KB
Binary file not shown.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-bin.zip
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists

gradlew

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
# you may not use this file except in compliance with the License.
88
# You may obtain a copy of the License at
99
#
10-
# http://www.apache.org/licenses/LICENSE-2.0
10+
# https://www.apache.org/licenses/LICENSE-2.0
1111
#
1212
# Unless required by applicable law or agreed to in writing, software
1313
# distributed under the License is distributed on an "AS IS" BASIS,
@@ -82,6 +82,7 @@ esac
8282

8383
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
8484

85+
8586
# Determine the Java command to use to start the JVM.
8687
if [ -n "$JAVA_HOME" ] ; then
8788
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
@@ -125,10 +126,11 @@ if $darwin; then
125126
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
126127
fi
127128

128-
# For Cygwin, switch paths to Windows format before running java
129-
if $cygwin ; then
129+
# For Cygwin or MSYS, switch paths to Windows format before running java
130+
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
130131
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
131132
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
133+
132134
JAVACMD=`cygpath --unix "$JAVACMD"`
133135

134136
# We build the pattern for arguments to be converted via cygpath
@@ -154,19 +156,19 @@ if $cygwin ; then
154156
else
155157
eval `echo args$i`="\"$arg\""
156158
fi
157-
i=$((i+1))
159+
i=`expr $i + 1`
158160
done
159161
case $i in
160-
(0) set -- ;;
161-
(1) set -- "$args0" ;;
162-
(2) set -- "$args0" "$args1" ;;
163-
(3) set -- "$args0" "$args1" "$args2" ;;
164-
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
165-
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
166-
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
167-
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
168-
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
169-
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
162+
0) set -- ;;
163+
1) set -- "$args0" ;;
164+
2) set -- "$args0" "$args1" ;;
165+
3) set -- "$args0" "$args1" "$args2" ;;
166+
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
167+
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
168+
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
169+
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
170+
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
171+
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
170172
esac
171173
fi
172174

@@ -175,14 +177,9 @@ save () {
175177
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
176178
echo " "
177179
}
178-
APP_ARGS=$(save "$@")
180+
APP_ARGS=`save "$@"`
179181

180182
# Collect all arguments for the java command, following the shell quoting and substitution rules
181183
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
182184

183-
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
184-
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
185-
cd "$(dirname "$0")"
186-
fi
187-
188185
exec "$JAVACMD" "$@"

gradlew.bat

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
@rem you may not use this file except in compliance with the License.
66
@rem You may obtain a copy of the License at
77
@rem
8-
@rem http://www.apache.org/licenses/LICENSE-2.0
8+
@rem https://www.apache.org/licenses/LICENSE-2.0
99
@rem
1010
@rem Unless required by applicable law or agreed to in writing, software
1111
@rem distributed under the License is distributed on an "AS IS" BASIS,
@@ -29,6 +29,9 @@ if "%DIRNAME%" == "" set DIRNAME=.
2929
set APP_BASE_NAME=%~n0
3030
set APP_HOME=%DIRNAME%
3131

32+
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
33+
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34+
3235
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
3336
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
3437

@@ -81,6 +84,7 @@ set CMD_LINE_ARGS=%*
8184

8285
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
8386

87+
8488
@rem Execute Gradle
8589
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
8690

kafka-connect-fitbit-source/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ dependencies {
33
api group: 'io.confluent', name: 'kafka-connect-avro-converter', version: confluentVersion
44
api group: 'org.radarcns', name: 'radar-schemas-commons', version: '0.5.3'
55

6+
implementation group: 'org.radarcns', name: 'oauth-client-util', version: '0.5.8'
67

78
implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: jacksonVersion
89
implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: jacksonVersion

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

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import static org.apache.kafka.common.config.ConfigDef.NO_DEFAULT_VALUE;
2121

2222
import java.lang.reflect.InvocationTargetException;
23+
import java.net.MalformedURLException;
24+
import java.net.URL;
2325
import java.nio.charset.StandardCharsets;
2426
import java.nio.file.Path;
2527
import java.nio.file.Paths;
@@ -122,6 +124,19 @@ public class FitbitRestSourceConnectorConfig extends RestSourceConnectorConfig {
122124
private static final String FITBIT_INTRADAY_CALORIES_TOPIC_DISPLAY = "Intraday calories topic";
123125
private static final String FITBIT_INTRADAY_CALORIES_TOPIC_DEFAULT = "connect_fitbit_intraday_calories";
124126

127+
128+
public static final String FITBIT_USER_REPOSITORY_CLIENT_ID_CONFIG = "fitbit.user.repository.client.id";
129+
private static final String FITBIT_USER_REPOSITORY_CLIENT_ID_DOC = "Client ID for connecting to the service repository.";
130+
private static final String FITBIT_USER_REPOSITORY_CLIENT_ID_DISPLAY = "Client ID for user repository.";
131+
132+
public static final String FITBIT_USER_REPOSITORY_CLIENT_SECRET_CONFIG = "fitbit.user.repository.client.secret";
133+
private static final String FITBIT_USER_REPOSITORY_CLIENT_SECRET_DOC = "Client secret for connecting to the service repository.";
134+
private static final String FITBIT_USER_REPOSITORY_CLIENT_SECRET_DISPLAY = "Client Secret for user repository.";
135+
136+
public static final String FITBIT_USER_REPOSITORY_TOKEN_URL_CONFIG = "fitbit.user.repository.oauth2.token.url";
137+
private static final String FITBIT_USER_REPOSITORY_TOKEN_URL_DOC = "OAuth 2.0 token url for retrieving client credentials.";
138+
private static final String FITBIT_USER_REPOSITORY_TOKEN_URL_DISPLAY = "OAuth 2.0 token URL.";
139+
125140
public static final String FITBIT_USER_REPOSITORY_FIRESTORE_FITBIT_COLLECTION_CONFIG = "fitbit.user.firebase.collection.fitbit.name";
126141
private static final String FITBIT_USER_REPOSITORY_FIRESTORE_FITBIT_COLLECTION_DOC = "Firestore Collection for retrieving Fitbit Auth details. Only used when a Firebase based user repository is used.";
127142
private static final String FITBIT_USER_REPOSITORY_FIRESTORE_FITBIT_COLLECTION_DISPLAY = "Firebase Fitbit collection name.";
@@ -242,6 +257,37 @@ public String toString() {
242257
Width.SHORT,
243258
FITBIT_USER_REPOSITORY_URL_DISPLAY)
244259

260+
261+
.define(FITBIT_USER_REPOSITORY_CLIENT_ID_CONFIG,
262+
Type.STRING,
263+
"",
264+
Importance.MEDIUM,
265+
FITBIT_USER_REPOSITORY_CLIENT_ID_DOC,
266+
group,
267+
++orderInGroup,
268+
Width.SHORT,
269+
FITBIT_USER_REPOSITORY_CLIENT_ID_DISPLAY)
270+
271+
.define(FITBIT_USER_REPOSITORY_CLIENT_SECRET_CONFIG,
272+
Type.PASSWORD,
273+
"",
274+
Importance.MEDIUM,
275+
FITBIT_USER_REPOSITORY_CLIENT_SECRET_DOC,
276+
group,
277+
++orderInGroup,
278+
Width.SHORT,
279+
FITBIT_USER_REPOSITORY_CLIENT_SECRET_DISPLAY)
280+
281+
.define(FITBIT_USER_REPOSITORY_TOKEN_URL_CONFIG,
282+
Type.STRING,
283+
"",
284+
Importance.MEDIUM,
285+
FITBIT_USER_REPOSITORY_TOKEN_URL_DOC,
286+
group,
287+
++orderInGroup,
288+
Width.SHORT,
289+
FITBIT_USER_REPOSITORY_TOKEN_URL_DISPLAY)
290+
245291
.define(FITBIT_INTRADAY_STEPS_TOPIC_CONFIG,
246292
Type.STRING,
247293
FITBIT_INTRADAY_STEPS_TOPIC_DEFAULT,
@@ -447,4 +493,25 @@ public String getFitbitUserRepositoryFirestoreFitbitCollection() {
447493
public String getFitbitUserRepositoryFirestoreUserCollection() {
448494
return getString(FITBIT_USER_REPOSITORY_FIRESTORE_USER_COLLECTION_CONFIG);
449495
}
496+
497+
public String getFitbitUserRepositoryClientId() {
498+
return getString(FITBIT_USER_REPOSITORY_CLIENT_ID_CONFIG);
499+
}
500+
501+
public String getFitbitUserRepositoryClientSecret() {
502+
return getPassword(FITBIT_USER_REPOSITORY_CLIENT_SECRET_CONFIG).value();
503+
}
504+
505+
public URL getFitbitUserRepositoryTokenUrl() {
506+
String value = getString(FITBIT_USER_REPOSITORY_TOKEN_URL_CONFIG);
507+
if (value == null || value.isEmpty()) {
508+
return null;
509+
} else {
510+
try {
511+
return new URL(getString(FITBIT_USER_REPOSITORY_TOKEN_URL_CONFIG));
512+
} catch (MalformedURLException e) {
513+
throw new ConfigException("Fitbit user repository token URL is invalid.");
514+
}
515+
}
516+
}
450517
}

0 commit comments

Comments
 (0)