Skip to content

Commit 52a509e

Browse files
authored
Merge pull request #178 from RADAR-base/release-1.1.4
Release 1.1.3
2 parents b231a69 + 68afc0c commit 52a509e

File tree

9 files changed

+188
-26
lines changed

9 files changed

+188
-26
lines changed

.github/workflows/publish_snapshots.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
env:
3737
OSSRH_USER: ${{ secrets.OSSRH_USER }}
3838
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
39-
run: ./gradlew -Psigning.gnupg.keyName=CBEF2CF0 -Psigning.gnupg.executable=gpg -Psigning.gnupg.passphrase=${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }} publish
39+
run: ./gradlew -Psigning.gnupg.keyName=${{ secrets.OSSRH_GPG_SECRET_KEY_NAME }} -Psigning.gnupg.executable=gpg -Psigning.gnupg.passphrase=${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }} publish
4040

4141
- name: Plugin has SNAPSHOT version
4242
run: ./gradlew :radar-commons-gradle:properties | grep '^version:.*-SNAPSHOT$'
@@ -45,4 +45,4 @@ jobs:
4545
env:
4646
OSSRH_USER: ${{ secrets.OSSRH_USER }}
4747
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
48-
run: ./gradlew -Psigning.gnupg.keyName=CBEF2CF0 -Psigning.gnupg.executable=gpg -Psigning.gnupg.passphrase=${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }} :radar-commons-gradle:publish
48+
run: ./gradlew -Psigning.gnupg.keyName=${{ secrets.OSSRH_GPG_SECRET_KEY_NAME }} -Psigning.gnupg.executable=gpg -Psigning.gnupg.passphrase=${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }} :radar-commons-gradle:publish

