From 27e99e775727b1b59e1fa9f6627e6dc09511947f Mon Sep 17 00:00:00 2001 From: Tim Yates Date: Tue, 9 Jan 2024 16:06:13 +0000 Subject: [PATCH 1/2] Fix MQTT with Jackson mqtt-core was based on serde-jackson which may be missing if the consuming project is using jackson. This change mirrors the fix for problem-json here https://github.com/micronaut-projects/micronaut-problem-json/pull/293 That is, make the serde-api and jackson annotations api dependencies of this project in place of the serde-jackson dependency. I have an external reproducer, but I cannot get it to fail when included in this project... Closes #332 --- .../main/groovy/io.micronaut.build.internal.mqtt-module.gradle | 1 + mqtt-core/build.gradle | 3 ++- test-suite-groovy/build.gradle | 1 + test-suite-kotlin/build.gradle | 1 + test-suite/build.gradle | 1 + 5 files changed, 6 insertions(+), 1 deletion(-) diff --git a/buildSrc/src/main/groovy/io.micronaut.build.internal.mqtt-module.gradle b/buildSrc/src/main/groovy/io.micronaut.build.internal.mqtt-module.gradle index 0403deb9..16d01e48 100644 --- a/buildSrc/src/main/groovy/io.micronaut.build.internal.mqtt-module.gradle +++ b/buildSrc/src/main/groovy/io.micronaut.build.internal.mqtt-module.gradle @@ -14,4 +14,5 @@ dependencies { testImplementation(mn.micronaut.management) testImplementation(mn.reactor) testImplementation(projects.testSuiteUtils) + testImplementation(mnSerde.micronaut.serde.jackson) } diff --git a/mqtt-core/build.gradle b/mqtt-core/build.gradle index 42206bb4..87bbd736 100644 --- a/mqtt-core/build.gradle +++ b/mqtt-core/build.gradle @@ -7,8 +7,9 @@ dependencies { api(mn.micronaut.inject) api(mn.micronaut.aop) api(mn.micronaut.messaging) + api(mnSerde.micronaut.serde.api) + api(mn.jackson.annotations) implementation(mn.micronaut.retry) - implementation(mnSerde.micronaut.serde.jackson) implementation(mn.reactor) compileOnly(libs.kotlin.stdlib.jdk8) } diff --git a/test-suite-groovy/build.gradle b/test-suite-groovy/build.gradle index 896a49c1..5cdee0cb 100644 --- a/test-suite-groovy/build.gradle +++ b/test-suite-groovy/build.gradle @@ -9,6 +9,7 @@ dependencies { testCompileOnly(mnValidation.micronaut.validation) testImplementation projects.testSuiteUtils testImplementation projects.micronautMqttv5 + testImplementation(mnSerde.micronaut.serde.jackson) } tasks.named('test') { diff --git a/test-suite-kotlin/build.gradle b/test-suite-kotlin/build.gradle index 8d15eb61..30a5c417 100644 --- a/test-suite-kotlin/build.gradle +++ b/test-suite-kotlin/build.gradle @@ -15,6 +15,7 @@ dependencies { testImplementation projects.testSuiteUtils testImplementation projects.micronautMqttv5 + testImplementation(mnSerde.micronaut.serde.jackson) } tasks.named('test') { diff --git a/test-suite/build.gradle b/test-suite/build.gradle index c74a4d89..d66f43e4 100644 --- a/test-suite/build.gradle +++ b/test-suite/build.gradle @@ -16,6 +16,7 @@ dependencies { testImplementation projects.testSuiteUtils testImplementation projects.micronautMqttv5 + testImplementation(mnSerde.micronaut.serde.jackson) } tasks.named('test') { From 682a09860520fab5de0a20d32ad2b74d65749cb8 Mon Sep 17 00:00:00 2001 From: Tim Yates Date: Tue, 9 Jan 2024 16:32:51 +0000 Subject: [PATCH 2/2] Add tests --- gradle/libs.versions.toml | 2 + settings.gradle | 1 + test-suite-jackson/build.gradle | 29 ++++++++++++++ .../main/java/example/micronaut/Odour.java | 32 +++++++++++++++ .../java/example/micronaut/SmellListener.java | 40 +++++++++++++++++++ .../src/main/resources/application.yml | 18 +++++++++ .../src/main/resources/logback.xml | 14 +++++++ .../src/test-resources/mosquitto.conf | 5 +++ .../example/micronaut/SubscriptionTest.java | 38 ++++++++++++++++++ 9 files changed, 179 insertions(+) create mode 100644 test-suite-jackson/build.gradle create mode 100644 test-suite-jackson/src/main/java/example/micronaut/Odour.java create mode 100644 test-suite-jackson/src/main/java/example/micronaut/SmellListener.java create mode 100644 test-suite-jackson/src/main/resources/application.yml create mode 100644 test-suite-jackson/src/main/resources/logback.xml create mode 100644 test-suite-jackson/src/test-resources/mosquitto.conf create mode 100644 test-suite-jackson/src/test/java/example/micronaut/SubscriptionTest.java diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a90b0899..0d077438 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,7 @@ [versions] micronaut-docs = "2.0.0" micronaut = "4.1.11" +micronaut-platform = "4.1.6" micronaut-gradle-plugin = "4.1.2" groovy = "4.0.15" spock = "2.3-groovy-4.0" @@ -23,6 +24,7 @@ micronaut-logging = "1.1.2" [libraries] # Core micronaut-core = { module = 'io.micronaut:micronaut-core-bom', version.ref = 'micronaut' } +micronaut-platform = { module = 'io.micronaut.platform:micronaut-platform', version.ref = 'micronaut-platform' } micronaut-reactor = { module = "io.micronaut.reactor:micronaut-reactor-bom", version.ref = "micronaut-reactor" } micronaut-serde = { module = "io.micronaut.serde:micronaut-serde-bom", version.ref = "micronaut-serde" } micronaut-validation = { module = "io.micronaut.validation:micronaut-validation-bom", version.ref = "micronaut-validation" } diff --git a/settings.gradle b/settings.gradle index 86a43a8b..f055582d 100644 --- a/settings.gradle +++ b/settings.gradle @@ -23,6 +23,7 @@ include 'mqtt-bom' include 'test-suite-groovy' include 'test-suite' +include 'test-suite-jackson' include 'test-suite-kotlin' include 'test-suite-mqttv3-graal' include 'test-suite-mqttv5-graal' diff --git a/test-suite-jackson/build.gradle b/test-suite-jackson/build.gradle new file mode 100644 index 00000000..615f18f8 --- /dev/null +++ b/test-suite-jackson/build.gradle @@ -0,0 +1,29 @@ +plugins { + id("io.micronaut.library") + id("io.micronaut.test-resources") +} + +version = "0.1" +group = "example.micronaut" + +repositories { + mavenCentral() +} + +dependencies { + implementation(projects.micronautMqttv5) + implementation(mn.micronaut.jackson.databind) + runtimeOnly(mn.snakeyaml) + runtimeOnly(mnLogging.logback.classic) + + testImplementation(libs.awaitility) +} + +micronaut { + version.set(libs.versions.micronaut.platform) + testRuntime("junit5") + processing { + incremental(true) + annotations("example.micronaut.*") + } +} diff --git a/test-suite-jackson/src/main/java/example/micronaut/Odour.java b/test-suite-jackson/src/main/java/example/micronaut/Odour.java new file mode 100644 index 00000000..4a8f85b5 --- /dev/null +++ b/test-suite-jackson/src/main/java/example/micronaut/Odour.java @@ -0,0 +1,32 @@ +/* + * Copyright 2017-2024 original authors + * + * 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 + * + * https://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 example.micronaut; + +import io.micronaut.core.annotation.Introspected; + +@Introspected +public class Odour { + + private final String name; + + public Odour(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/test-suite-jackson/src/main/java/example/micronaut/SmellListener.java b/test-suite-jackson/src/main/java/example/micronaut/SmellListener.java new file mode 100644 index 00000000..cd9020fc --- /dev/null +++ b/test-suite-jackson/src/main/java/example/micronaut/SmellListener.java @@ -0,0 +1,40 @@ +/* + * Copyright 2017-2024 original authors + * + * 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 + * + * https://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 example.micronaut; + +import io.micronaut.core.annotation.NonNull; +import io.micronaut.mqtt.annotation.MqttSubscriber; +import io.micronaut.mqtt.annotation.Topic; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@MqttSubscriber +public class SmellListener { + + private static final Logger LOG = LoggerFactory.getLogger(SmellListener.class); + private Odour smell; + + @Topic("house/livingroom/smell") + public void receive(Odour data) { + LOG.info("smell: {}", smell); + smell = data; + } + + @NonNull + public String getSmell() { + return smell == null ? "" : smell.getName(); + } +} diff --git a/test-suite-jackson/src/main/resources/application.yml b/test-suite-jackson/src/main/resources/application.yml new file mode 100644 index 00000000..9afdfb5c --- /dev/null +++ b/test-suite-jackson/src/main/resources/application.yml @@ -0,0 +1,18 @@ +#tag::mqtt[] +mqtt: + client: + server-uri: tcp://${mqtt.host}:${mqtt.port} + client-id: ${random.uuid} +#end::mqtt[] +#tag::test-resources[] +test-resources: + containers: + mosquitto: + image-name: eclipse-mosquitto + hostnames: + - mqtt.host + exposed-ports: + - mqtt.port: 1883 + ro-fs-bind: + - "src/test-resources/mosquitto.conf": /mosquitto/config/mosquitto.conf +#end::test-resources[] \ No newline at end of file diff --git a/test-suite-jackson/src/main/resources/logback.xml b/test-suite-jackson/src/main/resources/logback.xml new file mode 100644 index 00000000..2d77bdab --- /dev/null +++ b/test-suite-jackson/src/main/resources/logback.xml @@ -0,0 +1,14 @@ + + + + + + %cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n + + + + + + + diff --git a/test-suite-jackson/src/test-resources/mosquitto.conf b/test-suite-jackson/src/test-resources/mosquitto.conf new file mode 100644 index 00000000..bc8842e0 --- /dev/null +++ b/test-suite-jackson/src/test-resources/mosquitto.conf @@ -0,0 +1,5 @@ +persistence false +allow_anonymous true +connection_messages true +log_type all +listener 1883 \ No newline at end of file diff --git a/test-suite-jackson/src/test/java/example/micronaut/SubscriptionTest.java b/test-suite-jackson/src/test/java/example/micronaut/SubscriptionTest.java new file mode 100644 index 00000000..a804371d --- /dev/null +++ b/test-suite-jackson/src/test/java/example/micronaut/SubscriptionTest.java @@ -0,0 +1,38 @@ +package example.micronaut; + +import io.micronaut.mqtt.annotation.Topic; +import io.micronaut.mqtt.annotation.v5.MqttPublisher; +import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import jakarta.inject.Inject; +import org.junit.jupiter.api.Test; + +import java.util.concurrent.TimeUnit; + +import static org.awaitility.Awaitility.await; +import static org.junit.jupiter.api.Assertions.assertEquals; + +@MicronautTest +class SubscriptionTest { + + @Inject + SmellClient client; + + @Inject + SmellListener listener; + + @Test + void checkSubscriptionsAreReceived() { + client.publishLivingroomSmell(new Odour("cheesy")); + + await() + .atMost(5, TimeUnit.SECONDS) + .untilAsserted(() -> assertEquals("cheesy", listener.getSmell())); + } + + @MqttPublisher + interface SmellClient { + + @Topic("house/livingroom/smell") + void publishLivingroomSmell(Odour data); + } +}