diff --git a/.editorconfig b/.editorconfig
index 4e58bba..8db783a 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -12,6 +12,7 @@ ktlint_standard_function-signature = disabled
[{*.kt,*.kts}]
indent_style = space
max_line_length = 140
+indent_size = 2
ij_kotlin_code_style_defaults = KOTLIN_OFFICIAL
ij_continuation_indent_size = 2
ij_kotlin_allow_trailing_comma = false
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 90a7ad2..e11609d 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -2,9 +2,9 @@ name: Build
on:
push:
- branches: [main]
+ branches: [ main ]
pull_request:
- branches: [main]
+ branches: [ main ]
jobs:
build-and-test:
@@ -19,15 +19,18 @@ jobs:
- name: Check out Git repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- - name: Gradle Build and Test
- uses: gradle/gradle-build-action@v3.5.0
+ - name: Setup Gradle
+ uses: gradle/actions/setup-gradle@v4
with:
- arguments: --build-cache build test jacocoTestReport
+ gradle-version: current
+
+ - name: Gradle Build and Test
+ run: gradle --build-cache --configuration-cache build test koverXmlReport
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
- files: ./build/reports/kediatr-core/jacoco/test/jacocoTestReport.xml,./build/reports/kediatr-koin-starter/jacoco/test/jacocoTestReport.xml,./build/reports/kediatr-quarkus-starter/jacoco/test/jacocoTestReport.xml,./build/reports/kediatr-spring-boot-2x-starter/jacoco/test/jacocoTestReport.xml,./build/reports/kediatr-spring-boot-3x-starter/jacoco/test/jacocoTestReport.xml
+ files: '**/build/reports/kover/report.xml'
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false
diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml
index 8a0a161..f31fcf1 100644
--- a/.github/workflows/gradle-publish.yml
+++ b/.github/workflows/gradle-publish.yml
@@ -1,9 +1,9 @@
name: Publish to Maven
on:
- release:
- types: [created]
-
+ release:
+ types: [ created ]
+
jobs:
publish:
runs-on: ubuntu-latest
@@ -12,21 +12,21 @@ jobs:
packages: write
steps:
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- - name: Set up JDK 17
- uses: actions/setup-java@v4
- with:
- java-version: '17'
- distribution: 'temurin'
- server-id: github
- settings-path: ${{ github.workspace }}
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
+ - name: Set up JDK 17
+ uses: actions/setup-java@v4
+ with:
+ java-version: '17'
+ distribution: 'temurin'
+ server-id: github
+ settings-path: ${{ github.workspace }}
- - name: Publish to Maven Repository
- uses: gradle/gradle-build-action@v3.5.0
- with:
- arguments: --build-cache publish
- env:
- gpg_private_key: ${{ secrets.gpg_private_key }}
- gpg_passphrase: ${{ secrets.gpg_passphrase }}
- nexus_username: ${{ secrets.nexus_username }}
- nexus_password: ${{ secrets.nexus_password }}
+ - name: Publish to Maven Repository
+ uses: gradle/gradle-build-action@v3.5.0
+ with:
+ arguments: --build-cache publish
+ env:
+ gpg_private_key: ${{ secrets.gpg_private_key }}
+ gpg_passphrase: ${{ secrets.gpg_passphrase }}
+ nexus_username: ${{ secrets.nexus_username }}
+ nexus_password: ${{ secrets.nexus_password }}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 555cdd7..8285a04 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,14 +11,19 @@
# What's Changed
## New
+
* Support for Spring-Boot 3.1.0 #116 by @osoykan in https://github.com/Trendyol/kediatR/pull/117
## Package bumps
+
* Update dependency io.quarkus:quarkus-bom to v3.0.3.Final by @renovate in https://github.com/Trendyol/kediatR/pull/110
* Update plugin io.quarkus to v3.0.3.Final by @renovate in https://github.com/Trendyol/kediatR/pull/111
-* Update dependency org.jetbrains.kotlinx:kotlinx-coroutines-core to v1.7.1 by @renovate in https://github.com/Trendyol/kediatR/pull/114
-* Update dependency org.jetbrains.kotlinx:kotlinx-coroutines-test to v1.7.1 by @renovate in https://github.com/Trendyol/kediatR/pull/113
-* Update dependency org.jetbrains.kotlinx:kotlinx-coroutines-bom to v1.7.1 by @renovate in https://github.com/Trendyol/kediatR/pull/112
+* Update dependency org.jetbrains.kotlinx:kotlinx-coroutines-core to v1.7.1 by @renovate
+ in https://github.com/Trendyol/kediatR/pull/114
+* Update dependency org.jetbrains.kotlinx:kotlinx-coroutines-test to v1.7.1 by @renovate
+ in https://github.com/Trendyol/kediatR/pull/113
+* Update dependency org.jetbrains.kotlinx:kotlinx-coroutines-bom to v1.7.1 by @renovate
+ in https://github.com/Trendyol/kediatR/pull/112
**Full Changelog**: https://github.com/Trendyol/kediatR/compare/v2.1.0...3.0.0-SNAPSHOT
@@ -27,10 +32,14 @@
## What's Changed
### Enhancements
-* Add possibility to invoke publish method with custom publishStrategy by @awaniak in https://github.com/Trendyol/kediatR/pull/92
-* Make the quarkus starter work again with quarkus 3.x.x by @lucas-dclrcq in https://github.com/Trendyol/kediatR/pull/109
+
+* Add possibility to invoke publish method with custom publishStrategy by @awaniak
+ in https://github.com/Trendyol/kediatR/pull/92
+* Make the quarkus starter work again with quarkus 3.x.x by @lucas-dclrcq
+ in https://github.com/Trendyol/kediatR/pull/109
### New Contributors
+
* @renovate made their first contribution in https://github.com/Trendyol/kediatR/pull/44
* @awaniak made their first contribution in https://github.com/Trendyol/kediatR/pull/92
* @lucas-dclrcq made their first contribution in https://github.com/Trendyol/kediatR/pull/109
@@ -93,9 +102,12 @@
* Update plugin io.quarkus to v3.0.1.Final by @renovate in https://github.com/Trendyol/kediatR/pull/102
* Update plugin io.quarkus to v3.0.2.Final by @renovate in https://github.com/Trendyol/kediatR/pull/104
* Update dependency io.quarkus:quarkus-bom to v2.16.7.Final by @renovate in https://github.com/Trendyol/kediatR/pull/105
-* Update dependency org.jetbrains.kotlinx:kotlinx-coroutines-core to v1.7.0 by @renovate in https://github.com/Trendyol/kediatR/pull/107
-* Update dependency org.jetbrains.kotlinx:kotlinx-coroutines-test to v1.7.0 by @renovate in https://github.com/Trendyol/kediatR/pull/108
-* Update dependency org.jetbrains.kotlinx:kotlinx-coroutines-bom to v1.7.0 by @renovate in https://github.com/Trendyol/kediatR/pull/106
+* Update dependency org.jetbrains.kotlinx:kotlinx-coroutines-core to v1.7.0 by @renovate
+ in https://github.com/Trendyol/kediatR/pull/107
+* Update dependency org.jetbrains.kotlinx:kotlinx-coroutines-test to v1.7.0 by @renovate
+ in https://github.com/Trendyol/kediatR/pull/108
+* Update dependency org.jetbrains.kotlinx:kotlinx-coroutines-bom to v1.7.0 by @renovate
+ in https://github.com/Trendyol/kediatR/pull/106
**Full Changelog**: https://github.com/Trendyol/kediatR/compare/v2.0.0...v2.1.0
@@ -104,32 +116,37 @@
This is the announcement release for 2.0.0; in other words, SNAPSHOT is promoted to release.
# Breaking Changes
-- CommandBus renamed to Mediator #25
+
+- CommandBus renamed to Mediator #25
- ` executeCommand.* executeQuery.*, publishNotification.*` renamed to `send`
-- Pipeline behavior refactored with decorator pattern #31
-- Sync code is deleted; now it supports only async invocation #26
+- Pipeline behavior refactored with decorator pattern #31
+- Sync code is deleted; now it supports only async invocation #26
### Bug Fixes
- general:
- - fix name for pom while publishing ([4cf70ac](https://github.com/Trendyol/kediatR/commit/4cf70ac439ddf694decf779b601693bd902c150c))
+ - fix name for pom while
+ publishing ([4cf70ac](https://github.com/Trendyol/kediatR/commit/4cf70ac439ddf694decf779b601693bd902c150c))
## [v2.0-SNAPSHOT](https://github.com/Trendyol/kediatR/releases/tag/v2.0-SNAPSHOT) - 2022-10-19 09:10:36
# Breaking Changes
-- CommandBus renamed to Mediator #25
-- Pipeline behavior refactored with decorator pattern #31
-- Sync code is deleted; now it supports only async invocation #26
+
+- CommandBus renamed to Mediator #25
+- Pipeline behavior refactored with decorator pattern #31
+- Sync code is deleted; now it supports only async invocation #26
### Bug Fixes
- general:
- - fix the code snippet for sample kediatr-core usage ([e7f09ba](https://github.com/Trendyol/kediatR/commit/e7f09ba81cb07bd873dd22a9eca683b8d9b461eb)) ([#23](https://github.com/Trendyol/kediatR/pull/23))
+ - fix the code snippet for sample kediatr-core
+ usage ([e7f09ba](https://github.com/Trendyol/kediatR/commit/e7f09ba81cb07bd873dd22a9eca683b8d9b461eb)) ([#23](https://github.com/Trendyol/kediatR/pull/23))
### Refactor
- general:
- - refactor gradle ([3005893](https://github.com/Trendyol/kediatR/commit/3005893ece9745af2e78875c5334e10dc8373296))
- - refactor gradle ([023651c](https://github.com/Trendyol/kediatR/commit/023651c1b316029afdaa0bf4e3c199ab80515025))
+ - refactor gradle ([3005893](https://github.com/Trendyol/kediatR/commit/3005893ece9745af2e78875c5334e10dc8373296))
+ - refactor gradle ([023651c](https://github.com/Trendyol/kediatR/commit/023651c1b316029afdaa0bf4e3c199ab80515025))
-\* *This CHANGELOG was automatically generated by [auto-generate-changelog](https://github.com/BobAnkh/auto-generate-changelog)*
+\* *This CHANGELOG was automatically generated
+by [auto-generate-changelog](https://github.com/BobAnkh/auto-generate-changelog)*
diff --git a/README.md b/README.md
index 61c8a9a..aa849d7 100644
--- a/README.md
+++ b/README.md
@@ -2,48 +2,49 @@
-Mediator implementation in kotlin with native coroutine support. Supports Spring-Boot, Quarkus and Koin dependency providers.
+Mediator implementation in kotlin with native coroutine support. Supports Spring-Boot, Quarkus and Koin dependency
+providers.
Documentation is available at [https://trendyol.github.io/kediatR/](https://trendyol.github.io/kediatR/)
## Show me the code
```kotlin
-class PingCommand: Command // or
-class PingQuery: Query // or
-class PingNotification: Notification
-class PingCommandHandler: CommandHandler {
- override suspend fun handle(command: PingCommand) {
- println("Pong!")
- }
+class PingCommand : Command // or
+class PingQuery : Query // or
+class PingNotification : Notification
+class PingCommandHandler : CommandHandler {
+ override suspend fun handle(command: PingCommand) {
+ println("Pong!")
+ }
}
-class PingQueryHandler: QueryHandler {
- override suspend fun handle(query: PingQuery): String {
- return "Pong!"
- }
+class PingQueryHandler : QueryHandler {
+ override suspend fun handle(query: PingQuery): String {
+ return "Pong!"
+ }
}
-class PingNotificationHandler: NotificationHandler {
- override suspend fun handle(notification: PingNotification) {
- println("Pong!")
- }
+class PingNotificationHandler : NotificationHandler {
+ override suspend fun handle(notification: PingNotification) {
+ println("Pong!")
+ }
}
-class MeasurePipelineBehaviour: PipelineBehaviour {
- override suspend fun handle(
- request: TRequest,
- next: RequestHandlerDelegate
- ): TResponse {
- val start = System.currentTimeMillis()
- val response = next(request)
- val end = System.currentTimeMillis()
- println("Request ${request::class.simpleName} took ${end - start} ms")
- return response
- }
-}
+class MeasurePipelineBehaviour : PipelineBehaviour {
+ override suspend fun handle(
+ request: TRequest,
+ next: RequestHandlerDelegate
+ ): TResponse {
+ val start = System.currentTimeMillis()
+ val response = next(request)
+ val end = System.currentTimeMillis()
+ println("Request ${request::class.simpleName} took ${end - start} ms")
+ return response
+ }
+}
val mediator = // create mediator instance in-memory or with dependency injection, take a look at the documentation
-mediator.send(PingCommand()) // 1..1
+ mediator.send(PingCommand()) // 1..1
mediator.send(PingQuery()) // 1..1
mediator.send(PingNotification()) // 0..N
```
diff --git a/build.gradle.kts b/build.gradle.kts
index 369316d..c5ac9ae 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,25 +1,31 @@
group = "com.trendyol"
plugins {
- kotlin("jvm") version libs.versions.kotlin.get()
- id("kediatr-publishing") apply false
- id("com.palantir.git-version") version "3.1.0"
- java
+ kotlin("jvm") version libs.versions.kotlin.get()
+ java
+ id("kediatr-publishing") apply false
+ alias(libs.plugins.spotless)
}
-val versionDetails: groovy.lang.Closure by extra
-val details = versionDetails()
-version = details.lastTag
+version = properties["version"].toString()
subprojectsOf("projects") {
- apply {
- plugin("kotlin")
- plugin("kediatr-publishing")
- plugin("java")
- }
+ apply {
+ plugin("kotlin")
+ plugin("kediatr-publishing")
+ plugin("java")
+ plugin(rootProject.libs.plugins.spotless.pluginId)
+ }
- java {
- withSourcesJar()
- withJavadocJar()
+ spotless {
+ kotlin {
+ ktlint()
+ .setEditorConfigPath(rootProject.layout.projectDirectory.file(".editorconfig"))
}
+ }
+
+ java {
+ withSourcesJar()
+ withJavadocJar()
+ }
}
diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts
index 597a658..40636e1 100644
--- a/buildSrc/build.gradle.kts
+++ b/buildSrc/build.gradle.kts
@@ -1,9 +1,9 @@
plugins {
- `kotlin-dsl`
+ `kotlin-dsl`
}
repositories {
- mavenCentral()
- google()
- gradlePluginPortal()
+ mavenCentral()
+ google()
+ gradlePluginPortal()
}
diff --git a/buildSrc/src/main/kotlin/BuildConstants.kt b/buildSrc/src/main/kotlin/BuildConstants.kt
deleted file mode 100644
index 284889f..0000000
--- a/buildSrc/src/main/kotlin/BuildConstants.kt
+++ /dev/null
@@ -1,4 +0,0 @@
-object TaskNames {
- const val testAggregateReports = "testAggregateReports"
- const val codeCoverageReport = "codeCoverageReport"
-}
diff --git a/buildSrc/src/main/kotlin/Helpers.kt b/buildSrc/src/main/kotlin/Helpers.kt
index 2fda818..ef57687 100644
--- a/buildSrc/src/main/kotlin/Helpers.kt
+++ b/buildSrc/src/main/kotlin/Helpers.kt
@@ -1,78 +1,27 @@
-import org.gradle.api.Action
-import org.gradle.api.Project
-import org.gradle.api.Task
+import org.gradle.api.*
import org.gradle.api.provider.Property
import org.gradle.kotlin.dsl.invoke
fun Project.subprojectsOf(
- vararg parentProjects: String,
- action: Action,
+ vararg parentProjects: String,
+ action: Action,
): Unit = subprojects.filter { parentProjects.contains(it.parent?.name) }.forEach { action(it) }
fun Collection.of(
- vararg parentProjects: String,
- except: List = emptyList(),
- action: Action,
+ vararg parentProjects: String,
+ except: List = emptyList(),
+ action: Action,
): Unit = this.filter {
- parentProjects.contains(it.parent?.name) && !except.contains(it.name)
+ parentProjects.contains(it.parent?.name) && !except.contains(it.name)
}.forEach { action(it) }
fun Collection.of(
- vararg parentProjects: String,
- except: List = emptyList(),
+ vararg parentProjects: String,
+ except: List = emptyList(),
): List = this.filter {
- parentProjects.contains(it.parent?.name) && !except.contains(it.name)
+ parentProjects.contains(it.parent?.name) && !except.contains(it.name)
}
infix fun Property.by(value: T) {
- set(value)
+ set(value)
}
-
-fun Project.testProjects(): List = listOfNotNull(
- this.tasks.firstOrNull { it.name.contains("test") },
- tasks.firstOrNull { it.name.contains("e2eTest") },
- tasks.firstOrNull { it.name.contains("integrationTest") }
-)
-
-fun Project.compilationTasks(): List = this.tasks.filter { it.name.contains("compile") }
-
-fun Project.findTestProjectsRecursively(): List {
- val tasks = this.testProjects()
- if (tasks.isNotEmpty()) return tasks
- return this.subprojects.flatMap { it.findTestProjectsRecursively() }
-}
-
-fun Project.recursivelyContainsTask(name: String): Task? {
- val task = this.tasks.firstOrNull { it.name.contains(name) }
- if (task != null) return task
- return this.subprojects.firstNotNullOfOrNull { it.recursivelyContainsTask(name) }
-}
-
-fun Project.whenService(action: (Project) -> Unit): Unit = if (this.parent != null && this.parent!!.name == "projects") {
- action(this)
-} else Unit
-
-fun Project.goToService(): Project {
- if (this.parent != null && this.parent!!.name != "projects") {
- return this.parent!!.goToService()
- }
-
- if (this.parent != null && this.parent!!.name == "projects") {
- return this
- }
-
- throw IllegalStateException("Project is not a service")
-}
-
-fun Project.goToProjectLevel(of: String): Project {
- if (this.parent != null && this.parent!!.name != of) {
- return this.parent!!.goToProjectLevel(of)
- }
-
- if (this.parent != null && this.parent!!.name == of) {
- return this
- }
-
- throw IllegalStateException("Project is not a library")
-}
-
diff --git a/buildSrc/src/main/kotlin/kediatr-publishing.gradle.kts b/buildSrc/src/main/kotlin/kediatr-publishing.gradle.kts
index dafb86c..655d08f 100644
--- a/buildSrc/src/main/kotlin/kediatr-publishing.gradle.kts
+++ b/buildSrc/src/main/kotlin/kediatr-publishing.gradle.kts
@@ -1,89 +1,89 @@
plugins {
- `maven-publish`
- signing
- java
+ `maven-publish`
+ signing
+ java
}
fun getProperty(
- projectKey: String,
- environmentKey: String,
+ projectKey: String,
+ environmentKey: String,
): String? {
- return if (project.hasProperty(projectKey)) {
- project.property(projectKey) as? String?
- } else {
- System.getenv(environmentKey)
- }
+ return if (project.hasProperty(projectKey)) {
+ project.property(projectKey) as? String?
+ } else {
+ System.getenv(environmentKey)
+ }
}
afterEvaluate {
- publishing {
- publications {
- create("publish-${project.name}") {
- groupId = rootProject.group.toString()
- version = rootProject.version.toString()
- artifactId = project.name
- from(components["java"])
- pom {
- name.set(project.name)
- description.set(project.properties["projectDescription"].toString())
- url.set(project.properties["projectUrl"].toString())
- packaging = "jar"
- licenses {
- license {
- name.set(project.properties["licence"].toString())
- url.set(project.properties["licenceUrl"].toString())
- }
- }
- developers {
- developer {
- id.set("osoykan")
- name.set("Oguzhan Soykan")
- email.set("oguzhan.soykan@trendyol.com")
- }
- developer {
- id.set("canerpatir")
- name.set("Caner Patir")
- email.set("caner.patir@trendyol.com")
- }
- developer {
- id.set("bilal-kilic")
- name.set("Bilal Kilic")
- email.set("bilal.kilic@trendyol.com")
- }
- }
- scm {
- connection.set("scm:git@github.com:Trendyol/kediatR.git")
- developerConnection.set("scm:git:ssh://github.com:Trendyol/kediatR.git")
- url.set(project.properties["projectUrl"].toString())
- }
- }
+ publishing {
+ publications {
+ create("publish-${project.name}") {
+ groupId = rootProject.group.toString()
+ version = rootProject.version.toString()
+ artifactId = project.name
+ from(components["java"])
+ pom {
+ name.set(project.name)
+ description.set(project.properties["projectDescription"].toString())
+ url.set(project.properties["projectUrl"].toString())
+ packaging = "jar"
+ licenses {
+ license {
+ name.set(project.properties["licence"].toString())
+ url.set(project.properties["licenceUrl"].toString())
}
- }
-
- repositories {
- maven {
- val releasesRepoUrl = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
- val snapshotsRepoUrl = uri("https://oss.sonatype.org/content/repositories/snapshots/")
- url = if (rootProject.version.toString().endsWith("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl
- // url = rootProject.buildDir.resolve("publications").toURI()
- credentials {
- username = getProperty("nexus_username", "nexus_username")
- password = getProperty("nexus_password", "nexus_password")
- }
+ }
+ developers {
+ developer {
+ id.set("osoykan")
+ name.set("Oguzhan Soykan")
+ email.set("oguzhan.soykan@trendyol.com")
+ }
+ developer {
+ id.set("canerpatir")
+ name.set("Caner Patir")
+ email.set("caner.patir@trendyol.com")
}
+ developer {
+ id.set("bilal-kilic")
+ name.set("Bilal Kilic")
+ email.set("bilal.kilic@trendyol.com")
+ }
+ }
+ scm {
+ connection.set("scm:git@github.com:Trendyol/kediatR.git")
+ developerConnection.set("scm:git:ssh://github.com:Trendyol/kediatR.git")
+ url.set(project.properties["projectUrl"].toString())
+ }
}
+ }
}
- val signingKey = getProperty(projectKey = "gpg.key", environmentKey = "gpg_private_key")
- val passPhrase = getProperty(projectKey = "gpg.passphrase", environmentKey = "gpg_passphrase")
- signing {
- if (passPhrase == null) {
- logger.warn(
- "The passphrase for the signing key was not found. " +
- "Either provide it as env variable 'gpg_passphrase' or as project property 'gpg_passphrase'. " +
- "Otherwise the signing might fail!"
- )
+ repositories {
+ maven {
+ val releasesRepoUrl = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
+ val snapshotsRepoUrl = uri("https://oss.sonatype.org/content/repositories/snapshots/")
+ url = if (rootProject.version.toString().endsWith("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl
+ // url = rootProject.buildDir.resolve("publications").toURI()
+ credentials {
+ username = getProperty("nexus_username", "nexus_username")
+ password = getProperty("nexus_password", "nexus_password")
}
- useInMemoryPgpKeys(signingKey, passPhrase)
- sign(publishing.publications)
+ }
+ }
+ }
+
+ val signingKey = getProperty(projectKey = "gpg.key", environmentKey = "gpg_private_key")
+ val passPhrase = getProperty(projectKey = "gpg.passphrase", environmentKey = "gpg_passphrase")
+ signing {
+ if (passPhrase == null) {
+ logger.warn(
+ "The passphrase for the signing key was not found. " +
+ "Either provide it as env variable 'gpg_passphrase' or as project property 'gpg_passphrase'. " +
+ "Otherwise the signing might fail!"
+ )
}
+ useInMemoryPgpKeys(signingKey, passPhrase)
+ sign(publishing.publications)
+ }
}
diff --git a/buildSrc/src/main/kotlin/predef.kt b/buildSrc/src/main/kotlin/predef.kt
new file mode 100644
index 0000000..2489e55
--- /dev/null
+++ b/buildSrc/src/main/kotlin/predef.kt
@@ -0,0 +1,5 @@
+import org.gradle.api.provider.Provider
+import org.gradle.plugin.use.PluginDependency
+
+val Provider.pluginId: String
+ get() = get().pluginId
diff --git a/gradle.properties b/gradle.properties
index 52042b0..6017c05 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,6 +1,9 @@
org.gradle.parallel=false
org.gradle.caching=true
+org.gradle.configuration-cache=true
projectDescription=Mediator implementation in Kotlin with native coroutine support
projectUrl=https://github.com/Trendyol/kediatR
licenceUrl=https://github.com/Trendyol/kediatR/blob/master/LICENCE
licence=MIT Licence
+org.gradle.jvmargs=-XX:+UseParallelGC
+version="3.1.0"
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 4678650..251c696 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,6 +1,35 @@
[versions]
kotlin = "1.9.22"
+kotlinx = "1.9.0"
+kotest = "5.9.1"
+detekt = "1.23.7"
+junit = "5.11.3"
+koin = "4.0.0"
+quarkus = "3.16.0"
+jakarta = "4.1.0"
[libraries]
+kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx" }
+org-reflections = { module = "org.reflections:reflections", version = "0.10.2" }
+koin-core = { module = "io.insert-koin:koin-core", version.ref = "koin" }
+junitBom = { module = "org.junit:junit-bom", version.ref = "junit" }
+quarkusBom = { module = "io.quarkus:quarkus-bom", version.ref = "quarkus" }
+quarkus-arc = { module = "io.quarkus:quarkus-arc", version.ref = "quarkus" }
+jakarta-enterpise-cdi-api = { module = "jakarta.enterprise:jakarta.enterprise.cdi-api", version.ref = "jakarta" }
+
+# test
+kotest-property-jvm = { module = "io.kotest:kotest-property-jvm", version.ref = "kotest" }
+kotest-datatests = { module = "io.kotest:kotest-framework-datatest-jvm", version.ref = "kotest" }
+kotest-assertions-core = { module = "io.kotest:kotest-assertions-core", version.ref = "kotest" }
+kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinx" }
+koin-test = { module = "io.insert-koin:koin-test", version.ref = "koin" }
+koin-test-junit5 = { module = "io.insert-koin:koin-test-junit5", version.ref = "koin" }
+quarkus-junit5 = { module = "io.quarkus:quarkus-junit5", version.ref = "quarkus" }
+detekt-formatting = { module = "io.gitlab.arturbosch.detekt:detekt-formatting", version.ref = "detekt" }
[plugins]
+kover = { id = "org.jetbrains.kotlinx.kover", version = "0.8.3" }
+testLogger = { id = "com.adarshr.test-logger", version = "4.0.0" }
+detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" }
+spotless = { id = "com.diffplug.spotless", version = "6.25.0" }
+quarkus = { id = "io.quarkus", version.ref = "quarkus" }
diff --git a/projects/build.gradle.kts b/projects/build.gradle.kts
index 4b90b55..8374534 100644
--- a/projects/build.gradle.kts
+++ b/projects/build.gradle.kts
@@ -1,76 +1,49 @@
plugins {
- kotlin("jvm") version libs.versions.kotlin.get()
- jacoco
- `jacoco-report-aggregation`
- `test-report-aggregation`
- id("com.adarshr.test-logger") version "4.0.0"
- id("org.jlleitschuh.gradle.ktlint") version "12.1.1"
+ kotlin("jvm") version libs.versions.kotlin.get()
+ alias(libs.plugins.testLogger)
+ alias(libs.plugins.kover)
}
+kover {
+ reports {
+ filters {
+ excludes {
+ androidGeneratedClasses()
+ this.packages("**generated**")
+ this.classes("**generated**")
+ }
+ }
+ }
+}
subprojects {
- apply {
- plugin("com.adarshr.test-logger")
- plugin("org.jlleitschuh.gradle.ktlint")
- plugin("jacoco")
- }
-
- kotlin {
- jvmToolchain(17)
- }
+ apply {
+ plugin(rootProject.libs.plugins.kover.pluginId)
+ plugin(rootProject.libs.plugins.testLogger.pluginId)
+ }
- dependencies {
- implementation(platform("org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.9.0"))
- implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")
- }
+ kotlin {
+ jvmToolchain(17)
+ }
- dependencies {
- testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.9.0")
- testImplementation(platform("org.junit:junit-bom:5.11.3"))
- testImplementation("org.junit.jupiter:junit-jupiter")
- }
+ dependencies {
+ implementation(rootProject.libs.kotlinx.coroutines.core)
+ }
- tasks.test {
- useJUnitPlatform()
- testlogger {
- setTheme("mocha")
- showStandardStreams = true
- }
- reports {
- junitXml.required.set(true)
- html.required.set(true)
- }
- }
- jacoco {
- reportsDirectory.set(rootProject.layout.buildDirectory.dir("reports/${project.name}/jacoco"))
- }
- tasks.jacocoTestReport {
- dependsOn(tasks.test)
- reports {
- xml.required.set(true)
- html.required.set(false)
- csv.required.set(false)
- }
- executionData(this)
- }
-}
+ dependencies {
+ testImplementation(rootProject.libs.kotlinx.coroutines.test)
+ testImplementation(rootProject.libs.kotest.property.jvm)
+ testImplementation(rootProject.libs.kotest.datatests)
+ }
-tasks.create("jacocoRootReport") {
- enabled = false
- this.group = "Reporting"
- subprojects.forEach { dependsOn(it.tasks.test) }
- subprojects.forEach {
- sourceSets(it.sourceSets.getByName("main"))
- executionData.from(it.layout.buildDirectory.file("jacoco/test.exec"))
+ tasks.test {
+ useJUnitPlatform()
+ testlogger {
+ setTheme("mocha")
+ showStandardStreams = true
}
reports {
- html.required.set(false)
- xml.required.set(true)
- csv.required.set(false)
+ junitXml.required.set(true)
+ html.required.set(true)
}
-}
-
-tasks.testAggregateTestReport {
- subprojects.forEach { dependsOn(it.tasks.test) }
- subprojects.map { it.tasks.test }.forEach { testResults.from(it) }
- destinationDirectory.set(rootProject.layout.buildDirectory.dir("reports/tests"))
+ }
}
diff --git a/projects/kediatr-core/build.gradle.kts b/projects/kediatr-core/build.gradle.kts
index e96cd0a..79df1d5 100644
--- a/projects/kediatr-core/build.gradle.kts
+++ b/projects/kediatr-core/build.gradle.kts
@@ -1,7 +1,18 @@
+plugins {
+ `java-test-fixtures`
+}
+
+val testFixturesImplementation: Configuration by configurations.getting {
+ extendsFrom(configurations.implementation.get())
+}
+
dependencies {
- testImplementation(kotlin("test"))
+ testFixturesImplementation(libs.kotest.assertions.core)
+ testFixturesImplementation(junitLibs.junitJupiterApi)
+ testFixturesImplementation(libs.kotlinx.coroutines.test)
+ testFixturesRuntimeOnly(junitLibs.junitJupiterEngine)
}
kotlin {
- jvmToolchain(11)
+ jvmToolchain(11)
}
diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/AggregateException.kt b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/AggregateException.kt
index c20d68a..b48c519 100644
--- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/AggregateException.kt
+++ b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/AggregateException.kt
@@ -6,5 +6,5 @@ package com.trendyol.kediatr
* @since 1.0.9
*/
class AggregateException(val exceptions: Collection) : RuntimeException() {
- constructor(exceptions: Array) : this(exceptions.toList())
+ constructor(exceptions: Array) : this(exceptions.toList())
}
diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/CommandHandler.kt b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/CommandHandler.kt
index 579c2d0..aa982a4 100644
--- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/CommandHandler.kt
+++ b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/CommandHandler.kt
@@ -8,10 +8,10 @@ package com.trendyol.kediatr
* @see Command
*/
interface CommandHandler {
- /**
- * Handles a command
- *
- * @param command the command to handle
- */
- suspend fun handle(command: TCommand)
+ /**
+ * Handles a command
+ *
+ * @param command the command to handle
+ */
+ suspend fun handle(command: TCommand)
}
diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/CommandProvider.kt b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/CommandProvider.kt
index 7618646..19730ec 100644
--- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/CommandProvider.kt
+++ b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/CommandProvider.kt
@@ -6,12 +6,12 @@ package com.trendyol.kediatr
* @param type of handler
*/
internal class CommandProvider>(
- private val dependencyProvider: DependencyProvider,
- private val type: Class
+ private val dependencyProvider: DependencyProvider,
+ private val type: Class
) {
- fun get(): H {
- return dependencyProvider.getSingleInstanceOf(type)
- }
+ fun get(): H {
+ return dependencyProvider.getSingleInstanceOf(type)
+ }
}
/**
@@ -21,10 +21,10 @@ internal class CommandProvider>(
* @param type of handler
*/
internal class CommandWithResultProvider>(
- private val dependencyProvider: DependencyProvider,
- private val type: Class
+ private val dependencyProvider: DependencyProvider,
+ private val type: Class
) {
- fun get(): H {
- return dependencyProvider.getSingleInstanceOf(type)
- }
+ fun get(): H {
+ return dependencyProvider.getSingleInstanceOf(type)
+ }
}
diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/CommandWithResultHandler.kt b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/CommandWithResultHandler.kt
index 828b79f..a316bce 100644
--- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/CommandWithResultHandler.kt
+++ b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/CommandWithResultHandler.kt
@@ -8,10 +8,10 @@ package com.trendyol.kediatr
* @see Command
*/
interface CommandWithResultHandler, TResult> {
- /**
- * Handles a command
- *
- * @param command the command to handle
- */
- suspend fun handle(command: TCommand): TResult
+ /**
+ * Handles a command
+ *
+ * @param command the command to handle
+ */
+ suspend fun handle(command: TCommand): TResult
}
diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Container.kt b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Container.kt
index ea60054..f998d1e 100644
--- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Container.kt
+++ b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Container.kt
@@ -2,37 +2,37 @@ package com.trendyol.kediatr
@Suppress("UNCHECKED_CAST")
internal class Container(dependencyProvider: DependencyProvider) : Registrar() {
- val commandMap = HashMap, CommandProvider>>()
- val queryMap = HashMap, QueryProvider>>()
- val notificationMap = HashMap, MutableList>>>()
- val pipelineSet = HashSet>()
- val commandWithResultMap = HashMap, CommandWithResultProvider<*>>()
+ val commandMap = HashMap, CommandProvider>>()
+ val queryMap = HashMap, QueryProvider>>()
+ val notificationMap = HashMap, MutableList>>>()
+ val pipelineSet = HashSet>()
+ val commandWithResultMap = HashMap, CommandWithResultProvider<*>>()
- init {
+ init {
- registerFor, *>, Query<*>>(dependencyProvider) { key, value ->
- queryMap[key] = QueryProvider(dependencyProvider, value as Class>)
- }
+ registerFor, *>, Query<*>>(dependencyProvider) { key, value ->
+ queryMap[key] = QueryProvider(dependencyProvider, value as Class>)
+ }
- registerFor, Command>(dependencyProvider) { key, value ->
- commandMap[key] = CommandProvider(dependencyProvider, value)
- }
+ registerFor, Command>(dependencyProvider) { key, value ->
+ commandMap[key] = CommandProvider(dependencyProvider, value)
+ }
- registerFor, *>, CommandWithResult<*>>(dependencyProvider) { key, value ->
- commandWithResultMap[key] =
- CommandWithResultProvider(
- dependencyProvider,
- value as Class>
- )
- }
+ registerFor, *>, CommandWithResult<*>>(dependencyProvider) { key, value ->
+ commandWithResultMap[key] =
+ CommandWithResultProvider(
+ dependencyProvider,
+ value as Class>
+ )
+ }
- registerFor, Notification>(dependencyProvider) { key, value ->
- notificationMap.getOrPut(key) { mutableListOf() }
- .add(NotificationProvider(dependencyProvider, value as Class>))
- }
+ registerFor, Notification>(dependencyProvider) { key, value ->
+ notificationMap.getOrPut(key) { mutableListOf() }
+ .add(NotificationProvider(dependencyProvider, value as Class>))
+ }
- registerFor(dependencyProvider) { handler ->
- pipelineSet.add(PipelineProvider(dependencyProvider, handler))
- }
+ registerFor(dependencyProvider) { handler ->
+ pipelineSet.add(PipelineProvider(dependencyProvider, handler))
}
+ }
}
diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/DependencyProvider.kt b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/DependencyProvider.kt
index 220c95b..9514ef1 100644
--- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/DependencyProvider.kt
+++ b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/DependencyProvider.kt
@@ -1,7 +1,7 @@
package com.trendyol.kediatr
interface DependencyProvider {
- fun getSingleInstanceOf(clazz: Class): T
+ fun getSingleInstanceOf(clazz: Class): T
- fun getSubTypesOf(clazz: Class): Collection>
+ fun getSubTypesOf(clazz: Class): Collection>
}
diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Mediator.kt b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Mediator.kt
index 06ddb56..fdf0bed 100644
--- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Mediator.kt
+++ b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Mediator.kt
@@ -1,22 +1,22 @@
package com.trendyol.kediatr
interface Mediator {
- suspend fun , TResponse> send(query: TQuery): TResponse
+ suspend fun , TResponse> send(query: TQuery): TResponse
- suspend fun send(command: TCommand)
+ suspend fun send(command: TCommand)
- suspend fun , TResult> send(command: TCommand): TResult
+ suspend fun , TResult> send(command: TCommand): TResult
- /**
- * Publishes the given notification to appropriate notification handlers
- *
- * @since 1.0.9
- * @param T any [Notification] subclass to publish
- */
- suspend fun publish(notification: T)
+ /**
+ * Publishes the given notification to appropriate notification handlers
+ *
+ * @since 1.0.9
+ * @param T any [Notification] subclass to publish
+ */
+ suspend fun publish(notification: T)
- suspend fun publish(
- notification: T,
- publishStrategy: PublishStrategy
- )
+ suspend fun publish(
+ notification: T,
+ publishStrategy: PublishStrategy
+ )
}
diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/MediatorBuilder.kt b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/MediatorBuilder.kt
index 1fc56f2..8e10350 100644
--- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/MediatorBuilder.kt
+++ b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/MediatorBuilder.kt
@@ -1,28 +1,28 @@
package com.trendyol.kediatr
class MediatorBuilder(
- private val dependencyProvider: DependencyProvider
+ private val dependencyProvider: DependencyProvider
) {
- internal var defaultPublishStrategy: PublishStrategy = StopOnExceptionPublishStrategy()
- private set
+ internal var defaultPublishStrategy: PublishStrategy = StopOnExceptionPublishStrategy()
+ private set
- /**
- * Overrides default notification publishing strategy.
- * Default strategy is [StopOnExceptionPublishStrategy]
- *
- * @since 1.0.9
- * @see [PublishStrategy]
- * @see [ContinueOnExceptionPublishStrategy]
- * @see [StopOnExceptionPublishStrategy]
- * @see [ParallelNoWaitPublishStrategy]
- * @see [ParallelWhenAllPublishStrategy]
- */
- fun withPublishStrategy(publishStrategy: PublishStrategy): MediatorBuilder {
- this.defaultPublishStrategy = publishStrategy
- return this
- }
+ /**
+ * Overrides default notification publishing strategy.
+ * Default strategy is [StopOnExceptionPublishStrategy]
+ *
+ * @since 1.0.9
+ * @see [PublishStrategy]
+ * @see [ContinueOnExceptionPublishStrategy]
+ * @see [StopOnExceptionPublishStrategy]
+ * @see [ParallelNoWaitPublishStrategy]
+ * @see [ParallelWhenAllPublishStrategy]
+ */
+ fun withPublishStrategy(publishStrategy: PublishStrategy): MediatorBuilder {
+ this.defaultPublishStrategy = publishStrategy
+ return this
+ }
- fun build(registry: Registry = RegistryImpl(dependencyProvider)): Mediator {
- return MediatorImpl(registry, defaultPublishStrategy)
- }
+ fun build(registry: Registry = RegistryImpl(dependencyProvider)): Mediator {
+ return MediatorImpl(registry, defaultPublishStrategy)
+ }
}
diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/MediatorImpl.kt b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/MediatorImpl.kt
index bdc2d09..35eb824 100644
--- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/MediatorImpl.kt
+++ b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/MediatorImpl.kt
@@ -1,53 +1,53 @@
package com.trendyol.kediatr
class MediatorImpl(
- private val registry: Registry,
- private val defaultPublishStrategy: PublishStrategy = StopOnExceptionPublishStrategy()
+ private val registry: Registry,
+ private val defaultPublishStrategy: PublishStrategy = StopOnExceptionPublishStrategy()
) : Mediator {
- override suspend fun , TResponse> send(query: TQuery): TResponse =
- processPipeline(
- registry.getPipelineBehaviors(),
- query
- ) {
- registry.resolveQueryHandler(query.javaClass).handle(query)
- }
-
- override suspend fun send(command: TCommand) =
- processPipeline(
- registry.getPipelineBehaviors(),
- command
- ) {
- registry.resolveCommandHandler(command.javaClass).handle(command)
- }
-
- override suspend fun , TResult> send(command: TCommand): TResult =
- processPipeline(
- registry.getPipelineBehaviors(),
- command
- ) {
- registry.resolveCommandWithResultHandler(command.javaClass).handle(command)
- }
+ override suspend fun , TResponse> send(query: TQuery): TResponse =
+ processPipeline(
+ registry.getPipelineBehaviors(),
+ query
+ ) {
+ registry.resolveQueryHandler(query.javaClass).handle(query)
+ }
- override suspend fun publish(notification: T) = publish(notification, defaultPublishStrategy)
+ override suspend fun send(command: TCommand) =
+ processPipeline(
+ registry.getPipelineBehaviors(),
+ command
+ ) {
+ registry.resolveCommandHandler(command.javaClass).handle(command)
+ }
- override suspend fun publish(
- notification: T,
- publishStrategy: PublishStrategy
- ) = processPipeline(
- registry.getPipelineBehaviors(),
- notification
+ override suspend fun , TResult> send(command: TCommand): TResult =
+ processPipeline(
+ registry.getPipelineBehaviors(),
+ command
) {
- publishStrategy.publish(notification, registry.resolveNotificationHandlers(notification.javaClass))
+ registry.resolveCommandWithResultHandler(command.javaClass).handle(command)
}
- private suspend fun processPipeline(
- pipelineBehaviors: Collection,
- request: TRequest,
- handler: RequestHandlerDelegate
- ): TResponse =
- pipelineBehaviors
- .reversed()
- .fold(handler) { next, pipeline ->
- { pipeline.handle(request) { next(it) } }
- }(request)
+ override suspend fun publish(notification: T) = publish(notification, defaultPublishStrategy)
+
+ override suspend fun publish(
+ notification: T,
+ publishStrategy: PublishStrategy
+ ) = processPipeline(
+ registry.getPipelineBehaviors(),
+ notification
+ ) {
+ publishStrategy.publish(notification, registry.resolveNotificationHandlers(notification.javaClass))
+ }
+
+ private suspend fun processPipeline(
+ pipelineBehaviors: Collection,
+ request: TRequest,
+ handler: RequestHandlerDelegate
+ ): TResponse =
+ pipelineBehaviors
+ .reversed()
+ .fold(handler) { next, pipeline ->
+ { pipeline.handle(request) { next(it) } }
+ }(request)
}
diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/NotificationHandler.kt b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/NotificationHandler.kt
index 181a259..1a4c675 100644
--- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/NotificationHandler.kt
+++ b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/NotificationHandler.kt
@@ -8,10 +8,10 @@ package com.trendyol.kediatr
* @see Notification
*/
interface NotificationHandler where T : Notification {
- /**
- * Handles a notification
- *
- * @param notification the notification to handle
- */
- suspend fun handle(notification: T)
+ /**
+ * Handles a notification
+ *
+ * @param notification the notification to handle
+ */
+ suspend fun handle(notification: T)
}
diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/NotificationProvider.kt b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/NotificationProvider.kt
index 7c0ff9a..1b31e54 100644
--- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/NotificationProvider.kt
+++ b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/NotificationProvider.kt
@@ -1,10 +1,10 @@
package com.trendyol.kediatr
internal class NotificationProvider>(
- private val dependencyProvider: DependencyProvider,
- private val type: Class
+ private val dependencyProvider: DependencyProvider,
+ private val type: Class
) {
- fun get(): H {
- return dependencyProvider.getSingleInstanceOf(type)
- }
+ fun get(): H {
+ return dependencyProvider.getSingleInstanceOf(type)
+ }
}
diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/PipelineBehavior.kt b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/PipelineBehavior.kt
index 41564d3..9ee863b 100644
--- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/PipelineBehavior.kt
+++ b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/PipelineBehavior.kt
@@ -6,14 +6,14 @@ package com.trendyol.kediatr
* @since 1.0.12
*/
interface PipelineBehavior {
- /**
- * Process to invoke before handling any query, command or notification
- *
- * @param request the request to handle
- * @param next the represents the CommandHandler handle function
- */
- suspend fun handle(
- request: TRequest,
- next: RequestHandlerDelegate
- ): TResponse
+ /**
+ * Process to invoke before handling any query, command or notification
+ *
+ * @param request the request to handle
+ * @param next the represents the CommandHandler handle function
+ */
+ suspend fun handle(
+ request: TRequest,
+ next: RequestHandlerDelegate
+ ): TResponse
}
diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/PipelineProvider.kt b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/PipelineProvider.kt
index 5cf019a..efc1444 100644
--- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/PipelineProvider.kt
+++ b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/PipelineProvider.kt
@@ -6,10 +6,10 @@ package com.trendyol.kediatr
* @param type of pipeline behavior
*/
internal class PipelineProvider(
- private val dependencyProvider: DependencyProvider,
- private val type: Class
+ private val dependencyProvider: DependencyProvider,
+ private val type: Class
) {
- fun get(): H {
- return dependencyProvider.getSingleInstanceOf(type)
- }
+ fun get(): H {
+ return dependencyProvider.getSingleInstanceOf(type)
+ }
}
diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/PublishStrategies.kt b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/PublishStrategies.kt
index aec757a..8daa366 100644
--- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/PublishStrategies.kt
+++ b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/PublishStrategies.kt
@@ -3,68 +3,68 @@ package com.trendyol.kediatr
import kotlinx.coroutines.*
class ContinueOnExceptionPublishStrategy : PublishStrategy {
- override suspend fun publish(
- notification: T,
- notificationHandlers: Collection>,
- dispatcher: CoroutineDispatcher
- ) {
- coroutineScope {
- withContext(dispatcher) {
- val exceptions = mutableListOf()
- notificationHandlers.forEach {
- try {
- it.handle(notification)
- } catch (e: Exception) {
- exceptions.add(e)
- }
- }
- if (exceptions.isNotEmpty()) {
- throw AggregateException(exceptions)
- }
- }
+ override suspend fun publish(
+ notification: T,
+ notificationHandlers: Collection>,
+ dispatcher: CoroutineDispatcher
+ ) {
+ coroutineScope {
+ withContext(dispatcher) {
+ val exceptions = mutableListOf()
+ notificationHandlers.forEach {
+ try {
+ it.handle(notification)
+ } catch (e: Exception) {
+ exceptions.add(e)
+ }
}
+ if (exceptions.isNotEmpty()) {
+ throw AggregateException(exceptions)
+ }
+ }
}
+ }
}
class StopOnExceptionPublishStrategy : PublishStrategy {
- override suspend fun publish(
- notification: T,
- notificationHandlers: Collection>,
- dispatcher: CoroutineDispatcher
- ) {
- coroutineScope {
- withContext(dispatcher) {
- notificationHandlers.forEach { it.handle(notification) }
- }
- }
+ override suspend fun publish(
+ notification: T,
+ notificationHandlers: Collection>,
+ dispatcher: CoroutineDispatcher
+ ) {
+ coroutineScope {
+ withContext(dispatcher) {
+ notificationHandlers.forEach { it.handle(notification) }
+ }
}
+ }
}
class ParallelNoWaitPublishStrategy : PublishStrategy {
- override suspend fun publish(
- notification: T,
- notificationHandlers: Collection>,
- dispatcher: CoroutineDispatcher
- ) {
- coroutineScope {
- withContext(dispatcher) {
- notificationHandlers.forEach { launch { it.handle(notification) } }
- }
- }
+ override suspend fun publish(
+ notification: T,
+ notificationHandlers: Collection>,
+ dispatcher: CoroutineDispatcher
+ ) {
+ coroutineScope {
+ withContext(dispatcher) {
+ notificationHandlers.forEach { launch { it.handle(notification) } }
+ }
}
+ }
}
class ParallelWhenAllPublishStrategy : PublishStrategy {
- override suspend fun publish(
- notification: T,
- notificationHandlers: Collection>,
- dispatcher: CoroutineDispatcher
- ) {
- coroutineScope {
- withContext(dispatcher) {
- val deferredResults = notificationHandlers.map { async { it.handle(notification) } }
- deferredResults.awaitAll()
- }
- }
+ override suspend fun publish(
+ notification: T,
+ notificationHandlers: Collection>,
+ dispatcher: CoroutineDispatcher
+ ) {
+ coroutineScope {
+ withContext(dispatcher) {
+ val deferredResults = notificationHandlers.map { async { it.handle(notification) } }
+ deferredResults.awaitAll()
+ }
}
+ }
}
diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/PublishStrategy.kt b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/PublishStrategy.kt
index d49b78b..7d1dbbd 100644
--- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/PublishStrategy.kt
+++ b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/PublishStrategy.kt
@@ -4,9 +4,9 @@ import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
interface PublishStrategy {
- suspend fun publish(
- notification: T,
- notificationHandlers: Collection>,
- dispatcher: CoroutineDispatcher = Dispatchers.IO
- )
+ suspend fun publish(
+ notification: T,
+ notificationHandlers: Collection>,
+ dispatcher: CoroutineDispatcher = Dispatchers.IO
+ )
}
diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/QueryHandler.kt b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/QueryHandler.kt
index 0e546d4..b91f943 100644
--- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/QueryHandler.kt
+++ b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/QueryHandler.kt
@@ -8,10 +8,10 @@ package com.trendyol.kediatr
* @see Query
*/
interface QueryHandler, TResponse> {
- /**
- * Handles a query
- *
- * @param query the query to handle
- */
- suspend fun handle(query: TQuery): TResponse
+ /**
+ * Handles a query
+ *
+ * @param query the query to handle
+ */
+ suspend fun handle(query: TQuery): TResponse
}
diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/QueryProvider.kt b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/QueryProvider.kt
index 45db5d7..b8ff79a 100644
--- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/QueryProvider.kt
+++ b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/QueryProvider.kt
@@ -6,10 +6,10 @@ package com.trendyol.kediatr
* @param type of handler
*/
internal class QueryProvider>(
- private val dependencyProvider: DependencyProvider,
- private val type: Class
+ private val dependencyProvider: DependencyProvider,
+ private val type: Class
) {
- fun get(): H {
- return dependencyProvider.getSingleInstanceOf(type)
- }
+ fun get(): H {
+ return dependencyProvider.getSingleInstanceOf(type)
+ }
}
diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Registrar.kt b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Registrar.kt
index 2215180..1be01f7 100644
--- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Registrar.kt
+++ b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Registrar.kt
@@ -1,72 +1,71 @@
package com.trendyol.kediatr
-import java.lang.reflect.ParameterizedType
-import java.lang.reflect.TypeVariable
+import java.lang.reflect.*
@Suppress("UNCHECKED_CAST")
abstract class Registrar {
- protected inline fun registerFor(
- dependencyProvider: DependencyProvider,
- registrar: (key: Class, value: Class) -> Unit
- ) = dependencyProvider.getSubTypesOf(THandler::class.java).forEach {
- registerFor(it) { key, value ->
- registrar(key as Class, value as Class)
- }
+ protected inline fun registerFor(
+ dependencyProvider: DependencyProvider,
+ registrar: (key: Class, value: Class) -> Unit
+ ) = dependencyProvider.getSubTypesOf(THandler::class.java).forEach {
+ registerFor(it) { key, value ->
+ registrar(key as Class, value as Class)
}
+ }
+
+ protected inline fun registerFor(
+ handler: Class<*>,
+ registrar: (key: Class<*>, value: Class<*>) -> Unit
+ ) {
+ val interfaceOrBaseClass = THandler::class.java
+ if (!interfaceOrBaseClass.isAssignableFrom(handler)) return
+
+ handler.genericInterfaces
+ .filterIsInstance()
+ .map { extractParameter(it) }
+ .forEach { registrar(it, handler) }
- protected inline fun registerFor(
- handler: Class<*>,
- registrar: (key: Class<*>, value: Class<*>) -> Unit
- ) {
- val interfaceOrBaseClass = THandler::class.java
- if (!interfaceOrBaseClass.isAssignableFrom(handler)) return
+ when (handler.genericSuperclass) {
+ is ParameterizedType -> {
+ val inheritedHandler = (handler.genericSuperclass as ParameterizedType).rawType as Class<*>
+ inheritedHandler.genericInterfaces
+ .filterIsInstance()
+ .map { extractParameter(handler.genericSuperclass as ParameterizedType) }
+ .forEach { registrar(it, handler) }
+ }
- handler.genericInterfaces
+ is Class<*> -> {
+ val inheritedHandler = handler.genericSuperclass as Class<*>
+ if (interfaceOrBaseClass.isAssignableFrom(inheritedHandler)) {
+ inheritedHandler.genericInterfaces
.filterIsInstance()
.map { extractParameter(it) }
.forEach { registrar(it, handler) }
-
- when (handler.genericSuperclass) {
- is ParameterizedType -> {
- val inheritedHandler = (handler.genericSuperclass as ParameterizedType).rawType as Class<*>
- inheritedHandler.genericInterfaces
- .filterIsInstance()
- .map { extractParameter(handler.genericSuperclass as ParameterizedType) }
- .forEach { registrar(it, handler) }
- }
-
- is Class<*> -> {
- val inheritedHandler = handler.genericSuperclass as Class<*>
- if (interfaceOrBaseClass.isAssignableFrom(inheritedHandler)) {
- inheritedHandler.genericInterfaces
- .filterIsInstance()
- .map { extractParameter(it) }
- .forEach { registrar(it, handler) }
- }
- }
}
+ }
}
+ }
- protected inline fun registerFor(
- dependencyProvider: DependencyProvider,
- registrar: (value: Class) -> Unit
- ) = dependencyProvider.getSubTypesOf(T::class.java).forEach { handler ->
- registerFor(handler) { value -> registrar(value as Class) }
- }
+ protected inline fun registerFor(
+ dependencyProvider: DependencyProvider,
+ registrar: (value: Class) -> Unit
+ ) = dependencyProvider.getSubTypesOf(T::class.java).forEach { handler ->
+ registerFor(handler) { value -> registrar(value as Class) }
+ }
- protected inline fun registerFor(
- handler: Class<*>,
- registrar: (value: Class<*>) -> Unit
- ) {
- val interfaceOrBaseClass = T::class.java
- if (!interfaceOrBaseClass.isAssignableFrom(handler)) return
- registrar(handler)
- }
+ protected inline fun registerFor(
+ handler: Class<*>,
+ registrar: (value: Class<*>) -> Unit
+ ) {
+ val interfaceOrBaseClass = T::class.java
+ if (!interfaceOrBaseClass.isAssignableFrom(handler)) return
+ registrar(handler)
+ }
- protected fun extractParameter(genericInterface: ParameterizedType): Class<*> =
- when (val typeArgument = genericInterface.actualTypeArguments[0]) {
- is ParameterizedType -> typeArgument.rawType as Class<*>
- is TypeVariable<*> -> extractParameter((genericInterface.rawType as Class<*>).genericInterfaces[0] as ParameterizedType)
- else -> typeArgument as Class<*>
- }
+ protected fun extractParameter(genericInterface: ParameterizedType): Class<*> =
+ when (val typeArgument = genericInterface.actualTypeArguments[0]) {
+ is ParameterizedType -> typeArgument.rawType as Class<*>
+ is TypeVariable<*> -> extractParameter((genericInterface.rawType as Class<*>).genericInterfaces[0] as ParameterizedType)
+ else -> typeArgument as Class<*>
+ }
}
diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Registry.kt b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Registry.kt
index 61ea062..6eff2d1 100644
--- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Registry.kt
+++ b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/Registry.kt
@@ -1,17 +1,17 @@
package com.trendyol.kediatr
interface Registry {
- fun resolveCommandHandler(classOfCommand: Class): CommandHandler
+ fun resolveCommandHandler(classOfCommand: Class): CommandHandler
- fun , TResult> resolveCommandWithResultHandler(
- classOfCommand: Class
- ): CommandWithResultHandler
+ fun , TResult> resolveCommandWithResultHandler(
+ classOfCommand: Class
+ ): CommandWithResultHandler
- fun , TResult> resolveQueryHandler(classOfQuery: Class): QueryHandler
+ fun , TResult> resolveQueryHandler(classOfQuery: Class): QueryHandler
- fun resolveNotificationHandlers(
- classOfNotification: Class
- ): Collection>
+ fun resolveNotificationHandlers(
+ classOfNotification: Class
+ ): Collection>
- fun getPipelineBehaviors(): Collection
+ fun getPipelineBehaviors(): Collection
}
diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/RegistryImpl.kt b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/RegistryImpl.kt
index 4f01f6f..cc7451c 100644
--- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/RegistryImpl.kt
+++ b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/RegistryImpl.kt
@@ -3,38 +3,38 @@
package com.trendyol.kediatr
class RegistryImpl(
- dependencyProvider: DependencyProvider
+ dependencyProvider: DependencyProvider
) : Registry {
- private val registry = Container(dependencyProvider)
+ private val registry = Container(dependencyProvider)
- override fun resolveCommandHandler(classOfCommand: Class): CommandHandler {
- val handler =
- registry.commandMap[classOfCommand]?.get()
- ?: throw HandlerNotFoundException("handler could not be found for ${classOfCommand.name}")
- return handler as CommandHandler
- }
+ override fun resolveCommandHandler(classOfCommand: Class): CommandHandler {
+ val handler =
+ registry.commandMap[classOfCommand]?.get()
+ ?: throw HandlerNotFoundException("handler could not be found for ${classOfCommand.name}")
+ return handler as CommandHandler
+ }
- override fun , TResult> resolveCommandWithResultHandler(
- classOfCommand: Class
- ): CommandWithResultHandler {
- val handler =
- registry.commandWithResultMap[classOfCommand]?.get()
- ?: throw HandlerNotFoundException("handler could not be found for ${classOfCommand.name}")
- return handler as CommandWithResultHandler
- }
+ override fun , TResult> resolveCommandWithResultHandler(
+ classOfCommand: Class
+ ): CommandWithResultHandler {
+ val handler =
+ registry.commandWithResultMap[classOfCommand]?.get()
+ ?: throw HandlerNotFoundException("handler could not be found for ${classOfCommand.name}")
+ return handler as CommandWithResultHandler
+ }
- override fun resolveNotificationHandlers(
- classOfNotification: Class
- ): Collection> =
- registry.notificationMap.filter { (k, _) -> k.isAssignableFrom(classOfNotification) }
- .flatMap { (_, v) -> v.map { it.get() as NotificationHandler } }
+ override fun resolveNotificationHandlers(
+ classOfNotification: Class
+ ): Collection> =
+ registry.notificationMap.filter { (k, _) -> k.isAssignableFrom(classOfNotification) }
+ .flatMap { (_, v) -> v.map { it.get() as NotificationHandler } }
- override fun , TResult> resolveQueryHandler(classOfQuery: Class): QueryHandler {
- val handler =
- registry.queryMap[classOfQuery]?.get()
- ?: throw HandlerNotFoundException("handler could not be found for ${classOfQuery.name}")
- return handler as QueryHandler
- }
+ override fun , TResult> resolveQueryHandler(classOfQuery: Class): QueryHandler {
+ val handler =
+ registry.queryMap[classOfQuery]?.get()
+ ?: throw HandlerNotFoundException("handler could not be found for ${classOfQuery.name}")
+ return handler as QueryHandler
+ }
- override fun getPipelineBehaviors(): Collection = registry.pipelineSet.map { it.get() }
+ override fun getPipelineBehaviors(): Collection = registry.pipelineSet.map { it.get() }
}
diff --git a/projects/kediatr-core/src/test/kotlin/com/trendyol/kediatr/CommandHandlerTest.kt b/projects/kediatr-core/src/test/kotlin/com/trendyol/kediatr/CommandHandlerTest.kt
index 92392fb..e66f746 100644
--- a/projects/kediatr-core/src/test/kotlin/com/trendyol/kediatr/CommandHandlerTest.kt
+++ b/projects/kediatr-core/src/test/kotlin/com/trendyol/kediatr/CommandHandlerTest.kt
@@ -1,159 +1,5 @@
package com.trendyol.kediatr
-import kotlinx.coroutines.runBlocking
-import org.junit.jupiter.api.Nested
-import org.junit.jupiter.api.Test
-import kotlin.test.assertEquals
-import kotlin.test.assertFailsWith
-import kotlin.test.assertNotNull
+import com.trendyol.kediatr.coreUseCases.CommandHandlerUseCases
-class CommandHandlerTest {
- @Test
- fun async_commandHandler_should_be_fired() =
- runBlocking {
- class MyAsyncCommand : Command
-
- class MyCommandHandler : CommandHandler {
- var invocationCount = 0
-
- override suspend fun handle(command: MyAsyncCommand) {
- invocationCount++
- }
- }
-
- val handler = MyCommandHandler()
- val handlers: HashMap, Any> = hashMapOf(Pair(MyCommandHandler::class.java, handler))
- val provider = ManualDependencyProvider(handlers)
- val bus: Mediator = MediatorBuilder(provider).build()
- bus.send(MyAsyncCommand())
-
- assertEquals(1, handler.invocationCount)
- }
-
- @Test
- fun `should throw exception if given async command has not been registered before`() {
- class NonExistCommand : Command
-
- val handlers: HashMap, Any> = hashMapOf()
- val provider = ManualDependencyProvider(handlers)
- val bus: Mediator = MediatorBuilder(provider).build()
-
- val exception =
- assertFailsWith(HandlerNotFoundException::class) {
- runBlocking {
- bus.send(NonExistCommand())
- }
- }
-
- assertNotNull(exception)
- assertEquals("handler could not be found for ${NonExistCommand::class.java.typeName}", exception.message)
- }
-
- @Test
- fun inheritance_should_work() =
- runBlocking {
- class MyCommandForInheritance : Command
-
- abstract class MyCommandHandlerFor : CommandHandler
-
- class MyInheritedCommandHandler : MyCommandHandlerFor() {
- var invocationCount = 0
-
- override suspend fun handle(command: MyCommandForInheritance) {
- invocationCount++
- }
- }
-
- val handler = MyInheritedCommandHandler()
- val handlers: HashMap, Any> = hashMapOf(Pair(MyInheritedCommandHandler::class.java, handler))
- val provider = ManualDependencyProvider(handlers)
- val bus: Mediator = MediatorBuilder(provider).build()
- bus.send(MyCommandForInheritance())
-
- assertEquals(1, handler.invocationCount)
- }
-
- @Test
- fun inheritance_but_not_parameterized_should_work() =
- runBlocking {
- class MyCommandForInheritance : Command
-
- abstract class MyCommandHandlerBaseForSpecificCommand : CommandHandler
-
- class MyInheritedCommandHandlerForSpecificCommand : MyCommandHandlerBaseForSpecificCommand() {
- var invocationCount = 0
-
- override suspend fun handle(command: MyCommandForInheritance) {
- invocationCount++
- }
- }
-
- val handler = MyInheritedCommandHandlerForSpecificCommand()
- val handlers: HashMap, Any> =
- hashMapOf(Pair(MyInheritedCommandHandlerForSpecificCommand::class.java, handler))
- val provider = ManualDependencyProvider(handlers)
- val bus: Mediator = MediatorBuilder(provider).build()
- bus.send(MyCommandForInheritance())
-
- assertEquals(1, handler.invocationCount)
- }
-
- @Nested
- inner class ParameterizedTests {
- @Test
- fun async_command_should_be_fired() =
- runBlocking {
- class ParameterizedCommand(val param: T) : Command
-
- class ParameterizedCommandHandler : CommandHandler> {
- var invocationCount = 0
-
- override suspend fun handle(command: ParameterizedCommand) {
- invocationCount++
- }
- }
-
- // given
- val handler = ParameterizedCommandHandler>()
- val handlers: HashMap, Any> =
- hashMapOf(Pair(ParameterizedCommandHandler::class.java, handler))
- val provider = ManualDependencyProvider(handlers)
- val bus: Mediator = MediatorBuilder(provider).build()
-
- // when
- bus.send(ParameterizedCommand("MyParam"))
-
- // then
- assertEquals(1, handler.invocationCount)
- }
-
- @Test
- fun async_commandHandler_with_inheritance_should_be_fired() =
- runBlocking {
- class ParameterizedCommand