From c820485bd2db68d4d7d95abfe12f38bf5e916742 Mon Sep 17 00:00:00 2001 From: DamirDenis-Tudor <“denis-tudor.damir@student.tuiasi.ro”> Date: Mon, 16 Dec 2024 19:04:12 +0200 Subject: [PATCH 1/6] Ktor RabbitMQ plugin added. --- .../group.ktor.yaml | 3 + .../ktor-server-rabbitmq/3.0/application.conf | 19 ++++ .../ktor-server-rabbitmq/3.0/application.yaml | 12 +++ .../ktor-server-rabbitmq/3.0/documentation.md | 93 +++++++++++++++++++ .../ktor-server-rabbitmq/3.0/install.kt | 53 +++++++++++ .../3.0/manifest.ktor.yaml | 11 +++ .../ktor-server-rabbitmq/versions.ktor.yaml | 3 + 7 files changed, 194 insertions(+) create mode 100644 plugins/server/io.github.damirdenis-tudor/group.ktor.yaml create mode 100644 plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/application.conf create mode 100644 plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/application.yaml create mode 100644 plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/documentation.md create mode 100644 plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/install.kt create mode 100644 plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/manifest.ktor.yaml create mode 100644 plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/versions.ktor.yaml diff --git a/plugins/server/io.github.damirdenis-tudor/group.ktor.yaml b/plugins/server/io.github.damirdenis-tudor/group.ktor.yaml new file mode 100644 index 0000000..11df271 --- /dev/null +++ b/plugins/server/io.github.damirdenis-tudor/group.ktor.yaml @@ -0,0 +1,3 @@ +name: Damir Denis-Tudor +url: https://github.com/DamirDenis-Tudor +email: denis-tudor.damir@student.tuiasi.ro \ No newline at end of file diff --git a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/application.conf b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/application.conf new file mode 100644 index 0000000..e99ec7e --- /dev/null +++ b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/application.conf @@ -0,0 +1,19 @@ +ktor { + rabbitmq { + uri = "amqp://guest:guest@localhost:5672" + + defaultConnectionName = "default_connection" + + connectionAttempts = 10 + + attemptDelay = 5 + + tls { + enabled = false + keystorePath = "" + keystorePassword = "" + truststorePath = "" + truststorePassword = "" + } + } +} \ No newline at end of file diff --git a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/application.yaml b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/application.yaml new file mode 100644 index 0000000..c83ff57 --- /dev/null +++ b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/application.yaml @@ -0,0 +1,12 @@ +ktor: + rabbitmq: + uri: "amqp://guest:guest@localhost:5672" + defaultConnectionName: "default_connection" + connectionAttempts: 10 + attemptDelay: 5 + tls: + enabled: false + keystorePath: "" + keystorePassword: "" + truststorePath: "" + truststorePassword: "" diff --git a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/documentation.md b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/documentation.md new file mode 100644 index 0000000..23dedc4 --- /dev/null +++ b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/documentation.md @@ -0,0 +1,93 @@ + +#### This plugin provides access to all the core functionalities of the `com.rabbitmq:amqp-client` library. + +### Features + +- Seamlessly integrates with `Kotlin DSL`, making it readable, maintainable, and easy to use. +- Includes a built-in connection/channel management system. +- Provides a built-in mechanism for validating property combinations. + + +## Usage + +### Instalation +```kotlin +install(KabbitMQ) { + uri = "amqp://:@
:" + defaultConnectionName = "" + connectionAttempts = 20 + attemptDelay = 10 + + tlsEnabled = true + tlsKeystorePath = "" + tlsKeystorePassword = "" + tlsTruststorePath = "" + tlsTruststorePassword = "" +} +``` + +### Queue binding example +```kotlin +queueBind { + queue = "test-queue" + exchange = "test-exchange" + routingKey = "test-routing-key" + queueDeclare { + queue = "test-queue" + durable = true + } + exchangeDeclare { + exchange = "test-exchange" + type = BuiltinExchangeType.DIRECT + } +} +``` + +### Producer example +```kotlin +channel(id = 2, autoClose = true) { + repeat(10) { + basicPublish { + exchange = "test-exchange" + routingKey = "test-routing-key" + message { + Message(content = "Hello world!") + } + } + } +} +``` + +### Consumer Example +```kotlin +basicConsume { + queue = "test-queue" + autoAck = false + deliverCallback { tag, message -> + basicAck { + deliveryTag = tag + } + } +} +``` + +### Library Calls Example +```kotlin +channel("direct-calls"){ + basicPublish("test", "test-routing-key", null, "Hello!".toByteArray()) + + val consumer = object : DefaultConsumer(channel) { + override fun handleDelivery( + consumerTag: String?, + envelope: Envelope?, + properties: AMQP.BasicProperties?, + body: ByteArray? + ) { + + } + } + basicConsume(queueName, true, consumer) +} +``` + +### For additional details check [repo](https://github.com/DamirDenis-Tudor/ktor-server-rabbitmq). \ No newline at end of file diff --git a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/install.kt b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/install.kt new file mode 100644 index 0000000..26f096a --- /dev/null +++ b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/install.kt @@ -0,0 +1,53 @@ +import com.rabbitmq.client.BuiltinExchangeType +import io.github.damir.denis.tudor.ktor.server.rabbitmq.KabbitMQ +import io.github.damir.denis.tudor.ktor.server.rabbitmq.dsl.extensions.basicAck +import io.github.damir.denis.tudor.ktor.server.rabbitmq.dsl.extensions.exchangeDeclare +import io.github.damir.denis.tudor.ktor.server.rabbitmq.dsl.extensions.queueBind +import io.github.damir.denis.tudor.ktor.server.rabbitmq.dsl.extensions.queueDeclare +import io.ktor.server.application.* + +fun Application.install() { + install(KabbitMQ) { + uri = "amqp://:@
:" + defaultConnectionName = "" + connectionAttempts = 20 + attemptDelay = 10 + + tlsEnabled = true + tlsKeystorePath = "" + tlsKeystorePassword = "" + tlsTruststorePath = "" + tlsTruststorePassword = "" + } + + queueBind { + queue = "dlq" + exchange = "dlx" + routingKey = "dlq-dlx" + queueDeclare { + queue = "dlq" + durable = true + } + exchangeDeclare { + exchange = "dlx" + type = BuiltinExchangeType.DIRECT + } + } + + queueBind { + queue = "test-queue" + exchange = "test-exchange" + exchange = "test-routing-key" + queueDeclare { + queue = "test-queue" + arguments = mapOf( + "x-dead-letter-exchange" to "dlx", + "x-dead-letter-routing-key" to "dlq-dlx" + ) + } + exchangeDeclare { + exchange = "test-exchange" + type = BuiltinExchangeType.FANOUT + } + } +} diff --git a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/manifest.ktor.yaml b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/manifest.ktor.yaml new file mode 100644 index 0000000..33b44ea --- /dev/null +++ b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/manifest.ktor.yaml @@ -0,0 +1,11 @@ +name: ktor-server-rabbitmq +description: Adds Kafka support to your application +vcsLink: https://github.com/DamirDenis-Tudor/ktor-server-rabbitmq +license: Apache 2.0 + +category: Frameworks + +installation: + default: install.kt + application_conf: application.conf + application_yaml: application.yaml diff --git a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/versions.ktor.yaml b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/versions.ktor.yaml new file mode 100644 index 0000000..de2c71d --- /dev/null +++ b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/versions.ktor.yaml @@ -0,0 +1,3 @@ +# This file maps ktor versions to the required artifacts +# See templates/versions.ktor.yaml for more details +"[3.0,)": io.github.damirdenis-tudor:ktor-server-rabbitmq:1.1.+ \ No newline at end of file From 40eebe0915faefbb1bd87acdb5314e5c312c07ea Mon Sep 17 00:00:00 2001 From: DamirDenis-Tudor <“denis-tudor.damir@student.tuiasi.ro”> Date: Mon, 16 Dec 2024 22:22:26 +0200 Subject: [PATCH 2/6] Ktor RabbitMQ plugin: install.kt modified. --- .../ktor-server-rabbitmq/3.0/install.kt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/install.kt b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/install.kt index 26f096a..b8f42e6 100644 --- a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/install.kt +++ b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/install.kt @@ -12,12 +12,6 @@ fun Application.install() { defaultConnectionName = "" connectionAttempts = 20 attemptDelay = 10 - - tlsEnabled = true - tlsKeystorePath = "" - tlsKeystorePassword = "" - tlsTruststorePath = "" - tlsTruststorePassword = "" } queueBind { From ffeafed12a8e6aaede074cb195f3a00ca51857e9 Mon Sep 17 00:00:00 2001 From: DamirDenis-Tudor <“denis-tudor.damir@student.tuiasi.ro”> Date: Mon, 16 Dec 2024 22:45:11 +0200 Subject: [PATCH 3/6] Ktor RabbitMQ plugin: logo icon added. --- .../io.github.damirdenis-tudor/group.ktor.yaml | 3 ++- .../server/io.github.damirdenis-tudor/icon.png | Bin 0 -> 80926 bytes 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 plugins/server/io.github.damirdenis-tudor/icon.png diff --git a/plugins/server/io.github.damirdenis-tudor/group.ktor.yaml b/plugins/server/io.github.damirdenis-tudor/group.ktor.yaml index 11df271..f140f62 100644 --- a/plugins/server/io.github.damirdenis-tudor/group.ktor.yaml +++ b/plugins/server/io.github.damirdenis-tudor/group.ktor.yaml @@ -1,3 +1,4 @@ name: Damir Denis-Tudor url: https://github.com/DamirDenis-Tudor -email: denis-tudor.damir@student.tuiasi.ro \ No newline at end of file +email: denis-tudor.damir@student.tuiasi.ro +logo: icon.png \ No newline at end of file diff --git a/plugins/server/io.github.damirdenis-tudor/icon.png b/plugins/server/io.github.damirdenis-tudor/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..19bfc2ef9aef9bf42f065e9aa7ec8f8f83676bf7 GIT binary patch literal 80926 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 eoaXfZK>q>9&;oD;?rh}%0000 Date: Mon, 16 Dec 2024 23:35:33 +0200 Subject: [PATCH 4/6] Ktor RabbitMQ plugin: install.kt modified. --- .../ktor-server-rabbitmq/3.0/install.kt | 7 ++----- .../ktor-server-rabbitmq/3.0/manifest.ktor.yaml | 4 ++-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/install.kt b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/install.kt index b8f42e6..404dfb7 100644 --- a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/install.kt +++ b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/install.kt @@ -8,10 +8,7 @@ import io.ktor.server.application.* fun Application.install() { install(KabbitMQ) { - uri = "amqp://:@
:" - defaultConnectionName = "" - connectionAttempts = 20 - attemptDelay = 10 + uri = "amqp://guest:guest@localhost:5672" } queueBind { @@ -31,7 +28,7 @@ fun Application.install() { queueBind { queue = "test-queue" exchange = "test-exchange" - exchange = "test-routing-key" + routingKey = "test-routing-key" queueDeclare { queue = "test-queue" arguments = mapOf( diff --git a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/manifest.ktor.yaml b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/manifest.ktor.yaml index 33b44ea..e4a72bd 100644 --- a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/manifest.ktor.yaml +++ b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/manifest.ktor.yaml @@ -1,5 +1,5 @@ -name: ktor-server-rabbitmq -description: Adds Kafka support to your application +name: KabbitMQ +description: Adds RabbitMQ support to your application vcsLink: https://github.com/DamirDenis-Tudor/ktor-server-rabbitmq license: Apache 2.0 From 69fc1cf72e8834c752414f4400818969350077d5 Mon Sep 17 00:00:00 2001 From: DamirDenis-Tudor <“denis-tudor.damir@student.tuiasi.ro”> Date: Wed, 15 Jan 2025 12:27:36 +0200 Subject: [PATCH 5/6] Plugin updated to newest version. --- .../ktor-server-rabbitmq/3.0/application.conf | 9 +- .../ktor-server-rabbitmq/3.0/application.yaml | 12 --- .../ktor-server-rabbitmq/3.0/documentation.md | 84 +++++++++-------- .../ktor-server-rabbitmq/3.0/install.kt | 91 ++++++++++++------- .../3.0/manifest.ktor.yaml | 5 +- .../ktor-server-rabbitmq/versions.ktor.yaml | 4 +- 6 files changed, 110 insertions(+), 95 deletions(-) delete mode 100644 plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/application.yaml diff --git a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/application.conf b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/application.conf index e99ec7e..0f4deaa 100644 --- a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/application.conf +++ b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/application.conf @@ -1,19 +1,12 @@ ktor { rabbitmq { uri = "amqp://guest:guest@localhost:5672" - defaultConnectionName = "default_connection" - + dispatcherThreadPollSize = 4 connectionAttempts = 10 - attemptDelay = 5 - tls { enabled = false - keystorePath = "" - keystorePassword = "" - truststorePath = "" - truststorePassword = "" } } } \ No newline at end of file diff --git a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/application.yaml b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/application.yaml deleted file mode 100644 index c83ff57..0000000 --- a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/application.yaml +++ /dev/null @@ -1,12 +0,0 @@ -ktor: - rabbitmq: - uri: "amqp://guest:guest@localhost:5672" - defaultConnectionName: "default_connection" - connectionAttempts: 10 - attemptDelay: 5 - tls: - enabled: false - keystorePath: "" - keystorePassword: "" - truststorePath: "" - truststorePassword: "" diff --git a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/documentation.md b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/documentation.md index 23dedc4..6ad33cf 100644 --- a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/documentation.md +++ b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/documentation.md @@ -1,22 +1,25 @@ -#### This plugin provides access to all the core functionalities of the `com.rabbitmq:amqp-client` library. +#### This plugin provides access to major core functionalities of the `com.rabbitmq:amqp-client` library. ### Features -- Seamlessly integrates with `Kotlin DSL`, making it readable, maintainable, and easy to use. +- Integrated with coroutines and has a separate dispatcher. +- Seamlessly integrates with the Kotlin DSL, making it readable, maintainable, and easy to use. - Includes a built-in connection/channel management system. - Provides a built-in mechanism for validating property combinations. +- Gives the possibility to interact directly with the java library. ## Usage -### Instalation +### Installation ```kotlin install(KabbitMQ) { uri = "amqp://:@
:" defaultConnectionName = "" connectionAttempts = 20 attemptDelay = 10 + dispatcherThreadPollSize = 2 tlsEnabled = true tlsKeystorePath = "" @@ -28,31 +31,31 @@ install(KabbitMQ) { ### Queue binding example ```kotlin -queueBind { - queue = "test-queue" - exchange = "test-exchange" - routingKey = "test-routing-key" - queueDeclare { - queue = "test-queue" - durable = true - } - exchangeDeclare { - exchange = "test-exchange" - type = BuiltinExchangeType.DIRECT +rabbitmq { + queueBind { + queue = "demo-queue" + exchange = "demo-exchange" + routingKey = "demo-routing-key" + queueDeclare { + queue = "demo-queue" + durable = true + } + exchangeDeclare { + exchange = "demo-exchange" + type = "direct" + } } } ``` ### Producer example ```kotlin -channel(id = 2, autoClose = true) { +rabbitmq { repeat(10) { basicPublish { - exchange = "test-exchange" - routingKey = "test-routing-key" - message { - Message(content = "Hello world!") - } + exchange = "demo-exchange" + routingKey = "demo-routing-key" + message { "Hello World!" } } } } @@ -60,12 +63,12 @@ channel(id = 2, autoClose = true) { ### Consumer Example ```kotlin -basicConsume { - queue = "test-queue" - autoAck = false - deliverCallback { tag, message -> - basicAck { - deliveryTag = tag +rabbitmq { + basicConsume { + autoAck = true + queue = "demo-queue" + deliverCallback { tag, message -> + logger.info("Received message: $message") } } } @@ -73,20 +76,25 @@ basicConsume { ### Library Calls Example ```kotlin -channel("direct-calls"){ - basicPublish("test", "test-routing-key", null, "Hello!".toByteArray()) - - val consumer = object : DefaultConsumer(channel) { - override fun handleDelivery( - consumerTag: String?, - envelope: Envelope?, - properties: AMQP.BasicProperties?, - body: ByteArray? - ) { - +rabbitmq { + libConnection("lib_connection") { + with(createChannel()) { + basicPublish("demo-queue", "demo-routing-key", null, "Hello!".toByteArray()) + + val consumer = object : DefaultConsumer(channel) { + override fun handleDelivery( + consumerTag: String?, + envelope: Envelope?, + properties: AMQP.BasicProperties?, + body: ByteArray? + ) { + + } + } + + basicConsume("demo-queue", true, consumer) } } - basicConsume(queueName, true, consumer) } ``` diff --git a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/install.kt b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/install.kt index 404dfb7..5c61089 100644 --- a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/install.kt +++ b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/install.kt @@ -1,44 +1,73 @@ -import com.rabbitmq.client.BuiltinExchangeType -import io.github.damir.denis.tudor.ktor.server.rabbitmq.KabbitMQ -import io.github.damir.denis.tudor.ktor.server.rabbitmq.dsl.extensions.basicAck -import io.github.damir.denis.tudor.ktor.server.rabbitmq.dsl.extensions.exchangeDeclare -import io.github.damir.denis.tudor.ktor.server.rabbitmq.dsl.extensions.queueBind -import io.github.damir.denis.tudor.ktor.server.rabbitmq.dsl.extensions.queueDeclare +import io.github.damir.denis.tudor.ktor.server.rabbitmq.dsl.basicConsume +import io.github.damir.denis.tudor.ktor.server.rabbitmq.dsl.basicPublish +import io.github.damir.denis.tudor.ktor.server.rabbitmq.dsl.exchangeDeclare +import io.github.damir.denis.tudor.ktor.server.rabbitmq.dsl.queueBind +import io.github.damir.denis.tudor.ktor.server.rabbitmq.dsl.queueDeclare +import io.github.damir.denis.tudor.ktor.server.rabbitmq.plugin.RabbitMQ +import io.github.damir.denis.tudor.ktor.server.rabbitmq.plugin.rabbitmq import io.ktor.server.application.* +import io.ktor.server.request.receiveText +import io.ktor.server.response.respondText +import io.ktor.server.routing.application +import io.ktor.server.routing.get +import io.ktor.server.routing.routing fun Application.install() { - install(KabbitMQ) { - uri = "amqp://guest:guest@localhost:5672" - } + install(RabbitMQ) - queueBind { - queue = "dlq" - exchange = "dlx" - routingKey = "dlq-dlx" - queueDeclare { + rabbitmq { + queueBind { queue = "dlq" - durable = true - } - exchangeDeclare { exchange = "dlx" - type = BuiltinExchangeType.DIRECT + routingKey = "dlq-dlx" + exchangeDeclare { + exchange = "dlx" + type = "direct" + } + queueDeclare { + queue = "dlq" + durable = true + } + } + queueBind { + queue = "test-queue" + exchange = "test-exchange" + routingKey = "test-routing-key" + exchangeDeclare { + exchange = "test-exchange" + type = "direct" + } + queueDeclare { + queue = "test-queue" + arguments = mapOf( + "x-dead-letter-exchange" to "dlx", + "x-dead-letter-routing-key" to "dlq-dlx" + ) + } } } - queueBind { - queue = "test-queue" - exchange = "test-exchange" - routingKey = "test-routing-key" - queueDeclare { - queue = "test-queue" - arguments = mapOf( - "x-dead-letter-exchange" to "dlx", - "x-dead-letter-routing-key" to "dlq-dlx" - ) + routing { + get("/rabbitmq") { + rabbitmq { + basicPublish { + exchange = "demo-exchange" + routingKey = "demo-routing-key" + message { "Hello Ktor!" } + } + } + call.respondText("Hello RabbitMQ!") } - exchangeDeclare { - exchange = "test-exchange" - type = BuiltinExchangeType.FANOUT + + + rabbitmq { + basicConsume { + autoAck = true + queue = "demo-queue" + deliverCallback { tag, message -> + log.debug("Received message: $message") + } + } } } } diff --git a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/manifest.ktor.yaml b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/manifest.ktor.yaml index e4a72bd..c8e3d80 100644 --- a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/manifest.ktor.yaml +++ b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/manifest.ktor.yaml @@ -1,4 +1,4 @@ -name: KabbitMQ +name: RabbitMQ description: Adds RabbitMQ support to your application vcsLink: https://github.com/DamirDenis-Tudor/ktor-server-rabbitmq license: Apache 2.0 @@ -7,5 +7,4 @@ category: Frameworks installation: default: install.kt - application_conf: application.conf - application_yaml: application.yaml + application_conf: application.conf \ No newline at end of file diff --git a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/versions.ktor.yaml b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/versions.ktor.yaml index de2c71d..f378b18 100644 --- a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/versions.ktor.yaml +++ b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/versions.ktor.yaml @@ -1,3 +1 @@ -# This file maps ktor versions to the required artifacts -# See templates/versions.ktor.yaml for more details -"[3.0,)": io.github.damirdenis-tudor:ktor-server-rabbitmq:1.1.+ \ No newline at end of file +"[3.0,)": io.github.damirdenis-tudor:ktor-server-rabbitmq:1.2.2+ \ No newline at end of file From cb7eb861d15573f43d1db84f3132d244a4d116dd Mon Sep 17 00:00:00 2001 From: DamirDenis-Tudor Date: Fri, 17 Jan 2025 16:40:44 +0200 Subject: [PATCH 6/6] ktor-server-rabbitmq: updated with a version that fixes some instalation issues. --- .../ktor-server-rabbitmq/3.0/documentation.md | 20 ++++++++--- .../ktor-server-rabbitmq/3.0/install.kt | 34 ++++++++++++------- .../ktor-server-rabbitmq/versions.ktor.yaml | 2 +- 3 files changed, 38 insertions(+), 18 deletions(-) diff --git a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/documentation.md b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/documentation.md index 6ad33cf..0a322e7 100644 --- a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/documentation.md +++ b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/documentation.md @@ -14,7 +14,7 @@ ### Installation ```kotlin -install(KabbitMQ) { +install(RabbitMQ) { uri = "amqp://:@
:" defaultConnectionName = "" connectionAttempts = 20 @@ -74,6 +74,20 @@ rabbitmq { } ``` +### Consumer Example With Dispatchers.IO +```kotlin +rabbitmq { + basicConsume { + autoAck = true + queue = "demo-queue" + dispatcher = Dispatchers.IO + deliverCallback { tag, message -> + logger.info("Received message: $message") + } + } +} +``` + ### Library Calls Example ```kotlin rabbitmq { @@ -96,6 +110,4 @@ rabbitmq { } } } -``` - -### For additional details check [repo](https://github.com/DamirDenis-Tudor/ktor-server-rabbitmq). \ No newline at end of file +``` \ No newline at end of file diff --git a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/install.kt b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/install.kt index 5c61089..4ca1718 100644 --- a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/install.kt +++ b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/3.0/install.kt @@ -1,19 +1,19 @@ -import io.github.damir.denis.tudor.ktor.server.rabbitmq.dsl.basicConsume -import io.github.damir.denis.tudor.ktor.server.rabbitmq.dsl.basicPublish -import io.github.damir.denis.tudor.ktor.server.rabbitmq.dsl.exchangeDeclare -import io.github.damir.denis.tudor.ktor.server.rabbitmq.dsl.queueBind -import io.github.damir.denis.tudor.ktor.server.rabbitmq.dsl.queueDeclare -import io.github.damir.denis.tudor.ktor.server.rabbitmq.plugin.RabbitMQ -import io.github.damir.denis.tudor.ktor.server.rabbitmq.plugin.rabbitmq +import io.github.damir.denis.tudor.ktor.server.rabbitmq.RabbitMQ +import io.github.damir.denis.tudor.ktor.server.rabbitmq.dsl.* +import io.github.damir.denis.tudor.ktor.server.rabbitmq.rabbitMQ import io.ktor.server.application.* -import io.ktor.server.request.receiveText import io.ktor.server.response.respondText -import io.ktor.server.routing.application import io.ktor.server.routing.get import io.ktor.server.routing.routing +import kotlinx.coroutines.Dispatchers fun Application.install() { - install(RabbitMQ) + install(RabbitMQ) { + uri = "amqp://:@
:" + defaultConnectionName = "default-connection" + dispatcherThreadPollSize = 2 + tlsEnabled = false + } rabbitmq { queueBind { @@ -29,6 +29,9 @@ fun Application.install() { durable = true } } + } + + rabbitmq { queueBind { queue = "test-queue" exchange = "test-exchange" @@ -44,6 +47,10 @@ fun Application.install() { "x-dead-letter-routing-key" to "dlq-dlx" ) } + }.onSuccess{ response-> + log.info("Successfully bind queue: $response") + }.onFailure{ error -> + log.error("Failed to bind queue: $error") } } @@ -51,8 +58,8 @@ fun Application.install() { get("/rabbitmq") { rabbitmq { basicPublish { - exchange = "demo-exchange" - routingKey = "demo-routing-key" + exchange = "test-exchange" + routingKey = "test-routing-key" message { "Hello Ktor!" } } } @@ -63,7 +70,8 @@ fun Application.install() { rabbitmq { basicConsume { autoAck = true - queue = "demo-queue" + queue = "test-queue" + dispatcher = Dispatchers.rabbitMQ deliverCallback { tag, message -> log.debug("Received message: $message") } diff --git a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/versions.ktor.yaml b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/versions.ktor.yaml index f378b18..dafdb26 100644 --- a/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/versions.ktor.yaml +++ b/plugins/server/io.github.damirdenis-tudor/ktor-server-rabbitmq/versions.ktor.yaml @@ -1 +1 @@ -"[3.0,)": io.github.damirdenis-tudor:ktor-server-rabbitmq:1.2.2+ \ No newline at end of file +"[3.0,)": io.github.damirdenis-tudor:ktor-server-rabbitmq:1.3.+ \ No newline at end of file