问题
Currently, I am trying to write a 'notification service' based on Maven, Quarkus and SmallRye Reactive Messaging in Kotlin. As a base I have an example in Java which works fine and I was trying to "translate" it into Kotlin.
The way I want it to work is, that I send an HTTP request (e.g. GET http://localhost:8080/search/{word}) and the system sends the 'word' (here a String) to the queue 'queries' of the Artemis AMQP message Broker. Another system subscribes to the message Broker and fetches the 'word' in the queue 'queries' upon HTTP request (e.g. GET http://localhost:8080/receiver).
In Kotlin, however, it doesn't work and my best guess is, that the Emitter, doesn't send the 'word' unlike in Java.
Here the code I am using:
Kotlin
Sending
import io.smallrye.reactive.messaging.annotations.Emitter
import io.smallrye.reactive.messaging.annotations.Stream
import javax.ws.rs.GET
import javax.ws.rs.Path
import javax.ws.rs.PathParam
@Path("/search")
class ExampleService {
@Stream("queries")
val queryEmitter: Emitter<String>? = null
@GET
@Path("/{word}")
fun search(@PathParam("word") word: String?): String {
println("about to send word: " + word!!)
if (word.isNotEmpty()) {
var qE=queryEmitter?.send(word)
println("Emitter return : $qE")
return word
}
return "word was empty"
}
}
Receiving
import org.eclipse.microprofile.reactive.messaging.Incoming
import javax.ws.rs.GET
import javax.ws.rs.Path
import javax.ws.rs.Produces
import javax.ws.rs.core.MediaType
@Path("/receiver")
class AdsResource {
var word : String = "nothing happened so far"
@GET
@Produces(MediaType.TEXT_PLAIN)
fun getWords(): String {
return word
}
@Incoming("sink")
fun consume(message: String) {
println("got user query: $message")
word = message
}
}
And here is the Java version
Sending
import io.smallrye.reactive.messaging.annotations.Emitter;
import io.smallrye.reactive.messaging.annotations.Stream;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
@Path("/search")
public class SearchEndpoint {
@Stream("queries")
Emitter<String> queryEmitter;
@GET
@Path("/{word}")
public String search(@PathParam("word") String word) {
System.out.println("about to send word: " + word);
if (!word.isEmpty()) {
Emitter<String> qE = queryEmitter.send(word);
System.out.println("Emitter return: " + qE);
return word;
}
return "word was empty" ;
}
}
Receiving
import org.eclipse.microprofile.reactive.messaging.Incoming;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
@Path("/receiver")
public class AdsResource {
private String word = "";
@GET
public String getAd() {
System.out.println("got user query: " + word);
return word;
}
@Incoming("sink")
public void consume(String message) {
System.out.println("got user query: " + message);
word = message;
}
}
Here for the configuration files 'application.properties" for both Kotlin and Java
# Configures the AMQP broker credentials.
amqp-username=quarkus
amqp-password=quarkus
# Configure the AMQP connector to write to the `queries ` address
mp.messaging.outgoing.queries.connector=smallrye-amqp
mp.messaging.outgoing.queries.address=sink
mp.messaging.outgoing.queries.durable=true
# Configure the AMQP connector to read from the `queries ` queue
mp.messaging.incoming.sink.connector=smallrye-amqp
mp.messaging.incoming.sink.durable=true
Some information:
- The AMQP message broker I run through docker-compose based on this guide.
- Smallrye Reactive Messaging
Thanks in advance and let me know if I missed to provide information.
回答1:
The issue comes down to where Kotlin adds the @Stream
annotation in the bytecode.
Essentially to fix your problem you need to replace:
@Stream("queries")
with
@field: Stream("queries")
来源:https://stackoverflow.com/questions/57960858/smallrye-reactive-messagings-emitter-send-doesnt-send-in-kotlin-via-amqp-bro