buildSrc/src/main/kotlin/Versions.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
@Suppress("ConstPropertyName", "MemberVisibilityCanBePrivate")
22
object Versions {
3-
const val project = "1.1.2"
3+
const val project = "1.1.3"
44

55
object Plugins {
66
const val licenseReport = "2.5"
@@ -17,7 +17,7 @@ object Versions {
1717
const val slf4j = "2.0.13"
1818
const val confluent = "7.6.0"
1919
const val kafka = "${confluent}-ce"
20-
const val avro = "1.11.3"
20+
const val avro = "1.12.0"
2121
const val jackson = "2.15.3"
2222
const val okhttp = "4.12.0"
2323
const val junit = "5.10.0"

radar-commons-gradle/README.md

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22

33
A Gradle plugin to do some common RADAR-base tasks.
44

5+
<!-- TOC -->
6+
* [radar-commons-gradle](#radar-commons-gradle)
7+
* [Usage](#usage)
8+
* [radar-commons-gradle plugin](#radar-commons-gradle-plugin)
9+
* [radarKotlin extension](#radarkotlin-extension)
10+
* [Enable logging with log4j2](#enable-logging-with-log4j2)
11+
* [Enable monitoring with Sentry](#enable-monitoring-with-sentry)
12+
* [Enable Sentry source context](#enable-sentry-source-context)
13+
* [Customizing Sentry configuration](#customizing-sentry-configuration)
14+
<!-- TOC -->
15+
516
## Usage
617

718
Add the following block to `settings.gradle.kts` to get access to the RADAR-base plugins.
@@ -51,6 +62,13 @@ subprojects {
5162
kotlinVersion.set(Versions.Plugins.kotlin) // already has a default value
5263
junitVersion.set(Versions.junit) // already has a default value
5364
ktlintVersion.set(Versions.ktlint) // already has a default value
65+
slf4jVersion.set(Versions.slf4j) // already has a default value
66+
// log4j2Version.set(Versions.log4j2) // setting this will enable log4j2
67+
// sentryVersion.set(Versions.sentry) // setting this will enable Sentry monitoring
68+
// sentryEnabled.set(false) // setting this to true will enable Sentry monitoring
69+
// sentrySourceContextToken.set("") // setting this will upload the source code context to Sentry
70+
// sentryOrganization.set("radar-base") // already has a default value, only needed when setting 'sentrySourceContextToken'
71+
// sentryProject.set("") // already has a default value, only needed when setting 'sentrySourceContextToken'
5472
}
5573
5674
// Both values are required to be set to use radar-publishing.
@@ -68,3 +86,103 @@ subprojects {
6886
}
6987
}
7088
```
89+
90+
## radar-commons-gradle plugin
91+
92+
This plugin provides the basics for RADAR-base projects.
93+
94+
### radarKotlin extension
95+
96+
#### Enable logging with log4j2
97+
98+
By default, no logging implementation is added to projects (only the slf4j interface is included). To enable log4j2, add
99+
the following to your root project configurations:
100+
101+
```gradle
102+
...
103+
subprojects {
104+
...
105+
radarKotlin {
106+
log4j2Version.set(Versions.log4j2)
107+
}
108+
...
109+
}
110+
```
111+
112+
#### Enable monitoring with Sentry
113+
114+
1. Activate log4j2 logging (see [above](#enable-logging-with-log4j2))
115+
2. Activate Sentry in the _radarKotlin_ extension:
116+
117+
```gradle
118+
...
119+
subprojects {
120+
...
121+
radarKotlin {
122+
sentryEnabled.set(true)
123+
}
124+
...
125+
}
126+
```
127+
128+
3. Add a Sentry log Appender to the `log4j2.xml` configuration file to `src/main/resources`. For example:
129+
130+
```xml
131+
132+
<configuration status="warn">
133+
<appenders>
134+
<Console name="Console" target="SYSTEM_OUT">
135+
<PatternLayout
136+
pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"
137+
/>
138+
</Console>
139+
<Sentry name="Sentry" debug="false"/>
140+
</appenders>
141+
142+
<loggers>
143+
<root level="INFO">
144+
<appender-ref ref="Console"/>
145+
<appender-ref ref="Sentry" level="WARN"/>
146+
</root>
147+
</loggers>
148+
</configuration>
149+
```
150+
151+
4. Set the `SENTRY_DSN` environment variable at runtime to the DSN of your Sentry project.
152+
153+
#### Enable Sentry source context
154+
155+
Sentry can be configured to show the source code context of the error. For this to work, source code can be uploaded
156+
to the target sentry organization and project during the build phase. To enable this, set the following values:
157+
158+
```gradle
159+
...
160+
subprojects {
161+
...
162+
radarKotlin {
163+
sentrySourceContextToken.set("my-token")
164+
sentryOrganization.set("my-organization")
165+
sentryProject.set("my-project")
166+
}
167+
...
168+
}
169+
```
170+
171+
NOTE: The organization and project must correspond to the values for the monitoring environment in Sentry. The
172+
organization and project are encooded in Sentry OAuth token.
173+
174+
#### Customizing Sentry configuration
175+
176+
In a project that uses radar-commons-gradle, the Sentry configuration can be customized by using the _sentry_ extension
177+
like for instance:
178+
179+
build.gradle.kts
180+
181+
```gradle
182+
sentry {
183+
debug = true
184+
...
185+
}
186+
...
187+
188+
Additional information on config options: https://docs.sentry.io/platforms/java/guides/log4j2/gradle/

radar-commons-gradle/build.gradle.kts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ dependencies {
2929
implementation("com.github.ben-manes:gradle-versions-plugin:${Versions.gradleVersionsPlugin}")
3030
implementation("io.github.gradle-nexus:publish-plugin:${Versions.Plugins.publishPlugin}")
3131
implementation("org.jlleitschuh.gradle:ktlint-gradle:${Versions.ktlint}")
32-
implementation("com.github.jk1.dependency-license-report:com.github.jk1.dependency-license-report.gradle.plugin:${Versions.Plugins.licenseReport}")
32+
implementation(
33+
"com.github.jk1.dependency-license-report:com.github.jk1.dependency-license-report.gradle.plugin:${Versions.Plugins.licenseReport}",
34+
)
35+
implementation("io.sentry.jvm.gradle:io.sentry.jvm.gradle.gradle.plugin:${Versions.sentry}")
3336
}
3437

3538
gradlePlugin {
@@ -69,7 +72,7 @@ tasks.withType<Jar> {
6972
manifest {
7073
attributes(
7174
"Implementation-Title" to project.name,
72-
"Implementation-Version" to project.version
75+
"Implementation-Version" to project.version,
7376
)
7477
}
7578
}
@@ -135,13 +138,15 @@ publishing {
135138
}
136139
}
137140

138-
fun Project.propertyOrEnv(propertyName: String, envName: String): String? {
139-
return if (hasProperty(propertyName)) {
141+
fun Project.propertyOrEnv(
142+
propertyName: String,
143+
envName: String,
144+
): String? =
145+
if (hasProperty(propertyName)) {
140146
property(propertyName)?.toString()
141147
} else {
142148
System.getenv(envName)
143149
}
144-
}
145150

146151
nexusPublishing {
147152
this.repositories {
@@ -176,7 +181,7 @@ tasks.withType<PublishToMavenRepository> {
176181
// They should be copied from the Versions.kt file directly to maintain consistency.
177182
@Suppress("ConstPropertyName", "MemberVisibilityCanBePrivate")
178183
object Versions {
179-
const val project = "1.1.2"
184+
const val project = "1.1.3"
180185

181186
object Plugins {
182187
const val licenseReport = "2.5"
@@ -192,8 +197,8 @@ object Versions {
192197
const val java = 17
193198
const val slf4j = "2.0.13"
194199
const val confluent = "7.6.0"
195-
const val kafka = "${confluent}-ce"
196-
const val avro = "1.11.3"
200+
const val kafka = "$confluent-ce"
201+
const val avro = "1.12.0"
197202
const val jackson = "2.15.3"
198203
const val okhttp = "4.12.0"
199204
const val junit = "5.10.0"
@@ -209,4 +214,5 @@ object Versions {
209214
const val guava = "32.1.1-jre"
210215
const val gradleVersionsPlugin = "0.50.0"
211216
const val ktlint = "12.0.3"
217+
const val sentry = "4.10.0"
212218
}

radar-commons-gradle/src/main/kotlin/org/radarbase/gradle/plugin/RadarKotlinPlugin.kt

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package org.radarbase.gradle.plugin
22

33
import com.github.jk1.license.LicenseReportPlugin
4+
import io.sentry.android.gradle.extensions.SentryPluginExtension
5+
import io.sentry.jvm.gradle.SentryJvmPlugin
46
import org.gradle.api.Plugin
57
import org.gradle.api.Project
68
import org.gradle.api.plugins.ApplicationPlugin
@@ -42,6 +44,10 @@ interface RadarKotlinExtension {
4244
val log4j2Version: Property<String>
4345
val slf4jVersion: Property<String>
4446
val ktlintVersion: Property<String>
47+
val sentryEnabled: Property<Boolean>
48+
val sentryOrganization: Property<String>
49+
val sentryProject: Property<String>
50+
val sentrySourceContextToken: Property<String>
4551
}
4652

4753
class RadarKotlinPlugin : Plugin<Project> {
@@ -52,12 +58,19 @@ class RadarKotlinPlugin : Plugin<Project> {
5258
kotlinApiVersion.convention("")
5359
junitVersion.convention(Versions.junit)
5460
ktlintVersion.convention(Versions.ktlint)
55-
slf4jVersion.convention(Versions.ktlint)
61+
slf4jVersion.convention(Versions.slf4j)
62+
sentryEnabled.convention(false)
63+
sentryOrganization.convention("radar-base")
64+
sentryProject.convention(project.name)
65+
sentrySourceContextToken.convention("")
5666
}
5767

5868
apply(plugin = "kotlin")
5969
apply<KtlintPlugin>()
6070

71+
// SentryJvmPlugin will be removed in afterEvaluate when sentryEnabled == false.
72+
apply<SentryJvmPlugin>()
73+
6174
repositories {
6275
mavenCentral {
6376
mavenContent {
@@ -162,6 +175,20 @@ class RadarKotlinPlugin : Plugin<Project> {
162175
implementation("org.slf4j:slf4j-api:${extension.slf4jVersion.get()}")
163176
}
164177
}
178+
if (extension.sentryEnabled.get()) {
179+
val sentry = extensions.get("sentry") as SentryPluginExtension
180+
sentry.org.set(extension.sentryOrganization)
181+
sentry.projectName.set(extension.sentryProject)
182+
if (extension.sentrySourceContextToken.isPresent &&
183+
extension.sentrySourceContextToken.get().isNotEmpty()
184+
) {
185+
// Passing the source context token will activate upload of our source code to Sentry.
186+
sentry.includeSourceContext.set(true)
187+
sentry.authToken.set(extension.sentrySourceContextToken)
188+
}
189+
} else {
190+
plugins.removeIf({ it is SentryJvmPlugin })
191+
}
165192
if (extension.log4j2Version.isPresent) {
166193
dependencies {
167194
val log4j2Version = extension.log4j2Version.get()
@@ -171,6 +198,10 @@ class RadarKotlinPlugin : Plugin<Project> {
171198
runtimeOnly("org.apache.logging.log4j:log4j-slf4j2-impl:$log4j2Version")
172199
runtimeOnly("org.apache.logging.log4j:log4j-core:$log4j2Version")
173200
runtimeOnly("org.apache.logging.log4j:log4j-jul:$log4j2Version")
201+
if (extension.sentryEnabled.get()) {
202+
val annotationProcessor by configurations
203+
annotationProcessor("org.apache.logging.log4j:log4j-core:$log4j2Version")
204+
}
174205
} else {
175206
val testRuntimeOnly by configurations
176207
testRuntimeOnly("org.apache.logging.log4j:log4j-slf4j2-impl:$log4j2Version")

radar-commons-gradle/src/main/kotlin/org/radarbase/gradle/plugin/Versions.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ object Versions {
66
const val ktlint = "0.50.0"
77
const val java = 11
88
const val junit = "5.10.0"
9+
const val slf4j = "2.0.16"
910
}

radar-commons-kotlin/src/main/kotlin/org/radarbase/ktor/auth/ClientCredentialsConfig.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ data class ClientCredentialsConfig(
66
val tokenUrl: String,
77
val clientId: String? = null,
88
val clientSecret: String? = null,
9+
val scope: String? = null,
10+
val audience: String? = null,
911
) {
1012
/**
1113
* Fill in the client ID and client secret from environment variables. The variables are

radar-commons-kotlin/src/main/kotlin/org/radarbase/ktor/auth/OAuthClientProvider.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ fun Auth.clientCredentials(
5656
append("grant_type", "client_credentials")
5757
append("client_id", authConfig.clientId)
5858
append("client_secret", authConfig.clientSecret)
59+
authConfig.scope?.let { append("scope", it) }
60+
authConfig.audience?.let { append("audience", it) }
5961
},
6062
) {
6163
accept(ContentType.Application.Json)

radar-commons/src/test/java/org/radarbase/data/AvroDatumEncoderTest.java

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@
1616

1717
package org.radarbase.data;
1818

19-
import java.io.IOException;
20-
import java.util.Arrays;
21-
import java.util.UUID;
22-
import java.util.concurrent.ThreadLocalRandom;
2319
import junit.framework.TestCase;
2420
import org.apache.avro.specific.SpecificData;
2521
import org.radarbase.topic.AvroTopic;
@@ -29,9 +25,22 @@
2925
import org.slf4j.Logger;
3026
import org.slf4j.LoggerFactory;
3127

28+
import java.io.IOException;
29+
import java.util.UUID;
30+
import java.util.concurrent.ThreadLocalRandom;
31+
32+
import static org.junit.Assert.assertArrayEquals;
33+
3234
public class AvroDatumEncoderTest extends TestCase {
3335
private static final Logger logger = LoggerFactory.getLogger(AvroDatumEncoderTest.class);
3436

37+
public static String byteArrayToHex(byte[] a) {
38+
StringBuilder sb = new StringBuilder(a.length * 2);
39+
for (byte b : a)
40+
sb.append(String.format("%02x", b & 0xff));
41+
return sb.toString();
42+
}
43+
3544
public void testJson() throws IOException {
3645
AvroDatumEncoder encoder = new AvroDatumEncoder(SpecificData.get(), false);
3746
AvroTopic<ObservationKey, EmpaticaE4BloodVolumePulse> topic = new AvroTopic<>("keeeeys", ObservationKey.getClassSchema(), EmpaticaE4BloodVolumePulse.getClassSchema(), ObservationKey.class, EmpaticaE4BloodVolumePulse.class);
@@ -58,20 +67,13 @@ public void testBinary() throws IOException {
5867
byte[] expectedKey = {2, 8, 116, 101, 115, 116, 2, 97, 2, 98};
5968
System.out.println("key: 0x" + byteArrayToHex(key));
6069
System.out.println("expected: 0x" + byteArrayToHex(expectedKey));
61-
assertTrue(Arrays.equals(expectedKey, key));
70+
assertArrayEquals(expectedKey, key);
6271
byte[] value = valueEncoder.encode(new EmpaticaE4BloodVolumePulse(0d, 0d, 0f));
6372
// 8 bytes, 8 bytes, 4 bytes, all zero
6473
byte[] expectedValue = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
6574
System.out.println("value: 0x" + byteArrayToHex(value));
6675
System.out.println("expected: 0x" + byteArrayToHex(expectedValue));
67-
assertTrue(Arrays.equals(expectedValue, value));
68-
}
69-
70-
public static String byteArrayToHex(byte[] a) {
71-
StringBuilder sb = new StringBuilder(a.length * 2);
72-
for(byte b: a)
73-
sb.append(String.format("%02x", b & 0xff));
74-
return sb.toString();
76+
assertArrayEquals(expectedValue, value);
7577
}
7678

7779
public void testSize() throws IOException {

0 commit comments

Comments
 (0)