diff --git a/.github/workflows/pull-request-merge-check.yml b/.github/workflows/pull-request-merge-check.yml index 243369a7..0eff5c92 100644 --- a/.github/workflows/pull-request-merge-check.yml +++ b/.github/workflows/pull-request-merge-check.yml @@ -18,16 +18,16 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Gradle Wrapper Cache - uses: actions/cache@v3.3.2 + uses: actions/cache@v4.0.2 with: path: ~/.gradle/wrapper key: gradle-wrapper-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }} - name: Dependencies Cache - uses: actions/cache@v3.3.2 + uses: actions/cache@v4.0.2 with: path: | ~/.gradle/cache/jars-* @@ -37,7 +37,7 @@ jobs: restore-keys: gradle-dependencies- - name: Cache - uses: actions/cache@v3.3.2 + uses: actions/cache@v4.0.2 with: path: | ~/.gradle/caches/build-cache-* @@ -47,21 +47,21 @@ jobs: restore-keys: ${{ runner.os }}-gradle-build-${{ github.workflow }}- - name: Build Cache - uses: actions/cache@v3.3.2 + uses: actions/cache@v4.0.2 with: path: | build key: gradle-build-${{ hashFiles('**/*.gradle.kts') }}-${{ hashFiles('**/*.kt') }}-${{ github.sha }} - name: Set up JDK 21 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '21' distribution: 'temurin' - name: Build - uses: gradle/gradle-build-action@v2.8.1 + uses: gradle/gradle-build-action@v3.3.2 with: - arguments: testClasses + arguments: :hideout-core:testClasses unit-test: name: Unit Test @@ -69,16 +69,16 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Gradle Wrapper Cache - uses: actions/cache@v3.3.2 + uses: actions/cache@v4.0.2 with: path: ~/.gradle/wrapper key: gradle-wrapper-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }} - name: Dependencies Cache - uses: actions/cache@v3.3.2 + uses: actions/cache@v4.0.2 with: path: | ~/.gradle/cache/jars-* @@ -88,7 +88,7 @@ jobs: restore-keys: gradle-dependencies- - name: Cache - uses: actions/cache@v3.3.2 + uses: actions/cache@v4.0.2 with: path: | ~/.gradle/caches/build-cache-* @@ -98,26 +98,26 @@ jobs: restore-keys: ${{ runner.os }}-gradle-build-${{ github.workflow }}- - name: Build Cache - uses: actions/cache@v3.3.2 + uses: actions/cache@v4.0.2 with: path: | build key: gradle-build-${{ hashFiles('**/*.gradle.kts') }}-${{ hashFiles('src') }}-${{ github.sha }} - name: Set up JDK 21 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '21' distribution: 'temurin' - name: Unit Test - uses: gradle/gradle-build-action@v2.8.1 + uses: gradle/gradle-build-action@v3.3.2 with: - arguments: test + arguments: :hideout-core:test - name: Save Test Report if: always() - uses: actions/cache/save@v3 + uses: actions/cache/save@v4 with: path: build/test-results key: unit-test-report-${{ github.sha }} @@ -128,16 +128,16 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Gradle Wrapper Cache - uses: actions/cache@v3.3.2 + uses: actions/cache@v4.0.2 with: path: ~/.gradle/wrapper key: gradle-wrapper-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }} - name: Dependencies Cache - uses: actions/cache@v3.3.2 + uses: actions/cache@v4.0.2 with: path: | ~/.gradle/cache/jars-* @@ -147,7 +147,7 @@ jobs: restore-keys: gradle-dependencies- - name: Cache - uses: actions/cache@v3.3.2 + uses: actions/cache@v4.0.2 with: path: | ~/.gradle/caches/build-cache-* @@ -157,14 +157,14 @@ jobs: restore-keys: ${{ runner.os }}-gradle-build-${{ github.workflow }}- - name: Build Cache - uses: actions/cache@v3.3.2 + uses: actions/cache@v4.0.2 with: path: | build key: gradle-build-${{ hashFiles('**/*.gradle.kts') }}-${{ hashFiles('src') }}-${{ github.sha }} - name: Set up JDK 21 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '21' distribution: 'temurin' @@ -175,13 +175,13 @@ jobs: mongodb-version: latest - name: Unit Test - uses: gradle/gradle-build-action@v2.8.1 + uses: gradle/gradle-build-action@v3.3.2 with: - arguments: integrationTest + arguments: :hideout-core:integrationTest - name: Save Test Report if: always() - uses: actions/cache/save@v3 + uses: actions/cache/save@v4 with: path: build/test-results key: integration-test-report-${{ github.sha }} @@ -192,16 +192,16 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Gradle Wrapper Cache - uses: actions/cache@v3.3.2 + uses: actions/cache@v4.0.2 with: path: ~/.gradle/wrapper key: gradle-wrapper-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }} - name: Dependencies Cache - uses: actions/cache@v3.3.2 + uses: actions/cache@v4.0.2 with: path: | ~/.gradle/cache/jars-* @@ -211,7 +211,7 @@ jobs: restore-keys: gradle-dependencies- - name: Cache - uses: actions/cache@v3.3.2 + uses: actions/cache@v4.0.2 with: path: | ~/.gradle/caches/build-cache-* @@ -221,22 +221,22 @@ jobs: restore-keys: ${{ runner.os }}-gradle-build-${{ github.workflow }}- - name: Build Cache - uses: actions/cache@v3.3.2 + uses: actions/cache@v4.0.2 with: path: | build key: gradle-build-${{ hashFiles('**/*.gradle.kts') }}-${{ hashFiles('src') }}-${{ github.sha }} - name: Set up JDK 21 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '21' distribution: 'temurin' - name: Run Kover - uses: gradle/gradle-build-action@v2.8.1 + uses: gradle/gradle-build-action@v3.3.2 with: - arguments: koverXmlReport -x integrationTest -x e2eTest --rerun-tasks + arguments: :hideout-core:koverXmlReport -x :hideout-core:integrationTest -x :hideout-core:e2eTest --rerun-tasks - name: Add coverage report to PR if: always() @@ -259,25 +259,25 @@ jobs: runs-on: ubuntu-latest steps: - name: Restore Test Report - uses: actions/cache/restore@v3 + uses: actions/cache/restore@v4 with: path: build/test-results key: unit-test-report-${{ github.sha }} - name: Restore Test Report - uses: actions/cache/restore@v3 + uses: actions/cache/restore@v4 with: path: build/test-results key: integration-test-report-${{ github.sha }} - name: Restore Test Report - uses: actions/cache/restore@v3 + uses: actions/cache/restore@v4 with: path: build/test-results key: e2e-test-report-${{ github.sha }} - name: JUnit Test Report - uses: mikepenz/action-junit-report@v2 + uses: mikepenz/action-junit-report@v4 with: report_paths: '**/TEST-*.xml' @@ -287,16 +287,16 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Gradle Wrapper Cache - uses: actions/cache@v3.3.2 + uses: actions/cache@v4.0.2 with: path: ~/.gradle/wrapper key: gradle-wrapper-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }} - name: Dependencies Cache - uses: actions/cache@v3.3.2 + uses: actions/cache@v4.0.2 with: path: | ~/.gradle/cache/jars-* @@ -306,7 +306,7 @@ jobs: restore-keys: gradle-dependencies- - name: Cache - uses: actions/cache@v3.3.2 + uses: actions/cache@v4.0.2 with: path: | ~/.gradle/caches/build-cache-* @@ -316,22 +316,22 @@ jobs: restore-keys: ${{ runner.os }}-gradle-build-${{ github.workflow }}- - name: Build Cache - uses: actions/cache@v3.3.2 + uses: actions/cache@v4.0.2 with: path: | build key: gradle-build-${{ hashFiles('**/*.gradle.kts') }}-${{ hashFiles('src') }}-${{ github.sha }} - name: Set up JDK 21 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '21' distribution: 'temurin' - name: Build with Gradle - uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1 + uses: gradle/gradle-build-action@4c39dd82cd5e1ec7c6fa0173bb41b4b6bb3b86ff with: - arguments: detektMain + arguments: :hideout-core:detektMain - name: "reviewdog-suggester: Suggest any code changes based on diff with reviewdog" if: ${{ always() }} @@ -345,16 +345,16 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Gradle Wrapper Cache - uses: actions/cache@v3.3.2 + uses: actions/cache@v4.0.2 with: path: ~/.gradle/wrapper key: gradle-wrapper-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }} - name: Dependencies Cache - uses: actions/cache@v3.3.2 + uses: actions/cache@v4.0.2 with: path: | ~/.gradle/cache/jars-* @@ -364,7 +364,7 @@ jobs: restore-keys: gradle-dependencies- - name: Cache - uses: actions/cache@v3.3.2 + uses: actions/cache@v4.0.2 with: path: | ~/.gradle/caches/build-cache-* @@ -374,14 +374,14 @@ jobs: restore-keys: ${{ runner.os }}-gradle-build-${{ github.workflow }}- - name: Build Cache - uses: actions/cache@v3.3.2 + uses: actions/cache@v4.0.2 with: path: | build key: gradle-build-${{ hashFiles('**/*.gradle.kts') }}-${{ hashFiles('src') }}-${{ github.sha }} - name: Set up JDK 21 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '21' distribution: 'temurin' @@ -393,20 +393,20 @@ jobs: - name: setup-chrome id: setup-chrome - uses: browser-actions/setup-chrome@v1.4.0 + uses: browser-actions/setup-chrome@v1.6.1 - name: Add Path run: echo ${{ steps.setup-chrome.outputs.chrome-path }} >> $GITHUB_PATH - name: E2E Test - uses: gradle/gradle-build-action@v2.8.1 + uses: gradle/gradle-build-action@v3.3.2 with: - arguments: e2eTest + arguments: :hideout-core:e2eTest - name: Save Test Report if: always() - uses: actions/cache/save@v3 + uses: actions/cache/save@v4 with: path: build/test-results key: e2e-test-report-${{ github.sha }} diff --git a/.gitignore b/.gitignore index 6654d55e..215512d0 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,4 @@ out/ /files/ *.log +/hideout-core/files/ diff --git a/build.gradle.kts b/build.gradle.kts index ff7abe9d..c0e7f565 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,375 +1,28 @@ -import com.github.jk1.license.filter.DependencyFilter -import com.github.jk1.license.filter.LicenseBundleNormalizer -import com.github.jk1.license.importer.DependencyDataImporter -import com.github.jk1.license.importer.XmlReportImporter -import com.github.jk1.license.render.* -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -import org.openapitools.generator.gradle.plugin.tasks.GenerateTask - -val ktor_version: String by project -val kotlin_version: String by project -val exposed_version: String by project -val h2_version: String by project -val koin_version: String by project -val coroutines_version: String by project -val serialization_version: String by project +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ plugins { - kotlin("jvm") version "1.9.23" - id("io.gitlab.arturbosch.detekt") version "1.23.6" - id("org.springframework.boot") version "3.2.3" - kotlin("plugin.spring") version "1.9.23" - id("org.openapi.generator") version "7.4.0" - id("org.jetbrains.kotlinx.kover") version "0.7.6" - id("com.github.jk1.dependency-license-report") version "2.5" - + alias(libs.plugins.kotlin.jvm) } -apply { - plugin("io.spring.dependency-management") -} - -group = "dev.usbharu" -version = "0.0.1" - -sourceSets { - create("intTest") { - compileClasspath += sourceSets.main.get().output - runtimeClasspath += sourceSets.main.get().output - } - create("e2eTest") { - compileClasspath += sourceSets.main.get().output - runtimeClasspath += sourceSets.main.get().output - } -} - -val intTestImplementation by configurations.getting { - extendsFrom(configurations.implementation.get()) -} -val intTestRuntimeOnly by configurations.getting { - extendsFrom(configurations.runtimeOnly.get()) -} - -val e2eTestImplementation by configurations.getting { - extendsFrom(configurations.implementation.get()) -} - -val e2eTestRuntimeOnly by configurations.getting { - extendsFrom(configurations.runtimeOnly.get()) -} - -val integrationTest = task("integrationTest") { - description = "Runs integration tests." - group = "verification" - - testClassesDirs = sourceSets["intTest"].output.classesDirs - classpath = sourceSets["intTest"].runtimeClasspath - shouldRunAfter("test") - - useJUnitPlatform() -} - -val e2eTest = task("e2eTest") { - description = "Runs e2e tests." - group = "verification" - - testClassesDirs = sourceSets["e2eTest"].output.classesDirs - classpath = sourceSets["e2eTest"].runtimeClasspath - shouldRunAfter("test") - - useJUnitPlatform() -} - -tasks.check { - dependsOn(integrationTest) - dependsOn(e2eTest) -} - -tasks.withType { - useJUnitPlatform() - doFirst { - jvmArgs = arrayOf( - "--add-opens", "java.base/java.lang=ALL-UNNAMED", - "--add-opens", "java.base/java.util=ALL-UNNAMED", - "--add-opens", "java.naming/javax.naming=ALL-UNNAMED", - ).toMutableList() - } -} - - -tasks.withType { - kotlinOptions { - freeCompilerArgs += "-Xjsr305=strict" - } - dependsOn("openApiGenerateMastodonCompatibleApi") - mustRunAfter("openApiGenerateMastodonCompatibleApi") -} - - -tasks.clean { - delete += listOf("$rootDir/src/main/resources/static") -} - -tasks.create("openApiGenerateMastodonCompatibleApi", GenerateTask::class) { - generatorName.set("kotlin-spring") - inputSpec.set("$rootDir/src/main/resources/openapi/mastodon.yaml") - outputDir.set("$buildDir/generated/sources/mastodon") - apiPackage.set("dev.usbharu.hideout.controller.mastodon.generated") - modelPackage.set("dev.usbharu.hideout.domain.mastodon.model.generated") - configOptions.put("interfaceOnly", "true") - configOptions.put("useSpringBoot3", "true") - configOptions.put("reactive", "true") - additionalProperties.put("useTags", "true") - - importMappings.put("org.springframework.core.io.Resource", "org.springframework.web.multipart.MultipartFile") - typeMappings.put("org.springframework.core.io.Resource", "org.springframework.web.multipart.MultipartFile") - schemaMappings.put( - "StatusesRequest", - "dev.usbharu.hideout.mastodon.interfaces.api.status.StatusesRequest" - ) - templateDir.set("$rootDir/templates") -} - -repositories { - mavenCentral() - maven { - url = uri("https://git.usbharu.dev/api/packages/usbharu/maven") - } - maven { - name = "GitHubPackages" - url = uri("https://maven.pkg.github.com/usbharu/http-signature") - credentials { - - username = project.findProperty("gpr.user") as String? ?: System.getenv("USERNAME") - password = project.findProperty("gpr.key") as String? ?: System.getenv("TOKEN") - } - } - maven { - name = "GitHubPackages2" - url = uri("https://maven.pkg.github.com/multim-dev/emoji-kt") - credentials { - - username = project.findProperty("gpr.user") as String? ?: System.getenv("USERNAME") - password = project.findProperty("gpr.key") as String? ?: System.getenv("TOKEN") - } - } -} - -kotlin { - target { - compilations.all { - kotlinOptions.jvmTarget = JavaVersion.VERSION_21.toString() - } - } -} - -sourceSets.main { - kotlin.srcDirs( - "$buildDir/generated/ksp/main", - "$buildDir/generated/sources/openapi/src/main/kotlin", - "$buildDir/generated/sources/mastodon/src/main/kotlin" - ) -} - -val os = org.gradle.nativeplatform.platform.internal - .DefaultNativePlatform.getCurrentOperatingSystem() - dependencies { - implementation("io.ktor:ktor-serialization-jackson:$ktor_version") - implementation("org.jetbrains.exposed:exposed-core:$exposed_version") - implementation("org.jetbrains.exposed:exposed-jdbc:$exposed_version") - developmentOnly("com.h2database:h2:$h2_version") - implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:$serialization_version") - implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$serialization_version") - - implementation("org.springframework.boot:spring-boot-starter-actuator") - - implementation("org.springframework.boot:spring-boot-starter-web") - implementation("org.springframework.boot:spring-boot-starter-security") - implementation("org.springframework.boot:spring-boot-starter-thymeleaf") - implementation("org.springframework.boot:spring-boot-starter-oauth2-authorization-server") - implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server") - implementation("org.springframework.boot:spring-boot-starter-log4j2") - implementation("org.springframework.boot:spring-boot-starter-validation") - implementation("jakarta.validation:jakarta.validation-api") - implementation("jakarta.annotation:jakarta.annotation-api:2.1.0") - implementation("io.swagger.core.v3:swagger-annotations:2.2.6") - implementation("io.swagger.core.v3:swagger-models:2.2.6") - implementation("org.jetbrains.exposed:exposed-java-time:$exposed_version") - testImplementation("org.springframework.boot:spring-boot-starter-test") - implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310") - implementation("com.fasterxml.jackson.module:jackson-module-kotlin") - implementation("org.springframework.security:spring-security-oauth2-jose") - implementation("org.springframework.boot:spring-boot-starter-data-mongodb") - implementation("org.springframework.boot:spring-boot-starter-data-mongodb-reactive") - implementation("org.jetbrains.exposed:exposed-spring-boot-starter:$exposed_version") - implementation("io.trbl:blurhash:1.0.0") - implementation("software.amazon.awssdk:s3:2.25.23") - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version") - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:$coroutines_version") - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-slf4j:$coroutines_version") - implementation("dev.usbharu:http-signature:1.0.0") - - implementation("org.postgresql:postgresql:42.7.3") - implementation("com.twelvemonkeys.imageio:imageio-webp:3.10.1") - implementation("org.apache.tika:tika-core:2.9.1") - implementation("org.apache.tika:tika-parsers:2.9.1") - implementation("net.coobird:thumbnailator:0.4.20") - implementation("org.bytedeco:javacv:1.5.10") { - exclude(module = "opencv") - exclude(module = "flycapture") - exclude(module = "artoolkitplus") - exclude(module = "libdc1394") - exclude(module = "librealsense") - exclude(module = "librealsense2") - exclude(module = "tesseract") - exclude(module = "libfreenect") - exclude(module = "libfreenect2") - } - if (os.isWindows) { - implementation("org.bytedeco", "ffmpeg", "6.1.1-1.5.10", classifier = "windows-x86_64") - } else { - implementation("org.bytedeco", "ffmpeg", "6.1.1-1.5.10", classifier = "linux-x86_64") - } - implementation("org.flywaydb:flyway-core") - - implementation("dev.usbharu:emoji-kt:2.0.0") - implementation("org.jsoup:jsoup:1.17.2") - implementation("com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20240325.1") - - implementation("io.ktor:ktor-client-logging-jvm:$ktor_version") - - testImplementation("org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version") - testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version") - - implementation("io.ktor:ktor-client-core:$ktor_version") - implementation("io.ktor:ktor-client-cio:$ktor_version") - implementation("io.ktor:ktor-client-content-negotiation:$ktor_version") - testImplementation("io.ktor:ktor-client-mock:$ktor_version") - testImplementation("com.h2database:h2:$h2_version") - - testImplementation("org.mockito.kotlin:mockito-kotlin:5.2.1") - testImplementation("org.mockito:mockito-inline:5.2.0") - testImplementation("nl.jqno.equalsverifier:equalsverifier:3.15.6") - testImplementation("com.jparams:to-string-verifier:1.4.8") - - implementation("org.drewcarlson:kjob-core:0.6.0") - implementation("org.drewcarlson:kjob-mongo:0.6.0") - - detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.23.6") - - intTestImplementation("org.springframework.boot:spring-boot-starter-test") - intTestImplementation("org.springframework.security:spring-security-test") - intTestImplementation("org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version") - intTestImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version") - intTestImplementation("org.mockito.kotlin:mockito-kotlin:5.2.1") - intTestImplementation("com.h2database:h2:$h2_version") - - e2eTestImplementation("org.springframework.boot:spring-boot-starter-test") - e2eTestImplementation("org.springframework.security:spring-security-test") - e2eTestImplementation("org.springframework.boot:spring-boot-starter-webflux") - e2eTestImplementation("org.jsoup:jsoup:1.17.2") - e2eTestImplementation("com.intuit.karate:karate-junit5:1.4.1") - e2eTestImplementation("com.h2database:h2:$h2_version") - + implementation("dev.usbharu:hideout-core:0.0.1") + implementation("dev.usbharu:hideout-worker:0.0.1") } -detekt { - parallel = true - config = files("detekt.yml") - buildUponDefaultConfig = true - basePath = "${rootDir.absolutePath}/src/main/kotlin" - autoCorrect = true -} - -tasks.withType { - exclude("**/generated/**") - doFirst { - - } - setSource("src/main/kotlin") - exclude("build/") -} - -tasks.withType().configureEach { - exclude("**/org/koin/ksp/generated/**", "**/generated/**") -} - -tasks.withType().configureEach { - exclude("**/org/koin/ksp/generated/**", "**/generated/**") -} - -configurations.matching { it.name == "detekt" }.all { - resolutionStrategy.eachDependency { - if (requested.group == "org.jetbrains.kotlin") { - useVersion("1.9.22") - } - } -} - -configurations { - all { - exclude("org.springframework.boot", "spring-boot-starter-logging") - exclude("ch.qos.logback", "logback-classic") - } -} - -project.gradle.taskGraph.whenReady { - println(this.allTasks) - this.allTasks.map { println(it.name) } - if (this.hasTask(":koverGenerateArtifact")) { - println("has task") - val task = this.allTasks.find { it.name == "test" } - val verificationTask = task as VerificationTask - verificationTask.ignoreFailures = true - } -} - -kover { - - excludeSourceSets { - names("aot", "e2eTest", "intTest") - } -} - -koverReport { - filters { - excludes { - packages( - "dev.usbharu.hideout.activitypub.domain.exception", - "dev.usbharu.hideout.core.domain.exception", - "dev.usbharu.hideout.core.domain.exception.media", - "dev.usbharu.hideout.core.domain.exception.resource", - "dev.usbharu.hideout.core.domain.exception.resource.local" - ) - annotatedBy("org.springframework.context.annotation.Configuration") - annotatedBy("org.springframework.boot.context.properties.ConfigurationProperties") - packages( - "dev.usbharu.hideout.controller.mastodon.generated", - "dev.usbharu.hideout.domain.mastodon.model.generated" - ) - packages("org.springframework") - packages("org.jetbrains") - } - } -} - -springBoot { - buildInfo() -} - -licenseReport { - - excludeOwnGroup = true - - importers = arrayOf(XmlReportImporter("hideout", File("$projectDir/license-list.xml"))) - renderers = arrayOf( - InventoryHtmlReportRenderer(), - CsvReportRenderer(), - JsonReportRenderer(), - XmlReportRenderer() - ) - filters = arrayOf(LicenseBundleNormalizer("$projectDir/license-normalizer-bundle.json", true)) - allowedLicensesFile = File("$projectDir/allowed-licenses.json") - configurations = arrayOf("productionRuntimeClasspath") +tasks.register("run") { + dependsOn(gradle.includedBuild("hideout-core").task(":run")) } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index ba87773a..89909840 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,11 +1,4 @@ -ktor_version=2.3.9 -kotlin_version=1.9.23 -coroutines_version=1.8.0 -serialization_version=1.6.3 -kotlin.code.style=official -exposed_version=0.49.0 -h2_version=2.2.224 org.gradle.parallel=true org.gradle.configureondemand=true org.gradle.caching=true -org.gradle.jvmargs=-Xmx4096m -XX:+HeapDumpOnOutOfMemoryError -XX:+UseParallelGC +org.gradle.jvmargs=-Xmx4096m -XX:+HeapDumpOnOutOfMemoryError -XX:+UseParallelGC \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index ccebba77..d64cd491 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 509c4a29..1af9e093 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 79a61d42..1aa94a42 100755 --- a/gradlew +++ b/gradlew @@ -83,10 +83,8 @@ done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,10 +131,13 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. @@ -144,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -152,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -197,11 +198,15 @@ if "$cygwin" || "$msys" ; then done fi -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/allowed-licenses.json b/hideout-core/allowed-licenses.json similarity index 100% rename from allowed-licenses.json rename to hideout-core/allowed-licenses.json diff --git a/hideout-core/build.gradle.kts b/hideout-core/build.gradle.kts new file mode 100644 index 00000000..baac473f --- /dev/null +++ b/hideout-core/build.gradle.kts @@ -0,0 +1,343 @@ +import com.github.jk1.license.filter.DependencyFilter +import com.github.jk1.license.filter.LicenseBundleNormalizer +import com.github.jk1.license.importer.DependencyDataImporter +import com.github.jk1.license.importer.XmlReportImporter +import com.github.jk1.license.render.* +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +import org.openapitools.generator.gradle.plugin.tasks.GenerateTask + +val ktor_version: String by project +val kotlin_version: String by project +val h2_version: String by project +val coroutines_version: String by project + +plugins { + alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.detekt) + alias(libs.plugins.spring.boot) + alias(libs.plugins.kotlin.spring) + alias(libs.plugins.openapi.generator) + alias(libs.plugins.kover) + alias(libs.plugins.license.report) + +} + +apply { + plugin("io.spring.dependency-management") +} + +group = "dev.usbharu" +version = "0.0.1" + +sourceSets { + create("intTest") { + compileClasspath += sourceSets.main.get().output + runtimeClasspath += sourceSets.main.get().output + } + create("e2eTest") { + compileClasspath += sourceSets.main.get().output + runtimeClasspath += sourceSets.main.get().output + } +} + +val intTestImplementation by configurations.getting { + extendsFrom(configurations.implementation.get()) +} +val intTestRuntimeOnly by configurations.getting { + extendsFrom(configurations.runtimeOnly.get()) +} + +val e2eTestImplementation by configurations.getting { + extendsFrom(configurations.implementation.get()) +} + +val e2eTestRuntimeOnly by configurations.getting { + extendsFrom(configurations.runtimeOnly.get()) +} + +val integrationTest = task("integrationTest") { + description = "Runs integration tests." + group = "verification" + + testClassesDirs = sourceSets["intTest"].output.classesDirs + classpath = sourceSets["intTest"].runtimeClasspath + shouldRunAfter("test") + + useJUnitPlatform() +} + +val e2eTest = task("e2eTest") { + description = "Runs e2e tests." + group = "verification" + + testClassesDirs = sourceSets["e2eTest"].output.classesDirs + classpath = sourceSets["e2eTest"].runtimeClasspath + shouldRunAfter("test") + + useJUnitPlatform() +} + +tasks.check { + dependsOn(integrationTest) + dependsOn(e2eTest) +} + +tasks.withType { + useJUnitPlatform() + doFirst { + jvmArgs = arrayOf( + "--add-opens", "java.base/java.lang=ALL-UNNAMED", + "--add-opens", "java.base/java.util=ALL-UNNAMED", + "--add-opens", "java.naming/javax.naming=ALL-UNNAMED", + ).toMutableList() + } +} + + +tasks.withType { + kotlinOptions { + freeCompilerArgs += "-Xjsr305=strict" + } + dependsOn("openApiGenerateMastodonCompatibleApi") + mustRunAfter("openApiGenerateMastodonCompatibleApi") +} + + +tasks.clean { + delete += listOf("$rootDir/src/main/resources/static") +} + +tasks.create("openApiGenerateMastodonCompatibleApi", GenerateTask::class) { + generatorName.set("kotlin-spring") + inputSpec.set("$rootDir/src/main/resources/openapi/mastodon.yaml") + outputDir.set("$buildDir/generated/sources/mastodon") + apiPackage.set("dev.usbharu.hideout.controller.mastodon.generated") + modelPackage.set("dev.usbharu.hideout.domain.mastodon.model.generated") + configOptions.put("interfaceOnly", "true") + configOptions.put("useSpringBoot3", "true") + configOptions.put("reactive", "true") + additionalProperties.put("useTags", "true") + + importMappings.put("org.springframework.core.io.Resource", "org.springframework.web.multipart.MultipartFile") + typeMappings.put("org.springframework.core.io.Resource", "org.springframework.web.multipart.MultipartFile") + schemaMappings.put( + "StatusesRequest", + "dev.usbharu.hideout.mastodon.interfaces.api.status.StatusesRequest" + ) + templateDir.set("$rootDir/templates") +} + +repositories { + mavenCentral() + maven { + url = uri("https://git.usbharu.dev/api/packages/usbharu/maven") + } + maven { + name = "GitHubPackages" + url = uri("https://maven.pkg.github.com/usbharu/http-signature") + credentials { + + username = project.findProperty("gpr.user") as String? ?: System.getenv("USERNAME") + password = project.findProperty("gpr.key") as String? ?: System.getenv("TOKEN") + } + } + maven { + name = "GitHubPackages2" + url = uri("https://maven.pkg.github.com/multim-dev/emoji-kt") + credentials { + + username = project.findProperty("gpr.user") as String? ?: System.getenv("USERNAME") + password = project.findProperty("gpr.key") as String? ?: System.getenv("TOKEN") + } + } +} + +kotlin { + target { + compilations.all { + kotlinOptions.jvmTarget = JavaVersion.VERSION_21.toString() + } + } +} + +sourceSets.main { + kotlin.srcDirs( + "$buildDir/generated/ksp/main", + "$buildDir/generated/sources/openapi/src/main/kotlin", + "$buildDir/generated/sources/mastodon/src/main/kotlin" + ) +} + +val os = org.gradle.nativeplatform.platform.internal + .DefaultNativePlatform.getCurrentOperatingSystem() + +dependencies { + developmentOnly("com.h2database:h2:$h2_version") + detektPlugins(libs.detekt.formatting) + + implementation(libs.bundles.exposed) + implementation(libs.bundles.coroutines) + implementation(libs.bundles.ktor.client) + implementation(libs.bundles.apache.tika) + implementation(libs.bundles.openapi) + implementation(libs.bundles.owl.producer) + implementation(libs.bundles.owl.broker) + implementation(libs.bundles.spring.boot.oauth2) + implementation(libs.bundles.spring.boot.data.mongodb) + implementation(libs.bundles.spring.boot.data.mongodb) + implementation("org.springframework.boot:spring-boot-starter-actuator") + implementation("org.springframework.boot:spring-boot-starter-web") + implementation("org.springframework.boot:spring-boot-starter-security") + implementation("org.springframework.boot:spring-boot-starter-thymeleaf") + implementation("org.springframework.boot:spring-boot-starter-log4j2") + implementation("org.springframework.boot:spring-boot-starter-validation") + + implementation("dev.usbharu:owl-common-serialize-jackson:0.0.1") + implementation("io.trbl:blurhash:1.0.0") + implementation("software.amazon.awssdk:s3:2.25.23") + implementation("org.jsoup:jsoup:1.17.2") + implementation("com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20240325.1") + implementation("org.postgresql:postgresql:42.7.3") + implementation("com.twelvemonkeys.imageio:imageio-webp:3.10.1") + implementation("net.coobird:thumbnailator:0.4.20") + implementation("org.flywaydb:flyway-core") + + implementation(libs.javacv) { + exclude(module = "opencv") + exclude(module = "flycapture") + exclude(module = "artoolkitplus") + exclude(module = "libdc1394") + exclude(module = "librealsense") + exclude(module = "librealsense2") + exclude(module = "tesseract") + exclude(module = "libfreenect") + exclude(module = "libfreenect2") + } + if (os.isWindows) { + implementation(variantOf(libs.javacv.ffmpeg) { classifier("windows-x86_64") }) + } else { + implementation(variantOf(libs.javacv.ffmpeg) { classifier("linux-x86_64") }) + } + + implementation("dev.usbharu:http-signature:1.0.0") + implementation("dev.usbharu:emoji-kt:2.0.0") + + + + testImplementation("org.springframework.boot:spring-boot-starter-test") + testImplementation("org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version") + testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version") + + testImplementation("io.ktor:ktor-client-mock:$ktor_version") + testImplementation("com.h2database:h2:$h2_version") + + testImplementation("org.mockito.kotlin:mockito-kotlin:5.3.1") + testImplementation("org.mockito:mockito-inline:5.2.0") + testImplementation("nl.jqno.equalsverifier:equalsverifier:3.16.1") + testImplementation("com.jparams:to-string-verifier:1.4.8") + + intTestImplementation("org.springframework.boot:spring-boot-starter-test") + intTestImplementation("org.springframework.security:spring-security-test") + intTestImplementation("org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version") + intTestImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version") + intTestImplementation("org.mockito.kotlin:mockito-kotlin:5.3.1") + intTestImplementation("com.h2database:h2:$h2_version") + + e2eTestImplementation("org.springframework.boot:spring-boot-starter-test") + e2eTestImplementation("org.springframework.security:spring-security-test") + e2eTestImplementation("org.springframework.boot:spring-boot-starter-webflux") + e2eTestImplementation("org.jsoup:jsoup:1.17.2") + e2eTestImplementation("com.intuit.karate:karate-junit5:1.4.1") + e2eTestImplementation("com.h2database:h2:$h2_version") + +} + +detekt { + parallel = true + config = files("../detekt.yml") + buildUponDefaultConfig = true + basePath = "${rootDir.absolutePath}/src/main/kotlin" + autoCorrect = true +} + +tasks.withType { + exclude("**/generated/**") + doFirst { + + } + setSource("src/main/kotlin") + exclude("build/") +} + +tasks.withType().configureEach { + exclude("**/org/koin/ksp/generated/**", "**/generated/**") +} + +tasks.withType().configureEach { + exclude("**/org/koin/ksp/generated/**", "**/generated/**") +} + +configurations { + all { + exclude("org.springframework.boot", "spring-boot-starter-logging") + exclude("ch.qos.logback", "logback-classic") + } +} + +project.gradle.taskGraph.whenReady { + println(this.allTasks) + this.allTasks.map { println(it.name) } + if (this.hasTask(":koverGenerateArtifact")) { + println("has task") + val task = this.allTasks.find { it.name == "test" } + val verificationTask = task as VerificationTask + verificationTask.ignoreFailures = true + } +} + +kover { + excludeSourceSets { + names("aot", "e2eTest", "intTest") + } +} + +koverReport { + filters { + excludes { + packages( + "dev.usbharu.hideout.activitypub.domain.exception", + "dev.usbharu.hideout.core.domain.exception", + "dev.usbharu.hideout.core.domain.exception.media", + "dev.usbharu.hideout.core.domain.exception.resource", + "dev.usbharu.hideout.core.domain.exception.resource.local" + ) + annotatedBy("org.springframework.context.annotation.Configuration") + annotatedBy("org.springframework.boot.context.properties.ConfigurationProperties") + packages( + "dev.usbharu.hideout.controller.mastodon.generated", + "dev.usbharu.hideout.domain.mastodon.model.generated" + ) + packages("org.springframework") + packages("org.jetbrains") + } + } +} + +springBoot { + buildInfo() +} + +licenseReport { + excludeOwnGroup = true + + importers = arrayOf(XmlReportImporter("hideout", File("$projectDir/license-list.xml"))) + renderers = arrayOf( + InventoryHtmlReportRenderer(), + CsvReportRenderer(), + JsonReportRenderer(), + XmlReportRenderer() + ) + filters = arrayOf(LicenseBundleNormalizer("$projectDir/license-normalizer-bundle.json", true)) + allowedLicensesFile = File("$projectDir/allowed-licenses.json") + configurations = arrayOf("productionRuntimeClasspath") +} \ No newline at end of file diff --git a/hideout-core/gradle.properties b/hideout-core/gradle.properties new file mode 100644 index 00000000..24ab6c1a --- /dev/null +++ b/hideout-core/gradle.properties @@ -0,0 +1,24 @@ +# +# Copyright (C) 2024 usbharu +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +ktor_version=2.3.11 +kotlin_version=1.9.24 +coroutines_version=1.8.1 +kotlin.code.style=official +h2_version=2.2.224 +org.gradle.parallel=true +org.gradle.configureondemand=true +org.gradle.caching=true +org.gradle.jvmargs=-Xmx4096m -XX:+HeapDumpOnOutOfMemoryError -XX:+UseParallelGC diff --git a/hideout-core/gradle/wrapper/gradle-wrapper.jar b/hideout-core/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000..249e5832 Binary files /dev/null and b/hideout-core/gradle/wrapper/gradle-wrapper.jar differ diff --git a/hideout-core/gradle/wrapper/gradle-wrapper.properties b/hideout-core/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..78d47568 --- /dev/null +++ b/hideout-core/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri May 03 17:44:28 JST 2024 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/hideout-core/gradlew b/hideout-core/gradlew new file mode 100644 index 00000000..1b6c7873 --- /dev/null +++ b/hideout-core/gradlew @@ -0,0 +1,234 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/hideout-core/gradlew.bat b/hideout-core/gradlew.bat new file mode 100644 index 00000000..107acd32 --- /dev/null +++ b/hideout-core/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/license-normalizer-bundle.json b/hideout-core/license-normalizer-bundle.json similarity index 100% rename from license-normalizer-bundle.json rename to hideout-core/license-normalizer-bundle.json diff --git a/hideout-core/settings.gradle.kts b/hideout-core/settings.gradle.kts new file mode 100644 index 00000000..81e7fae4 --- /dev/null +++ b/hideout-core/settings.gradle.kts @@ -0,0 +1,18 @@ +plugins { + id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" +} +rootProject.name = "hideout-core" + +includeBuild("../owl") + +dependencyResolutionManagement { + repositories { + mavenCentral() + } + + versionCatalogs { + create("libs") { + from(files("../libs.versions.toml")) + } + } +} \ No newline at end of file diff --git a/src/e2eTest/kotlin/AssertionUtil.kt b/hideout-core/src/e2eTest/kotlin/AssertionUtil.kt similarity index 100% rename from src/e2eTest/kotlin/AssertionUtil.kt rename to hideout-core/src/e2eTest/kotlin/AssertionUtil.kt diff --git a/src/e2eTest/kotlin/KarateUtil.kt b/hideout-core/src/e2eTest/kotlin/KarateUtil.kt similarity index 100% rename from src/e2eTest/kotlin/KarateUtil.kt rename to hideout-core/src/e2eTest/kotlin/KarateUtil.kt diff --git a/src/e2eTest/kotlin/federation/FollowAcceptTest.kt b/hideout-core/src/e2eTest/kotlin/federation/FollowAcceptTest.kt similarity index 100% rename from src/e2eTest/kotlin/federation/FollowAcceptTest.kt rename to hideout-core/src/e2eTest/kotlin/federation/FollowAcceptTest.kt diff --git a/src/e2eTest/kotlin/federation/InboxCommonTest.kt b/hideout-core/src/e2eTest/kotlin/federation/InboxCommonTest.kt similarity index 100% rename from src/e2eTest/kotlin/federation/InboxCommonTest.kt rename to hideout-core/src/e2eTest/kotlin/federation/InboxCommonTest.kt diff --git a/src/e2eTest/kotlin/oauth2/OAuth2LoginTest.kt b/hideout-core/src/e2eTest/kotlin/oauth2/OAuth2LoginTest.kt similarity index 100% rename from src/e2eTest/kotlin/oauth2/OAuth2LoginTest.kt rename to hideout-core/src/e2eTest/kotlin/oauth2/OAuth2LoginTest.kt diff --git a/src/e2eTest/resources/application.yml b/hideout-core/src/e2eTest/resources/application.yml similarity index 100% rename from src/e2eTest/resources/application.yml rename to hideout-core/src/e2eTest/resources/application.yml diff --git a/src/e2eTest/resources/federation/FollowAcceptMockServer.feature b/hideout-core/src/e2eTest/resources/federation/FollowAcceptMockServer.feature similarity index 100% rename from src/e2eTest/resources/federation/FollowAcceptMockServer.feature rename to hideout-core/src/e2eTest/resources/federation/FollowAcceptMockServer.feature diff --git a/src/e2eTest/resources/federation/FollowAcceptTest.feature b/hideout-core/src/e2eTest/resources/federation/FollowAcceptTest.feature similarity index 100% rename from src/e2eTest/resources/federation/FollowAcceptTest.feature rename to hideout-core/src/e2eTest/resources/federation/FollowAcceptTest.feature diff --git a/src/e2eTest/resources/federation/InboxCommonTest.feature b/hideout-core/src/e2eTest/resources/federation/InboxCommonTest.feature similarity index 100% rename from src/e2eTest/resources/federation/InboxCommonTest.feature rename to hideout-core/src/e2eTest/resources/federation/InboxCommonTest.feature diff --git a/src/e2eTest/resources/federation/InboxxCommonMockServerTest.feature b/hideout-core/src/e2eTest/resources/federation/InboxxCommonMockServerTest.feature similarity index 100% rename from src/e2eTest/resources/federation/InboxxCommonMockServerTest.feature rename to hideout-core/src/e2eTest/resources/federation/InboxxCommonMockServerTest.feature diff --git a/src/e2eTest/resources/karate-config.js b/hideout-core/src/e2eTest/resources/karate-config.js similarity index 100% rename from src/e2eTest/resources/karate-config.js rename to hideout-core/src/e2eTest/resources/karate-config.js diff --git a/src/e2eTest/resources/logback.xml b/hideout-core/src/e2eTest/resources/logback.xml similarity index 100% rename from src/e2eTest/resources/logback.xml rename to hideout-core/src/e2eTest/resources/logback.xml diff --git a/src/e2eTest/resources/oauth2/Oauth2LoginTest.feature b/hideout-core/src/e2eTest/resources/oauth2/Oauth2LoginTest.feature similarity index 100% rename from src/e2eTest/resources/oauth2/Oauth2LoginTest.feature rename to hideout-core/src/e2eTest/resources/oauth2/Oauth2LoginTest.feature diff --git a/src/e2eTest/resources/oauth2/user.sql b/hideout-core/src/e2eTest/resources/oauth2/user.sql similarity index 100% rename from src/e2eTest/resources/oauth2/user.sql rename to hideout-core/src/e2eTest/resources/oauth2/user.sql diff --git a/src/intTest/kotlin/activitypub/inbox/InboxTest.kt b/hideout-core/src/intTest/kotlin/activitypub/inbox/InboxTest.kt similarity index 95% rename from src/intTest/kotlin/activitypub/inbox/InboxTest.kt rename to hideout-core/src/intTest/kotlin/activitypub/inbox/InboxTest.kt index aab8b225..40f9ffdf 100644 --- a/src/intTest/kotlin/activitypub/inbox/InboxTest.kt +++ b/hideout-core/src/intTest/kotlin/activitypub/inbox/InboxTest.kt @@ -18,6 +18,8 @@ package activitypub.inbox import dev.usbharu.hideout.SpringApplication import dev.usbharu.hideout.util.Base64Util +import dev.usbharu.owl.producer.api.OwlProducer +import kotlinx.coroutines.runBlocking import org.flywaydb.core.Flyway import org.junit.jupiter.api.AfterAll import org.junit.jupiter.api.BeforeEach @@ -150,9 +152,12 @@ class InboxTest { companion object { @JvmStatic @AfterAll - fun dropDatabase(@Autowired flyway: Flyway) { + fun dropDatabase(@Autowired flyway: Flyway, @Autowired owlProducer: OwlProducer) { flyway.clean() flyway.migrate() + runBlocking { + owlProducer.stop() + } } } } diff --git a/src/intTest/kotlin/activitypub/note/NoteTest.kt b/hideout-core/src/intTest/kotlin/activitypub/note/NoteTest.kt similarity index 97% rename from src/intTest/kotlin/activitypub/note/NoteTest.kt rename to hideout-core/src/intTest/kotlin/activitypub/note/NoteTest.kt index 604d4ee3..62d7d3ce 100644 --- a/src/intTest/kotlin/activitypub/note/NoteTest.kt +++ b/hideout-core/src/intTest/kotlin/activitypub/note/NoteTest.kt @@ -17,6 +17,8 @@ package activitypub.note import dev.usbharu.hideout.SpringApplication +import dev.usbharu.owl.producer.api.OwlProducer +import kotlinx.coroutines.runBlocking import org.flywaydb.core.Flyway import org.junit.jupiter.api.AfterAll import org.junit.jupiter.api.BeforeEach @@ -230,9 +232,12 @@ class NoteTest { companion object { @JvmStatic @AfterAll - fun dropDatabase(@Autowired flyway: Flyway) { + fun dropDatabase(@Autowired flyway: Flyway, @Autowired owlProducer: OwlProducer) { flyway.clean() flyway.migrate() + runBlocking { + owlProducer.stop() + } } } } diff --git a/src/intTest/kotlin/activitypub/webfinger/WebFingerTest.kt b/hideout-core/src/intTest/kotlin/activitypub/webfinger/WebFingerTest.kt similarity index 93% rename from src/intTest/kotlin/activitypub/webfinger/WebFingerTest.kt rename to hideout-core/src/intTest/kotlin/activitypub/webfinger/WebFingerTest.kt index 171ceb98..a12bbfd4 100644 --- a/src/intTest/kotlin/activitypub/webfinger/WebFingerTest.kt +++ b/hideout-core/src/intTest/kotlin/activitypub/webfinger/WebFingerTest.kt @@ -18,6 +18,8 @@ package activitypub.webfinger import dev.usbharu.hideout.SpringApplication import dev.usbharu.hideout.application.external.Transaction +import dev.usbharu.owl.producer.api.OwlProducer +import kotlinx.coroutines.runBlocking import org.flywaydb.core.Flyway import org.junit.jupiter.api.AfterAll import org.junit.jupiter.api.Test @@ -103,9 +105,12 @@ class WebFingerTest { companion object { @JvmStatic @AfterAll - fun dropDatabase(@Autowired flyway: Flyway) { + fun dropDatabase(@Autowired flyway: Flyway, @Autowired owlProducer: OwlProducer) { flyway.clean() flyway.migrate() + runBlocking { + owlProducer.stop() + } } } } diff --git a/src/intTest/kotlin/mastodon/account/AccountApiPaginationTest.kt b/hideout-core/src/intTest/kotlin/mastodon/account/AccountApiPaginationTest.kt similarity index 96% rename from src/intTest/kotlin/mastodon/account/AccountApiPaginationTest.kt rename to hideout-core/src/intTest/kotlin/mastodon/account/AccountApiPaginationTest.kt index 861c5c23..81971e7a 100644 --- a/src/intTest/kotlin/mastodon/account/AccountApiPaginationTest.kt +++ b/hideout-core/src/intTest/kotlin/mastodon/account/AccountApiPaginationTest.kt @@ -20,6 +20,8 @@ import com.fasterxml.jackson.core.type.TypeReference import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import dev.usbharu.hideout.SpringApplication import dev.usbharu.hideout.domain.mastodon.model.generated.Status +import dev.usbharu.owl.producer.api.OwlProducer +import kotlinx.coroutines.runBlocking import org.assertj.core.api.Assertions.assertThat import org.flywaydb.core.Flyway import org.junit.jupiter.api.AfterAll @@ -152,9 +154,13 @@ class AccountApiPaginationTest { companion object { @JvmStatic @AfterAll - fun dropDatabase(@Autowired flyway: Flyway) { + fun dropDatabase(@Autowired flyway: Flyway, @Autowired owlProducer: OwlProducer) { flyway.clean() flyway.migrate() + runBlocking { + owlProducer.stop() + } } + } } \ No newline at end of file diff --git a/src/intTest/kotlin/mastodon/account/AccountApiTest.kt b/hideout-core/src/intTest/kotlin/mastodon/account/AccountApiTest.kt similarity index 98% rename from src/intTest/kotlin/mastodon/account/AccountApiTest.kt rename to hideout-core/src/intTest/kotlin/mastodon/account/AccountApiTest.kt index 77f785c9..c936764d 100644 --- a/src/intTest/kotlin/mastodon/account/AccountApiTest.kt +++ b/hideout-core/src/intTest/kotlin/mastodon/account/AccountApiTest.kt @@ -19,6 +19,8 @@ package mastodon.account import dev.usbharu.hideout.SpringApplication import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.infrastructure.exposedquery.FollowerQueryServiceImpl +import dev.usbharu.owl.producer.api.OwlProducer +import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.runTest import org.assertj.core.api.Assertions.assertThat import org.flywaydb.core.Flyway @@ -462,9 +464,12 @@ class AccountApiTest { companion object { @JvmStatic @AfterAll - fun dropDatabase(@Autowired flyway: Flyway) { + fun dropDatabase(@Autowired flyway: Flyway, @Autowired owlProducer: OwlProducer) { flyway.clean() flyway.migrate() + runBlocking { + owlProducer.stop() + } } } } diff --git a/src/intTest/kotlin/mastodon/apps/AppTest.kt b/hideout-core/src/intTest/kotlin/mastodon/apps/AppTest.kt similarity index 94% rename from src/intTest/kotlin/mastodon/apps/AppTest.kt rename to hideout-core/src/intTest/kotlin/mastodon/apps/AppTest.kt index 65e42b4a..8ce170eb 100644 --- a/src/intTest/kotlin/mastodon/apps/AppTest.kt +++ b/hideout-core/src/intTest/kotlin/mastodon/apps/AppTest.kt @@ -18,6 +18,8 @@ package mastodon.apps import dev.usbharu.hideout.SpringApplication import dev.usbharu.hideout.core.infrastructure.springframework.oauth2.RegisteredClient +import dev.usbharu.owl.producer.api.OwlProducer +import kotlinx.coroutines.runBlocking import org.assertj.core.api.Assertions.assertThat import org.flywaydb.core.Flyway import org.jetbrains.exposed.sql.selectAll @@ -107,9 +109,12 @@ class AppTest { companion object { @JvmStatic @AfterAll - fun dropDatabase(@Autowired flyway: Flyway) { + fun dropDatabase(@Autowired flyway: Flyway, @Autowired owlProducer: OwlProducer) { flyway.clean() flyway.migrate() + runBlocking { + owlProducer.stop() + } } } } diff --git a/src/intTest/kotlin/mastodon/filter/FilterTest.kt b/hideout-core/src/intTest/kotlin/mastodon/filter/FilterTest.kt similarity index 98% rename from src/intTest/kotlin/mastodon/filter/FilterTest.kt rename to hideout-core/src/intTest/kotlin/mastodon/filter/FilterTest.kt index 89fe1f5c..bb3dccae 100644 --- a/src/intTest/kotlin/mastodon/filter/FilterTest.kt +++ b/hideout-core/src/intTest/kotlin/mastodon/filter/FilterTest.kt @@ -22,6 +22,8 @@ import dev.usbharu.hideout.domain.mastodon.model.generated.FilterKeywordsPostReq import dev.usbharu.hideout.domain.mastodon.model.generated.FilterPostRequest import dev.usbharu.hideout.domain.mastodon.model.generated.FilterPostRequestKeyword import dev.usbharu.hideout.domain.mastodon.model.generated.V1FilterPostRequest +import dev.usbharu.owl.producer.api.OwlProducer +import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.runTest import org.flywaydb.core.Flyway import org.junit.jupiter.api.AfterAll @@ -702,9 +704,12 @@ class FilterTest { companion object { @JvmStatic @AfterAll - fun dropDatabase(@Autowired flyway: Flyway) { + fun dropDatabase(@Autowired flyway: Flyway, @Autowired owlProducer: OwlProducer) { flyway.clean() flyway.migrate() + runBlocking { + owlProducer.stop() + } } } } \ No newline at end of file diff --git a/src/intTest/kotlin/mastodon/media/MediaTest.kt b/hideout-core/src/intTest/kotlin/mastodon/media/MediaTest.kt similarity index 95% rename from src/intTest/kotlin/mastodon/media/MediaTest.kt rename to hideout-core/src/intTest/kotlin/mastodon/media/MediaTest.kt index b745cf0c..77f23281 100644 --- a/src/intTest/kotlin/mastodon/media/MediaTest.kt +++ b/hideout-core/src/intTest/kotlin/mastodon/media/MediaTest.kt @@ -20,6 +20,8 @@ import dev.usbharu.hideout.SpringApplication import dev.usbharu.hideout.core.service.media.MediaDataStore import dev.usbharu.hideout.core.service.media.MediaSaveRequest import dev.usbharu.hideout.core.service.media.SuccessSavedMedia +import dev.usbharu.owl.producer.api.OwlProducer +import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.runTest import org.flywaydb.core.Flyway import org.junit.jupiter.api.AfterAll @@ -131,9 +133,12 @@ class MediaTest { companion object { @JvmStatic @AfterAll - fun dropDatabase(@Autowired flyway: Flyway) { + fun dropDatabase(@Autowired flyway: Flyway, @Autowired owlProducer: OwlProducer) { flyway.clean() flyway.migrate() + runBlocking { + owlProducer.stop() + } } } diff --git a/src/intTest/kotlin/mastodon/notifications/ExposedNotificationsApiPaginationTest.kt b/hideout-core/src/intTest/kotlin/mastodon/notifications/ExposedNotificationsApiPaginationTest.kt similarity index 96% rename from src/intTest/kotlin/mastodon/notifications/ExposedNotificationsApiPaginationTest.kt rename to hideout-core/src/intTest/kotlin/mastodon/notifications/ExposedNotificationsApiPaginationTest.kt index ba30f9a7..7405caf6 100644 --- a/src/intTest/kotlin/mastodon/notifications/ExposedNotificationsApiPaginationTest.kt +++ b/hideout-core/src/intTest/kotlin/mastodon/notifications/ExposedNotificationsApiPaginationTest.kt @@ -20,6 +20,8 @@ import com.fasterxml.jackson.core.type.TypeReference import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import dev.usbharu.hideout.SpringApplication import dev.usbharu.hideout.domain.mastodon.model.generated.Notification +import dev.usbharu.owl.producer.api.OwlProducer +import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.runTest import org.assertj.core.api.Assertions.assertThat import org.flywaydb.core.Flyway @@ -172,9 +174,12 @@ class ExposedNotificationsApiPaginationTest { companion object { @JvmStatic @AfterAll - fun dropDatabase(@Autowired flyway: Flyway) { + fun dropDatabase(@Autowired flyway: Flyway, @Autowired owlProducer: OwlProducer) { flyway.clean() flyway.migrate() + runBlocking { + owlProducer.stop() + } } } } \ No newline at end of file diff --git a/src/intTest/kotlin/mastodon/notifications/MongodbNotificationsApiPaginationTest.kt b/hideout-core/src/intTest/kotlin/mastodon/notifications/MongodbNotificationsApiPaginationTest.kt similarity index 96% rename from src/intTest/kotlin/mastodon/notifications/MongodbNotificationsApiPaginationTest.kt rename to hideout-core/src/intTest/kotlin/mastodon/notifications/MongodbNotificationsApiPaginationTest.kt index 58c67aaa..0de15332 100644 --- a/src/intTest/kotlin/mastodon/notifications/MongodbNotificationsApiPaginationTest.kt +++ b/hideout-core/src/intTest/kotlin/mastodon/notifications/MongodbNotificationsApiPaginationTest.kt @@ -23,6 +23,8 @@ import dev.usbharu.hideout.domain.mastodon.model.generated.Notification import dev.usbharu.hideout.mastodon.domain.model.MastodonNotification import dev.usbharu.hideout.mastodon.domain.model.NotificationType import dev.usbharu.hideout.mastodon.infrastructure.mongorepository.MongoMastodonNotificationRepository +import dev.usbharu.owl.producer.api.OwlProducer +import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.runTest import org.assertj.core.api.Assertions import org.flywaydb.core.Flyway @@ -178,7 +180,7 @@ class MongodbNotificationsApiPaginationTest { @JvmStatic @BeforeAll fun setupMongodb( - @Autowired mongoMastodonNotificationRepository: MongoMastodonNotificationRepository + @Autowired mongoMastodonNotificationRepository: MongoMastodonNotificationRepository, ) { mongoMastodonNotificationRepository.deleteAll() @@ -203,11 +205,14 @@ class MongodbNotificationsApiPaginationTest { @AfterAll fun dropDatabase( @Autowired flyway: Flyway, - @Autowired mongodbMastodonNotificationRepository: MongoMastodonNotificationRepository + @Autowired mongodbMastodonNotificationRepository: MongoMastodonNotificationRepository, + @Autowired owlProducer: OwlProducer, ) { flyway.clean() flyway.migrate() - + runBlocking { + owlProducer.stop() + } mongodbMastodonNotificationRepository.deleteAll() } } diff --git a/src/intTest/kotlin/mastodon/status/StatusTest.kt b/hideout-core/src/intTest/kotlin/mastodon/status/StatusTest.kt similarity index 97% rename from src/intTest/kotlin/mastodon/status/StatusTest.kt rename to hideout-core/src/intTest/kotlin/mastodon/status/StatusTest.kt index 4c805205..817d5dfc 100644 --- a/src/intTest/kotlin/mastodon/status/StatusTest.kt +++ b/hideout-core/src/intTest/kotlin/mastodon/status/StatusTest.kt @@ -22,6 +22,8 @@ import dev.usbharu.hideout.core.domain.model.emoji.UnicodeEmoji import dev.usbharu.hideout.core.infrastructure.exposedrepository.CustomEmojis import dev.usbharu.hideout.core.infrastructure.exposedrepository.Reactions import dev.usbharu.hideout.core.infrastructure.exposedrepository.toReaction +import dev.usbharu.owl.producer.api.OwlProducer +import kotlinx.coroutines.runBlocking import org.assertj.core.api.Assertions.assertThat import org.flywaydb.core.Flyway import org.jetbrains.exposed.sql.and @@ -236,9 +238,12 @@ class StatusTest { companion object { @JvmStatic @AfterAll - fun dropDatabase(@Autowired flyway: Flyway) { + fun dropDatabase(@Autowired flyway: Flyway, @Autowired owlProducer: OwlProducer) { flyway.clean() flyway.migrate() + runBlocking { + owlProducer.stop() + } } } } diff --git a/src/intTest/kotlin/mastodon/timelines/TimelineApiTest.kt b/hideout-core/src/intTest/kotlin/mastodon/timelines/TimelineApiTest.kt similarity index 94% rename from src/intTest/kotlin/mastodon/timelines/TimelineApiTest.kt rename to hideout-core/src/intTest/kotlin/mastodon/timelines/TimelineApiTest.kt index 5ebcb3a9..21719e85 100644 --- a/src/intTest/kotlin/mastodon/timelines/TimelineApiTest.kt +++ b/hideout-core/src/intTest/kotlin/mastodon/timelines/TimelineApiTest.kt @@ -17,6 +17,8 @@ package mastodon.timelines import dev.usbharu.hideout.SpringApplication +import dev.usbharu.owl.producer.api.OwlProducer +import kotlinx.coroutines.runBlocking import org.flywaydb.core.Flyway import org.junit.jupiter.api.AfterAll import org.junit.jupiter.api.BeforeEach @@ -123,9 +125,12 @@ class TimelineApiTest { companion object { @JvmStatic @AfterAll - fun dropDatabase(@Autowired flyway: Flyway) { + fun dropDatabase(@Autowired flyway: Flyway, @Autowired owlProducer: OwlProducer) { flyway.clean() flyway.migrate() + runBlocking { + owlProducer.stop() + } } } } diff --git a/src/intTest/kotlin/util/SpringApplicationTestBase.kt b/hideout-core/src/intTest/kotlin/util/SpringApplicationTestBase.kt similarity index 100% rename from src/intTest/kotlin/util/SpringApplicationTestBase.kt rename to hideout-core/src/intTest/kotlin/util/SpringApplicationTestBase.kt diff --git a/src/intTest/kotlin/util/TestTransaction.kt b/hideout-core/src/intTest/kotlin/util/TestTransaction.kt similarity index 100% rename from src/intTest/kotlin/util/TestTransaction.kt rename to hideout-core/src/intTest/kotlin/util/TestTransaction.kt diff --git a/src/intTest/kotlin/util/WithHttpSignature.kt b/hideout-core/src/intTest/kotlin/util/WithHttpSignature.kt similarity index 100% rename from src/intTest/kotlin/util/WithHttpSignature.kt rename to hideout-core/src/intTest/kotlin/util/WithHttpSignature.kt diff --git a/src/intTest/kotlin/util/WithHttpSignatureSecurityContextFactory.kt b/hideout-core/src/intTest/kotlin/util/WithHttpSignatureSecurityContextFactory.kt similarity index 100% rename from src/intTest/kotlin/util/WithHttpSignatureSecurityContextFactory.kt rename to hideout-core/src/intTest/kotlin/util/WithHttpSignatureSecurityContextFactory.kt diff --git a/src/intTest/kotlin/util/WithMockHttpSignature.kt b/hideout-core/src/intTest/kotlin/util/WithMockHttpSignature.kt similarity index 100% rename from src/intTest/kotlin/util/WithMockHttpSignature.kt rename to hideout-core/src/intTest/kotlin/util/WithMockHttpSignature.kt diff --git a/src/intTest/kotlin/util/WithMockHttpSignatureSecurityContextFactory.kt b/hideout-core/src/intTest/kotlin/util/WithMockHttpSignatureSecurityContextFactory.kt similarity index 100% rename from src/intTest/kotlin/util/WithMockHttpSignatureSecurityContextFactory.kt rename to hideout-core/src/intTest/kotlin/util/WithMockHttpSignatureSecurityContextFactory.kt diff --git a/src/intTest/resources/application.yml b/hideout-core/src/intTest/resources/application.yml similarity index 100% rename from src/intTest/resources/application.yml rename to hideout-core/src/intTest/resources/application.yml diff --git a/src/intTest/resources/junit-platform.properties b/hideout-core/src/intTest/resources/junit-platform.properties similarity index 100% rename from src/intTest/resources/junit-platform.properties rename to hideout-core/src/intTest/resources/junit-platform.properties diff --git a/src/intTest/resources/logback.xml b/hideout-core/src/intTest/resources/logback.xml similarity index 100% rename from src/intTest/resources/logback.xml rename to hideout-core/src/intTest/resources/logback.xml diff --git a/src/intTest/resources/media/400x400.png b/hideout-core/src/intTest/resources/media/400x400.png similarity index 100% rename from src/intTest/resources/media/400x400.png rename to hideout-core/src/intTest/resources/media/400x400.png diff --git a/src/intTest/resources/sql/accounts/apiV1AccountsIdFollowPost フォローできる.sql b/hideout-core/src/intTest/resources/sql/accounts/apiV1AccountsIdFollowPost フォローできる.sql similarity index 100% rename from src/intTest/resources/sql/accounts/apiV1AccountsIdFollowPost フォローできる.sql rename to hideout-core/src/intTest/resources/sql/accounts/apiV1AccountsIdFollowPost フォローできる.sql diff --git a/src/intTest/resources/sql/accounts/test-accounts-statuses.sql b/hideout-core/src/intTest/resources/sql/accounts/test-accounts-statuses.sql similarity index 100% rename from src/intTest/resources/sql/accounts/test-accounts-statuses.sql rename to hideout-core/src/intTest/resources/sql/accounts/test-accounts-statuses.sql diff --git a/src/intTest/resources/sql/filter/test-filter.sql b/hideout-core/src/intTest/resources/sql/filter/test-filter.sql similarity index 100% rename from src/intTest/resources/sql/filter/test-filter.sql rename to hideout-core/src/intTest/resources/sql/filter/test-filter.sql diff --git a/src/intTest/resources/sql/note/httpSignature認証でフォロワーがfollowers投稿を取得できる.sql b/hideout-core/src/intTest/resources/sql/note/httpSignature認証でフォロワーがfollowers投稿を取得できる.sql similarity index 100% rename from src/intTest/resources/sql/note/httpSignature認証でフォロワーがfollowers投稿を取得できる.sql rename to hideout-core/src/intTest/resources/sql/note/httpSignature認証でフォロワーがfollowers投稿を取得できる.sql diff --git a/src/intTest/resources/sql/note/httpSignature認証でフォロワーがpublic投稿を取得できる.sql b/hideout-core/src/intTest/resources/sql/note/httpSignature認証でフォロワーがpublic投稿を取得できる.sql similarity index 100% rename from src/intTest/resources/sql/note/httpSignature認証でフォロワーがpublic投稿を取得できる.sql rename to hideout-core/src/intTest/resources/sql/note/httpSignature認証でフォロワーがpublic投稿を取得できる.sql diff --git a/src/intTest/resources/sql/note/httpSignature認証でフォロワーがunlisted投稿を取得できる.sql b/hideout-core/src/intTest/resources/sql/note/httpSignature認証でフォロワーがunlisted投稿を取得できる.sql similarity index 100% rename from src/intTest/resources/sql/note/httpSignature認証でフォロワーがunlisted投稿を取得できる.sql rename to hideout-core/src/intTest/resources/sql/note/httpSignature認証でフォロワーがunlisted投稿を取得できる.sql diff --git a/src/intTest/resources/sql/note/メディア付き投稿はattachmentにDocumentとして画像が存在する.sql b/hideout-core/src/intTest/resources/sql/note/メディア付き投稿はattachmentにDocumentとして画像が存在する.sql similarity index 100% rename from src/intTest/resources/sql/note/メディア付き投稿はattachmentにDocumentとして画像が存在する.sql rename to hideout-core/src/intTest/resources/sql/note/メディア付き投稿はattachmentにDocumentとして画像が存在する.sql diff --git a/src/intTest/resources/sql/note/リプライになっている投稿はinReplyToが存在する.sql b/hideout-core/src/intTest/resources/sql/note/リプライになっている投稿はinReplyToが存在する.sql similarity index 100% rename from src/intTest/resources/sql/note/リプライになっている投稿はinReplyToが存在する.sql rename to hideout-core/src/intTest/resources/sql/note/リプライになっている投稿はinReplyToが存在する.sql diff --git a/src/intTest/resources/sql/note/匿名でfollowers投稿を取得しようとすると404.sql b/hideout-core/src/intTest/resources/sql/note/匿名でfollowers投稿を取得しようとすると404.sql similarity index 100% rename from src/intTest/resources/sql/note/匿名でfollowers投稿を取得しようとすると404.sql rename to hideout-core/src/intTest/resources/sql/note/匿名でfollowers投稿を取得しようとすると404.sql diff --git a/src/intTest/resources/sql/note/匿名でpublic投稿を取得できる.sql b/hideout-core/src/intTest/resources/sql/note/匿名でpublic投稿を取得できる.sql similarity index 100% rename from src/intTest/resources/sql/note/匿名でpublic投稿を取得できる.sql rename to hideout-core/src/intTest/resources/sql/note/匿名でpublic投稿を取得できる.sql diff --git a/src/intTest/resources/sql/note/匿名でunlisted投稿を取得できる.sql b/hideout-core/src/intTest/resources/sql/note/匿名でunlisted投稿を取得できる.sql similarity index 100% rename from src/intTest/resources/sql/note/匿名でunlisted投稿を取得できる.sql rename to hideout-core/src/intTest/resources/sql/note/匿名でunlisted投稿を取得できる.sql diff --git a/src/intTest/resources/sql/notification/test-mastodon_notifications.sql b/hideout-core/src/intTest/resources/sql/notification/test-mastodon_notifications.sql similarity index 100% rename from src/intTest/resources/sql/notification/test-mastodon_notifications.sql rename to hideout-core/src/intTest/resources/sql/notification/test-mastodon_notifications.sql diff --git a/src/intTest/resources/sql/notification/test-notifications.sql b/hideout-core/src/intTest/resources/sql/notification/test-notifications.sql similarity index 100% rename from src/intTest/resources/sql/notification/test-notifications.sql rename to hideout-core/src/intTest/resources/sql/notification/test-notifications.sql diff --git a/src/intTest/resources/sql/test-custom-emoji.sql b/hideout-core/src/intTest/resources/sql/test-custom-emoji.sql similarity index 100% rename from src/intTest/resources/sql/test-custom-emoji.sql rename to hideout-core/src/intTest/resources/sql/test-custom-emoji.sql diff --git a/src/intTest/resources/sql/test-post.sql b/hideout-core/src/intTest/resources/sql/test-post.sql similarity index 100% rename from src/intTest/resources/sql/test-post.sql rename to hideout-core/src/intTest/resources/sql/test-post.sql diff --git a/src/intTest/resources/sql/test-user.sql b/hideout-core/src/intTest/resources/sql/test-user.sql similarity index 100% rename from src/intTest/resources/sql/test-user.sql rename to hideout-core/src/intTest/resources/sql/test-user.sql diff --git a/src/intTest/resources/sql/test-user2.sql b/hideout-core/src/intTest/resources/sql/test-user2.sql similarity index 100% rename from src/intTest/resources/sql/test-user2.sql rename to hideout-core/src/intTest/resources/sql/test-user2.sql diff --git a/src/main/kotlin/dev/usbharu/hideout/SpringApplication.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/SpringApplication.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/SpringApplication.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/SpringApplication.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/ActivityPubProcessException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/ActivityPubProcessException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/ActivityPubProcessException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/ActivityPubProcessException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/FailedProcessException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/FailedProcessException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/FailedProcessException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/FailedProcessException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/FailedToGetActivityPubResourceException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/FailedToGetActivityPubResourceException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/FailedToGetActivityPubResourceException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/FailedToGetActivityPubResourceException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/HttpSignatureUnauthorizedException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/HttpSignatureUnauthorizedException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/HttpSignatureUnauthorizedException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/HttpSignatureUnauthorizedException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/IllegalActivityPubObjectException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/IllegalActivityPubObjectException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/IllegalActivityPubObjectException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/IllegalActivityPubObjectException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/JsonParseException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/JsonParseException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/JsonParseException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/JsonParseException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Accept.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Accept.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Accept.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Accept.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Announce.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Announce.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Announce.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Announce.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Create.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Create.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Create.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Create.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Delete.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Delete.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Delete.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Delete.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Document.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Document.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Document.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Document.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Emoji.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Emoji.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Emoji.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Emoji.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Follow.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Follow.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Follow.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Follow.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/HasActor.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/HasActor.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/HasActor.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/HasActor.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/HasId.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/HasId.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/HasId.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/HasId.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/HasName.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/HasName.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/HasName.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/HasName.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Image.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Image.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Image.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Image.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/JsonLd.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/JsonLd.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/JsonLd.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/JsonLd.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Key.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Key.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Key.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Key.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Like.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Like.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Like.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Like.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Note.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Note.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Note.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Note.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Person.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Person.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Person.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Person.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Reject.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Reject.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Reject.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Reject.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Tombstone.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Tombstone.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Tombstone.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Tombstone.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Undo.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Undo.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Undo.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Undo.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/nodeinfo/Nodeinfo.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/nodeinfo/Nodeinfo.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/nodeinfo/Nodeinfo.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/nodeinfo/Nodeinfo.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/nodeinfo/Nodeinfo2_0.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/nodeinfo/Nodeinfo2_0.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/nodeinfo/Nodeinfo2_0.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/nodeinfo/Nodeinfo2_0.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/objects/Object.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/objects/Object.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/objects/Object.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/objects/Object.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/objects/ObjectDeserializer.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/objects/ObjectDeserializer.kt similarity index 98% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/objects/ObjectDeserializer.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/objects/ObjectDeserializer.kt index 09e3063d..1a554745 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/objects/ObjectDeserializer.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/objects/ObjectDeserializer.kt @@ -60,7 +60,7 @@ class ObjectDeserializer : JsonDeserializer() { ExtendedActivityVocabulary.Add -> null ExtendedActivityVocabulary.Announce -> p.codec.treeToValue(treeNode, Announce::class.java) ExtendedActivityVocabulary.Arrive -> null - ExtendedActivityVocabulary.Block -> p.codec.treeToValue(treeNode, Block::class.java) + ExtendedActivityVocabulary.Block -> null ExtendedActivityVocabulary.Create -> p.codec.treeToValue(treeNode, Create::class.java) ExtendedActivityVocabulary.Delete -> p.codec.treeToValue(treeNode, Delete::class.java) ExtendedActivityVocabulary.Dislike -> null diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/objects/ObjectValue.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/objects/ObjectValue.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/objects/ObjectValue.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/objects/ObjectValue.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/webfinger/WebFinger.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/webfinger/WebFinger.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/webfinger/WebFinger.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/webfinger/WebFinger.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/ExposedAnnounceQueryService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/ExposedAnnounceQueryService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/ExposedAnnounceQueryService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/ExposedAnnounceQueryService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/actor/UserAPController.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/actor/UserAPController.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/actor/UserAPController.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/actor/UserAPController.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/actor/UserAPControllerImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/actor/UserAPControllerImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/actor/UserAPControllerImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/actor/UserAPControllerImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/hostmeta/HostMetaController.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/hostmeta/HostMetaController.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/hostmeta/HostMetaController.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/hostmeta/HostMetaController.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxController.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxController.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxController.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxController.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxControllerImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxControllerImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxControllerImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxControllerImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/nodeinfo/NodeinfoController.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/nodeinfo/NodeinfoController.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/nodeinfo/NodeinfoController.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/nodeinfo/NodeinfoController.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/note/NoteApController.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/note/NoteApController.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/note/NoteApController.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/note/NoteApController.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/note/NoteApControllerImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/note/NoteApControllerImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/note/NoteApControllerImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/note/NoteApControllerImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/outbox/OutboxController.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/outbox/OutboxController.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/outbox/OutboxController.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/outbox/OutboxController.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/outbox/OutboxControllerImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/outbox/OutboxControllerImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/outbox/OutboxControllerImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/outbox/OutboxControllerImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/webfinger/WebFingerController.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/webfinger/WebFingerController.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/webfinger/WebFingerController.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/webfinger/WebFingerController.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/query/AnnounceQueryService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/query/AnnounceQueryService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/query/AnnounceQueryService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/query/AnnounceQueryService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/query/NoteQueryService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/query/NoteQueryService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/query/NoteQueryService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/query/NoteQueryService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApAcceptProcessor.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApAcceptProcessor.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApAcceptProcessor.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApAcceptProcessor.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApSendAcceptService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApSendAcceptService.kt similarity index 75% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApSendAcceptService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApSendAcceptService.kt index d27016b0..ea1793e6 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApSendAcceptService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApSendAcceptService.kt @@ -19,9 +19,8 @@ package dev.usbharu.hideout.activitypub.service.activity.accept import dev.usbharu.hideout.activitypub.domain.model.Accept import dev.usbharu.hideout.activitypub.domain.model.Follow import dev.usbharu.hideout.core.domain.model.actor.Actor -import dev.usbharu.hideout.core.external.job.DeliverAcceptJob -import dev.usbharu.hideout.core.external.job.DeliverAcceptJobParam -import dev.usbharu.hideout.core.service.job.JobQueueParentService +import dev.usbharu.hideout.core.external.job.DeliverAcceptTask +import dev.usbharu.owl.producer.api.OwlProducer import org.springframework.stereotype.Service interface ApSendAcceptService { @@ -30,11 +29,10 @@ interface ApSendAcceptService { @Service class ApSendAcceptServiceImpl( - private val jobQueueParentService: JobQueueParentService, - private val deliverAcceptJob: DeliverAcceptJob + private val owlProducer: OwlProducer, ) : ApSendAcceptService { override suspend fun sendAcceptFollow(actor: Actor, target: Actor) { - val deliverAcceptJobParam = DeliverAcceptJobParam( + val deliverAcceptTask = DeliverAcceptTask( Accept( apObject = Follow( apObject = actor.url, @@ -46,6 +44,6 @@ class ApSendAcceptServiceImpl( actor.id ) - jobQueueParentService.scheduleTypeSafe(deliverAcceptJob, deliverAcceptJobParam) + owlProducer.publishTask(deliverAcceptTask) } } diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/announce/ApAnnounceProcessor.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/announce/ApAnnounceProcessor.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/announce/ApAnnounceProcessor.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/announce/ApAnnounceProcessor.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateServiceImpl.kt similarity index 80% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateServiceImpl.kt index 0d37ea10..0fb4a1e8 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateServiceImpl.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateServiceImpl.kt @@ -16,7 +16,6 @@ package dev.usbharu.hideout.activitypub.service.activity.create -import com.fasterxml.jackson.databind.ObjectMapper import dev.usbharu.hideout.activitypub.domain.model.Create import dev.usbharu.hideout.activitypub.query.NoteQueryService import dev.usbharu.hideout.application.config.ApplicationConfig @@ -24,20 +23,19 @@ import dev.usbharu.hideout.core.domain.exception.resource.PostNotFoundException import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.post.Post -import dev.usbharu.hideout.core.external.job.DeliverPostJob +import dev.usbharu.hideout.core.external.job.DeliverCreateTask import dev.usbharu.hideout.core.query.FollowerQueryService -import dev.usbharu.hideout.core.service.job.JobQueueParentService +import dev.usbharu.owl.producer.api.OwlProducer import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @Service class ApSendCreateServiceImpl( private val followerQueryService: FollowerQueryService, - private val objectMapper: ObjectMapper, - private val jobQueueParentService: JobQueueParentService, private val noteQueryService: NoteQueryService, private val applicationConfig: ApplicationConfig, - private val actorRepository: ActorRepository + private val actorRepository: ActorRepository, + private val owlProducer: OwlProducer, ) : ApSendCreateService { override suspend fun createNote(post: Post) { logger.info("CREATE Create Local Note ${post.url}") @@ -56,11 +54,7 @@ class ApSendCreateServiceImpl( id = "${applicationConfig.url}/create/note/${post.id}" ) followers.forEach { followerEntity -> - jobQueueParentService.schedule(DeliverPostJob) { - props[DeliverPostJob.actor] = userEntity.url - props[DeliverPostJob.inbox] = followerEntity.inbox - props[DeliverPostJob.create] = objectMapper.writeValueAsString(create) - } + owlProducer.publishTask(DeliverCreateTask(create, userEntity.url, followerEntity.inbox)) } logger.debug("SUCCESS Create Local Note ${post.url}") diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/CreateActivityProcessor.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/CreateActivityProcessor.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/CreateActivityProcessor.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/CreateActivityProcessor.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt similarity index 84% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt index 55e68c78..4570808d 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt @@ -24,10 +24,9 @@ import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException import dev.usbharu.hideout.core.domain.model.actor.Actor import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.post.Post -import dev.usbharu.hideout.core.external.job.DeliverDeleteJob -import dev.usbharu.hideout.core.external.job.DeliverDeleteJobParam +import dev.usbharu.hideout.core.external.job.DeliverDeleteTask import dev.usbharu.hideout.core.query.FollowerQueryService -import dev.usbharu.hideout.core.service.job.JobQueueParentService +import dev.usbharu.owl.producer.api.OwlProducer import org.springframework.stereotype.Service import java.time.Instant @@ -38,11 +37,10 @@ interface APSendDeleteService { @Service class APSendDeleteServiceImpl( - private val jobQueueParentService: JobQueueParentService, - private val delverDeleteJob: DeliverDeleteJob, private val followerQueryService: FollowerQueryService, private val applicationConfig: ApplicationConfig, - private val actorRepository: ActorRepository + private val actorRepository: ActorRepository, + private val owlProducer: OwlProducer, ) : APSendDeleteService { override suspend fun sendDeleteNote(deletedPost: Post) { val actor = @@ -57,12 +55,13 @@ class APSendDeleteServiceImpl( ) followersById.forEach { - val jobProps = DeliverDeleteJobParam( + val jobProps = DeliverDeleteTask( delete, it.inbox, actor.id ) - jobQueueParentService.scheduleTypeSafe(delverDeleteJob, jobProps) + + owlProducer.publishTask(jobProps) } } @@ -77,7 +76,7 @@ class APSendDeleteServiceImpl( ) followers.forEach { - DeliverDeleteJobParam( + DeliverDeleteTask( delete = delete, it.inbox, deletedActor.id diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APFollowProcessor.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APFollowProcessor.kt similarity index 76% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APFollowProcessor.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APFollowProcessor.kt index da4fbbbb..3cc8cc68 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APFollowProcessor.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APFollowProcessor.kt @@ -16,34 +16,31 @@ package dev.usbharu.hideout.activitypub.service.activity.follow -import com.fasterxml.jackson.databind.ObjectMapper import dev.usbharu.hideout.activitypub.domain.model.Follow import dev.usbharu.hideout.activitypub.service.common.AbstractActivityPubProcessor import dev.usbharu.hideout.activitypub.service.common.ActivityPubProcessContext import dev.usbharu.hideout.activitypub.service.common.ActivityType import dev.usbharu.hideout.application.external.Transaction -import dev.usbharu.hideout.core.external.job.ReceiveFollowJob -import dev.usbharu.hideout.core.external.job.ReceiveFollowJobParam -import dev.usbharu.hideout.core.service.job.JobQueueParentService +import dev.usbharu.hideout.core.external.job.ReceiveFollowTask +import dev.usbharu.owl.producer.api.OwlProducer import org.springframework.stereotype.Service @Service class APFollowProcessor( transaction: Transaction, - private val jobQueueParentService: JobQueueParentService, - private val objectMapper: ObjectMapper + private val owlProducer: OwlProducer, ) : AbstractActivityPubProcessor(transaction) { override suspend fun internalProcess(activity: ActivityPubProcessContext) { logger.info("FOLLOW from: {} to {}", activity.activity.actor, activity.activity.apObject) // inboxをジョブキューに乗せているので既に不要だが、フォロー承認制アカウントを実装する際に必要なので残す - val jobProps = ReceiveFollowJobParam( + val jobProps = ReceiveFollowTask( activity.activity.actor, - objectMapper.writeValueAsString(activity.activity), + activity.activity, activity.activity.apObject ) - jobQueueParentService.scheduleTypeSafe(ReceiveFollowJob, jobProps) + owlProducer.publishTask(jobProps) } override fun isSupported(activityType: ActivityType): Boolean = activityType == ActivityType.Follow diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowService.kt similarity index 65% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowService.kt index c9afab20..9d69e7be 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowService.kt @@ -16,12 +16,10 @@ package dev.usbharu.hideout.activitypub.service.activity.follow -import com.fasterxml.jackson.databind.ObjectMapper import dev.usbharu.hideout.activitypub.domain.model.Follow -import dev.usbharu.hideout.core.external.job.ReceiveFollowJob -import dev.usbharu.hideout.core.service.job.JobQueueParentService +import dev.usbharu.hideout.core.external.job.ReceiveFollowTask +import dev.usbharu.owl.producer.api.OwlProducer import org.slf4j.LoggerFactory -import org.springframework.beans.factory.annotation.Qualifier import org.springframework.stereotype.Service interface APReceiveFollowService { @@ -30,16 +28,11 @@ interface APReceiveFollowService { @Service class APReceiveFollowServiceImpl( - private val jobQueueParentService: JobQueueParentService, - @Qualifier("activitypub") private val objectMapper: ObjectMapper + private val owlProducer: OwlProducer, ) : APReceiveFollowService { override suspend fun receiveFollow(follow: Follow) { logger.info("FOLLOW from: {} to: {}", follow.actor, follow.apObject) - jobQueueParentService.schedule(ReceiveFollowJob) { - props[ReceiveFollowJob.actor] = follow.actor - props[ReceiveFollowJob.follow] = objectMapper.writeValueAsString(follow) - props[ReceiveFollowJob.targetActor] = follow.apObject - } + owlProducer.publishTask(ReceiveFollowTask(follow.actor, follow, follow.apObject)) return } diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APSendFollowService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APSendFollowService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APSendFollowService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APSendFollowService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APLikeProcessor.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APLikeProcessor.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APLikeProcessor.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APLikeProcessor.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionService.kt similarity index 57% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionService.kt index ea218c6e..fac9ccff 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionService.kt @@ -16,18 +16,20 @@ package dev.usbharu.hideout.activitypub.service.activity.like -import com.fasterxml.jackson.databind.ObjectMapper +import dev.usbharu.hideout.activitypub.domain.model.Like +import dev.usbharu.hideout.activitypub.domain.model.Undo +import dev.usbharu.hideout.application.config.ApplicationConfig import dev.usbharu.hideout.core.domain.exception.resource.PostNotFoundException import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.post.PostRepository import dev.usbharu.hideout.core.domain.model.reaction.Reaction -import dev.usbharu.hideout.core.external.job.DeliverReactionJob -import dev.usbharu.hideout.core.external.job.DeliverRemoveReactionJob +import dev.usbharu.hideout.core.external.job.DeliverReactionTask +import dev.usbharu.hideout.core.external.job.DeliverUndoTask import dev.usbharu.hideout.core.query.FollowerQueryService -import dev.usbharu.hideout.core.service.job.JobQueueParentService -import org.springframework.beans.factory.annotation.Qualifier +import dev.usbharu.owl.producer.api.OwlProducer import org.springframework.stereotype.Service +import java.time.Instant interface APReactionService { suspend fun reaction(like: Reaction) @@ -36,11 +38,11 @@ interface APReactionService { @Service class APReactionServiceImpl( - private val jobQueueParentService: JobQueueParentService, private val followerQueryService: FollowerQueryService, private val actorRepository: ActorRepository, - @Qualifier("activitypub") private val objectMapper: ObjectMapper, - private val postRepository: PostRepository + private val postRepository: PostRepository, + private val applicationConfig: ApplicationConfig, + private val owlProducer: OwlProducer, ) : APReactionService { override suspend fun reaction(like: Reaction) { val followers = followerQueryService.findFollowersById(like.actorId) @@ -48,13 +50,18 @@ class APReactionServiceImpl( val post = postRepository.findById(like.postId) ?: throw PostNotFoundException.withId(like.postId) followers.forEach { follower -> - jobQueueParentService.schedule(DeliverReactionJob) { - props[DeliverReactionJob.actor] = user.url - props[DeliverReactionJob.reaction] = "❤" - props[DeliverReactionJob.inbox] = follower.inbox - props[DeliverReactionJob.postUrl] = post.url - props[DeliverReactionJob.id] = post.id.toString() - } + owlProducer.publishTask( + DeliverReactionTask( + actor = user.url, + like = Like( + actor = user.url, + id = "${applicationConfig.url}/like/note/${post.id}", + content = "❤", + apObject = post.url + ), + inbox = follower.inbox + ) + ) } } @@ -64,12 +71,23 @@ class APReactionServiceImpl( val post = postRepository.findById(like.postId) ?: throw PostNotFoundException.withId(like.postId) followers.forEach { follower -> - jobQueueParentService.schedule(DeliverRemoveReactionJob) { - props[DeliverRemoveReactionJob.actor] = user.url - props[DeliverRemoveReactionJob.inbox] = follower.inbox - props[DeliverRemoveReactionJob.id] = post.id.toString() - props[DeliverRemoveReactionJob.like] = objectMapper.writeValueAsString(like) - } + owlProducer.publishTask( + DeliverUndoTask( + signer = user.id, + inbox = follower.inbox, + undo = Undo( + actor = user.url, + id = "${applicationConfig.url}/undo/like/${post.id}", + apObject = Like( + actor = user.url, + id = "${applicationConfig.url}/like/note/${post.id}", + content = "❤", + apObject = post.url + ), + published = Instant.now().toString(), + ) + ) + ) } } } diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/ApRejectProcessor.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/ApRejectProcessor.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/ApRejectProcessor.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/ApRejectProcessor.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/ApSendRejectService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/ApSendRejectService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/ApSendRejectService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/ApSendRejectService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/ApSendRejectServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/ApSendRejectServiceImpl.kt similarity index 75% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/ApSendRejectServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/ApSendRejectServiceImpl.kt index 9977be3f..eef8dc2f 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/ApSendRejectServiceImpl.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/ApSendRejectServiceImpl.kt @@ -20,19 +20,17 @@ import dev.usbharu.hideout.activitypub.domain.model.Follow import dev.usbharu.hideout.activitypub.domain.model.Reject import dev.usbharu.hideout.application.config.ApplicationConfig import dev.usbharu.hideout.core.domain.model.actor.Actor -import dev.usbharu.hideout.core.external.job.DeliverRejectJob -import dev.usbharu.hideout.core.external.job.DeliverRejectJobParam -import dev.usbharu.hideout.core.service.job.JobQueueParentService +import dev.usbharu.hideout.core.external.job.DeliverRejectTask +import dev.usbharu.owl.producer.api.OwlProducer import org.springframework.stereotype.Service @Service class ApSendRejectServiceImpl( private val applicationConfig: ApplicationConfig, - private val jobQueueParentService: JobQueueParentService, - private val deliverRejectJob: DeliverRejectJob + private val owlProducer: OwlProducer, ) : ApSendRejectService { override suspend fun sendRejectFollow(actor: Actor, target: Actor) { - val deliverRejectJobParam = DeliverRejectJobParam( + val deliverRejectTask = DeliverRejectTask( Reject( actor.url, "${applicationConfig.url}/reject/${actor.id}/${target.id}", @@ -42,6 +40,6 @@ class ApSendRejectServiceImpl( actor.id ) - jobQueueParentService.scheduleTypeSafe(deliverRejectJob, deliverRejectJobParam) + owlProducer.publishTask(deliverRejectTask) } } diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APSendUndoService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APSendUndoService.kt similarity index 93% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APSendUndoService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APSendUndoService.kt index 330a0e1b..80d4828b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APSendUndoService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APSendUndoService.kt @@ -20,5 +20,4 @@ import dev.usbharu.hideout.core.domain.model.actor.Actor interface APSendUndoService { suspend fun sendUndoFollow(actor: Actor, target: Actor) - suspend fun sendUndoBlock(actor: Actor, target: Actor) } diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APSendUndoServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APSendUndoServiceImpl.kt similarity index 54% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APSendUndoServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APSendUndoServiceImpl.kt index 49444259..576e9463 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APSendUndoServiceImpl.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APSendUndoServiceImpl.kt @@ -16,25 +16,22 @@ package dev.usbharu.hideout.activitypub.service.activity.undo -import dev.usbharu.hideout.activitypub.domain.model.Block import dev.usbharu.hideout.activitypub.domain.model.Follow import dev.usbharu.hideout.activitypub.domain.model.Undo import dev.usbharu.hideout.application.config.ApplicationConfig import dev.usbharu.hideout.core.domain.model.actor.Actor -import dev.usbharu.hideout.core.external.job.DeliverUndoJob -import dev.usbharu.hideout.core.external.job.DeliverUndoJobParam -import dev.usbharu.hideout.core.service.job.JobQueueParentService +import dev.usbharu.hideout.core.external.job.DeliverUndoTask +import dev.usbharu.owl.producer.api.OwlProducer import org.springframework.stereotype.Service import java.time.Instant @Service class APSendUndoServiceImpl( - private val jobQueueParentService: JobQueueParentService, - private val deliverUndoJob: DeliverUndoJob, - private val applicationConfig: ApplicationConfig + private val applicationConfig: ApplicationConfig, + private val owlProducer: OwlProducer, ) : APSendUndoService { override suspend fun sendUndoFollow(actor: Actor, target: Actor) { - val deliverUndoJobParam = DeliverUndoJobParam( + val deliverUndoTask = DeliverUndoTask( Undo( actor = actor.url, id = "${applicationConfig.url}/undo/follow/${actor.id}/${target.url}", @@ -48,25 +45,7 @@ class APSendUndoServiceImpl( actor.id ) - jobQueueParentService.scheduleTypeSafe(deliverUndoJob, deliverUndoJobParam) + owlProducer.publishTask(deliverUndoTask) } - override suspend fun sendUndoBlock(actor: Actor, target: Actor) { - val deliverUndoJobParam = DeliverUndoJobParam( - Undo( - actor = actor.url, - id = "${applicationConfig.url}/undo/block/${actor.id}/${target.url}", - apObject = Block( - apObject = actor.url, - actor = target.url, - id = "${applicationConfig.url}/block/${actor.id}/${target.id}" - ), - published = Instant.now().toString() - ), - target.inbox, - actor.id - ) - - jobQueueParentService.scheduleTypeSafe(deliverUndoJob, deliverUndoJobParam) - } } diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APUndoProcessor.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APUndoProcessor.kt similarity index 91% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APUndoProcessor.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APUndoProcessor.kt index 805d8211..bd80e6f9 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APUndoProcessor.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APUndoProcessor.kt @@ -56,11 +56,6 @@ class APUndoProcessor( return } - "Block" -> { - block(undo) - return - } - "Accept" -> { accept(undo) return @@ -112,16 +107,6 @@ class APUndoProcessor( return } - private suspend fun block(undo: Undo) { - val block = undo.apObject as Block - - val blocker = apUserService.fetchPersonWithEntity(undo.actor, block.apObject).second - val target = actorRepository.findByUrl(block.apObject) ?: throw UserNotFoundException.withUrl(block.apObject) - - relationshipService.unblock(blocker.id, target.id) - return - } - private suspend fun follow(undo: Undo) { val follow = undo.apObject as Follow diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APRequestService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APRequestService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APRequestService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APRequestService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APRequestServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APRequestServiceImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APRequestServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APRequestServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APResourceResolveService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APResourceResolveService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APResourceResolveService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APResourceResolveService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APResourceResolveServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APResourceResolveServiceImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APResourceResolveServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APResourceResolveServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APService.kt similarity index 51% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APService.kt index 67812116..64aa581b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APService.kt @@ -19,9 +19,9 @@ package dev.usbharu.hideout.activitypub.service.common import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.ObjectMapper import dev.usbharu.hideout.activitypub.domain.exception.JsonParseException -import dev.usbharu.hideout.core.external.job.InboxJob -import dev.usbharu.hideout.core.service.job.JobQueueParentService +import dev.usbharu.hideout.core.external.job.InboxTask import dev.usbharu.httpsignature.common.HttpRequest +import dev.usbharu.owl.producer.api.OwlProducer import org.slf4j.Logger import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Qualifier @@ -38,161 +38,10 @@ interface APService { ) } -enum class ActivityType { - Accept, - Add, - Announce, - Arrive, - Block, - Create, - Delete, - Dislike, - Flag, - Follow, - Ignore, - Invite, - Join, - Leave, - Like, - Listen, - Move, - Offer, - Question, - Reject, - Read, - Remove, - TentativeReject, - TentativeAccept, - Travel, - Undo, - Update, - View, - Other -} - -enum class ActivityVocabulary { - Object, - Link, - Activity, - IntransitiveActivity, - Collection, - OrderedCollection, - CollectionPage, - OrderedCollectionPage, - Accept, - Add, - Announce, - Arrive, - Block, - Create, - Delete, - Dislike, - Flag, - Follow, - Ignore, - Invite, - Join, - Leave, - Like, - Listen, - Move, - Offer, - Question, - Reject, - Read, - Remove, - TentativeReject, - TentativeAccept, - Travel, - Undo, - Update, - View, - Application, - Group, - Organization, - Person, - Service, - Article, - Audio, - Document, - Event, - Image, - Note, - Page, - Place, - Profile, - Relationship, - Tombstone, - Video, - Mention, -} - -enum class ExtendedActivityVocabulary { - Object, - Link, - Activity, - IntransitiveActivity, - Collection, - OrderedCollection, - CollectionPage, - OrderedCollectionPage, - Accept, - Add, - Announce, - Arrive, - Block, - Create, - Delete, - Dislike, - Flag, - Follow, - Ignore, - Invite, - Join, - Leave, - Like, - Listen, - Move, - Offer, - Question, - Reject, - Read, - Remove, - TentativeReject, - TentativeAccept, - Travel, - Undo, - Update, - View, - Application, - Group, - Organization, - Person, - Service, - Article, - Audio, - Document, - Event, - Image, - Note, - Page, - Place, - Profile, - Relationship, - Tombstone, - Video, - Mention, - Emoji -} - -enum class ExtendedVocabulary { - Emoji -} - @Service class APServiceImpl( @Qualifier("activitypub") private val objectMapper: ObjectMapper, - private val jobQueueParentService: JobQueueParentService + private val owlProducer: OwlProducer, ) : APService { val logger: Logger = LoggerFactory.getLogger(APServiceImpl::class.java) @@ -221,14 +70,14 @@ class APServiceImpl( if (type.isArray) { try { return type.firstNotNullOf { jsonNode: JsonNode -> - ActivityType.values().firstOrNull { it.name.equals(jsonNode.asText(), true) } + ActivityType.entries.firstOrNull { it.name.equals(jsonNode.asText(), true) } } } catch (e: NoSuchElementException) { throw IllegalArgumentException("No valid TYPE", e) } } try { - return ActivityType.values().first { it.name.equals(type.asText(), true) } + return ActivityType.entries.first { it.name.equals(type.asText(), true) } } catch (e: NoSuchElementException) { throw IllegalArgumentException("No valid TYPE", e) } @@ -241,13 +90,14 @@ class APServiceImpl( map: Map> ) { logger.debug("process activity: {}", type) - jobQueueParentService.schedule(InboxJob) { - props[it.json] = json - props[it.type] = type.name - val writeValueAsString = objectMapper.writeValueAsString(httpRequest) - props[it.httpRequest] = writeValueAsString - props[it.headers] = objectMapper.writeValueAsString(map) - } + owlProducer.publishTask( + InboxTask( + json, + type, + httpRequest, + map + ) + ) return } } diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/AbstractActivityPubProcessor.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/AbstractActivityPubProcessor.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/AbstractActivityPubProcessor.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/AbstractActivityPubProcessor.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ActivityPubProcessContext.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ActivityPubProcessContext.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ActivityPubProcessContext.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ActivityPubProcessContext.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ActivityPubProcessor.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ActivityPubProcessor.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ActivityPubProcessor.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ActivityPubProcessor.kt diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ActivityType.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ActivityType.kt new file mode 100644 index 00000000..acd1fcb6 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ActivityType.kt @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout.activitypub.service.common + +enum class ActivityType { + Accept, + Add, + Announce, + Arrive, + Block, + Create, + Delete, + Dislike, + Flag, + Follow, + Ignore, + Invite, + Join, + Leave, + Like, + Listen, + Move, + Offer, + Question, + Reject, + Read, + Remove, + TentativeReject, + TentativeAccept, + Travel, + Undo, + Update, + View, + Other +} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ActivityVocabulary.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ActivityVocabulary.kt new file mode 100644 index 00000000..4d42dfff --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ActivityVocabulary.kt @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout.activitypub.service.common + +enum class ActivityVocabulary { + Object, + Link, + Activity, + IntransitiveActivity, + Collection, + OrderedCollection, + CollectionPage, + OrderedCollectionPage, + Accept, + Add, + Announce, + Arrive, + Block, + Create, + Delete, + Dislike, + Flag, + Follow, + Ignore, + Invite, + Join, + Leave, + Like, + Listen, + Move, + Offer, + Question, + Reject, + Read, + Remove, + TentativeReject, + TentativeAccept, + Travel, + Undo, + Update, + View, + Application, + Group, + Organization, + Person, + Service, + Article, + Audio, + Document, + Event, + Image, + Note, + Page, + Place, + Profile, + Relationship, + Tombstone, + Video, + Mention, +} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ExtendedActivityVocabulary.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ExtendedActivityVocabulary.kt new file mode 100644 index 00000000..b8150064 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ExtendedActivityVocabulary.kt @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout.activitypub.service.common + +enum class ExtendedActivityVocabulary { + Object, + Link, + Activity, + IntransitiveActivity, + Collection, + OrderedCollection, + CollectionPage, + OrderedCollectionPage, + Accept, + Add, + Announce, + Arrive, + Block, + Create, + Delete, + Dislike, + Flag, + Follow, + Ignore, + Invite, + Join, + Leave, + Like, + Listen, + Move, + Offer, + Question, + Reject, + Read, + Remove, + TentativeReject, + TentativeAccept, + Travel, + Undo, + Update, + View, + Application, + Group, + Organization, + Person, + Service, + Article, + Audio, + Document, + Event, + Image, + Note, + Page, + Place, + Profile, + Relationship, + Tombstone, + Video, + Mention, + Emoji +} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobProcessor.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ExtendedVocabulary.kt similarity index 71% rename from src/main/kotlin/dev/usbharu/hideout/core/service/job/JobProcessor.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ExtendedVocabulary.kt index eb6daa17..ef1c06c6 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobProcessor.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ExtendedVocabulary.kt @@ -14,11 +14,8 @@ * limitations under the License. */ -package dev.usbharu.hideout.core.service.job +package dev.usbharu.hideout.activitypub.service.common -import dev.usbharu.hideout.core.external.job.HideoutJob - -interface JobProcessor> { - suspend fun process(param: @UnsafeVariance T) - fun job(): R +enum class ExtendedVocabulary { + Emoji } diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/emoji/EmojiService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/emoji/EmojiService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/emoji/EmojiService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/emoji/EmojiService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/emoji/EmojiServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/emoji/EmojiServiceImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/emoji/EmojiServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/emoji/EmojiServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/NoteApApiService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/NoteApApiService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/NoteApApiService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/NoteApApiService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/NoteApApiServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/NoteApApiServiceImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/NoteApApiServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/NoteApApiServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/user/APUserService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/user/APUserService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/user/APUserService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/user/APUserService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/webfinger/WebFingerApiService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/webfinger/WebFingerApiService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/webfinger/WebFingerApiService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/activitypub/service/webfinger/WebFingerApiService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/application/config/ActivityPubConfig.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/ActivityPubConfig.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/application/config/ActivityPubConfig.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/ActivityPubConfig.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/application/config/AwsConfig.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/AwsConfig.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/application/config/AwsConfig.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/AwsConfig.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/application/config/CaptchaConfig.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/CaptchaConfig.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/application/config/CaptchaConfig.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/CaptchaConfig.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/application/config/HtmlSanitizeConfig.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/HtmlSanitizeConfig.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/application/config/HtmlSanitizeConfig.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/HtmlSanitizeConfig.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/application/config/HttpClientConfig.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/HttpClientConfig.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/application/config/HttpClientConfig.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/HttpClientConfig.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/application/config/HttpSignatureConfig.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/HttpSignatureConfig.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/application/config/HttpSignatureConfig.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/HttpSignatureConfig.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/application/config/MdcXrequestIdFilter.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/MdcXrequestIdFilter.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/application/config/MdcXrequestIdFilter.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/MdcXrequestIdFilter.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/application/config/MediaConfig.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/MediaConfig.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/application/config/MediaConfig.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/MediaConfig.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/application/config/MvcConfigurer.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/MvcConfigurer.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/application/config/MvcConfigurer.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/MvcConfigurer.kt diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/OwlConfig.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/OwlConfig.kt new file mode 100644 index 00000000..e5454e23 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/OwlConfig.kt @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout.application.config + +import com.fasterxml.jackson.databind.ObjectMapper +import dev.usbharu.owl.broker.ModuleContext +import dev.usbharu.owl.common.property.* +import dev.usbharu.owl.common.retry.RetryPolicyFactory +import dev.usbharu.owl.producer.api.OWL +import dev.usbharu.owl.producer.api.OwlProducer +import dev.usbharu.owl.producer.defaultimpl.DEFAULT +import dev.usbharu.owl.producer.embedded.EMBEDDED +import dev.usbharu.owl.producer.embedded.EMBEDDED_GRPC +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.beans.factory.annotation.Qualifier +import org.springframework.boot.context.properties.ConfigurationProperties +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import java.util.* + +@Configuration +class OwlConfig(private val producerConfig: ProducerConfig) { + @Bean + fun producer( + @Autowired(required = false) retryPolicyFactory: RetryPolicyFactory? = null, + @Qualifier("activitypub") objectMapper: ObjectMapper, + ): OwlProducer { + return when (producerConfig.mode) { + ProducerMode.EMBEDDED -> { + OWL(EMBEDDED) { + if (retryPolicyFactory != null) { + this.retryPolicyFactory = retryPolicyFactory + } + if (producerConfig.port != null) { + this.port = producerConfig.port.toString() + } + val moduleContext = ServiceLoader.load(ModuleContext::class.java).firstOrNull() + if (moduleContext != null) { + this.moduleContext = moduleContext + } + this.propertySerializerFactory = CustomPropertySerializerFactory( + setOf( + IntegerPropertySerializer(), + StringPropertyValueSerializer(), + DoublePropertySerializer(), + BooleanPropertySerializer(), + LongPropertySerializer(), + FloatPropertySerializer(), + ObjectPropertySerializer(objectMapper), + ) + ) + } + } + + ProducerMode.GRPC -> { + OWL(EMBEDDED_GRPC) { + } + } + + ProducerMode.EMBEDDED_GRPC -> { + OWL(DEFAULT) { + } + } + } + } +} + +@ConfigurationProperties("hideout.owl.producer") +data class ProducerConfig(val mode: ProducerMode = ProducerMode.EMBEDDED, val port: Int? = null) + +enum class ProducerMode { + GRPC, + EMBEDDED, + EMBEDDED_GRPC +} diff --git a/src/main/kotlin/dev/usbharu/hideout/application/config/SecurityConfig.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/SecurityConfig.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/application/config/SecurityConfig.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/SecurityConfig.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/application/config/SpringConfig.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/SpringConfig.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/application/config/SpringConfig.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/SpringConfig.kt diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/external/OwlProducerRunner.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/external/OwlProducerRunner.kt new file mode 100644 index 00000000..ca86bce1 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/external/OwlProducerRunner.kt @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout.application.external + +import dev.usbharu.owl.common.task.TaskDefinition +import dev.usbharu.owl.producer.api.OwlProducer +import kotlinx.coroutines.runBlocking +import org.springframework.beans.factory.DisposableBean +import org.springframework.boot.ApplicationArguments +import org.springframework.boot.ApplicationRunner +import org.springframework.stereotype.Component + +@Component +class OwlProducerRunner(private val owlProducer: OwlProducer, private val taskDefinitions: List>) : + ApplicationRunner, DisposableBean { + override fun run(args: ApplicationArguments?) { + runBlocking { + owlProducer.start() + taskDefinitions.forEach { taskDefinition -> owlProducer.registerTask(taskDefinition) } + } + } + + override fun destroy() { + System.err.println("destroy aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") + runBlocking { + owlProducer.stop() + } + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/application/external/Transaction.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/external/Transaction.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/application/external/Transaction.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/application/external/Transaction.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ExposedPaginationExtension.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ExposedPaginationExtension.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ExposedPaginationExtension.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ExposedPaginationExtension.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ExposedTransaction.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ExposedTransaction.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ExposedTransaction.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ExposedTransaction.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/Page.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/Page.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/Page.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/Page.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/PaginationList.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/PaginationList.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/PaginationList.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/PaginationList.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/QueryMapper.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/QueryMapper.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/QueryMapper.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/QueryMapper.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ResultRowMapper.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ResultRowMapper.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ResultRowMapper.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ResultRowMapper.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/springframework/RoleHierarchyAuthorizationManagerFactory.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/springframework/RoleHierarchyAuthorizationManagerFactory.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/application/infrastructure/springframework/RoleHierarchyAuthorizationManagerFactory.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/springframework/RoleHierarchyAuthorizationManagerFactory.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/application/service/id/IdGenerateService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/service/id/IdGenerateService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/application/service/id/IdGenerateService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/application/service/id/IdGenerateService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/application/service/id/SnowflakeIdGenerateService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/service/id/SnowflakeIdGenerateService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/application/service/id/SnowflakeIdGenerateService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/application/service/id/SnowflakeIdGenerateService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/application/service/id/TwitterSnowflakeIdGenerateService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/service/id/TwitterSnowflakeIdGenerateService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/application/service/id/TwitterSnowflakeIdGenerateService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/application/service/id/TwitterSnowflakeIdGenerateService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/application/service/init/MetaService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/service/init/MetaService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/application/service/init/MetaService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/application/service/init/MetaService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/application/service/init/MetaServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/service/init/MetaServiceImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/application/service/init/MetaServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/application/service/init/MetaServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/application/service/init/ServerInitialiseService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/service/init/ServerInitialiseService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/application/service/init/ServerInitialiseService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/application/service/init/ServerInitialiseService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/application/service/init/ServerInitialiseServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/service/init/ServerInitialiseServiceImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/application/service/init/ServerInitialiseServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/application/service/init/ServerInitialiseServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/FailedToGetResourcesException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/FailedToGetResourcesException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/exception/FailedToGetResourcesException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/FailedToGetResourcesException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/HideoutException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/HideoutException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/exception/HideoutException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/HideoutException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/HttpSignatureVerifyException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/HttpSignatureVerifyException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/exception/HttpSignatureVerifyException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/HttpSignatureVerifyException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/NotInitException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/NotInitException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/exception/NotInitException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/NotInitException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/SQLExceptionTranslator.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/SQLExceptionTranslator.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/exception/SQLExceptionTranslator.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/SQLExceptionTranslator.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/SpringDataAccessExceptionSQLExceptionTranslator.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/SpringDataAccessExceptionSQLExceptionTranslator.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/exception/SpringDataAccessExceptionSQLExceptionTranslator.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/SpringDataAccessExceptionSQLExceptionTranslator.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/UserNotFoundException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/UserNotFoundException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/exception/UserNotFoundException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/UserNotFoundException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/MediaConvertException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/MediaConvertException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/MediaConvertException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/MediaConvertException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/MediaException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/MediaException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/MediaException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/MediaException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/MediaFileSizeException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/MediaFileSizeException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/MediaFileSizeException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/MediaFileSizeException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/MediaFileSizeIsZeroException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/MediaFileSizeIsZeroException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/MediaFileSizeIsZeroException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/MediaFileSizeIsZeroException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/MediaProcessException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/MediaProcessException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/MediaProcessException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/MediaProcessException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/MediaSaveException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/MediaSaveException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/MediaSaveException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/MediaSaveException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/RemoteMediaFileSizeException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/RemoteMediaFileSizeException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/RemoteMediaFileSizeException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/RemoteMediaFileSizeException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/UnsupportedMediaException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/UnsupportedMediaException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/UnsupportedMediaException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/UnsupportedMediaException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/DuplicateException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/DuplicateException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/DuplicateException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/DuplicateException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/NotFoundException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/NotFoundException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/NotFoundException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/NotFoundException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/PostNotFoundException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/PostNotFoundException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/PostNotFoundException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/PostNotFoundException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/ResourceAccessException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/ResourceAccessException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/ResourceAccessException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/ResourceAccessException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/UserNotFoundException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/UserNotFoundException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/UserNotFoundException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/UserNotFoundException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/local/LocalUserNotFoundException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/local/LocalUserNotFoundException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/local/LocalUserNotFoundException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/local/LocalUserNotFoundException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Acct.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Acct.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Acct.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Acct.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Actor.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Actor.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Actor.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Actor.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/ActorRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/ActorRepository.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/ActorRepository.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/ActorRepository.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/deletedActor/DeletedActor.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/deletedActor/DeletedActor.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/deletedActor/DeletedActor.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/deletedActor/DeletedActor.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/deletedActor/DeletedActorRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/deletedActor/DeletedActorRepository.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/deletedActor/DeletedActorRepository.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/deletedActor/DeletedActorRepository.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/emoji/CustomEmoji.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/emoji/CustomEmoji.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/emoji/CustomEmoji.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/emoji/CustomEmoji.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/emoji/CustomEmojiRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/emoji/CustomEmojiRepository.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/emoji/CustomEmojiRepository.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/emoji/CustomEmojiRepository.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/Filter.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/Filter.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/Filter.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/Filter.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterAction.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterAction.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterAction.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterAction.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterMode.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterMode.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterMode.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterMode.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterRepository.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterRepository.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterRepository.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterType.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterType.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterType.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterType.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filterkeyword/FilterKeyword.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filterkeyword/FilterKeyword.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/filterkeyword/FilterKeyword.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filterkeyword/FilterKeyword.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filterkeyword/FilterKeywordRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filterkeyword/FilterKeywordRepository.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/filterkeyword/FilterKeywordRepository.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filterkeyword/FilterKeywordRepository.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/Instance.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/Instance.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/Instance.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/Instance.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/InstanceRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/InstanceRepository.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/InstanceRepository.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/InstanceRepository.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/Nodeinfo.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/Nodeinfo.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/Nodeinfo.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/Nodeinfo.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/Nodeinfo2_0.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/Nodeinfo2_0.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/Nodeinfo2_0.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/Nodeinfo2_0.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/media/Media.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/media/Media.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/media/Media.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/media/Media.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/media/MediaRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/media/MediaRepository.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/media/MediaRepository.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/media/MediaRepository.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/meta/Jwt.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/meta/Jwt.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/meta/Jwt.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/meta/Jwt.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/meta/Meta.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/meta/Meta.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/meta/Meta.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/meta/Meta.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/meta/MetaRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/meta/MetaRepository.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/meta/MetaRepository.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/meta/MetaRepository.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/notification/ExposedNotificationRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/notification/ExposedNotificationRepository.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/notification/ExposedNotificationRepository.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/notification/ExposedNotificationRepository.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/notification/Notification.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/notification/Notification.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/notification/Notification.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/notification/Notification.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/notification/NotificationRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/notification/NotificationRepository.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/notification/NotificationRepository.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/notification/NotificationRepository.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/Post.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/Post.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/Post.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/Post.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/PostRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/PostRepository.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/PostRepository.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/PostRepository.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/Visibility.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/Visibility.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/Visibility.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/Visibility.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/Reaction.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/Reaction.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/Reaction.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/Reaction.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/ReactionRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/ReactionRepository.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/ReactionRepository.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/ReactionRepository.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/Relationship.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/Relationship.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/Relationship.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/Relationship.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepository.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepository.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepository.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepositoryImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepositoryImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepositoryImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepositoryImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/timeline/Timeline.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/timeline/Timeline.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/timeline/Timeline.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/timeline/Timeline.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/timeline/TimelineRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/timeline/TimelineRepository.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/timeline/TimelineRepository.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/timeline/TimelineRepository.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/userdetails/UserDetail.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/userdetails/UserDetail.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/userdetails/UserDetail.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/userdetails/UserDetail.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/userdetails/UserDetailRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/userdetails/UserDetailRepository.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/domain/model/userdetails/UserDetailRepository.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/userdetails/UserDetailRepository.kt diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverAcceptTask.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverAcceptTask.kt new file mode 100644 index 00000000..b7b19949 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverAcceptTask.kt @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout.core.external.job + +import dev.usbharu.hideout.activitypub.domain.model.Accept +import dev.usbharu.owl.common.property.* +import dev.usbharu.owl.common.task.PropertyDefinition +import dev.usbharu.owl.common.task.Task +import dev.usbharu.owl.common.task.TaskDefinition +import org.springframework.stereotype.Component + +data class DeliverAcceptTask( + val accept: Accept, + val inbox: String, + val signer: Long, +) : Task() + +@Component +data object DeliverAcceptTaskDef : TaskDefinition { + override val name: String + get() = "DeliverAccept" + override val priority: Int + get() = 10 + override val maxRetry: Int + get() = 5 + override val retryPolicy: String + get() = "" + override val timeoutMilli: Long + get() = 1000 + override val propertyDefinition: PropertyDefinition + get() = PropertyDefinition( + mapOf( + "accept" to PropertyType.binary, + "inbox" to PropertyType.string, + "signer" to PropertyType.number, + ) + ) + override val type: Class + get() = DeliverAcceptTask::class.java + + override fun serialize(task: DeliverAcceptTask): Map> { + return mapOf( + "accept" to ObjectPropertyValue(task.accept), + "inbox" to StringPropertyValue(task.inbox), + "signer" to LongPropertyValue(task.signer) + ) + } + + override fun deserialize(value: Map>): DeliverAcceptTask { + return DeliverAcceptTask( + value.getValue("accept").value as Accept, + value.getValue("inbox").value as String, + value.getValue("signer").value as Long, + ) + } +} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverCreateTask.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverCreateTask.kt new file mode 100644 index 00000000..2c645290 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverCreateTask.kt @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout.core.external.job + +import dev.usbharu.hideout.activitypub.domain.model.Create +import dev.usbharu.owl.common.task.Task +import dev.usbharu.owl.common.task.TaskDefinition +import org.springframework.stereotype.Component + +data class DeliverCreateTask( + val create: Create, + val inbox: String, + val actor: String, +) : Task() + +@Component +data object DeliverCreateTaskDef : TaskDefinition { + override val type: Class + get() = DeliverCreateTask::class.java +} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverDeleteTask.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverDeleteTask.kt new file mode 100644 index 00000000..6ce63ad2 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverDeleteTask.kt @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout.core.external.job + +import dev.usbharu.hideout.activitypub.domain.model.Delete +import dev.usbharu.owl.common.task.Task +import dev.usbharu.owl.common.task.TaskDefinition +import org.springframework.stereotype.Component + +data class DeliverDeleteTask( + val delete: Delete, + val inbox: String, + val signer: Long, +) : Task() + +@Component +data object DeliverDeleteTaskDef : TaskDefinition { + override val type: Class + get() = DeliverDeleteTask::class.java +} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverReactionTask.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverReactionTask.kt new file mode 100644 index 00000000..c1c73154 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverReactionTask.kt @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout.core.external.job + +import dev.usbharu.hideout.activitypub.domain.model.Like +import dev.usbharu.owl.common.task.Task +import dev.usbharu.owl.common.task.TaskDefinition +import org.springframework.stereotype.Component + +data class DeliverReactionTask( + val actor: String, + val like: Like, + val inbox: String, +) : Task() + +@Component +data object DeliverReactionTaskDef : TaskDefinition { + override val type: Class + get() = DeliverReactionTask::class.java +} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverRejectTask.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverRejectTask.kt new file mode 100644 index 00000000..5bb47432 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverRejectTask.kt @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout.core.external.job + +import dev.usbharu.hideout.activitypub.domain.model.Reject +import dev.usbharu.owl.common.task.Task +import dev.usbharu.owl.common.task.TaskDefinition +import org.springframework.stereotype.Component + +data class DeliverRejectTask( + val reject: Reject, + val inbox: String, + val signer: Long, +) : Task() + +@Component +data object DeliverRejectTaskDef : TaskDefinition { + override val type: Class + get() = DeliverRejectTask::class.java +} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverUndoTask.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverUndoTask.kt new file mode 100644 index 00000000..3ae7f129 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverUndoTask.kt @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout.core.external.job + +import dev.usbharu.hideout.activitypub.domain.model.Undo +import dev.usbharu.owl.common.task.Task +import dev.usbharu.owl.common.task.TaskDefinition +import org.springframework.stereotype.Component + +data class DeliverUndoTask( + val undo: Undo, + val inbox: String, + val signer: Long, +) : Task() + +@Component +data object DeliverUndoTaskDef : TaskDefinition { + override val type: Class + get() = DeliverUndoTask::class.java +} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/job/InboxTask.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/job/InboxTask.kt new file mode 100644 index 00000000..de6b926f --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/job/InboxTask.kt @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout.core.external.job + +import dev.usbharu.hideout.activitypub.service.common.ActivityType +import dev.usbharu.httpsignature.common.HttpRequest +import dev.usbharu.owl.common.property.ObjectPropertyValue +import dev.usbharu.owl.common.property.PropertyValue +import dev.usbharu.owl.common.property.StringPropertyValue +import dev.usbharu.owl.common.task.Task +import dev.usbharu.owl.common.task.TaskDefinition +import org.springframework.stereotype.Component + +data class InboxTask( + val json: String, + val type: ActivityType, + val httpRequest: HttpRequest, + val headers: Map>, +) : Task() + +@Component +data object InboxTaskDef : TaskDefinition { + override val type: Class + get() = InboxTask::class.java + + override fun serialize(task: InboxTask): Map> { + return mapOf( + "json" to StringPropertyValue(task.json), + "type" to ObjectPropertyValue(task.type), + "httpRequest" to ObjectPropertyValue(task.httpRequest), + "headers" to ObjectPropertyValue(task.headers), + ) + } + + override fun deserialize(value: Map>): InboxTask { + return InboxTask( + value.getValue("json").value as String, + value.getValue("type").value as ActivityType, + value.getValue("httpRequest").value as HttpRequest, + value.getValue("headers").value as Map>, + ) + } +} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/job/ReceiveFollowTask.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/job/ReceiveFollowTask.kt new file mode 100644 index 00000000..a72b0d5a --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/job/ReceiveFollowTask.kt @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout.core.external.job + +import dev.usbharu.hideout.activitypub.domain.model.Follow +import dev.usbharu.owl.common.property.ObjectPropertyValue +import dev.usbharu.owl.common.property.PropertyValue +import dev.usbharu.owl.common.property.StringPropertyValue +import dev.usbharu.owl.common.task.Task +import dev.usbharu.owl.common.task.TaskDefinition +import org.springframework.stereotype.Component + +data class ReceiveFollowTask( + val actor: String, + val follow: Follow, + val targetActor: String, +) : Task() + +@Component +data object ReceiveFollowTaskDef : TaskDefinition { + override val type: Class + get() = ReceiveFollowTask::class.java + + override fun serialize(task: ReceiveFollowTask): Map> { + return mapOf( + "actor" to StringPropertyValue(task.actor), + "follow" to ObjectPropertyValue(task.follow), + "targetActor" to StringPropertyValue(task.targetActor) + ) + } + + override fun deserialize(value: Map>): ReceiveFollowTask { + return ReceiveFollowTask( + value.getValue("actor").value as String, + value.getValue("follow").value as Follow, + value.getValue("targetActor").value as String, + ) + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/PostQueryMapper.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/PostQueryMapper.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/PostQueryMapper.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/PostQueryMapper.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/PostResultRowMapper.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/PostResultRowMapper.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/PostResultRowMapper.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/PostResultRowMapper.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/UserQueryMapper.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/UserQueryMapper.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/UserQueryMapper.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/UserQueryMapper.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/UserResultRowMapper.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/UserResultRowMapper.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/UserResultRowMapper.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/UserResultRowMapper.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/FollowerQueryServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/FollowerQueryServiceImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/FollowerQueryServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/FollowerQueryServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/AbstractRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/AbstractRepository.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/AbstractRepository.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/AbstractRepository.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ActorRepositoryImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ActorRepositoryImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ActorRepositoryImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ActorRepositoryImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/CustomEmojiRepositoryImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/CustomEmojiRepositoryImpl.kt similarity index 99% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/CustomEmojiRepositoryImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/CustomEmojiRepositoryImpl.kt index c377d721..a73378ad 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/CustomEmojiRepositoryImpl.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/CustomEmojiRepositoryImpl.kt @@ -110,7 +110,7 @@ object CustomEmojis : Table("emojis") { val instanceId = long("instance_id").references(Instance.id).nullable() val url = varchar("url", 255).uniqueIndex() val category = varchar("category", 255).nullable() - val createdAt = timestamp("created_at").defaultExpression(CurrentTimestamp()) + val createdAt = timestamp("created_at").defaultExpression(CurrentTimestamp) override val primaryKey: PrimaryKey = PrimaryKey(id) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/DeletedActorRepositoryImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/DeletedActorRepositoryImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/DeletedActorRepositoryImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/DeletedActorRepositoryImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedFilterKeywordRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedFilterKeywordRepository.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedFilterKeywordRepository.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedFilterKeywordRepository.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedFilterRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedFilterRepository.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedFilterRepository.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedFilterRepository.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedTimelineRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedTimelineRepository.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedTimelineRepository.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedTimelineRepository.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/InstanceRepositoryImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/InstanceRepositoryImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/InstanceRepositoryImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/InstanceRepositoryImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MetaRepositoryImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MetaRepositoryImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MetaRepositoryImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MetaRepositoryImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/PostRepositoryImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/PostRepositoryImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/PostRepositoryImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/PostRepositoryImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ReactionRepositoryImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ReactionRepositoryImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ReactionRepositoryImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ReactionRepositoryImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/httpsignature/HttpRequestMixIn.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/httpsignature/HttpRequestMixIn.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/httpsignature/HttpRequestMixIn.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/httpsignature/HttpRequestMixIn.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/mongorepository/MongoTimelineRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/mongorepository/MongoTimelineRepository.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/mongorepository/MongoTimelineRepository.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/mongorepository/MongoTimelineRepository.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/mongorepository/MongoTimelineRepositoryWrapper.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/mongorepository/MongoTimelineRepositoryWrapper.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/mongorepository/MongoTimelineRepositoryWrapper.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/mongorepository/MongoTimelineRepositoryWrapper.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureFilter.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureFilter.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureFilter.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureFilter.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureHeaderChecker.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureHeaderChecker.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureHeaderChecker.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureHeaderChecker.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureUser.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureUser.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureUser.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureUser.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureUserDetailsService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureUserDetailsService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureUserDetailsService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureUserDetailsService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureVerifierComposite.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureVerifierComposite.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureVerifierComposite.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureVerifierComposite.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/ExposedOAuth2AuthorizationConsentService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/ExposedOAuth2AuthorizationConsentService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/ExposedOAuth2AuthorizationConsentService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/ExposedOAuth2AuthorizationConsentService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/ExposedOAuth2AuthorizationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/ExposedOAuth2AuthorizationService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/ExposedOAuth2AuthorizationService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/ExposedOAuth2AuthorizationService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/RegisteredClientRepositoryImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/RegisteredClientRepositoryImpl.kt similarity index 99% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/RegisteredClientRepositoryImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/RegisteredClientRepositoryImpl.kt index 2ea06e5c..68a3177d 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/RegisteredClientRepositoryImpl.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/RegisteredClientRepositoryImpl.kt @@ -190,7 +190,7 @@ class RegisteredClientRepositoryImpl : RegisteredClientRepository { object RegisteredClient : Table("registered_client") { val id: Column = varchar("id", 100) val clientId: Column = varchar("client_id", 100) - val clientIdIssuedAt: Column = timestamp("client_id_issued_at").defaultExpression(CurrentTimestamp()) + val clientIdIssuedAt: Column = timestamp("client_id_issued_at").defaultExpression(CurrentTimestamp) val clientSecret: Column = varchar("client_secret", 200).nullable().default(null) val clientSecretExpiresAt: Column = timestamp("client_secret_expires_at").nullable().default(null) val clientName: Column = varchar("client_name", 200) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/SecureTokenGenerator.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/SecureTokenGenerator.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/SecureTokenGenerator.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/SecureTokenGenerator.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/SecureTokenGeneratorImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/SecureTokenGeneratorImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/SecureTokenGeneratorImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/SecureTokenGeneratorImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/UserDetailsImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/UserDetailsImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/UserDetailsImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/UserDetailsImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/UserDetailsServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/UserDetailsServiceImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/UserDetailsServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/UserDetailsServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/security/LoginUserContextHolder.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/security/LoginUserContextHolder.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/security/LoginUserContextHolder.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/security/LoginUserContextHolder.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/security/OAuth2JwtLoginUserContextHolder.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/security/OAuth2JwtLoginUserContextHolder.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/security/OAuth2JwtLoginUserContextHolder.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/security/OAuth2JwtLoginUserContextHolder.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/auth/AuthController.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/auth/AuthController.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/auth/AuthController.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/auth/AuthController.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/auth/SignUpForm.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/auth/SignUpForm.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/auth/SignUpForm.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/auth/SignUpForm.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/media/LocalFileController.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/media/LocalFileController.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/media/LocalFileController.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/media/LocalFileController.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/query/FollowerQueryService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/query/FollowerQueryService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/query/FollowerQueryService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/query/FollowerQueryService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/query/model/ExposedFilterQueryService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/query/model/ExposedFilterQueryService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/query/model/ExposedFilterQueryService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/query/model/ExposedFilterQueryService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/query/model/FilterQueryModel.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/query/model/FilterQueryModel.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/query/model/FilterQueryModel.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/query/model/FilterQueryModel.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/query/model/FilterQueryService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/query/model/FilterQueryService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/query/model/FilterQueryService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/query/model/FilterQueryService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/filter/FilterKeyword.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/filter/FilterKeyword.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/filter/FilterKeyword.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/filter/FilterKeyword.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/filter/FilterResult.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/filter/FilterResult.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/filter/FilterResult.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/filter/FilterResult.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/filter/MuteProcessService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/filter/MuteProcessService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/filter/MuteProcessService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/filter/MuteProcessService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/filter/MuteProcessServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/filter/MuteProcessServiceImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/filter/MuteProcessServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/filter/MuteProcessServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/filter/MuteService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/filter/MuteService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/filter/MuteService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/filter/MuteService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/filter/MuteServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/filter/MuteServiceImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/filter/MuteServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/filter/MuteServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/follow/SendFollowDto.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/follow/SendFollowDto.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/follow/SendFollowDto.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/follow/SendFollowDto.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/instance/InstanceCreateDto.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/instance/InstanceCreateDto.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/instance/InstanceCreateDto.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/instance/InstanceCreateDto.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/instance/InstanceService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/instance/InstanceService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/instance/InstanceService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/instance/InstanceService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/ApatcheTikaFileTypeDeterminationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/ApatcheTikaFileTypeDeterminationService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/ApatcheTikaFileTypeDeterminationService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/ApatcheTikaFileTypeDeterminationService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/FileType.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/FileType.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/FileType.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/FileType.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/FileTypeDeterminationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/FileTypeDeterminationService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/FileTypeDeterminationService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/FileTypeDeterminationService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/LocalFileSystemMediaDataStore.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/LocalFileSystemMediaDataStore.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/LocalFileSystemMediaDataStore.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/LocalFileSystemMediaDataStore.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaBlurhashService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaBlurhashService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaBlurhashService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaBlurhashService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaBlurhashServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaBlurhashServiceImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaBlurhashServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaBlurhashServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaDataStore.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaDataStore.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaDataStore.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaDataStore.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaFileRenameService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaFileRenameService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaFileRenameService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaFileRenameService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaSave.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaSave.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaSave.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaSave.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaSaveRequest.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaSaveRequest.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaSaveRequest.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaSaveRequest.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaServiceImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/MimeType.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/MimeType.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/MimeType.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/MimeType.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/ProcessedFile.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/ProcessedFile.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/ProcessedFile.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/ProcessedFile.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/ProcessedMedia.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/ProcessedMedia.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/ProcessedMedia.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/ProcessedMedia.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/ProcessedMediaPath.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/ProcessedMediaPath.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/ProcessedMediaPath.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/ProcessedMediaPath.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/RemoteMedia.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/RemoteMedia.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/RemoteMedia.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/RemoteMedia.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/RemoteMediaDownloadService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/RemoteMediaDownloadService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/RemoteMediaDownloadService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/RemoteMediaDownloadService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/RemoteMediaDownloadServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/RemoteMediaDownloadServiceImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/RemoteMediaDownloadServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/RemoteMediaDownloadServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/S3MediaDataStore.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/S3MediaDataStore.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/S3MediaDataStore.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/S3MediaDataStore.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/SavedMedia.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/SavedMedia.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/SavedMedia.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/SavedMedia.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/ThumbnailGenerateService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/ThumbnailGenerateService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/ThumbnailGenerateService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/ThumbnailGenerateService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/ThumbnailGenerateServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/ThumbnailGenerateServiceImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/ThumbnailGenerateServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/ThumbnailGenerateServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/UUIDMediaFileRenameService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/UUIDMediaFileRenameService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/UUIDMediaFileRenameService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/UUIDMediaFileRenameService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/MediaConverter.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/MediaConverter.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/MediaConverter.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/MediaConverter.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/MediaConverterRoot.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/MediaConverterRoot.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/MediaConverterRoot.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/MediaConverterRoot.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/MediaConverterRootImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/MediaConverterRootImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/MediaConverterRootImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/MediaConverterRootImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/MediaProcessService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/MediaProcessService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/MediaProcessService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/MediaProcessService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/MediaProcessServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/MediaProcessServiceImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/MediaProcessServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/MediaProcessServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/image/ImageMediaProcessService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/image/ImageMediaProcessService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/image/ImageMediaProcessService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/image/ImageMediaProcessService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/image/ImageMediaProcessorConfiguration.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/image/ImageMediaProcessorConfiguration.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/image/ImageMediaProcessorConfiguration.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/image/ImageMediaProcessorConfiguration.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/movie/MovieMediaProcessService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/movie/MovieMediaProcessService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/movie/MovieMediaProcessService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/movie/MovieMediaProcessService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/notification/NotificationRequest.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/notification/NotificationRequest.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/notification/NotificationRequest.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/notification/NotificationRequest.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/notification/NotificationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/notification/NotificationService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/notification/NotificationService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/notification/NotificationService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/notification/NotificationServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/notification/NotificationServiceImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/notification/NotificationServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/notification/NotificationServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/notification/NotificationStore.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/notification/NotificationStore.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/notification/NotificationStore.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/notification/NotificationStore.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/notification/RelationshipNotificationManagementService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/notification/RelationshipNotificationManagementService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/notification/RelationshipNotificationManagementService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/notification/RelationshipNotificationManagementService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/notification/RelationshipNotificationManagementServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/notification/RelationshipNotificationManagementServiceImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/notification/RelationshipNotificationManagementServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/notification/RelationshipNotificationManagementServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/post/DefaultPostContentFormatter.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/post/DefaultPostContentFormatter.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/post/DefaultPostContentFormatter.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/post/DefaultPostContentFormatter.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/post/FormattedPostContent.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/post/FormattedPostContent.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/post/FormattedPostContent.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/post/FormattedPostContent.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostContentFormatter.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostContentFormatter.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/post/PostContentFormatter.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostContentFormatter.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostCreateDto.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostCreateDto.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/post/PostCreateDto.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostCreateDto.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/post/PostService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImpl.kt similarity index 95% rename from src/main/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImpl.kt index 24b24aa1..057a5224 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImpl.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImpl.kt @@ -17,7 +17,6 @@ package dev.usbharu.hideout.core.service.relationship import dev.usbharu.hideout.activitypub.service.activity.accept.ApSendAcceptService -import dev.usbharu.hideout.activitypub.service.activity.block.APSendBlockService import dev.usbharu.hideout.activitypub.service.activity.follow.APSendFollowService import dev.usbharu.hideout.activitypub.service.activity.reject.ApSendRejectService import dev.usbharu.hideout.activitypub.service.activity.undo.APSendUndoService @@ -39,12 +38,11 @@ class RelationshipServiceImpl( private val applicationConfig: ApplicationConfig, private val relationshipRepository: RelationshipRepository, private val apSendFollowService: APSendFollowService, - private val apSendBlockService: APSendBlockService, private val apSendAcceptService: ApSendAcceptService, private val apSendRejectService: ApSendRejectService, private val apSendUndoService: APSendUndoService, private val actorRepository: ActorRepository, - private val notificationService: NotificationService + private val notificationService: NotificationService, ) : RelationshipService { override suspend fun followRequest(actorId: Long, targetId: Long) { logger.info("START Follow Request userId: {} targetId: {}", actorId, targetId) @@ -145,12 +143,6 @@ class RelationshipServiceImpl( if (blockedInverseRelationship != null) { relationshipRepository.save(blockedInverseRelationship) } - - val remoteUser = isRemoteUser(targetId) - - if (remoteUser != null) { - apSendBlockService.sendBlock(user, remoteUser) - } } override suspend fun acceptFollowRequest(actorId: Long, targetId: Long, force: Boolean) { @@ -298,12 +290,6 @@ class RelationshipServiceImpl( val copy = relationship.copy(blocking = false) relationshipRepository.save(copy) - - val remoteUser = isRemoteUser(targetId) - if (remoteUser != null) { - val user = actorRepository.findById(actorId) ?: throw UserNotFoundException.withId(actorId) - apSendUndoService.sendUndoBlock(user, remoteUser) - } } override suspend fun mute(actorId: Long, targetId: Long) { diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/resource/CacheManager.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/resource/CacheManager.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/resource/CacheManager.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/resource/CacheManager.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/resource/InMemoryCacheManager.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/resource/InMemoryCacheManager.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/resource/InMemoryCacheManager.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/resource/InMemoryCacheManager.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/resource/KtorResolveResponse.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/resource/KtorResolveResponse.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/resource/KtorResolveResponse.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/resource/KtorResolveResponse.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/resource/KtorResourceResolveService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/resource/KtorResourceResolveService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/resource/KtorResourceResolveService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/resource/KtorResourceResolveService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/resource/ResolveResponse.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/resource/ResolveResponse.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/resource/ResolveResponse.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/resource/ResolveResponse.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/resource/ResourceResolveService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/resource/ResourceResolveService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/resource/ResourceResolveService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/resource/ResourceResolveService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/timeline/ExposedGenerateTimelineService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/timeline/ExposedGenerateTimelineService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/timeline/ExposedGenerateTimelineService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/timeline/ExposedGenerateTimelineService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/timeline/GenerateTimelineService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/timeline/GenerateTimelineService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/timeline/GenerateTimelineService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/timeline/GenerateTimelineService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/timeline/MongoGenerateTimelineService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/timeline/MongoGenerateTimelineService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/timeline/MongoGenerateTimelineService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/timeline/MongoGenerateTimelineService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/timeline/TimelineService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/timeline/TimelineService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/timeline/TimelineService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/timeline/TimelineService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/user/RemoteUserCreateDto.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/user/RemoteUserCreateDto.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/user/RemoteUserCreateDto.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/user/RemoteUserCreateDto.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UpdateUserDto.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/user/UpdateUserDto.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/user/UpdateUserDto.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/user/UpdateUserDto.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserAuthService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserAuthService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/user/UserAuthService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserAuthService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserAuthServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserAuthServiceImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/user/UserAuthServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserAuthServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserCreateDto.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserCreateDto.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/user/UserCreateDto.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserCreateDto.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/user/UserService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/generate/JsonOrFormBind.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/generate/JsonOrFormBind.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/generate/JsonOrFormBind.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/generate/JsonOrFormBind.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/generate/JsonOrFormModelMethodProcessor.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/generate/JsonOrFormModelMethodProcessor.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/generate/JsonOrFormModelMethodProcessor.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/generate/JsonOrFormModelMethodProcessor.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/config/MastodonApiSecurityConfig.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/config/MastodonApiSecurityConfig.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/config/MastodonApiSecurityConfig.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/config/MastodonApiSecurityConfig.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/exception/AccountNotFoundException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/exception/AccountNotFoundException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/domain/exception/AccountNotFoundException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/exception/AccountNotFoundException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/exception/ClientException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/exception/ClientException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/domain/exception/ClientException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/exception/ClientException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/exception/MastodonApiException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/exception/MastodonApiException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/domain/exception/MastodonApiException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/exception/MastodonApiException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/exception/ServerException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/exception/ServerException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/domain/exception/ServerException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/exception/ServerException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/exception/StatusNotFoundException.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/exception/StatusNotFoundException.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/domain/exception/StatusNotFoundException.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/exception/StatusNotFoundException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/model/MastodonApiErrorResponse.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/model/MastodonApiErrorResponse.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/domain/model/MastodonApiErrorResponse.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/model/MastodonApiErrorResponse.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/model/MastodonNotification.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/model/MastodonNotification.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/domain/model/MastodonNotification.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/model/MastodonNotification.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/model/MastodonNotificationRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/model/MastodonNotificationRepository.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/domain/model/MastodonNotificationRepository.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/model/MastodonNotificationRepository.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/model/NotificationType.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/model/NotificationType.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/domain/model/NotificationType.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/domain/model/NotificationType.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/AccountQueryServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/AccountQueryServiceImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/AccountQueryServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/AccountQueryServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/StatusQueryServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/StatusQueryServiceImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/StatusQueryServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/StatusQueryServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedrepository/ExposedMastodonNotificationRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedrepository/ExposedMastodonNotificationRepository.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedrepository/ExposedMastodonNotificationRepository.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedrepository/ExposedMastodonNotificationRepository.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/mongorepository/MongoMastodonNotificationRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/mongorepository/MongoMastodonNotificationRepository.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/mongorepository/MongoMastodonNotificationRepository.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/mongorepository/MongoMastodonNotificationRepository.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/mongorepository/MongoMastodonNotificationRepositoryWrapper.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/mongorepository/MongoMastodonNotificationRepositoryWrapper.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/mongorepository/MongoMastodonNotificationRepositoryWrapper.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/mongorepository/MongoMastodonNotificationRepositoryWrapper.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/springweb/MastodonApiControllerAdvice.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/springweb/MastodonApiControllerAdvice.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/springweb/MastodonApiControllerAdvice.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/springweb/MastodonApiControllerAdvice.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/account/MastodonAccountApiController.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/account/MastodonAccountApiController.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/account/MastodonAccountApiController.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/account/MastodonAccountApiController.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/apps/MastodonAppsApiController.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/apps/MastodonAppsApiController.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/apps/MastodonAppsApiController.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/apps/MastodonAppsApiController.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/filter/MastodonFilterApiController.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/filter/MastodonFilterApiController.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/filter/MastodonFilterApiController.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/filter/MastodonFilterApiController.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/instance/MastodonInstanceApiController.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/instance/MastodonInstanceApiController.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/instance/MastodonInstanceApiController.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/instance/MastodonInstanceApiController.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/media/MastodonMediaApiController.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/media/MastodonMediaApiController.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/media/MastodonMediaApiController.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/media/MastodonMediaApiController.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/media/MediaRequest.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/media/MediaRequest.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/media/MediaRequest.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/media/MediaRequest.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/notification/MastodonNotificationApiController.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/notification/MastodonNotificationApiController.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/notification/MastodonNotificationApiController.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/notification/MastodonNotificationApiController.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/status/MastodonStatusesApiContoller.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/status/MastodonStatusesApiContoller.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/status/MastodonStatusesApiContoller.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/status/MastodonStatusesApiContoller.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/status/StatusQuery.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/status/StatusQuery.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/status/StatusQuery.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/status/StatusQuery.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/status/StatusesRequest.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/status/StatusesRequest.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/status/StatusesRequest.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/status/StatusesRequest.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/timeline/MastodonTimelineApiController.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/timeline/MastodonTimelineApiController.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/timeline/MastodonTimelineApiController.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/timeline/MastodonTimelineApiController.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/query/AccountQueryService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/query/AccountQueryService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/query/AccountQueryService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/query/AccountQueryService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/query/StatusQueryService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/query/StatusQueryService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/query/StatusQueryService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/query/StatusQueryService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/app/AppApiService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/service/app/AppApiService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/service/app/AppApiService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/service/app/AppApiService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/filter/MastodonFilterApiService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/service/filter/MastodonFilterApiService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/service/filter/MastodonFilterApiService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/service/filter/MastodonFilterApiService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/instance/InstanceApiService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/service/instance/InstanceApiService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/service/instance/InstanceApiService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/service/instance/InstanceApiService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/media/MediaApiService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/service/media/MediaApiService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/service/media/MediaApiService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/service/media/MediaApiService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/media/MediaApiServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/service/media/MediaApiServiceImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/service/media/MediaApiServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/service/media/MediaApiServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/notification/MastodonNotificationStore.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/service/notification/MastodonNotificationStore.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/service/notification/MastodonNotificationStore.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/service/notification/MastodonNotificationStore.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/notification/NotificationApiService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/service/notification/NotificationApiService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/service/notification/NotificationApiService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/service/notification/NotificationApiService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/notification/NotificationApiServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/service/notification/NotificationApiServiceImpl.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/service/notification/NotificationApiServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/service/notification/NotificationApiServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/status/StatusesApiService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/service/status/StatusesApiService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/service/status/StatusesApiService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/service/status/StatusesApiService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/timeline/TimelineApiService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/service/timeline/TimelineApiService.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/mastodon/service/timeline/TimelineApiService.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/mastodon/service/timeline/TimelineApiService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/util/AcctUtil.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/util/AcctUtil.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/util/AcctUtil.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/util/AcctUtil.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/util/Base64Util.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/util/Base64Util.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/util/Base64Util.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/util/Base64Util.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/util/CollectionUtil.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/util/CollectionUtil.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/util/CollectionUtil.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/util/CollectionUtil.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/util/EmojiUtil.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/util/EmojiUtil.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/util/EmojiUtil.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/util/EmojiUtil.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/util/HttpUtil.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/util/HttpUtil.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/util/HttpUtil.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/util/HttpUtil.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/util/InstantParseUtil.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/util/InstantParseUtil.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/util/InstantParseUtil.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/util/InstantParseUtil.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/util/LruCache.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/util/LruCache.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/util/LruCache.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/util/LruCache.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/util/RsaUtil.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/util/RsaUtil.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/util/RsaUtil.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/util/RsaUtil.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/util/ServerUtil.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/util/ServerUtil.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/util/ServerUtil.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/util/ServerUtil.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/util/TempFileUtil.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/util/TempFileUtil.kt similarity index 100% rename from src/main/kotlin/dev/usbharu/hideout/util/TempFileUtil.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/util/TempFileUtil.kt diff --git a/src/main/resources/META-INF/native-image/jni-config.json b/hideout-core/src/main/resources/META-INF/native-image/jni-config.json similarity index 100% rename from src/main/resources/META-INF/native-image/jni-config.json rename to hideout-core/src/main/resources/META-INF/native-image/jni-config.json diff --git a/src/main/resources/META-INF/native-image/predefined-classes-config.json b/hideout-core/src/main/resources/META-INF/native-image/predefined-classes-config.json similarity index 100% rename from src/main/resources/META-INF/native-image/predefined-classes-config.json rename to hideout-core/src/main/resources/META-INF/native-image/predefined-classes-config.json diff --git a/src/main/resources/META-INF/native-image/proxy-config.json b/hideout-core/src/main/resources/META-INF/native-image/proxy-config.json similarity index 100% rename from src/main/resources/META-INF/native-image/proxy-config.json rename to hideout-core/src/main/resources/META-INF/native-image/proxy-config.json diff --git a/src/main/resources/META-INF/native-image/reflect-config.json b/hideout-core/src/main/resources/META-INF/native-image/reflect-config.json similarity index 100% rename from src/main/resources/META-INF/native-image/reflect-config.json rename to hideout-core/src/main/resources/META-INF/native-image/reflect-config.json diff --git a/src/main/resources/META-INF/native-image/resource-config.json b/hideout-core/src/main/resources/META-INF/native-image/resource-config.json similarity index 100% rename from src/main/resources/META-INF/native-image/resource-config.json rename to hideout-core/src/main/resources/META-INF/native-image/resource-config.json diff --git a/src/main/resources/META-INF/native-image/serialization-config.json b/hideout-core/src/main/resources/META-INF/native-image/serialization-config.json similarity index 100% rename from src/main/resources/META-INF/native-image/serialization-config.json rename to hideout-core/src/main/resources/META-INF/native-image/serialization-config.json diff --git a/src/main/resources/application.yml b/hideout-core/src/main/resources/application.yml similarity index 96% rename from src/main/resources/application.yml rename to hideout-core/src/main/resources/application.yml index 5756484e..52bc6eba 100644 --- a/src/main/resources/application.yml +++ b/hideout-core/src/main/resources/application.yml @@ -1,6 +1,9 @@ hideout: - url: "https://test-hideout.usbharu.dev" + url: "https://test-hideout-dev.usbharu.dev" use-mongodb: true + owl: + producer: + standalone: embedded security: jwt: generate: true diff --git a/src/main/resources/db/migration/V1707799249__Filter.sql b/hideout-core/src/main/resources/db/migration/V1707799249__Filter.sql similarity index 100% rename from src/main/resources/db/migration/V1707799249__Filter.sql rename to hideout-core/src/main/resources/db/migration/V1707799249__Filter.sql diff --git a/src/main/resources/db/migration/V1__Init_DB.sql b/hideout-core/src/main/resources/db/migration/V1__Init_DB.sql similarity index 100% rename from src/main/resources/db/migration/V1__Init_DB.sql rename to hideout-core/src/main/resources/db/migration/V1__Init_DB.sql diff --git a/src/main/resources/icon.png b/hideout-core/src/main/resources/icon.png similarity index 100% rename from src/main/resources/icon.png rename to hideout-core/src/main/resources/icon.png diff --git a/hideout-core/src/main/resources/log4j2.xml b/hideout-core/src/main/resources/log4j2.xml new file mode 100644 index 00000000..7c9b917d --- /dev/null +++ b/hideout-core/src/main/resources/log4j2.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/logback.xml b/hideout-core/src/main/resources/logback.xml similarity index 100% rename from src/main/resources/logback.xml rename to hideout-core/src/main/resources/logback.xml diff --git a/src/main/resources/openapi/mastodon.yaml b/hideout-core/src/main/resources/openapi/mastodon.yaml similarity index 100% rename from src/main/resources/openapi/mastodon.yaml rename to hideout-core/src/main/resources/openapi/mastodon.yaml diff --git a/src/main/resources/templates/sign_up.html b/hideout-core/src/main/resources/templates/sign_up.html similarity index 100% rename from src/main/resources/templates/sign_up.html rename to hideout-core/src/main/resources/templates/sign_up.html diff --git a/src/test/kotlin/dev/usbharu/hideout/EqualsAndToStringTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/EqualsAndToStringTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/EqualsAndToStringTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/EqualsAndToStringTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/AnnounceTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/AnnounceTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/AnnounceTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/AnnounceTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/CreateTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/CreateTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/CreateTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/CreateTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/DeleteSerializeTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/DeleteSerializeTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/DeleteSerializeTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/DeleteSerializeTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/DocumentTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/DocumentTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/DocumentTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/DocumentTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/JsonLdSerializeTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/JsonLdSerializeTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/JsonLdSerializeTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/JsonLdSerializeTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/KeySerializeTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/KeySerializeTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/KeySerializeTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/KeySerializeTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/NoteSerializeTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/NoteSerializeTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/NoteSerializeTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/NoteSerializeTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/PersonSerializeTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/PersonSerializeTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/PersonSerializeTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/PersonSerializeTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/RejectTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/RejectTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/RejectTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/RejectTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/UndoTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/UndoTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/UndoTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/UndoTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/objects/ObjectSerializeTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/objects/ObjectSerializeTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/objects/ObjectSerializeTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/objects/ObjectSerializeTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/actor/ActorAPControllerImplTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/actor/ActorAPControllerImplTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/actor/ActorAPControllerImplTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/actor/ActorAPControllerImplTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxControllerImplTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxControllerImplTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxControllerImplTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxControllerImplTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/note/NoteApControllerImplTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/note/NoteApControllerImplTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/note/NoteApControllerImplTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/note/NoteApControllerImplTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/outbox/OutboxControllerImplTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/outbox/OutboxControllerImplTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/outbox/OutboxControllerImplTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/outbox/OutboxControllerImplTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/webfinger/WebFingerControllerTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/webfinger/WebFingerControllerTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/webfinger/WebFingerControllerTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/webfinger/WebFingerControllerTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApAcceptProcessorTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApAcceptProcessorTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApAcceptProcessorTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApAcceptProcessorTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APSendFollowServiceImplTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APSendFollowServiceImplTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APSendFollowServiceImplTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APSendFollowServiceImplTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/common/APRequestServiceImplTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/service/common/APRequestServiceImplTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/activitypub/service/common/APRequestServiceImplTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/service/common/APRequestServiceImplTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/common/APResourceResolveServiceImplTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/service/common/APResourceResolveServiceImplTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/activitypub/service/common/APResourceResolveServiceImplTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/service/common/APResourceResolveServiceImplTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/common/APServiceImplTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/service/common/APServiceImplTest.kt similarity index 84% rename from src/test/kotlin/dev/usbharu/hideout/activitypub/service/common/APServiceImplTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/service/common/APServiceImplTest.kt index 39c31feb..b924baeb 100644 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/common/APServiceImplTest.kt +++ b/hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/service/common/APServiceImplTest.kt @@ -27,7 +27,7 @@ class APServiceImplTest { @Test fun `parseActivity 正常なActivityをパースできる`() { val apServiceImpl = APServiceImpl( - objectMapper = objectMapper, jobQueueParentService = mock() + objectMapper = objectMapper, owlProducer = mock() ) //language=JSON @@ -39,7 +39,7 @@ class APServiceImplTest { @Test fun `parseActivity Typeが配列のActivityをパースできる`() { val apServiceImpl = APServiceImpl( - objectMapper = objectMapper, jobQueueParentService = mock() + objectMapper = objectMapper, owlProducer = mock() ) //language=JSON @@ -51,7 +51,7 @@ class APServiceImplTest { @Test fun `parseActivity Typeが配列で関係ない物が入っていてもパースできる`() { val apServiceImpl = APServiceImpl( - objectMapper = objectMapper, jobQueueParentService = mock() + objectMapper = objectMapper, owlProducer = mock() ) //language=JSON @@ -64,7 +64,7 @@ class APServiceImplTest { fun `parseActivity jsonとして解釈できない場合JsonParseExceptionがthrowされる`() { val apServiceImpl = APServiceImpl( - objectMapper = objectMapper, jobQueueParentService = mock() + objectMapper = objectMapper, owlProducer = mock() ) //language=JSON @@ -77,7 +77,7 @@ class APServiceImplTest { fun `parseActivity 空の場合JsonParseExceptionがthrowされる`() { val apServiceImpl = APServiceImpl( - objectMapper = objectMapper, jobQueueParentService = mock() + objectMapper = objectMapper, owlProducer = mock() ) //language=JSON @@ -90,7 +90,7 @@ class APServiceImplTest { fun `parseActivity jsonにtypeプロパティがない場合JsonParseExceptionがthrowされる`() { val apServiceImpl = APServiceImpl( - objectMapper = objectMapper, jobQueueParentService = mock() + objectMapper = objectMapper, owlProducer = mock() ) //language=JSON @@ -103,7 +103,7 @@ class APServiceImplTest { fun `parseActivity typeが配列でないときtypeが未定義の場合IllegalArgumentExceptionがthrowされる`() { val apServiceImpl = APServiceImpl( - objectMapper = objectMapper, jobQueueParentService = mock() + objectMapper = objectMapper, owlProducer = mock() ) //language=JSON @@ -116,7 +116,7 @@ class APServiceImplTest { fun `parseActivity typeが配列のとき定義済みのtypeを見つけられなかった場合IllegalArgumentExceptionがthrowされる`() { val apServiceImpl = APServiceImpl( - objectMapper = objectMapper, jobQueueParentService = mock() + objectMapper = objectMapper, owlProducer = mock() ) //language=JSON @@ -129,7 +129,7 @@ class APServiceImplTest { fun `parseActivity typeが空の場合IllegalArgumentExceptionがthrowされる`() { val apServiceImpl = APServiceImpl( - objectMapper = objectMapper, jobQueueParentService = mock() + objectMapper = objectMapper, owlProducer = mock() ) //language=JSON @@ -142,7 +142,7 @@ class APServiceImplTest { fun `parseActivity typeに指定されている文字の判定がcase-insensitiveで行われる`() { val apServiceImpl = APServiceImpl( - objectMapper = objectMapper, jobQueueParentService = mock() + objectMapper = objectMapper, owlProducer = mock() ) //language=JSON @@ -155,7 +155,7 @@ class APServiceImplTest { fun `parseActivity typeが配列のとき指定されている文字の判定がcase-insensitiveで行われる`() { val apServiceImpl = APServiceImpl( - objectMapper = objectMapper, jobQueueParentService = mock() + objectMapper = objectMapper, owlProducer = mock() ) //language=JSON @@ -168,7 +168,7 @@ class APServiceImplTest { fun `parseActivity activityがarrayのときJsonParseExceptionがthrowされる`() { val apServiceImpl = APServiceImpl( - objectMapper = objectMapper, jobQueueParentService = mock() + objectMapper = objectMapper, owlProducer = mock() ) //language=JSON @@ -181,7 +181,7 @@ class APServiceImplTest { fun `parseActivity activityがvalueのときJsonParseExceptionがthrowされる`() { val apServiceImpl = APServiceImpl( - objectMapper = objectMapper, jobQueueParentService = mock() + objectMapper = objectMapper, owlProducer = mock() ) //language=JSON diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteServiceImplTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteServiceImplTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteServiceImplTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteServiceImplTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/ApNoteJobServiceImplTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/ApNoteJobServiceImplTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/ApNoteJobServiceImplTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/ApNoteJobServiceImplTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/ap/ContextDeserializerTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/ap/ContextDeserializerTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/ap/ContextDeserializerTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/ap/ContextDeserializerTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/ap/ContextSerializerTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/ap/ContextSerializerTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/ap/ContextSerializerTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/ap/ContextSerializerTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ExposedPaginationExtensionKtTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ExposedPaginationExtensionKtTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ExposedPaginationExtensionKtTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ExposedPaginationExtensionKtTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/PageTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/PageTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/PageTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/PageTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/PaginationListKtTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/PaginationListKtTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/PaginationListKtTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/PaginationListKtTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/application/service/id/TwitterSnowflakeIdGenerateServiceTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/application/service/id/TwitterSnowflakeIdGenerateServiceTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/application/service/id/TwitterSnowflakeIdGenerateServiceTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/application/service/id/TwitterSnowflakeIdGenerateServiceTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/application/service/init/MetaServiceImplTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/application/service/init/MetaServiceImplTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/application/service/init/MetaServiceImplTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/application/service/init/MetaServiceImplTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/application/service/init/ServerInitialiseServiceImplTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/application/service/init/ServerInitialiseServiceImplTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/application/service/init/ServerInitialiseServiceImplTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/application/service/init/ServerInitialiseServiceImplTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/core/domain/model/actor/ActorTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/domain/model/actor/ActorTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/core/domain/model/actor/ActorTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/core/domain/model/actor/ActorTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureHeaderCheckerTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureHeaderCheckerTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureHeaderCheckerTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureHeaderCheckerTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/filter/MuteProcessServiceImplTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/filter/MuteProcessServiceImplTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/core/service/filter/MuteProcessServiceImplTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/filter/MuteProcessServiceImplTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/filter/MuteServiceImplTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/filter/MuteServiceImplTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/core/service/filter/MuteServiceImplTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/filter/MuteServiceImplTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/media/ApatcheTikaFileTypeDeterminationServiceTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/media/ApatcheTikaFileTypeDeterminationServiceTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/core/service/media/ApatcheTikaFileTypeDeterminationServiceTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/media/ApatcheTikaFileTypeDeterminationServiceTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/media/LocalFileSystemMediaDataStoreTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/media/LocalFileSystemMediaDataStoreTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/core/service/media/LocalFileSystemMediaDataStoreTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/media/LocalFileSystemMediaDataStoreTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/media/MediaServiceImplTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/media/MediaServiceImplTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/core/service/media/MediaServiceImplTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/media/MediaServiceImplTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/notification/FollowNotificationRequestTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/notification/FollowNotificationRequestTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/core/service/notification/FollowNotificationRequestTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/notification/FollowNotificationRequestTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/notification/FollowRequestNotificationRequestTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/notification/FollowRequestNotificationRequestTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/core/service/notification/FollowRequestNotificationRequestTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/notification/FollowRequestNotificationRequestTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/notification/MentionNotificationRequestTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/notification/MentionNotificationRequestTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/core/service/notification/MentionNotificationRequestTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/notification/MentionNotificationRequestTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/notification/NotificationServiceImplTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/notification/NotificationServiceImplTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/core/service/notification/NotificationServiceImplTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/notification/NotificationServiceImplTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/notification/PostNotificationRequestTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/notification/PostNotificationRequestTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/core/service/notification/PostNotificationRequestTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/notification/PostNotificationRequestTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/notification/ReactionNotificationRequestTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/notification/ReactionNotificationRequestTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/core/service/notification/ReactionNotificationRequestTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/notification/ReactionNotificationRequestTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/notification/RelationshipNotificationManagementServiceImplTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/notification/RelationshipNotificationManagementServiceImplTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/core/service/notification/RelationshipNotificationManagementServiceImplTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/notification/RelationshipNotificationManagementServiceImplTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/notification/RepostNotificationRequestTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/notification/RepostNotificationRequestTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/core/service/notification/RepostNotificationRequestTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/notification/RepostNotificationRequestTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/post/DefaultPostContentFormatterTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/post/DefaultPostContentFormatterTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/core/service/post/DefaultPostContentFormatterTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/post/DefaultPostContentFormatterTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImplTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImplTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImplTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImplTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImplTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImplTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImplTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImplTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImplTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImplTest.kt similarity index 97% rename from src/test/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImplTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImplTest.kt index de976be0..4af69e07 100644 --- a/src/test/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImplTest.kt +++ b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImplTest.kt @@ -17,7 +17,6 @@ package dev.usbharu.hideout.core.service.relationship import dev.usbharu.hideout.activitypub.service.activity.accept.ApSendAcceptService -import dev.usbharu.hideout.activitypub.service.activity.block.APSendBlockService import dev.usbharu.hideout.activitypub.service.activity.follow.APSendFollowService import dev.usbharu.hideout.activitypub.service.activity.reject.ApSendRejectService import dev.usbharu.hideout.activitypub.service.activity.undo.APSendUndoService @@ -55,9 +54,6 @@ class RelationshipServiceImplTest { @Mock private lateinit var apSendFollowService: APSendFollowService - @Mock - private lateinit var apSendBlockService: APSendBlockService - @Mock private lateinit var apSendAcceptService: ApSendAcceptService @@ -272,8 +268,6 @@ class RelationshipServiceImplTest { ) ) ) - - verify(apSendBlockService, times(1)).sendBlock(eq(localUser), eq(remoteUser)) } @Test @@ -657,7 +651,6 @@ class RelationshipServiceImplTest { @Test fun `unblock ローカルユーザーの場合永続化される`() = runTest { - whenever(actorRepository.findById(eq(5678))).doReturn(UserBuilder.localUserOf(domain = "example.com")) whenever(relationshipRepository.findByUserIdAndTargetUserId(eq(1234), eq(5678))).doReturn( Relationship( actorId = 1234, @@ -685,17 +678,10 @@ class RelationshipServiceImplTest { ) ) ) - - verify(apSendUndoService, never()).sendUndoBlock(any(), any()) } @Test fun `unblock リモートユーザーの場合永続化されて配送される`() = runTest { - val localUser = UserBuilder.localUserOf(domain = "example.com") - whenever(actorRepository.findById(eq(1234))).doReturn(localUser) - - val remoteUser = UserBuilder.remoteUserOf(domain = "remote.example.com") - whenever(actorRepository.findById(eq(5678))).doReturn(remoteUser) whenever(relationshipRepository.findByUserIdAndTargetUserId(eq(1234), eq(5678))).doReturn( Relationship( @@ -724,8 +710,6 @@ class RelationshipServiceImplTest { ) ) ) - - verify(apSendUndoService, times(1)).sendUndoBlock(eq(localUser), eq(remoteUser)) } @Test diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/resource/KtorResourceResolveServiceTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/resource/KtorResourceResolveServiceTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/core/service/resource/KtorResourceResolveServiceTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/resource/KtorResourceResolveServiceTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/timeline/TimelineServiceTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/timeline/TimelineServiceTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/core/service/timeline/TimelineServiceTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/timeline/TimelineServiceTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/user/ActorServiceTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/user/ActorServiceTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/core/service/user/ActorServiceTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/core/service/user/ActorServiceTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/mastodon/domain/model/NotificationTypeTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/mastodon/domain/model/NotificationTypeTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/mastodon/domain/model/NotificationTypeTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/mastodon/domain/model/NotificationTypeTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/account/MastodonAccountApiControllerTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/account/MastodonAccountApiControllerTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/account/MastodonAccountApiControllerTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/account/MastodonAccountApiControllerTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/apps/MastodonAppsApiControllerTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/apps/MastodonAppsApiControllerTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/apps/MastodonAppsApiControllerTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/apps/MastodonAppsApiControllerTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/instance/MastodonInstanceApiControllerTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/instance/MastodonInstanceApiControllerTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/instance/MastodonInstanceApiControllerTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/instance/MastodonInstanceApiControllerTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/media/MastodonMediaApiControllerTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/media/MastodonMediaApiControllerTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/media/MastodonMediaApiControllerTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/media/MastodonMediaApiControllerTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/status/MastodonStatusesApiControllerTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/status/MastodonStatusesApiControllerTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/status/MastodonStatusesApiControllerTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/status/MastodonStatusesApiControllerTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/timeline/MastodonTimelineApiControllerTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/timeline/MastodonTimelineApiControllerTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/timeline/MastodonTimelineApiControllerTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/timeline/MastodonTimelineApiControllerTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiServiceImplTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiServiceImplTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiServiceImplTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiServiceImplTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/util/EmojiUtilTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/util/EmojiUtilTest.kt similarity index 100% rename from src/test/kotlin/dev/usbharu/hideout/util/EmojiUtilTest.kt rename to hideout-core/src/test/kotlin/dev/usbharu/hideout/util/EmojiUtilTest.kt diff --git a/src/test/kotlin/utils/JsonObjectMapper.kt b/hideout-core/src/test/kotlin/utils/JsonObjectMapper.kt similarity index 100% rename from src/test/kotlin/utils/JsonObjectMapper.kt rename to hideout-core/src/test/kotlin/utils/JsonObjectMapper.kt diff --git a/src/test/kotlin/utils/PostBuilder.kt b/hideout-core/src/test/kotlin/utils/PostBuilder.kt similarity index 100% rename from src/test/kotlin/utils/PostBuilder.kt rename to hideout-core/src/test/kotlin/utils/PostBuilder.kt diff --git a/src/test/kotlin/utils/TestApplicationConfig.kt b/hideout-core/src/test/kotlin/utils/TestApplicationConfig.kt similarity index 100% rename from src/test/kotlin/utils/TestApplicationConfig.kt rename to hideout-core/src/test/kotlin/utils/TestApplicationConfig.kt diff --git a/src/test/kotlin/utils/TestTransaction.kt b/hideout-core/src/test/kotlin/utils/TestTransaction.kt similarity index 100% rename from src/test/kotlin/utils/TestTransaction.kt rename to hideout-core/src/test/kotlin/utils/TestTransaction.kt diff --git a/src/test/kotlin/utils/UserBuilder.kt b/hideout-core/src/test/kotlin/utils/UserBuilder.kt similarity index 100% rename from src/test/kotlin/utils/UserBuilder.kt rename to hideout-core/src/test/kotlin/utils/UserBuilder.kt diff --git a/src/test/resources/400x400.png b/hideout-core/src/test/resources/400x400.png similarity index 100% rename from src/test/resources/400x400.png rename to hideout-core/src/test/resources/400x400.png diff --git a/src/test/resources/empty.conf b/hideout-core/src/test/resources/empty.conf similarity index 100% rename from src/test/resources/empty.conf rename to hideout-core/src/test/resources/empty.conf diff --git a/src/test/resources/junit-platform.properties b/hideout-core/src/test/resources/junit-platform.properties similarity index 100% rename from src/test/resources/junit-platform.properties rename to hideout-core/src/test/resources/junit-platform.properties diff --git a/templates/api.mustache b/hideout-core/templates/api.mustache similarity index 100% rename from templates/api.mustache rename to hideout-core/templates/api.mustache diff --git a/templates/apiController.mustache b/hideout-core/templates/apiController.mustache similarity index 100% rename from templates/apiController.mustache rename to hideout-core/templates/apiController.mustache diff --git a/templates/apiDelegate.mustache b/hideout-core/templates/apiDelegate.mustache similarity index 100% rename from templates/apiDelegate.mustache rename to hideout-core/templates/apiDelegate.mustache diff --git a/templates/apiInterface.mustache b/hideout-core/templates/apiInterface.mustache similarity index 100% rename from templates/apiInterface.mustache rename to hideout-core/templates/apiInterface.mustache diff --git a/templates/apiUtil.mustache b/hideout-core/templates/apiUtil.mustache similarity index 100% rename from templates/apiUtil.mustache rename to hideout-core/templates/apiUtil.mustache diff --git a/templates/api_test.mustache b/hideout-core/templates/api_test.mustache similarity index 100% rename from templates/api_test.mustache rename to hideout-core/templates/api_test.mustache diff --git a/templates/beanValidation.mustache b/hideout-core/templates/beanValidation.mustache similarity index 100% rename from templates/beanValidation.mustache rename to hideout-core/templates/beanValidation.mustache diff --git a/templates/beanValidationModel.mustache b/hideout-core/templates/beanValidationModel.mustache similarity index 100% rename from templates/beanValidationModel.mustache rename to hideout-core/templates/beanValidationModel.mustache diff --git a/templates/beanValidationPath.mustache b/hideout-core/templates/beanValidationPath.mustache similarity index 100% rename from templates/beanValidationPath.mustache rename to hideout-core/templates/beanValidationPath.mustache diff --git a/templates/beanValidationPathParams.mustache b/hideout-core/templates/beanValidationPathParams.mustache similarity index 100% rename from templates/beanValidationPathParams.mustache rename to hideout-core/templates/beanValidationPathParams.mustache diff --git a/templates/beanValidationQueryParams.mustache b/hideout-core/templates/beanValidationQueryParams.mustache similarity index 100% rename from templates/beanValidationQueryParams.mustache rename to hideout-core/templates/beanValidationQueryParams.mustache diff --git a/templates/bodyParams.mustache b/hideout-core/templates/bodyParams.mustache similarity index 100% rename from templates/bodyParams.mustache rename to hideout-core/templates/bodyParams.mustache diff --git a/templates/dataClass.mustache b/hideout-core/templates/dataClass.mustache similarity index 100% rename from templates/dataClass.mustache rename to hideout-core/templates/dataClass.mustache diff --git a/templates/dataClassOptVar.mustache b/hideout-core/templates/dataClassOptVar.mustache similarity index 100% rename from templates/dataClassOptVar.mustache rename to hideout-core/templates/dataClassOptVar.mustache diff --git a/templates/dataClassReqVar.mustache b/hideout-core/templates/dataClassReqVar.mustache similarity index 100% rename from templates/dataClassReqVar.mustache rename to hideout-core/templates/dataClassReqVar.mustache diff --git a/templates/enumClass.mustache b/hideout-core/templates/enumClass.mustache similarity index 100% rename from templates/enumClass.mustache rename to hideout-core/templates/enumClass.mustache diff --git a/templates/exceptions.mustache b/hideout-core/templates/exceptions.mustache similarity index 100% rename from templates/exceptions.mustache rename to hideout-core/templates/exceptions.mustache diff --git a/templates/formParams.mustache b/hideout-core/templates/formParams.mustache similarity index 100% rename from templates/formParams.mustache rename to hideout-core/templates/formParams.mustache diff --git a/templates/generatedAnnotation.mustache b/hideout-core/templates/generatedAnnotation.mustache similarity index 100% rename from templates/generatedAnnotation.mustache rename to hideout-core/templates/generatedAnnotation.mustache diff --git a/templates/headerParams.mustache b/hideout-core/templates/headerParams.mustache similarity index 100% rename from templates/headerParams.mustache rename to hideout-core/templates/headerParams.mustache diff --git a/templates/homeController.mustache b/hideout-core/templates/homeController.mustache similarity index 100% rename from templates/homeController.mustache rename to hideout-core/templates/homeController.mustache diff --git a/templates/interfaceOptVar.mustache b/hideout-core/templates/interfaceOptVar.mustache similarity index 100% rename from templates/interfaceOptVar.mustache rename to hideout-core/templates/interfaceOptVar.mustache diff --git a/templates/interfaceReqVar.mustache b/hideout-core/templates/interfaceReqVar.mustache similarity index 100% rename from templates/interfaceReqVar.mustache rename to hideout-core/templates/interfaceReqVar.mustache diff --git a/templates/libraries/spring-boot/README.mustache b/hideout-core/templates/libraries/spring-boot/README.mustache similarity index 100% rename from templates/libraries/spring-boot/README.mustache rename to hideout-core/templates/libraries/spring-boot/README.mustache diff --git a/templates/libraries/spring-boot/application.mustache b/hideout-core/templates/libraries/spring-boot/application.mustache similarity index 100% rename from templates/libraries/spring-boot/application.mustache rename to hideout-core/templates/libraries/spring-boot/application.mustache diff --git a/templates/libraries/spring-boot/buildGradle-sb3-Kts.mustache b/hideout-core/templates/libraries/spring-boot/buildGradle-sb3-Kts.mustache similarity index 100% rename from templates/libraries/spring-boot/buildGradle-sb3-Kts.mustache rename to hideout-core/templates/libraries/spring-boot/buildGradle-sb3-Kts.mustache diff --git a/templates/libraries/spring-boot/buildGradleKts.mustache b/hideout-core/templates/libraries/spring-boot/buildGradleKts.mustache similarity index 100% rename from templates/libraries/spring-boot/buildGradleKts.mustache rename to hideout-core/templates/libraries/spring-boot/buildGradleKts.mustache diff --git a/templates/libraries/spring-boot/defaultBasePath.mustache b/hideout-core/templates/libraries/spring-boot/defaultBasePath.mustache similarity index 100% rename from templates/libraries/spring-boot/defaultBasePath.mustache rename to hideout-core/templates/libraries/spring-boot/defaultBasePath.mustache diff --git a/templates/libraries/spring-boot/pom-sb3.mustache b/hideout-core/templates/libraries/spring-boot/pom-sb3.mustache similarity index 100% rename from templates/libraries/spring-boot/pom-sb3.mustache rename to hideout-core/templates/libraries/spring-boot/pom-sb3.mustache diff --git a/templates/libraries/spring-boot/pom.mustache b/hideout-core/templates/libraries/spring-boot/pom.mustache similarity index 100% rename from templates/libraries/spring-boot/pom.mustache rename to hideout-core/templates/libraries/spring-boot/pom.mustache diff --git a/templates/libraries/spring-boot/settingsGradle.mustache b/hideout-core/templates/libraries/spring-boot/settingsGradle.mustache similarity index 100% rename from templates/libraries/spring-boot/settingsGradle.mustache rename to hideout-core/templates/libraries/spring-boot/settingsGradle.mustache diff --git a/templates/libraries/spring-boot/springBootApplication.mustache b/hideout-core/templates/libraries/spring-boot/springBootApplication.mustache similarity index 100% rename from templates/libraries/spring-boot/springBootApplication.mustache rename to hideout-core/templates/libraries/spring-boot/springBootApplication.mustache diff --git a/templates/libraries/spring-boot/swagger-ui.mustache b/hideout-core/templates/libraries/spring-boot/swagger-ui.mustache similarity index 100% rename from templates/libraries/spring-boot/swagger-ui.mustache rename to hideout-core/templates/libraries/spring-boot/swagger-ui.mustache diff --git a/templates/libraries/spring-cloud/README.mustache b/hideout-core/templates/libraries/spring-cloud/README.mustache similarity index 100% rename from templates/libraries/spring-cloud/README.mustache rename to hideout-core/templates/libraries/spring-cloud/README.mustache diff --git a/templates/libraries/spring-cloud/apiClient.mustache b/hideout-core/templates/libraries/spring-cloud/apiClient.mustache similarity index 100% rename from templates/libraries/spring-cloud/apiClient.mustache rename to hideout-core/templates/libraries/spring-cloud/apiClient.mustache diff --git a/templates/libraries/spring-cloud/apiKeyRequestInterceptor.mustache b/hideout-core/templates/libraries/spring-cloud/apiKeyRequestInterceptor.mustache similarity index 100% rename from templates/libraries/spring-cloud/apiKeyRequestInterceptor.mustache rename to hideout-core/templates/libraries/spring-cloud/apiKeyRequestInterceptor.mustache diff --git a/templates/libraries/spring-cloud/buildGradle-sb3-Kts.mustache b/hideout-core/templates/libraries/spring-cloud/buildGradle-sb3-Kts.mustache similarity index 100% rename from templates/libraries/spring-cloud/buildGradle-sb3-Kts.mustache rename to hideout-core/templates/libraries/spring-cloud/buildGradle-sb3-Kts.mustache diff --git a/templates/libraries/spring-cloud/buildGradleKts.mustache b/hideout-core/templates/libraries/spring-cloud/buildGradleKts.mustache similarity index 100% rename from templates/libraries/spring-cloud/buildGradleKts.mustache rename to hideout-core/templates/libraries/spring-cloud/buildGradleKts.mustache diff --git a/templates/libraries/spring-cloud/clientConfiguration.mustache b/hideout-core/templates/libraries/spring-cloud/clientConfiguration.mustache similarity index 100% rename from templates/libraries/spring-cloud/clientConfiguration.mustache rename to hideout-core/templates/libraries/spring-cloud/clientConfiguration.mustache diff --git a/templates/libraries/spring-cloud/pom-sb3.mustache b/hideout-core/templates/libraries/spring-cloud/pom-sb3.mustache similarity index 100% rename from templates/libraries/spring-cloud/pom-sb3.mustache rename to hideout-core/templates/libraries/spring-cloud/pom-sb3.mustache diff --git a/templates/libraries/spring-cloud/pom.mustache b/hideout-core/templates/libraries/spring-cloud/pom.mustache similarity index 100% rename from templates/libraries/spring-cloud/pom.mustache rename to hideout-core/templates/libraries/spring-cloud/pom.mustache diff --git a/templates/libraries/spring-cloud/settingsGradle.mustache b/hideout-core/templates/libraries/spring-cloud/settingsGradle.mustache similarity index 100% rename from templates/libraries/spring-cloud/settingsGradle.mustache rename to hideout-core/templates/libraries/spring-cloud/settingsGradle.mustache diff --git a/templates/methodBody.mustache b/hideout-core/templates/methodBody.mustache similarity index 100% rename from templates/methodBody.mustache rename to hideout-core/templates/methodBody.mustache diff --git a/templates/model.mustache b/hideout-core/templates/model.mustache similarity index 100% rename from templates/model.mustache rename to hideout-core/templates/model.mustache diff --git a/templates/modelMutable.mustache b/hideout-core/templates/modelMutable.mustache similarity index 100% rename from templates/modelMutable.mustache rename to hideout-core/templates/modelMutable.mustache diff --git a/templates/openapi.mustache b/hideout-core/templates/openapi.mustache similarity index 100% rename from templates/openapi.mustache rename to hideout-core/templates/openapi.mustache diff --git a/templates/optionalDataType.mustache b/hideout-core/templates/optionalDataType.mustache similarity index 100% rename from templates/optionalDataType.mustache rename to hideout-core/templates/optionalDataType.mustache diff --git a/templates/pathParams.mustache b/hideout-core/templates/pathParams.mustache similarity index 100% rename from templates/pathParams.mustache rename to hideout-core/templates/pathParams.mustache diff --git a/templates/queryParams.mustache b/hideout-core/templates/queryParams.mustache similarity index 100% rename from templates/queryParams.mustache rename to hideout-core/templates/queryParams.mustache diff --git a/templates/returnTypes.mustache b/hideout-core/templates/returnTypes.mustache similarity index 100% rename from templates/returnTypes.mustache rename to hideout-core/templates/returnTypes.mustache diff --git a/templates/returnValue.mustache b/hideout-core/templates/returnValue.mustache similarity index 100% rename from templates/returnValue.mustache rename to hideout-core/templates/returnValue.mustache diff --git a/templates/service.mustache b/hideout-core/templates/service.mustache similarity index 100% rename from templates/service.mustache rename to hideout-core/templates/service.mustache diff --git a/templates/serviceImpl.mustache b/hideout-core/templates/serviceImpl.mustache similarity index 100% rename from templates/serviceImpl.mustache rename to hideout-core/templates/serviceImpl.mustache diff --git a/templates/springdocDocumentationConfig.mustache b/hideout-core/templates/springdocDocumentationConfig.mustache similarity index 100% rename from templates/springdocDocumentationConfig.mustache rename to hideout-core/templates/springdocDocumentationConfig.mustache diff --git a/templates/springfoxDocumentationConfig.mustache b/hideout-core/templates/springfoxDocumentationConfig.mustache similarity index 100% rename from templates/springfoxDocumentationConfig.mustache rename to hideout-core/templates/springfoxDocumentationConfig.mustache diff --git a/templates/typeInfoAnnotation.mustache b/hideout-core/templates/typeInfoAnnotation.mustache similarity index 100% rename from templates/typeInfoAnnotation.mustache rename to hideout-core/templates/typeInfoAnnotation.mustache diff --git a/hideout-worker/build.gradle.kts b/hideout-worker/build.gradle.kts new file mode 100644 index 00000000..db74eb66 --- /dev/null +++ b/hideout-worker/build.gradle.kts @@ -0,0 +1,68 @@ +plugins { + alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.kotlin.spring) + alias(libs.plugins.spring.boot) +} + +apply { + plugin("io.spring.dependency-management") +} + +group = "dev.usbharu" +version = "1.0-SNAPSHOT" + +repositories { + mavenCentral() + maven { + url = uri("https://git.usbharu.dev/api/packages/usbharu/maven") + } + maven { + name = "GitHubPackages" + url = uri("https://maven.pkg.github.com/usbharu/http-signature") + credentials { + + username = project.findProperty("gpr.user") as String? ?: System.getenv("USERNAME") + password = project.findProperty("gpr.key") as String? ?: System.getenv("TOKEN") + } + } + maven { + name = "GitHubPackages2" + url = uri("https://maven.pkg.github.com/multim-dev/emoji-kt") + credentials { + + username = project.findProperty("gpr.user") as String? ?: System.getenv("USERNAME") + password = project.findProperty("gpr.key") as String? ?: System.getenv("TOKEN") + } + } +} + +dependencies { + testImplementation(kotlin("test")) + implementation("dev.usbharu:owl-consumer:0.0.1") + implementation("dev.usbharu:owl-common:0.0.1") + implementation("dev.usbharu:owl-common-serialize-jackson:0.0.1") + implementation("dev.usbharu:hideout-core:0.0.1") + implementation("dev.usbharu:http-signature:1.0.0") + implementation("org.springframework.boot:spring-boot-starter") + implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation("org.springframework.boot:spring-boot-starter-log4j2") + implementation(libs.jackson.databind) + implementation(libs.jackson.module.kotlin) + implementation(libs.bundles.coroutines) + + testImplementation("org.springframework.boot:spring-boot-starter-test") +} + +configurations { + all { + exclude("org.springframework.boot", "spring-boot-starter-logging") + exclude("ch.qos.logback", "logback-classic") + } +} + +tasks.test { + useJUnitPlatform() +} +kotlin { + jvmToolchain(21) +} \ No newline at end of file diff --git a/hideout-worker/gradle/wrapper/gradle-wrapper.jar b/hideout-worker/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000..249e5832 Binary files /dev/null and b/hideout-worker/gradle/wrapper/gradle-wrapper.jar differ diff --git a/hideout-worker/gradle/wrapper/gradle-wrapper.properties b/hideout-worker/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..cb13ebfe --- /dev/null +++ b/hideout-worker/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,9 @@ +#Fri May 03 17:39:23 JST 2024 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/hideout-worker/gradlew b/hideout-worker/gradlew new file mode 100644 index 00000000..1b6c7873 --- /dev/null +++ b/hideout-worker/gradlew @@ -0,0 +1,234 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/hideout-worker/gradlew.bat b/hideout-worker/gradlew.bat new file mode 100644 index 00000000..107acd32 --- /dev/null +++ b/hideout-worker/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/hideout-worker/settings.gradle.kts b/hideout-worker/settings.gradle.kts new file mode 100644 index 00000000..cf826ffd --- /dev/null +++ b/hideout-worker/settings.gradle.kts @@ -0,0 +1,18 @@ +plugins { + id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" +} +rootProject.name = "hideout-worker" + +dependencyResolutionManagement { + repositories { + mavenCentral() + } + + versionCatalogs { + create("libs") { + from(files("../libs.versions.toml")) + } + } +} + +includeBuild("../hideout-core") \ No newline at end of file diff --git a/hideout-worker/src/main/kotlin/dev/usbharu/hideout/HideoutWorker.kt b/hideout-worker/src/main/kotlin/dev/usbharu/hideout/HideoutWorker.kt new file mode 100644 index 00000000..3ef74a43 --- /dev/null +++ b/hideout-worker/src/main/kotlin/dev/usbharu/hideout/HideoutWorker.kt @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout + +import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.boot.context.properties.ConfigurationPropertiesScan +import org.springframework.boot.runApplication + +@SpringBootApplication +@ConfigurationPropertiesScan +class HideoutWorker + +fun main(args: Array) { + runApplication(*args) +} \ No newline at end of file diff --git a/hideout-worker/src/main/kotlin/dev/usbharu/hideout/SpringTaskRunnerLoader.kt b/hideout-worker/src/main/kotlin/dev/usbharu/hideout/SpringTaskRunnerLoader.kt new file mode 100644 index 00000000..6ff0b4a3 --- /dev/null +++ b/hideout-worker/src/main/kotlin/dev/usbharu/hideout/SpringTaskRunnerLoader.kt @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout + +import dev.usbharu.owl.consumer.TaskRunner +import dev.usbharu.owl.consumer.TaskRunnerLoader +import org.springframework.stereotype.Component + +@Component +class SpringTaskRunnerLoader(private val taskRunners: List) : TaskRunnerLoader { + override fun load(): Map = taskRunners.associateBy { it.name } +} \ No newline at end of file diff --git a/hideout-worker/src/main/kotlin/dev/usbharu/hideout/WorkerRunner.kt b/hideout-worker/src/main/kotlin/dev/usbharu/hideout/WorkerRunner.kt new file mode 100644 index 00000000..47f0b98e --- /dev/null +++ b/hideout-worker/src/main/kotlin/dev/usbharu/hideout/WorkerRunner.kt @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout + +import com.fasterxml.jackson.databind.ObjectMapper +import dev.usbharu.hideout.worker.SpringConsumerConfig +import dev.usbharu.owl.common.property.* +import dev.usbharu.owl.consumer.StandaloneConsumer +import dev.usbharu.owl.consumer.StandaloneConsumerConfig +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import org.springframework.beans.factory.annotation.Qualifier +import org.springframework.boot.ApplicationArguments +import org.springframework.boot.ApplicationRunner +import org.springframework.stereotype.Component + +@Component +class WorkerRunner( + private val springTaskRunnerLoader: SpringTaskRunnerLoader, + @Qualifier("activitypub") private val objectMapper: ObjectMapper, + private val springCConsumerConfig: SpringConsumerConfig, +) : ApplicationRunner { + override fun run(args: ApplicationArguments?) { + GlobalScope.launch(Dispatchers.Default) { + val consumer = StandaloneConsumer( + taskRunnerLoader = springTaskRunnerLoader, + propertySerializerFactory = CustomPropertySerializerFactory( + setOf( + IntegerPropertySerializer(), + StringPropertyValueSerializer(), + DoublePropertySerializer(), + BooleanPropertySerializer(), + LongPropertySerializer(), + FloatPropertySerializer(), + ObjectPropertySerializer(objectMapper), + ) + ), + config = StandaloneConsumerConfig( + springCConsumerConfig.address, + springCConsumerConfig.port, + springCConsumerConfig.name, + springCConsumerConfig.hostname, + springCConsumerConfig.concurrency + ) + ) + consumer.init() + consumer.start() + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APDeliverAcceptJobProcessor.kt b/hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/DeliverAcceptTaskRunner.kt similarity index 50% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APDeliverAcceptJobProcessor.kt rename to hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/DeliverAcceptTaskRunner.kt index 466824b4..b557e259 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APDeliverAcceptJobProcessor.kt +++ b/hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/DeliverAcceptTaskRunner.kt @@ -14,27 +14,33 @@ * limitations under the License. */ -package dev.usbharu.hideout.activitypub.service.activity.accept +package dev.usbharu.hideout.worker import dev.usbharu.hideout.activitypub.service.common.APRequestService import dev.usbharu.hideout.application.external.Transaction import dev.usbharu.hideout.core.domain.model.actor.ActorRepository -import dev.usbharu.hideout.core.external.job.DeliverAcceptJob -import dev.usbharu.hideout.core.external.job.DeliverAcceptJobParam -import dev.usbharu.hideout.core.service.job.JobProcessor -import org.springframework.stereotype.Service +import dev.usbharu.hideout.core.external.job.DeliverAcceptTask +import dev.usbharu.hideout.core.external.job.DeliverAcceptTaskDef +import dev.usbharu.owl.consumer.AbstractTaskRunner +import dev.usbharu.owl.consumer.TaskRequest +import dev.usbharu.owl.consumer.TaskResult +import org.springframework.stereotype.Component -@Service -class APDeliverAcceptJobProcessor( +@Component +class DeliverAcceptTaskRunner( private val apRequestService: APRequestService, - private val deliverAcceptJob: DeliverAcceptJob, + private val actorRepository: ActorRepository, private val transaction: Transaction, - private val actorRepository: ActorRepository -) : - JobProcessor { - override suspend fun process(param: DeliverAcceptJobParam): Unit = transaction.transaction { - apRequestService.apPost(param.inbox, param.accept, actorRepository.findById(param.signer)) - } +) : AbstractTaskRunner(DeliverAcceptTaskDef) { + override suspend fun typedRun(typedParam: DeliverAcceptTask, taskRequest: TaskRequest): TaskResult { - override fun job(): DeliverAcceptJob = deliverAcceptJob -} + transaction.transaction { + apRequestService.apPost( + typedParam.inbox, + typedParam.accept, + actorRepository.findById(typedParam.signer) + ) + } + return TaskResult.ok() + } +} \ No newline at end of file diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APDeliverUndoJobProcessor.kt b/hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/DeliverCreateTaskRunner.kt similarity index 51% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APDeliverUndoJobProcessor.kt rename to hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/DeliverCreateTaskRunner.kt index c72ee374..7780d00d 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APDeliverUndoJobProcessor.kt +++ b/hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/DeliverCreateTaskRunner.kt @@ -14,26 +14,31 @@ * limitations under the License. */ -package dev.usbharu.hideout.activitypub.service.activity.undo +package dev.usbharu.hideout.worker import dev.usbharu.hideout.activitypub.service.common.APRequestService import dev.usbharu.hideout.application.external.Transaction import dev.usbharu.hideout.core.domain.model.actor.ActorRepository -import dev.usbharu.hideout.core.external.job.DeliverUndoJob -import dev.usbharu.hideout.core.external.job.DeliverUndoJobParam -import dev.usbharu.hideout.core.service.job.JobProcessor -import org.springframework.stereotype.Service +import dev.usbharu.hideout.core.external.job.DeliverCreateTask +import dev.usbharu.hideout.core.external.job.DeliverCreateTaskDef +import dev.usbharu.owl.consumer.AbstractTaskRunner +import dev.usbharu.owl.consumer.TaskRequest +import dev.usbharu.owl.consumer.TaskResult +import org.springframework.stereotype.Component -@Service -class APDeliverUndoJobProcessor( - private val deliverUndoJob: DeliverUndoJob, - private val apRequestService: APRequestService, +@Component +class DeliverCreateTaskRunner( private val transaction: Transaction, - private val actorRepository: ActorRepository -) : JobProcessor { - override suspend fun process(param: DeliverUndoJobParam): Unit = transaction.transaction { - apRequestService.apPost(param.inbox, param.undo, actorRepository.findById(param.signer)) - } + private val apRequestService: APRequestService, + private val actorRepository: ActorRepository, +) : AbstractTaskRunner(DeliverCreateTaskDef) { + override suspend fun typedRun(typedParam: DeliverCreateTask, taskRequest: TaskRequest): TaskResult { + transaction.transaction { + val signer = actorRepository.findByUrl(typedParam.actor) - override fun job(): DeliverUndoJob = deliverUndoJob -} + apRequestService.apPost(typedParam.inbox, typedParam.create, signer) + } + + return TaskResult.ok() + } +} \ No newline at end of file diff --git a/hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/DeliverDeleteTaskRunner.kt b/hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/DeliverDeleteTaskRunner.kt new file mode 100644 index 00000000..92961616 --- /dev/null +++ b/hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/DeliverDeleteTaskRunner.kt @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout.worker + +import dev.usbharu.hideout.activitypub.service.common.APRequestService +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository +import dev.usbharu.hideout.core.external.job.DeliverDeleteTask +import dev.usbharu.hideout.core.external.job.DeliverDeleteTaskDef +import dev.usbharu.owl.consumer.AbstractTaskRunner +import dev.usbharu.owl.consumer.TaskRequest +import dev.usbharu.owl.consumer.TaskResult +import org.springframework.stereotype.Component + +@Component +class DeliverDeleteTaskRunner( + private val apRequestService: APRequestService, + private val actorRepository: ActorRepository, +) : + AbstractTaskRunner(DeliverDeleteTaskDef) { + override suspend fun typedRun(typedParam: DeliverDeleteTask, taskRequest: TaskRequest): TaskResult { + apRequestService.apPost(typedParam.inbox, typedParam.delete, actorRepository.findById(typedParam.signer)) + return TaskResult.ok() + } +} \ No newline at end of file diff --git a/hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/DeliverReactionTaskRunner.kt b/hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/DeliverReactionTaskRunner.kt new file mode 100644 index 00000000..6408a73c --- /dev/null +++ b/hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/DeliverReactionTaskRunner.kt @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout.worker + +import dev.usbharu.hideout.activitypub.service.common.APRequestService +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository +import dev.usbharu.hideout.core.external.job.DeliverReactionTask +import dev.usbharu.hideout.core.external.job.DeliverReactionTaskDef +import dev.usbharu.owl.consumer.AbstractTaskRunner +import dev.usbharu.owl.consumer.TaskRequest +import dev.usbharu.owl.consumer.TaskResult +import org.springframework.stereotype.Component + +@Component +class DeliverReactionTaskRunner( + private val apRequestService: APRequestService, + private val actorRepository: ActorRepository, +) : AbstractTaskRunner(DeliverReactionTaskDef) { + override suspend fun typedRun(typedParam: DeliverReactionTask, taskRequest: TaskRequest): TaskResult { + val signer = actorRepository.findByUrl(typedParam.actor) + + apRequestService.apPost( + typedParam.inbox, + typedParam.like, + signer + ) + + return TaskResult.ok() + } +} \ No newline at end of file diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeliverDeleteJobProcessor.kt b/hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/DeliverRejectTaskRunner.kt similarity index 51% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeliverDeleteJobProcessor.kt rename to hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/DeliverRejectTaskRunner.kt index 53fd000e..7558197b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeliverDeleteJobProcessor.kt +++ b/hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/DeliverRejectTaskRunner.kt @@ -14,26 +14,30 @@ * limitations under the License. */ -package dev.usbharu.hideout.activitypub.service.activity.delete +package dev.usbharu.hideout.worker import dev.usbharu.hideout.activitypub.service.common.APRequestService import dev.usbharu.hideout.application.external.Transaction import dev.usbharu.hideout.core.domain.model.actor.ActorRepository -import dev.usbharu.hideout.core.external.job.DeliverDeleteJob -import dev.usbharu.hideout.core.external.job.DeliverDeleteJobParam -import dev.usbharu.hideout.core.service.job.JobProcessor -import org.springframework.stereotype.Service +import dev.usbharu.hideout.core.external.job.DeliverRejectTask +import dev.usbharu.hideout.core.external.job.DeliverRejectTaskDef +import dev.usbharu.owl.consumer.AbstractTaskRunner +import dev.usbharu.owl.consumer.TaskRequest +import dev.usbharu.owl.consumer.TaskResult +import org.springframework.stereotype.Component -@Service -class APDeliverDeleteJobProcessor( - private val apRequestService: APRequestService, +@Component +class DeliverRejectTaskRunner( private val transaction: Transaction, - private val deliverDeleteJob: DeliverDeleteJob, - private val actorRepository: ActorRepository -) : JobProcessor { - override suspend fun process(param: DeliverDeleteJobParam): Unit = transaction.transaction { - apRequestService.apPost(param.inbox, param.delete, actorRepository.findById(param.signer)) - } + private val apRequestService: APRequestService, + private val actorRepository: ActorRepository, +) : AbstractTaskRunner(DeliverRejectTaskDef) { + override suspend fun typedRun(typedParam: DeliverRejectTask, taskRequest: TaskRequest): TaskResult { + val signer = transaction.transaction { + actorRepository.findById(typedParam.signer) + } + apRequestService.apPost(typedParam.inbox, typedParam.reject, signer) - override fun job(): DeliverDeleteJob = deliverDeleteJob -} + return TaskResult.ok() + } +} \ No newline at end of file diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/APDeliverRejectJobProcessor.kt b/hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/DeliverUndoTaskRunner.kt similarity index 55% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/APDeliverRejectJobProcessor.kt rename to hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/DeliverUndoTaskRunner.kt index 2e628d37..c811d2a6 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/APDeliverRejectJobProcessor.kt +++ b/hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/DeliverUndoTaskRunner.kt @@ -14,27 +14,30 @@ * limitations under the License. */ -package dev.usbharu.hideout.activitypub.service.activity.reject +package dev.usbharu.hideout.worker import dev.usbharu.hideout.activitypub.service.common.APRequestService import dev.usbharu.hideout.application.external.Transaction import dev.usbharu.hideout.core.domain.model.actor.ActorRepository -import dev.usbharu.hideout.core.external.job.DeliverRejectJob -import dev.usbharu.hideout.core.external.job.DeliverRejectJobParam -import dev.usbharu.hideout.core.service.job.JobProcessor +import dev.usbharu.hideout.core.external.job.DeliverUndoTask +import dev.usbharu.hideout.core.external.job.DeliverUndoTaskDef +import dev.usbharu.owl.consumer.AbstractTaskRunner +import dev.usbharu.owl.consumer.TaskRequest +import dev.usbharu.owl.consumer.TaskResult import org.springframework.stereotype.Component @Component -class APDeliverRejectJobProcessor( - private val apRequestService: APRequestService, - private val deliverRejectJob: DeliverRejectJob, +class DeliverUndoTaskRunner( private val transaction: Transaction, - private val actorRepository: ActorRepository -) : - JobProcessor { - override suspend fun process(param: DeliverRejectJobParam): Unit = transaction.transaction { - apRequestService.apPost(param.inbox, param.reject, actorRepository.findById(param.signer)) - } + private val apRequestService: APRequestService, + private val actorRepository: ActorRepository, +) : AbstractTaskRunner(DeliverUndoTaskDef) { + override suspend fun typedRun(typedParam: DeliverUndoTask, taskRequest: TaskRequest): TaskResult { + val signer = transaction.transaction { + actorRepository.findById(typedParam.signer) + } + apRequestService.apPost(typedParam.inbox, typedParam.undo, signer) - override fun job(): DeliverRejectJob = deliverRejectJob -} + return TaskResult.ok() + } +} \ No newline at end of file diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/inbox/InboxJobProcessor.kt b/hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/InboxTaskRunner.kt similarity index 79% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/inbox/InboxJobProcessor.kt rename to hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/InboxTaskRunner.kt index 9e5d0786..1a5be9a4 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/inbox/InboxJobProcessor.kt +++ b/hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/InboxTaskRunner.kt @@ -14,19 +14,17 @@ * limitations under the License. */ -package dev.usbharu.hideout.activitypub.service.inbox +package dev.usbharu.hideout.worker import com.fasterxml.jackson.core.JsonParseException import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue import dev.usbharu.hideout.activitypub.domain.model.objects.Object import dev.usbharu.hideout.activitypub.service.common.ActivityPubProcessContext import dev.usbharu.hideout.activitypub.service.common.ActivityPubProcessor import dev.usbharu.hideout.activitypub.service.objects.user.APUserService import dev.usbharu.hideout.application.external.Transaction -import dev.usbharu.hideout.core.external.job.InboxJob -import dev.usbharu.hideout.core.external.job.InboxJobParam -import dev.usbharu.hideout.core.service.job.JobProcessor +import dev.usbharu.hideout.core.external.job.InboxTask +import dev.usbharu.hideout.core.external.job.InboxTaskDef import dev.usbharu.hideout.util.RsaUtil import dev.usbharu.httpsignature.common.HttpHeaders import dev.usbharu.httpsignature.common.HttpMethod @@ -35,28 +33,85 @@ import dev.usbharu.httpsignature.common.PublicKey import dev.usbharu.httpsignature.verify.HttpSignatureVerifier import dev.usbharu.httpsignature.verify.Signature import dev.usbharu.httpsignature.verify.SignatureHeaderParser +import dev.usbharu.owl.consumer.AbstractTaskRunner +import dev.usbharu.owl.consumer.TaskRequest +import dev.usbharu.owl.consumer.TaskResult import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Value -import org.springframework.stereotype.Service +import org.springframework.stereotype.Component -@Service -class InboxJobProcessor( +@Component +class InboxTaskRunner( private val activityPubProcessorList: List>, - private val objectMapper: ObjectMapper, private val signatureHeaderParser: SignatureHeaderParser, private val signatureVerifier: HttpSignatureVerifier, private val apUserService: APUserService, - private val transaction: Transaction -) : JobProcessor { + private val objectMapper: ObjectMapper, + private val transaction: Transaction, +) : AbstractTaskRunner(InboxTaskDef) { @Value("\${hideout.debug.trace-inbox:false}") private var traceJson: Boolean = false + override suspend fun typedRun(typedParam: InboxTask, taskRequest: TaskRequest): TaskResult { + val jsonNode = objectMapper.readTree(typedParam.json) + + logger.info("START Process inbox. type: {}", typedParam.type) + if (traceJson) { + logger.trace("type: {}\njson: \n{}", typedParam.type, jsonNode.toPrettyString()) + } + + val map = typedParam.headers + + val httpRequest = typedParam.httpRequest.copy(headers = HttpHeaders(map)) + + logger.trace("Request: {}\nheaders: {}", httpRequest, map) + + val signature = parseSignatureHeader(httpRequest.headers) + + logger.debug("Has signature? {}", signature != null) + + // todo 不正なactorを取得してしまわないようにする + val verify = + signature?.let { + verifyHttpSignature( + httpRequest, + it, + transaction, + jsonNode.get("actor")?.asText() ?: signature.keyId + ) + } + ?: false + + logger.debug("Is verifying success? {}", verify) + + val activityPubProcessor = + activityPubProcessorList.firstOrNull { it.isSupported(typedParam.type) } as? ActivityPubProcessor + + if (activityPubProcessor == null) { + logger.warn("ActivityType {} is not support.", typedParam.type) + throw IllegalStateException("ActivityPubProcessor not found. type: ${typedParam.type}") + } + + val value = try { + objectMapper.treeToValue(jsonNode, activityPubProcessor.type()) + } catch (e: JsonParseException) { + logger.warn("Invalid JSON\n\n{}\n\n", jsonNode.toPrettyString()) + throw e + } + activityPubProcessor.process(ActivityPubProcessContext(value, jsonNode, httpRequest, signature, verify)) + + logger.info("SUCCESS Process inbox. type: {}", typedParam.type) + + + return TaskResult.ok() + } + private suspend fun verifyHttpSignature( httpRequest: HttpRequest, signature: Signature, transaction: Transaction, - actor: String + actor: String, ): Boolean { val requiredHeaders = when (httpRequest.method) { HttpMethod.GET -> getRequiredHeaders @@ -96,62 +151,9 @@ class InboxJobProcessor( } } - override suspend fun process(param: InboxJobParam) { - val jsonNode = objectMapper.readTree(param.json) - - logger.info("START Process inbox. type: {}", param.type) - if (traceJson) { - logger.trace("type: {}\njson: \n{}", param.type, jsonNode.toPrettyString()) - } - - val map = objectMapper.readValue>>(param.headers) - - val httpRequest = objectMapper.readValue(param.httpRequest).copy(headers = HttpHeaders(map)) - - logger.trace("Request: {}\nheaders: {}", httpRequest, map) - - val signature = parseSignatureHeader(httpRequest.headers) - - logger.debug("Has signature? {}", signature != null) - - // todo 不正なactorを取得してしまわないようにする - val verify = - signature?.let { - verifyHttpSignature( - httpRequest, - it, - transaction, - jsonNode.get("actor")?.asText() ?: signature.keyId - ) - } - ?: false - - logger.debug("Is verifying success? {}", verify) - - val activityPubProcessor = - activityPubProcessorList.firstOrNull { it.isSupported(param.type) } as? ActivityPubProcessor - - if (activityPubProcessor == null) { - logger.warn("ActivityType {} is not support.", param.type) - throw IllegalStateException("ActivityPubProcessor not found. type: ${param.type}") - } - - val value = try { - objectMapper.treeToValue(jsonNode, activityPubProcessor.type()) - } catch (e: JsonParseException) { - logger.warn("Invalid JSON\n\n{}\n\n", jsonNode.toPrettyString()) - throw e - } - activityPubProcessor.process(ActivityPubProcessContext(value, jsonNode, httpRequest, signature, verify)) - - logger.info("SUCCESS Process inbox. type: {}", param.type) - } - - override fun job(): InboxJob = InboxJob - companion object { - private val logger = LoggerFactory.getLogger(InboxJobProcessor::class.java) + private val logger = LoggerFactory.getLogger(InboxTaskRunner::class.java) private val postRequiredHeaders = listOf("(request-target)", "date", "host", "digest") private val getRequiredHeaders = listOf("(request-target)", "date", "host") } -} +} \ No newline at end of file diff --git a/hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/ReceiveFollowTaskRunner.kt b/hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/ReceiveFollowTaskRunner.kt new file mode 100644 index 00000000..458f4f4c --- /dev/null +++ b/hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/ReceiveFollowTaskRunner.kt @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout.worker + +import dev.usbharu.hideout.activitypub.service.objects.user.APUserService +import dev.usbharu.hideout.application.external.Transaction +import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository +import dev.usbharu.hideout.core.external.job.ReceiveFollowTask +import dev.usbharu.hideout.core.external.job.ReceiveFollowTaskDef +import dev.usbharu.hideout.core.service.relationship.RelationshipService +import dev.usbharu.owl.consumer.AbstractTaskRunner +import dev.usbharu.owl.consumer.TaskRequest +import dev.usbharu.owl.consumer.TaskResult +import org.springframework.stereotype.Component + +@Component +class ReceiveFollowTaskRunner( + private val transaction: Transaction, + private val apUserService: APUserService, + private val actorRepository: ActorRepository, + private val relationshipService: RelationshipService, +) : AbstractTaskRunner(ReceiveFollowTaskDef) { + override suspend fun typedRun(typedParam: ReceiveFollowTask, taskRequest: TaskRequest): TaskResult { + + transaction.transaction { + + apUserService.fetchPerson(typedParam.actor, typedParam.targetActor) + val targetEntity = actorRepository.findByUrl(typedParam.targetActor) ?: throw UserNotFoundException.withUrl( + typedParam.targetActor + ) + val followActorEntity = actorRepository.findByUrl(typedParam.follow.actor) + ?: throw UserNotFoundException.withUrl(typedParam.follow.actor) + relationshipService.followRequest(followActorEntity.id, targetEntity.id) + } + + return TaskResult.ok() + } +} \ No newline at end of file diff --git a/hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/SpringConsumerConfig.kt b/hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/SpringConsumerConfig.kt new file mode 100644 index 00000000..2fa99d6b --- /dev/null +++ b/hideout-worker/src/main/kotlin/dev/usbharu/hideout/worker/SpringConsumerConfig.kt @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout.worker + +import org.springframework.boot.context.properties.ConfigurationProperties + +@ConfigurationProperties("hideout.worker") +data class SpringConsumerConfig( + val address: String = "localhost", + val port: Int = 50051, + val name: String = "hideout-worker", + val hostname: String = "localhost", + val concurrency: Int = 10, +) diff --git a/libs.versions.toml b/libs.versions.toml new file mode 100644 index 00000000..6c326cb3 --- /dev/null +++ b/libs.versions.toml @@ -0,0 +1,92 @@ +[versions] + +kotlin = "1.9.24" +ktor = "2.3.9" +exposed = "0.50.1" +javacv-ffmpeg = "6.1.1-1.5.10" +detekt = "1.23.6" +coroutines = "1.8.1" +swagger = "2.2.6" +serialization = "1.6.3" +kjob = "0.6.0" +tika = "2.9.1" +owl = "0.0.1" +jackson = "2.15.4" + +[libraries] + +exposed-core = { module = "org.jetbrains.exposed:exposed-core", version.ref = "exposed" } +exposed-jdbc = { module = "org.jetbrains.exposed:exposed-jdbc", version.ref = "exposed" } +exposed-spring = { module = "org.jetbrains.exposed:exposed-spring-boot-starter", version.ref = "exposed" } +exposed-java-time = { module = "org.jetbrains.exposed:exposed-java-time", version.ref = "exposed" } + +cotoutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" } +cotoutines-reactor = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-reactor", version.ref = "coroutines" } +cotoutines-slf4j = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-slf4j", version.ref = "coroutines" } + +javacv = { module = "org.bytedeco:javacv", version = "1.5.10" } +javacv-ffmpeg = { module = "org.bytedeco:ffmpeg", version.ref = "javacv-ffmpeg" } + +detekt-formatting = { module = "io.gitlab.arturbosch.detekt:detekt-formatting", version.ref = "detekt" } + +ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" } +ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" } +ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" } +ktor-client-mock = { module = "io.ktor:ktor-client-client-mock", version.ref = "ktor" } +ktor-client-logging-jvm = { module = "io.ktor:ktor-client-logging-jvm", version.ref = "ktor" } +ktor-serialization-jackson = { module = "io.ktor:ktor-serialization-jackson", version.ref = "ktor" } + +spring-boot-oauth2-authorization = { module = "org.springframework.boot:spring-boot-starter-oauth2-authorization-server" } +spring-boot-oauth2-resource = { module = "org.springframework.boot:spring-boot-starter-oauth2-resource-server" } +spring-boot-oauth2-jose = { module = "org.springframework.security:spring-security-oauth2-jose" } + +spring-boot-data-mongodb = { module = "org.springframework.boot:spring-boot-starter-data-mongodb" } +spring-boot-data-mongodb-reactive = { module = "org.springframework.boot:spring-boot-starter-data-mongodb-reactive" } + +jakarta-validation = { module = "jakarta.validation:jakarta.validation-api", version = "3.0.2" } +jakarta-annotation = { module = "jakarta.annotation:jakarta.annotation-api", version = "2.1.1" } +swagger-annotations = { module = "io.swagger.core.v3:swagger-annotations", version.ref = "swagger" } +swagger-models = { module = "io.swagger.core.v3:swagger-models", version.ref = "swagger" } + +serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "serialization" } +serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization" } + +apache-tika-core = { module = "org.apache.tika:tika-core", version.ref = "tika" } +apache-tika-parsers = { module = "org.apache.tika:tika-parsers", version.ref = "tika" } + +kjon-core = { module = "org.drewcarlson:kjob-core", version.ref = "kjob" } +kjon-mongo = { module = "org.drewcarlson:kjob-mongo", version.ref = "kjob" } + +owl-producer-api = { module = "dev.usbharu:owl-producer-api", version.ref = "owl" } +owl-producer-default = { module = "dev.usbharu:owl-producer-default", version.ref = "owl" } +owl-producer-embedded = { module = "dev.usbharu:owl-producer-embedded", version.ref = "owl" } +owl-broker = { module = "dev.usbharu:owl-broker", version.ref = "owl" } +owl-broker-mongodb = { module = "dev.usbharu:owl-broker-mongodb", version.ref = "owl" } + +jackson-databind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" } +jackson-module-kotlin = { module = "com.fasterxml.jackson.module:jackson-module-kotlin", version.ref = "jackson" } + +[bundles] + +exposed = ["exposed-core", "exposed-java-time", "exposed-jdbc", "exposed-spring"] +coroutines = ["cotoutines-core", "cotoutines-reactor", "cotoutines-slf4j"] +ktor-client = ["ktor-client-cio", "ktor-client-content-negotiation", "ktor-client-core", "ktor-client-logging-jvm", "ktor-serialization-jackson"] +spring-boot-oauth2 = ["spring-boot-oauth2-authorization", "spring-boot-oauth2-jose", "spring-boot-oauth2-resource"] +spring-boot-data-mongodb = ["spring-boot-data-mongodb", "spring-boot-data-mongodb-reactive"] +openapi = ["jakarta-annotation", "jakarta-validation", "swagger-annotations", "swagger-models"] +serialization = ["serialization-core", "serialization-json"] +apache-tika = ["apache-tika-core", "apache-tika-parsers"] +kjob = ["kjon-core", "kjon-mongo"] +owl-producer = ["owl-producer-api", "owl-producer-default", "owl-producer-embedded"] +owl-broker = ["owl-broker", "owl-broker-mongodb"] +jackson = ["jackson-databind", "jackson-module-kotlin"] + +[plugins] + +kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } +spring-boot = { id = "org.springframework.boot", version = "3.2.5" } +detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" } +kotlin-spring = { id = "org.jetbrains.kotlin.plugin.spring", version.ref = "kotlin" } +kover = { id = "org.jetbrains.kotlinx.kover", version = "0.7.6" } +openapi-generator = { id = "org.openapi.generator", version = "7.4.0" } +license-report = { id = "com.github.jk1.dependency-license-report", version = "2.5" } \ No newline at end of file diff --git a/owl/.gitignore b/owl/.gitignore new file mode 100644 index 00000000..bf3e1b20 --- /dev/null +++ b/owl/.gitignore @@ -0,0 +1,43 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store +/.idea/ diff --git a/owl/.gitkeep b/owl/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/owl/build.gradle.kts b/owl/build.gradle.kts new file mode 100644 index 00000000..0e74414e --- /dev/null +++ b/owl/build.gradle.kts @@ -0,0 +1,37 @@ +plugins { + alias(libs.plugins.kotlin.jvm) +} + + +allprojects { + group = "dev.usbharu" + version = "0.0.1" + + + repositories { + mavenCentral() + } +} + +subprojects { + apply { + plugin("org.jetbrains.kotlin.jvm") + } + kotlin { + jvmToolchain(17) + } + + dependencies { + implementation("org.slf4j:slf4j-api:2.0.13") + testImplementation("org.junit.jupiter:junit-jupiter:5.10.2") + + + } + + + tasks.test { + useJUnitPlatform() + } + + +} \ No newline at end of file diff --git a/owl/gradle.properties b/owl/gradle.properties new file mode 100644 index 00000000..c02d6c9d --- /dev/null +++ b/owl/gradle.properties @@ -0,0 +1,5 @@ +kotlin.code.style=official +org.gradle.daemon=true +org.gradle.parallel=true +org.gradle.configureondemand=true + diff --git a/owl/gradle/wrapper/gradle-wrapper.jar b/owl/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000..e6441136 Binary files /dev/null and b/owl/gradle/wrapper/gradle-wrapper.jar differ diff --git a/owl/gradle/wrapper/gradle-wrapper.properties b/owl/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..b82aa23a --- /dev/null +++ b/owl/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/owl/gradlew b/owl/gradlew new file mode 100644 index 00000000..1aa94a42 --- /dev/null +++ b/owl/gradlew @@ -0,0 +1,249 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/owl/gradlew.bat b/owl/gradlew.bat new file mode 100644 index 00000000..7101f8e4 --- /dev/null +++ b/owl/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/owl/owl-broker/build.gradle.kts b/owl/owl-broker/build.gradle.kts new file mode 100644 index 00000000..1f307eaa --- /dev/null +++ b/owl/owl-broker/build.gradle.kts @@ -0,0 +1,64 @@ +plugins { + alias(libs.plugins.kotlin.jvm) + id("com.google.protobuf") version "0.9.4" + id("com.google.devtools.ksp") version "1.9.24-1.0.20" +} + +apply { + plugin("com.google.devtools.ksp") +} + + +group = "dev.usbharu" +version = "0.0.1" + +repositories { + mavenCentral() +} + +dependencies { + implementation("io.grpc:grpc-kotlin-stub:1.4.1") + implementation("io.grpc:grpc-protobuf:1.63.0") + implementation("com.google.protobuf:protobuf-kotlin:4.26.1") + implementation("io.grpc:grpc-netty:1.63.0") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1") + implementation(project(":owl-common")) + implementation("org.apache.logging.log4j:log4j-slf4j2-impl:2.23.1") + implementation(platform("io.insert-koin:koin-bom:3.5.6")) + implementation(platform("io.insert-koin:koin-annotations-bom:1.3.1")) + implementation("io.insert-koin:koin-core") + compileOnly("io.insert-koin:koin-annotations") + ksp("io.insert-koin:koin-ksp-compiler:1.3.1") +} + +tasks.test { + useJUnitPlatform() +} +kotlin { + jvmToolchain(17) +} + +protobuf { + protoc { + artifact = "com.google.protobuf:protoc:4.26.1" + } + plugins { + create("grpc") { + artifact = "io.grpc:protoc-gen-grpc-java:1.63.0" + } + create("grpckt") { + artifact = "io.grpc:protoc-gen-grpc-kotlin:1.4.1:jdk8@jar" + } + } + generateProtoTasks { + all().forEach { + it.plugins { + create("grpc") + create("grpckt") + } + it.builtins { + create("kotlin") + } + } + } +} \ No newline at end of file diff --git a/owl/owl-broker/owl-broker-mongodb/build.gradle.kts b/owl/owl-broker/owl-broker-mongodb/build.gradle.kts new file mode 100644 index 00000000..7ad79773 --- /dev/null +++ b/owl/owl-broker/owl-broker-mongodb/build.gradle.kts @@ -0,0 +1,38 @@ +plugins { + application + kotlin("jvm") + id("com.google.devtools.ksp") version "1.9.24-1.0.20" +} + +apply { + plugin("com.google.devtools.ksp") +} + +group = "dev.usbharu" +version = "0.0.1" + +repositories { + mavenCentral() +} + +dependencies { + implementation("org.mongodb:mongodb-driver-kotlin-coroutine:5.1.0") + implementation(project(":owl-broker")) + implementation(project(":owl-common")) + implementation(platform("io.insert-koin:koin-bom:3.5.6")) + implementation(platform("io.insert-koin:koin-annotations-bom:1.3.1")) + implementation("io.insert-koin:koin-core") + compileOnly("io.insert-koin:koin-annotations") + ksp("io.insert-koin:koin-ksp-compiler:1.3.1") +} + +tasks.test { + useJUnitPlatform() +} +kotlin { + jvmToolchain(17) +} + +application { + mainClass = "dev.usbharu.owl.broker.MainKt" +} \ No newline at end of file diff --git a/owl/owl-broker/owl-broker-mongodb/src/main/kotlin/dev/usbharu/owl/broker/mongodb/MongoModule.kt b/owl/owl-broker/owl-broker-mongodb/src/main/kotlin/dev/usbharu/owl/broker/mongodb/MongoModule.kt new file mode 100644 index 00000000..9b770dde --- /dev/null +++ b/owl/owl-broker/owl-broker-mongodb/src/main/kotlin/dev/usbharu/owl/broker/mongodb/MongoModule.kt @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.mongodb + +import org.koin.core.annotation.ComponentScan +import org.koin.core.annotation.Module + +@Module +@ComponentScan("dev.usbharu.owl.broker.mongodb") +class MongoModule + diff --git a/owl/owl-broker/owl-broker-mongodb/src/main/kotlin/dev/usbharu/owl/broker/mongodb/MongoModuleContext.kt b/owl/owl-broker/owl-broker-mongodb/src/main/kotlin/dev/usbharu/owl/broker/mongodb/MongoModuleContext.kt new file mode 100644 index 00000000..e3ab269b --- /dev/null +++ b/owl/owl-broker/owl-broker-mongodb/src/main/kotlin/dev/usbharu/owl/broker/mongodb/MongoModuleContext.kt @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.mongodb + +import com.mongodb.ConnectionString +import com.mongodb.MongoClientSettings +import com.mongodb.kotlin.client.coroutine.MongoClient +import dev.usbharu.owl.broker.ModuleContext +import org.bson.UuidRepresentation +import org.koin.core.module.Module +import org.koin.dsl.module +import org.koin.ksp.generated.module + +class MongoModuleContext : ModuleContext { + override fun module(): Module { + val module = MongoModule().module + module.includes(module { + single { + val clientSettings = + MongoClientSettings.builder() + .applyConnectionString( + ConnectionString( + System.getProperty( + "owl.broker.mongo.url", + "mongodb://localhost:27017" + ) + ) + ) + .uuidRepresentation(UuidRepresentation.STANDARD).build() + + + MongoClient.create(clientSettings) + .getDatabase(System.getProperty("owl.broker.mongo.database", "mongo-test")) + } + }) + return module + } +} \ No newline at end of file diff --git a/owl/owl-broker/owl-broker-mongodb/src/main/kotlin/dev/usbharu/owl/broker/mongodb/MongodbConsumerRepository.kt b/owl/owl-broker/owl-broker-mongodb/src/main/kotlin/dev/usbharu/owl/broker/mongodb/MongodbConsumerRepository.kt new file mode 100644 index 00000000..43207580 --- /dev/null +++ b/owl/owl-broker/owl-broker-mongodb/src/main/kotlin/dev/usbharu/owl/broker/mongodb/MongodbConsumerRepository.kt @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.mongodb + +import com.mongodb.client.model.Filters +import com.mongodb.client.model.ReplaceOptions +import com.mongodb.kotlin.client.coroutine.MongoDatabase +import dev.usbharu.owl.broker.domain.model.consumer.Consumer +import dev.usbharu.owl.broker.domain.model.consumer.ConsumerRepository +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.singleOrNull +import kotlinx.coroutines.withContext +import org.bson.BsonType +import org.bson.codecs.pojo.annotations.BsonId +import org.bson.codecs.pojo.annotations.BsonRepresentation +import org.koin.core.annotation.Singleton +import java.util.* + +@Singleton +class MongodbConsumerRepository(database: MongoDatabase) : ConsumerRepository { + + private val collection = database.getCollection("consumers") + override suspend fun save(consumer: Consumer): Consumer = withContext(Dispatchers.IO) { + collection.replaceOne(Filters.eq("_id", consumer.id.toString()), ConsumerMongodb.of(consumer), ReplaceOptions().upsert(true)) + return@withContext consumer + } + + override suspend fun findById(id: UUID): Consumer? = withContext(Dispatchers.IO) { + return@withContext collection.find(Filters.eq("_id", id.toString())).singleOrNull()?.toConsumer() + } +} + +data class ConsumerMongodb( + @BsonId + @BsonRepresentation(BsonType.STRING) + val id: String, + val name: String, + val hostname: String, + val tasks: List +){ + + fun toConsumer():Consumer{ + return Consumer( + UUID.fromString(id), name, hostname, tasks + ) + } + companion object{ + fun of(consumer: Consumer):ConsumerMongodb{ + return ConsumerMongodb( + consumer.id.toString(), + consumer.name, + consumer.hostname, + consumer.tasks + ) + } + } +} \ No newline at end of file diff --git a/owl/owl-broker/owl-broker-mongodb/src/main/kotlin/dev/usbharu/owl/broker/mongodb/MongodbProducerRepository.kt b/owl/owl-broker/owl-broker-mongodb/src/main/kotlin/dev/usbharu/owl/broker/mongodb/MongodbProducerRepository.kt new file mode 100644 index 00000000..3593e5f8 --- /dev/null +++ b/owl/owl-broker/owl-broker-mongodb/src/main/kotlin/dev/usbharu/owl/broker/mongodb/MongodbProducerRepository.kt @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.mongodb + +import com.mongodb.client.model.Filters +import com.mongodb.client.model.ReplaceOptions +import com.mongodb.kotlin.client.coroutine.MongoDatabase +import dev.usbharu.owl.broker.domain.model.producer.Producer +import dev.usbharu.owl.broker.domain.model.producer.ProducerRepository +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.koin.core.annotation.Singleton +import java.time.Instant +import java.util.* + +@Singleton +class MongodbProducerRepository(database: MongoDatabase) : ProducerRepository { + + private val collection = database.getCollection("producers") + + override suspend fun save(producer: Producer): Producer = withContext(Dispatchers.IO) { + collection.replaceOne( + Filters.eq("_id", producer.id.toString()), + ProducerMongodb.of(producer), + ReplaceOptions().upsert(true) + ) + return@withContext producer + } +} + +data class ProducerMongodb( + val id: String, + val name: String, + val hostname: String, + val registeredTask: List, + val createdAt: Instant +) { + fun toProducer(): Producer { + return Producer( + id = UUID.fromString(id), + name = name, + hostname = hostname, + registeredTask = registeredTask, + createdAt = createdAt + ) + } + + companion object { + fun of(producer: Producer): ProducerMongodb { + return ProducerMongodb( + id = producer.id.toString(), + name = producer.name, + hostname = producer.hostname, + registeredTask = producer.registeredTask, + createdAt = producer.createdAt + ) + } + } +} \ No newline at end of file diff --git a/owl/owl-broker/owl-broker-mongodb/src/main/kotlin/dev/usbharu/owl/broker/mongodb/MongodbQueuedTaskRepository.kt b/owl/owl-broker/owl-broker-mongodb/src/main/kotlin/dev/usbharu/owl/broker/mongodb/MongodbQueuedTaskRepository.kt new file mode 100644 index 00000000..a20f1d02 --- /dev/null +++ b/owl/owl-broker/owl-broker-mongodb/src/main/kotlin/dev/usbharu/owl/broker/mongodb/MongodbQueuedTaskRepository.kt @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.mongodb + +import com.mongodb.client.model.Filters.* +import com.mongodb.client.model.FindOneAndUpdateOptions +import com.mongodb.client.model.ReplaceOptions +import com.mongodb.client.model.ReturnDocument +import com.mongodb.client.model.Sorts +import com.mongodb.client.model.Updates.set +import com.mongodb.kotlin.client.coroutine.MongoDatabase +import dev.usbharu.owl.broker.domain.model.queuedtask.QueuedTask +import dev.usbharu.owl.broker.domain.model.queuedtask.QueuedTaskRepository +import dev.usbharu.owl.broker.domain.model.task.Task +import dev.usbharu.owl.common.property.PropertySerializeUtils +import dev.usbharu.owl.common.property.PropertySerializerFactory +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.withContext +import org.bson.BsonType +import org.bson.codecs.pojo.annotations.BsonId +import org.bson.codecs.pojo.annotations.BsonRepresentation +import org.koin.core.annotation.Singleton +import java.time.Instant +import java.util.* + +@Singleton +class MongodbQueuedTaskRepository( + private val propertySerializerFactory: PropertySerializerFactory, + database: MongoDatabase +) : QueuedTaskRepository { + + private val collection = database.getCollection("queued_task") + override suspend fun save(queuedTask: QueuedTask): QueuedTask { + withContext(Dispatchers.IO) { + collection.replaceOne( + eq("_id", queuedTask.task.id.toString()), QueuedTaskMongodb.of(propertySerializerFactory, queuedTask), + ReplaceOptions().upsert(true) + ) + } + return queuedTask + } + + override suspend fun findByTaskIdAndAssignedConsumerIsNullAndUpdate(id: UUID, update: QueuedTask): QueuedTask { + return withContext(Dispatchers.IO) { + + val findOneAndUpdate = collection.findOneAndUpdate( + and( + eq("_id", id.toString()), + eq(QueuedTaskMongodb::isActive.name, true) + ), + listOf( + set(QueuedTaskMongodb::assignedConsumer.name, update.assignedConsumer?.toString()), + set(QueuedTaskMongodb::assignedAt.name, update.assignedAt), + set(QueuedTaskMongodb::queuedAt.name, update.queuedAt), + set(QueuedTaskMongodb::isActive.name, update.isActive) + ), + FindOneAndUpdateOptions().upsert(false).returnDocument(ReturnDocument.AFTER) + ) + if (findOneAndUpdate == null) { + TODO() + } + findOneAndUpdate.toQueuedTask(propertySerializerFactory) + } + } + + override fun findByTaskNameInAndIsActiveIsTrueAndOrderByPriority( + tasks: List, + limit: Int + ): Flow { + return collection.find( + and( + `in`("task.name", tasks), + eq(QueuedTaskMongodb::isActive.name, true) + ) + ).sort(Sorts.descending("priority")).map { it.toQueuedTask(propertySerializerFactory) }.flowOn(Dispatchers.IO) + } + + override fun findByQueuedAtBeforeAndIsActiveIsTrue(instant: Instant): Flow { + return collection.find( + and( + lte(QueuedTaskMongodb::queuedAt.name, instant), + eq(QueuedTaskMongodb::isActive.name, true) + ) + ) + .map { it.toQueuedTask(propertySerializerFactory) }.flowOn(Dispatchers.IO) + } +} + +data class QueuedTaskMongodb( + @BsonId + @BsonRepresentation(BsonType.STRING) + val id: String, + val task: TaskMongodb, + val attempt: Int, + val queuedAt: Instant, + val priority:Int, + val isActive: Boolean, + val timeoutAt: Instant?, + val assignedConsumer: String?, + val assignedAt: Instant? +) { + + fun toQueuedTask(propertySerializerFactory: PropertySerializerFactory): QueuedTask { + return QueuedTask( + attempt = attempt, + queuedAt = queuedAt, + task = task.toTask(propertySerializerFactory), + priority = priority, + isActive = isActive, + timeoutAt = timeoutAt, + assignedConsumer = assignedConsumer?.let { UUID.fromString(it) }, + assignedAt = assignedAt + ) + } + + data class TaskMongodb( + val name: String, + val id: String, + val publishProducerId: String, + val publishedAt: Instant, + val nextRetry: Instant, + val completedAt: Instant?, + val attempt: Int, + val properties: Map + ) { + + fun toTask(propertySerializerFactory: PropertySerializerFactory): Task { + return Task( + name = name, + id = UUID.fromString(id), + publishProducerId = UUID.fromString(publishProducerId), + publishedAt = publishedAt, + nextRetry = nextRetry, + completedAt = completedAt, + attempt = attempt, + properties = PropertySerializeUtils.deserialize(propertySerializerFactory, properties) + ) + } + + companion object { + fun of(propertySerializerFactory: PropertySerializerFactory, task: Task): TaskMongodb { + return TaskMongodb( + task.name, + task.id.toString(), + task.publishProducerId.toString(), + task.publishedAt, + task.nextRetry, + task.completedAt, + task.attempt, + PropertySerializeUtils.serialize(propertySerializerFactory, task.properties) + ) + } + } + } + + companion object { + fun of(propertySerializerFactory: PropertySerializerFactory, queuedTask: QueuedTask): QueuedTaskMongodb { + return QueuedTaskMongodb( + queuedTask.task.id.toString(), + TaskMongodb.of(propertySerializerFactory, queuedTask.task), + queuedTask.attempt, + queuedTask.queuedAt, + queuedTask.priority, + queuedTask.isActive, + queuedTask.timeoutAt, + queuedTask.assignedConsumer?.toString(), + queuedTask.assignedAt + ) + } + } +} \ No newline at end of file diff --git a/owl/owl-broker/owl-broker-mongodb/src/main/kotlin/dev/usbharu/owl/broker/mongodb/MongodbTaskDefinitionRepository.kt b/owl/owl-broker/owl-broker-mongodb/src/main/kotlin/dev/usbharu/owl/broker/mongodb/MongodbTaskDefinitionRepository.kt new file mode 100644 index 00000000..ced2b19a --- /dev/null +++ b/owl/owl-broker/owl-broker-mongodb/src/main/kotlin/dev/usbharu/owl/broker/mongodb/MongodbTaskDefinitionRepository.kt @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.mongodb + +import com.mongodb.client.model.Filters +import com.mongodb.client.model.ReplaceOptions +import com.mongodb.kotlin.client.coroutine.MongoDatabase +import dev.usbharu.owl.broker.domain.model.taskdefinition.TaskDefinition +import dev.usbharu.owl.broker.domain.model.taskdefinition.TaskDefinitionRepository +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.singleOrNull +import kotlinx.coroutines.withContext +import org.bson.BsonType +import org.bson.codecs.pojo.annotations.BsonId +import org.bson.codecs.pojo.annotations.BsonRepresentation +import org.koin.core.annotation.Singleton + +@Singleton +class MongodbTaskDefinitionRepository(database: MongoDatabase) : TaskDefinitionRepository { + + private val collection = database.getCollection("task_definition") + override suspend fun save(taskDefinition: TaskDefinition): TaskDefinition = withContext(Dispatchers.IO) { + collection.replaceOne( + Filters.eq("_id", taskDefinition.name), + TaskDefinitionMongodb.of(taskDefinition), + ReplaceOptions().upsert(true) + ) + return@withContext taskDefinition + } + + override suspend fun deleteByName(name: String): Unit = withContext(Dispatchers.IO) { + collection.deleteOne(Filters.eq("_id",name)) + } + + override suspend fun findByName(name: String): TaskDefinition? = withContext(Dispatchers.IO) { + return@withContext collection.find(Filters.eq("_id", name)).singleOrNull()?.toTaskDefinition() + } +} + +data class TaskDefinitionMongodb( + @BsonId + @BsonRepresentation(BsonType.STRING) + val name: String, + val priority: Int, + val maxRetry: Int, + val timeoutMilli: Long, + val propertyDefinitionHash: Long, + val retryPolicy: String +) { + fun toTaskDefinition(): TaskDefinition { + return TaskDefinition( + name = name, + priority = priority, + maxRetry = maxRetry, + timeoutMilli = timeoutMilli, + propertyDefinitionHash = propertyDefinitionHash, + retryPolicy = retryPolicy + ) + } + + companion object { + fun of(taskDefinition: TaskDefinition): TaskDefinitionMongodb { + return TaskDefinitionMongodb( + name = taskDefinition.name, + priority = taskDefinition.priority, + maxRetry = taskDefinition.maxRetry, + timeoutMilli = taskDefinition.timeoutMilli, + propertyDefinitionHash = taskDefinition.propertyDefinitionHash, + retryPolicy = taskDefinition.retryPolicy + ) + } + } +} \ No newline at end of file diff --git a/owl/owl-broker/owl-broker-mongodb/src/main/kotlin/dev/usbharu/owl/broker/mongodb/MongodbTaskRepository.kt b/owl/owl-broker/owl-broker-mongodb/src/main/kotlin/dev/usbharu/owl/broker/mongodb/MongodbTaskRepository.kt new file mode 100644 index 00000000..2d7215ae --- /dev/null +++ b/owl/owl-broker/owl-broker-mongodb/src/main/kotlin/dev/usbharu/owl/broker/mongodb/MongodbTaskRepository.kt @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.mongodb + +import com.mongodb.client.model.Filters +import com.mongodb.client.model.ReplaceOneModel +import com.mongodb.client.model.ReplaceOptions +import com.mongodb.kotlin.client.coroutine.MongoDatabase +import dev.usbharu.owl.broker.domain.model.task.Task +import dev.usbharu.owl.broker.domain.model.task.TaskRepository +import dev.usbharu.owl.common.property.PropertySerializeUtils +import dev.usbharu.owl.common.property.PropertySerializerFactory +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.singleOrNull +import kotlinx.coroutines.withContext +import org.bson.BsonType +import org.bson.codecs.pojo.annotations.BsonId +import org.bson.codecs.pojo.annotations.BsonRepresentation +import org.koin.core.annotation.Singleton +import java.time.Instant +import java.util.* + +@Singleton +class MongodbTaskRepository(database: MongoDatabase, private val propertySerializerFactory: PropertySerializerFactory) : + TaskRepository { + + private val collection = database.getCollection("tasks") + override suspend fun save(task: Task): Task = withContext(Dispatchers.IO) { + collection.replaceOne( + Filters.eq("_id", task.id.toString()), TaskMongodb.of(propertySerializerFactory, task), + ReplaceOptions().upsert(true) + ) + return@withContext task + } + + override suspend fun saveAll(tasks: List): Unit = withContext(Dispatchers.IO) { + collection.bulkWrite(tasks.map { + ReplaceOneModel( + Filters.eq(it.id.toString()), + TaskMongodb.of(propertySerializerFactory, it), + ReplaceOptions().upsert(true) + ) + }) + } + + override fun findByNextRetryBeforeAndCompletedAtIsNull(timestamp: Instant): Flow { + return collection.find( + Filters.and( + Filters.lte(TaskMongodb::nextRetry.name, timestamp), + Filters.eq(TaskMongodb::completedAt.name, null) + ) + ) + .map { it.toTask(propertySerializerFactory) }.flowOn(Dispatchers.IO) + } + + override suspend fun findById(uuid: UUID): Task? = withContext(Dispatchers.IO) { + collection.find(Filters.eq(uuid.toString())).singleOrNull()?.toTask(propertySerializerFactory) + } + + override suspend fun findByIdAndUpdate(id: UUID, task: Task) { + collection.replaceOne( + Filters.eq("_id", task.id.toString()), TaskMongodb.of(propertySerializerFactory, task), + ReplaceOptions().upsert(false) + ) + } + + override suspend fun findByPublishProducerIdAndCompletedAtIsNotNull(publishProducerId: UUID): Flow { + return collection + .find(Filters.eq(TaskMongodb::publishProducerId.name, publishProducerId.toString())) + .map { it.toTask(propertySerializerFactory) } + } +} + +data class TaskMongodb( + val name: String, + @BsonId + @BsonRepresentation(BsonType.STRING) + val id: String, + val publishProducerId: String, + val publishedAt: Instant, + val nextRetry: Instant, + val completedAt: Instant?, + val attempt: Int, + val properties: Map +) { + + fun toTask(propertySerializerFactory: PropertySerializerFactory): Task { + return Task( + name = name, + id = UUID.fromString(id), + publishProducerId = UUID.fromString(publishProducerId), + publishedAt = publishedAt, + nextRetry = nextRetry, + completedAt = completedAt, + attempt = attempt, + properties = PropertySerializeUtils.deserialize(propertySerializerFactory, properties) + ) + } + + companion object { + fun of(propertySerializerFactory: PropertySerializerFactory, task: Task): TaskMongodb { + return TaskMongodb( + task.name, + task.id.toString(), + task.publishProducerId.toString(), + task.publishedAt, + task.nextRetry, + task.completedAt, + task.attempt, + PropertySerializeUtils.serialize(propertySerializerFactory, task.properties) + ) + } + } +} \ No newline at end of file diff --git a/owl/owl-broker/owl-broker-mongodb/src/main/kotlin/dev/usbharu/owl/broker/mongodb/MongodbTaskResultRepository.kt b/owl/owl-broker/owl-broker-mongodb/src/main/kotlin/dev/usbharu/owl/broker/mongodb/MongodbTaskResultRepository.kt new file mode 100644 index 00000000..ed000fe2 --- /dev/null +++ b/owl/owl-broker/owl-broker-mongodb/src/main/kotlin/dev/usbharu/owl/broker/mongodb/MongodbTaskResultRepository.kt @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.mongodb + +import com.mongodb.client.model.Filters +import com.mongodb.client.model.ReplaceOptions +import com.mongodb.kotlin.client.coroutine.MongoDatabase +import dev.usbharu.owl.broker.domain.model.taskresult.TaskResult +import dev.usbharu.owl.broker.domain.model.taskresult.TaskResultRepository +import dev.usbharu.owl.common.property.PropertySerializeUtils +import dev.usbharu.owl.common.property.PropertySerializerFactory +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.withContext +import org.bson.BsonType +import org.bson.codecs.pojo.annotations.BsonId +import org.bson.codecs.pojo.annotations.BsonRepresentation +import org.koin.core.annotation.Singleton +import java.util.* + +@Singleton +class MongodbTaskResultRepository( + database: MongoDatabase, + private val propertySerializerFactory: PropertySerializerFactory +) : TaskResultRepository { + + private val collection = database.getCollection("task_results") + override suspend fun save(taskResult: TaskResult): TaskResult = withContext(Dispatchers.IO) { + collection.replaceOne( + Filters.eq(taskResult.id.toString()), TaskResultMongodb.of(propertySerializerFactory, taskResult), + ReplaceOptions().upsert(true) + ) + return@withContext taskResult + } + + override fun findByTaskId(id: UUID): Flow { + return collection.find(Filters.eq(id.toString())).map { it.toTaskResult(propertySerializerFactory) }.flowOn(Dispatchers.IO) + } +} + +data class TaskResultMongodb( + @BsonId + @BsonRepresentation(BsonType.STRING) + val id: String, + val taskId: String, + val success: Boolean, + val attempt: Int, + val result: Map, + val message: String +) { + + fun toTaskResult(propertySerializerFactory: PropertySerializerFactory): TaskResult { + return TaskResult( + UUID.fromString(id), + UUID.fromString(taskId), + success, + attempt, + PropertySerializeUtils.deserialize(propertySerializerFactory, result), + message + ) + } + + companion object { + fun of(propertySerializerFactory: PropertySerializerFactory, taskResult: TaskResult): TaskResultMongodb { + return TaskResultMongodb( + taskResult.id.toString(), + taskResult.taskId.toString(), + taskResult.success, + taskResult.attempt, + PropertySerializeUtils.serialize(propertySerializerFactory, taskResult.result), + taskResult.message + ) + + } + + } +} \ No newline at end of file diff --git a/owl/owl-broker/owl-broker-mongodb/src/main/resources/META-INF/services/dev.usbharu.owl.broker.ModuleContext b/owl/owl-broker/owl-broker-mongodb/src/main/resources/META-INF/services/dev.usbharu.owl.broker.ModuleContext new file mode 100644 index 00000000..0a1dface --- /dev/null +++ b/owl/owl-broker/owl-broker-mongodb/src/main/resources/META-INF/services/dev.usbharu.owl.broker.ModuleContext @@ -0,0 +1 @@ +dev.usbharu.owl.broker.mongodb.MongoModuleContext \ No newline at end of file diff --git a/owl/owl-broker/owl-broker-mongodb/src/test/kotlin/dev/usbharu/owl/broker/mongodb/MongodbConsumerRepositoryTest.kt b/owl/owl-broker/owl-broker-mongodb/src/test/kotlin/dev/usbharu/owl/broker/mongodb/MongodbConsumerRepositoryTest.kt new file mode 100644 index 00000000..b71c5ea4 --- /dev/null +++ b/owl/owl-broker/owl-broker-mongodb/src/test/kotlin/dev/usbharu/owl/broker/mongodb/MongodbConsumerRepositoryTest.kt @@ -0,0 +1,48 @@ +package dev.usbharu.owl.broker.mongodb + +import com.mongodb.ConnectionString +import com.mongodb.MongoClientSettings +import com.mongodb.kotlin.client.coroutine.MongoClient +import dev.usbharu.owl.broker.domain.model.consumer.Consumer +import kotlinx.coroutines.runBlocking +import org.bson.UuidRepresentation +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import java.util.* + + +class MongodbConsumerRepositoryTest { + @Test + fun name() { + + val clientSettings = + MongoClientSettings.builder().applyConnectionString(ConnectionString("mongodb://localhost:27017")) + .uuidRepresentation(UuidRepresentation.STANDARD).build() + + + val database = MongoClient.create(clientSettings).getDatabase("mongo-test") + + val mongodbConsumerRepository = MongodbConsumerRepository(database) + + val consumer = Consumer( + UUID.randomUUID(), + name = "test", + hostname = "aaa", + tasks = listOf("a", "b", "c") + ) + runBlocking { + mongodbConsumerRepository.save(consumer) + + val findById = mongodbConsumerRepository.findById(UUID.randomUUID()) + assertEquals(null, findById) + + val findById1 = mongodbConsumerRepository.findById(consumer.id) + assertEquals(consumer, findById1) + + mongodbConsumerRepository.save(consumer.copy(name = "test2")) + + val findById2 = mongodbConsumerRepository.findById(consumer.id) + assertEquals(consumer.copy(name = "test2"), findById2) + } + } +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/Main.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/Main.kt new file mode 100644 index 00000000..265a9487 --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/Main.kt @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker + +import dev.usbharu.owl.common.retry.DefaultRetryPolicyFactory +import dev.usbharu.owl.common.retry.ExponentialRetryPolicy +import dev.usbharu.owl.common.retry.RetryPolicyFactory +import kotlinx.coroutines.runBlocking +import org.koin.core.context.startKoin +import org.koin.dsl.module +import org.koin.ksp.generated.defaultModule +import org.slf4j.LoggerFactory +import java.util.* + +val logger = LoggerFactory.getLogger("MAIN") + +fun main() { + val moduleContexts = ServiceLoader.load(ModuleContext::class.java) + + val moduleContext = moduleContexts.first() + + logger.info("Use module name: {}", moduleContext) + + + val koin = startKoin { + printLogger() + + val module = module { + single { + DefaultRetryPolicyFactory(mapOf("" to ExponentialRetryPolicy())) + } + } + modules(defaultModule, module, moduleContext.module()) + } + + val application = koin.koin.get() + + runBlocking { + application.start(50051).join() + } +} \ No newline at end of file diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobQueueWorkerService.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/ModuleContext.kt similarity index 57% rename from src/main/kotlin/dev/usbharu/hideout/core/service/job/JobQueueWorkerService.kt rename to owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/ModuleContext.kt index 2fbfceda..fbb32f7c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobQueueWorkerService.kt +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/ModuleContext.kt @@ -14,17 +14,16 @@ * limitations under the License. */ -package dev.usbharu.hideout.core.service.job +package dev.usbharu.owl.broker -import kjob.core.dsl.KJobFunctions -import org.springframework.stereotype.Service -import dev.usbharu.hideout.core.external.job.HideoutJob as HJ -import kjob.core.dsl.JobContextWithProps as JCWP -import kjob.core.dsl.JobRegisterContext as JRC +import org.koin.core.module.Module -@Service -interface JobQueueWorkerService { - fun > init( - defines: List>.(R) -> KJobFunctions>>> - ) +interface ModuleContext { + fun module():Module } + +data object EmptyModuleContext : ModuleContext { + override fun module(): Module { + return org.koin.dsl.module { } + } +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/OwlBrokerApplication.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/OwlBrokerApplication.kt new file mode 100644 index 00000000..6ed8527e --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/OwlBrokerApplication.kt @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker + +import dev.usbharu.owl.broker.interfaces.grpc.* +import dev.usbharu.owl.broker.service.TaskManagementService +import io.grpc.Server +import io.grpc.ServerBuilder +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch +import org.koin.core.annotation.Singleton + +@Singleton +class OwlBrokerApplication( + private val assignmentTaskService: AssignmentTaskService, + private val definitionTaskService: DefinitionTaskService, + private val producerService: ProducerService, + private val subscribeTaskService: SubscribeTaskService, + private val taskPublishService: TaskPublishService, + private val taskManagementService: TaskManagementService, + private val taskResultSubscribeService: TaskResultSubscribeService, + private val taskResultService: TaskResultService, +) { + + private lateinit var server: Server + + fun start(port: Int,coroutineScope: CoroutineScope = GlobalScope):Job { + server = ServerBuilder.forPort(port) + .addService(assignmentTaskService) + .addService(definitionTaskService) + .addService(producerService) + .addService(subscribeTaskService) + .addService(taskPublishService) + .addService(taskResultSubscribeService) + .addService(taskResultService) + .build() + + server.start() + Runtime.getRuntime().addShutdownHook( + Thread { + server.shutdown() + } + ) + + return coroutineScope.launch { + taskManagementService.startManagement(this) + } + } + + fun stop() { + server.shutdown() + } + +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/exception/InvalidRepositoryException.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/exception/InvalidRepositoryException.kt new file mode 100644 index 00000000..9019c314 --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/exception/InvalidRepositoryException.kt @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.domain.exception + +class InvalidRepositoryException : RuntimeException { + constructor() : super() + constructor(message: String?) : super(message) + constructor(message: String?, cause: Throwable?) : super(message, cause) + constructor(cause: Throwable?) : super(cause) + constructor(message: String?, cause: Throwable?, enableSuppression: Boolean, writableStackTrace: Boolean) : super( + message, + cause, + enableSuppression, + writableStackTrace + ) +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/exception/repository/FailedSaveException.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/exception/repository/FailedSaveException.kt new file mode 100644 index 00000000..4cb68305 --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/exception/repository/FailedSaveException.kt @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.domain.exception.repository + +class FailedSaveException : RuntimeException { + constructor() : super() + constructor(message: String?) : super(message) + constructor(message: String?, cause: Throwable?) : super(message, cause) + constructor(cause: Throwable?) : super(cause) + constructor(message: String?, cause: Throwable?, enableSuppression: Boolean, writableStackTrace: Boolean) : super( + message, + cause, + enableSuppression, + writableStackTrace + ) +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/exception/repository/RecordNotFoundException.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/exception/repository/RecordNotFoundException.kt new file mode 100644 index 00000000..62921c46 --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/exception/repository/RecordNotFoundException.kt @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.domain.exception.repository + +open class RecordNotFoundException : RuntimeException { + constructor() : super() + constructor(message: String?) : super(message) + constructor(message: String?, cause: Throwable?) : super(message, cause) + constructor(cause: Throwable?) : super(cause) + constructor(message: String?, cause: Throwable?, enableSuppression: Boolean, writableStackTrace: Boolean) : super( + message, + cause, + enableSuppression, + writableStackTrace + ) +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/exception/service/IncompatibleTaskException.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/exception/service/IncompatibleTaskException.kt new file mode 100644 index 00000000..9f940bc2 --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/exception/service/IncompatibleTaskException.kt @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.domain.exception.service + +class IncompatibleTaskException : RuntimeException { + constructor() : super() + constructor(message: String?) : super(message) + constructor(message: String?, cause: Throwable?) : super(message, cause) + constructor(cause: Throwable?) : super(cause) + constructor(message: String?, cause: Throwable?, enableSuppression: Boolean, writableStackTrace: Boolean) : super( + message, + cause, + enableSuppression, + writableStackTrace + ) +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/exception/service/QueueCannotDequeueException.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/exception/service/QueueCannotDequeueException.kt new file mode 100644 index 00000000..49b47dbf --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/exception/service/QueueCannotDequeueException.kt @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.domain.exception.service + +class QueueCannotDequeueException : RuntimeException { + constructor() : super() + constructor(message: String?) : super(message) + constructor(message: String?, cause: Throwable?) : super(message, cause) + constructor(cause: Throwable?) : super(cause) + constructor(message: String?, cause: Throwable?, enableSuppression: Boolean, writableStackTrace: Boolean) : super( + message, + cause, + enableSuppression, + writableStackTrace + ) +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/exception/service/TaskNotRegisterException.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/exception/service/TaskNotRegisterException.kt new file mode 100644 index 00000000..ca894165 --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/exception/service/TaskNotRegisterException.kt @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.domain.exception.service + +class TaskNotRegisterException : RuntimeException { + constructor() : super() + constructor(message: String?) : super(message) + constructor(message: String?, cause: Throwable?) : super(message, cause) + constructor(cause: Throwable?) : super(cause) + constructor(message: String?, cause: Throwable?, enableSuppression: Boolean, writableStackTrace: Boolean) : super( + message, + cause, + enableSuppression, + writableStackTrace + ) +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/consumer/Consumer.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/consumer/Consumer.kt new file mode 100644 index 00000000..27fe78b2 --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/consumer/Consumer.kt @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.domain.model.consumer + +import java.util.* + +data class Consumer( + val id: UUID, + val name: String, + val hostname: String, + val tasks: List +) diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/consumer/ConsumerRepository.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/consumer/ConsumerRepository.kt new file mode 100644 index 00000000..34ebb0af --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/consumer/ConsumerRepository.kt @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.domain.model.consumer + +import java.util.* + +interface ConsumerRepository { + suspend fun save(consumer: Consumer):Consumer + + suspend fun findById(id:UUID):Consumer? +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/producer/Producer.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/producer/Producer.kt new file mode 100644 index 00000000..eebbafd4 --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/producer/Producer.kt @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.domain.model.producer + +import java.time.Instant +import java.util.* + +data class Producer( + val id:UUID, + val name:String, + val hostname:String, + val registeredTask:List, + val createdAt: Instant +) diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/producer/ProducerRepository.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/producer/ProducerRepository.kt new file mode 100644 index 00000000..932cef10 --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/producer/ProducerRepository.kt @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.domain.model.producer + +interface ProducerRepository { + suspend fun save(producer: Producer):Producer +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/queuedtask/QueuedTask.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/queuedtask/QueuedTask.kt new file mode 100644 index 00000000..b9dab655 --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/queuedtask/QueuedTask.kt @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.domain.model.queuedtask + +import dev.usbharu.owl.broker.domain.model.task.Task +import java.time.Instant +import java.util.* + +/** + * @param attempt キューされた時点での試行回数より1多い + * @param isActive trueならアサイン可能 falseならアサイン済みかタイムアウト等で無効 + */ +data class QueuedTask( + val attempt: Int, + val queuedAt: Instant, + val task: Task, + val priority: Int, + val isActive: Boolean, + val timeoutAt: Instant?, + val assignedConsumer: UUID?, + val assignedAt: Instant? +) diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/queuedtask/QueuedTaskRepository.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/queuedtask/QueuedTaskRepository.kt new file mode 100644 index 00000000..9f3c12a7 --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/queuedtask/QueuedTaskRepository.kt @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.domain.model.queuedtask + +import kotlinx.coroutines.flow.Flow +import java.time.Instant +import java.util.* + +interface QueuedTaskRepository { + suspend fun save(queuedTask: QueuedTask):QueuedTask + + /** + * トランザクションの代わり + */ + suspend fun findByTaskIdAndAssignedConsumerIsNullAndUpdate(id:UUID,update:QueuedTask):QueuedTask + + fun findByTaskNameInAndIsActiveIsTrueAndOrderByPriority(tasks: List, limit: Int): Flow + + fun findByQueuedAtBeforeAndIsActiveIsTrue(instant: Instant): Flow +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/task/Task.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/task/Task.kt new file mode 100644 index 00000000..8bf3a162 --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/task/Task.kt @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.domain.model.task + +import dev.usbharu.owl.common.property.PropertyValue +import java.time.Instant +import java.util.* + +/** + * @param attempt 失敗を含めて試行した回数 + */ +data class Task( + val name:String, + val id: UUID, + val publishProducerId:UUID, + val publishedAt: Instant, + val nextRetry:Instant, + val completedAt: Instant? = null, + val attempt: Int, + val properties: Map> +) diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/task/TaskRepository.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/task/TaskRepository.kt new file mode 100644 index 00000000..009dea2d --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/task/TaskRepository.kt @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.domain.model.task + +import kotlinx.coroutines.flow.Flow +import java.time.Instant +import java.util.* + +interface TaskRepository { + suspend fun save(task: Task):Task + + suspend fun saveAll(tasks:List) + + fun findByNextRetryBeforeAndCompletedAtIsNull(timestamp:Instant): Flow + + suspend fun findById(uuid: UUID): Task? + + suspend fun findByIdAndUpdate(id:UUID,task: Task) + + suspend fun findByPublishProducerIdAndCompletedAtIsNotNull(publishProducerId:UUID):Flow +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/taskdefinition/TaskDefinition.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/taskdefinition/TaskDefinition.kt new file mode 100644 index 00000000..8fcb8f1e --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/taskdefinition/TaskDefinition.kt @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.domain.model.taskdefinition + +data class TaskDefinition( + val name: String, + val priority: Int, + val maxRetry: Int, + val timeoutMilli: Long, + val propertyDefinitionHash: Long, + val retryPolicy:String +) diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/taskdefinition/TaskDefinitionRepository.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/taskdefinition/TaskDefinitionRepository.kt new file mode 100644 index 00000000..2a1c3c6a --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/taskdefinition/TaskDefinitionRepository.kt @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.domain.model.taskdefinition + +interface TaskDefinitionRepository { + suspend fun save(taskDefinition: TaskDefinition): TaskDefinition + suspend fun deleteByName(name:String) + + suspend fun findByName(name:String):TaskDefinition? +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/taskresult/TaskResult.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/taskresult/TaskResult.kt new file mode 100644 index 00000000..b024d04c --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/taskresult/TaskResult.kt @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.domain.model.taskresult + +import dev.usbharu.owl.common.property.PropertyValue +import java.util.* + +data class TaskResult( + val id: UUID, + val taskId:UUID, + val success: Boolean, + val attempt: Int, + val result: Map>, + val message: String +) diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/taskresult/TaskResultRepository.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/taskresult/TaskResultRepository.kt new file mode 100644 index 00000000..4118cfed --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/domain/model/taskresult/TaskResultRepository.kt @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.domain.model.taskresult + +import kotlinx.coroutines.flow.Flow +import java.util.* + +interface TaskResultRepository { + suspend fun save(taskResult: TaskResult):TaskResult + fun findByTaskId(id:UUID): Flow +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/external/GrpcExtension.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/external/GrpcExtension.kt new file mode 100644 index 00000000..4271b55c --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/external/GrpcExtension.kt @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.external + +import com.google.protobuf.Timestamp +import dev.usbharu.owl.Uuid +import java.time.Instant +import java.util.* + +fun Uuid.UUID.toUUID(): UUID = UUID(mostSignificantUuidBits, leastSignificantUuidBits) + +fun UUID.toUUID(): Uuid.UUID = Uuid + .UUID + .newBuilder() + .setMostSignificantUuidBits(mostSignificantBits) + .setLeastSignificantUuidBits(leastSignificantBits) + .build() + +fun Timestamp.toInstant(): Instant = Instant.ofEpochSecond(seconds, nanos.toLong()) + +fun Instant.toTimestamp():Timestamp = Timestamp.newBuilder().setSeconds(this.epochSecond).setNanos(this.nano).build() \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/interfaces/grpc/AssignmentTaskService.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/interfaces/grpc/AssignmentTaskService.kt new file mode 100644 index 00000000..9c71b8e0 --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/interfaces/grpc/AssignmentTaskService.kt @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.interfaces.grpc + + +import dev.usbharu.owl.AssignmentTaskServiceGrpcKt +import dev.usbharu.owl.Task +import dev.usbharu.owl.broker.external.toTimestamp +import dev.usbharu.owl.broker.external.toUUID +import dev.usbharu.owl.broker.service.QueuedTaskAssigner +import dev.usbharu.owl.common.property.PropertySerializeUtils +import dev.usbharu.owl.common.property.PropertySerializerFactory +import io.grpc.Status +import io.grpc.StatusException +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flatMapMerge +import kotlinx.coroutines.flow.map +import org.koin.core.annotation.Singleton +import org.slf4j.LoggerFactory +import kotlin.coroutines.CoroutineContext +import kotlin.coroutines.EmptyCoroutineContext + +@Singleton +class AssignmentTaskService( + coroutineContext: CoroutineContext = EmptyCoroutineContext, + private val queuedTaskAssigner: QueuedTaskAssigner, + private val propertySerializerFactory: PropertySerializerFactory +) : + AssignmentTaskServiceGrpcKt.AssignmentTaskServiceCoroutineImplBase(coroutineContext) { + + override fun ready(requests: Flow): Flow { + + return try { + requests + .flatMapMerge { + queuedTaskAssigner.ready(it.consumerId.toUUID(), it.numberOfConcurrent) + } + .map { + Task.TaskRequest + .newBuilder() + .setName(it.task.name) + .setId(it.task.id.toUUID()) + .setAttempt(it.attempt) + .setQueuedAt(it.queuedAt.toTimestamp()) + .putAllProperties( + PropertySerializeUtils.serialize( + propertySerializerFactory, + it.task.properties + ) + ) + .build() + } + } catch (e: Exception) { + logger.warn("Error while reading requests", e) + throw StatusException(Status.INTERNAL.withDescription("Error while reading requests").withCause(e)) + } + } + + companion object { + private val logger = LoggerFactory.getLogger(AssignmentTaskService::class.java) + } +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/interfaces/grpc/DefinitionTaskService.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/interfaces/grpc/DefinitionTaskService.kt new file mode 100644 index 00000000..3ce2b5b0 --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/interfaces/grpc/DefinitionTaskService.kt @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.interfaces.grpc + +import com.google.protobuf.Empty +import dev.usbharu.owl.DefinitionTask +import dev.usbharu.owl.DefinitionTask.TaskDefined +import dev.usbharu.owl.DefinitionTaskServiceGrpcKt.DefinitionTaskServiceCoroutineImplBase +import dev.usbharu.owl.broker.domain.model.taskdefinition.TaskDefinition +import dev.usbharu.owl.broker.service.RegisterTaskService +import org.koin.core.annotation.Singleton +import kotlin.coroutines.CoroutineContext +import kotlin.coroutines.EmptyCoroutineContext + +@Singleton +class DefinitionTaskService(coroutineContext: CoroutineContext = EmptyCoroutineContext,private val registerTaskService: RegisterTaskService) : + DefinitionTaskServiceCoroutineImplBase(coroutineContext) { + override suspend fun register(request: DefinitionTask.TaskDefinition): TaskDefined { + registerTaskService.registerTask( + TaskDefinition( + request.name, + request.priority, + request.maxRetry, + request.timeoutMilli, + request.propertyDefinitionHash, + request.retryPolicy + ) + ) + return TaskDefined + .newBuilder() + .setTaskId( + request.name + ) + .build() + } + + override suspend fun unregister(request: DefinitionTask.TaskUnregister): Empty { + registerTaskService.unregisterTask(request.name) + return Empty.getDefaultInstance() + } +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/interfaces/grpc/ProducerService.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/interfaces/grpc/ProducerService.kt new file mode 100644 index 00000000..c01bec69 --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/interfaces/grpc/ProducerService.kt @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.interfaces.grpc + +import dev.usbharu.owl.ProducerOuterClass +import dev.usbharu.owl.ProducerServiceGrpcKt.ProducerServiceCoroutineImplBase +import dev.usbharu.owl.broker.external.toUUID +import dev.usbharu.owl.broker.service.ProducerService +import dev.usbharu.owl.broker.service.RegisterProducerRequest +import org.koin.core.annotation.Singleton +import kotlin.coroutines.CoroutineContext +import kotlin.coroutines.EmptyCoroutineContext + +@Singleton +class ProducerService( + coroutineContext: CoroutineContext = EmptyCoroutineContext, + private val producerService: ProducerService +) : + ProducerServiceCoroutineImplBase(coroutineContext) { + override suspend fun registerProducer(request: ProducerOuterClass.Producer): ProducerOuterClass.RegisterProducerResponse { + val registerProducer = producerService.registerProducer( + RegisterProducerRequest( + request.name, request.hostname + ) + ) + return ProducerOuterClass.RegisterProducerResponse.newBuilder().setId(registerProducer.toUUID()).build() + } +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/interfaces/grpc/SubscribeTaskService.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/interfaces/grpc/SubscribeTaskService.kt new file mode 100644 index 00000000..f521ca0c --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/interfaces/grpc/SubscribeTaskService.kt @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.interfaces.grpc + +import dev.usbharu.owl.Consumer +import dev.usbharu.owl.SubscribeTaskServiceGrpcKt.SubscribeTaskServiceCoroutineImplBase +import dev.usbharu.owl.broker.external.toUUID +import dev.usbharu.owl.broker.service.ConsumerService +import dev.usbharu.owl.broker.service.RegisterConsumerRequest +import org.koin.core.annotation.Singleton +import kotlin.coroutines.CoroutineContext +import kotlin.coroutines.EmptyCoroutineContext + +@Singleton +class SubscribeTaskService( + coroutineContext: CoroutineContext = EmptyCoroutineContext, + private val consumerService: ConsumerService +) : + SubscribeTaskServiceCoroutineImplBase(coroutineContext) { + override suspend fun subscribeTask(request: Consumer.SubscribeTaskRequest): Consumer.SubscribeTaskResponse { + val id = + consumerService.registerConsumer(RegisterConsumerRequest(request.name, request.hostname, request.tasksList)) + return Consumer.SubscribeTaskResponse.newBuilder().setId(id.toUUID()).build() + } +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/interfaces/grpc/TaskPublishService.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/interfaces/grpc/TaskPublishService.kt new file mode 100644 index 00000000..13d2f8ed --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/interfaces/grpc/TaskPublishService.kt @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.interfaces.grpc + +import dev.usbharu.owl.PublishTaskOuterClass +import dev.usbharu.owl.PublishTaskOuterClass.PublishedTask +import dev.usbharu.owl.PublishTaskOuterClass.PublishedTasks +import dev.usbharu.owl.TaskPublishServiceGrpcKt.TaskPublishServiceCoroutineImplBase +import dev.usbharu.owl.broker.external.toUUID +import dev.usbharu.owl.broker.service.PublishTask +import dev.usbharu.owl.broker.service.TaskPublishService +import dev.usbharu.owl.common.property.PropertySerializeUtils +import dev.usbharu.owl.common.property.PropertySerializerFactory +import io.grpc.Status +import io.grpc.StatusException +import org.koin.core.annotation.Singleton +import org.slf4j.LoggerFactory +import kotlin.coroutines.CoroutineContext +import kotlin.coroutines.EmptyCoroutineContext + +@Singleton +class TaskPublishService( + coroutineContext: CoroutineContext = EmptyCoroutineContext, + private val taskPublishService: TaskPublishService, + private val propertySerializerFactory: PropertySerializerFactory +) : + TaskPublishServiceCoroutineImplBase(coroutineContext) { + + override suspend fun publishTask(request: PublishTaskOuterClass.PublishTask): PublishedTask { + + logger.warn("aaaaaaaaaaa") + + + + return try { + + val publishedTask = taskPublishService.publishTask( + PublishTask( + request.name, + request.producerId.toUUID(), + PropertySerializeUtils.deserialize(propertySerializerFactory, request.propertiesMap) + ) + ) + PublishedTask.newBuilder().setName(publishedTask.name).setId(publishedTask.id.toUUID()).build() + } catch (e: Throwable) { + logger.warn("exception ", e) + throw StatusException(Status.INTERNAL) + } + } + + override suspend fun publishTasks(request: PublishTaskOuterClass.PublishTasks): PublishedTasks { + + val tasks = request.propertiesArrayList.map { + PublishTask( + request.name, + request.producerId.toUUID(), + PropertySerializeUtils.deserialize(propertySerializerFactory, it.propertiesMap) + ) + } + + val publishTasks = taskPublishService.publishTasks(tasks) + + return PublishedTasks.newBuilder().setName(request.name).addAllId(publishTasks.map { it.id.toUUID() }).build() + } + + companion object { + private val logger = + LoggerFactory.getLogger(dev.usbharu.owl.broker.interfaces.grpc.TaskPublishService::class.java) + } +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/interfaces/grpc/TaskResultService.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/interfaces/grpc/TaskResultService.kt new file mode 100644 index 00000000..1a82a7ef --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/interfaces/grpc/TaskResultService.kt @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.interfaces.grpc + +import com.google.protobuf.Empty +import dev.usbharu.owl.TaskResultOuterClass +import dev.usbharu.owl.TaskResultServiceGrpcKt +import dev.usbharu.owl.broker.domain.model.taskresult.TaskResult +import dev.usbharu.owl.broker.external.toUUID +import dev.usbharu.owl.broker.service.TaskManagementService +import dev.usbharu.owl.common.property.PropertySerializeUtils +import dev.usbharu.owl.common.property.PropertySerializerFactory +import io.grpc.Status +import io.grpc.StatusException +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.onEach +import org.koin.core.annotation.Singleton +import org.slf4j.LoggerFactory +import java.util.* +import kotlin.coroutines.CoroutineContext +import kotlin.coroutines.EmptyCoroutineContext + +@Singleton +class TaskResultService( + coroutineContext: CoroutineContext = EmptyCoroutineContext, + private val taskManagementService: TaskManagementService, + private val propertySerializerFactory: PropertySerializerFactory +) : + TaskResultServiceGrpcKt.TaskResultServiceCoroutineImplBase(coroutineContext) { + override suspend fun tasKResult(requests: Flow): Empty { + try { + requests.onEach { + taskManagementService.queueProcessed( + TaskResult( + id = UUID.randomUUID(), + taskId = it.id.toUUID(), + success = it.success, + attempt = it.attempt, + result = PropertySerializeUtils.deserialize(propertySerializerFactory, it.resultMap), + message = it.message + ) + ) + }.collect() + } catch (e: CancellationException) { + throw e + } catch (e: Exception) { + logger.warn("Error while executing task results", e) + throw StatusException(Status.INTERNAL.withDescription("Error while executing task results").withCause(e)) + } + return Empty.getDefaultInstance() + } + + companion object { + private val logger = LoggerFactory.getLogger(TaskResultService::class.java) + } +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/interfaces/grpc/TaskResultSubscribeService.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/interfaces/grpc/TaskResultSubscribeService.kt new file mode 100644 index 00000000..287dc449 --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/interfaces/grpc/TaskResultSubscribeService.kt @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.interfaces.grpc + +import dev.usbharu.owl.* +import dev.usbharu.owl.broker.external.toUUID +import dev.usbharu.owl.broker.service.TaskManagementService +import dev.usbharu.owl.common.property.PropertySerializeUtils +import dev.usbharu.owl.common.property.PropertySerializerFactory +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map +import org.koin.core.annotation.Singleton +import kotlin.coroutines.CoroutineContext +import kotlin.coroutines.EmptyCoroutineContext + +@Singleton +class TaskResultSubscribeService( + private val taskManagementService: TaskManagementService, + private val propertySerializerFactory: PropertySerializerFactory, + coroutineContext: CoroutineContext = EmptyCoroutineContext +) : + TaskResultSubscribeServiceGrpcKt.TaskResultSubscribeServiceCoroutineImplBase(coroutineContext) { + override fun subscribe(request: Uuid.UUID): Flow { + return taskManagementService + .subscribeResult(request.toUUID()) + .map { + taskResults { + id = it.id.toUUID() + name = it.name + attempt = it.attempt + success = it.success + results.addAll(it.results.map { + taskResult { + id = it.taskId.toUUID() + success = it.success + attempt = it.attempt + result.putAll(PropertySerializeUtils.serialize(propertySerializerFactory, it.result)) + message = it.message + } + }) + } + } + } +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/AssignQueuedTaskDecider.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/AssignQueuedTaskDecider.kt new file mode 100644 index 00000000..e8ff8b41 --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/AssignQueuedTaskDecider.kt @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.service + +import dev.usbharu.owl.broker.domain.exception.repository.RecordNotFoundException +import dev.usbharu.owl.broker.domain.model.consumer.ConsumerRepository +import dev.usbharu.owl.broker.domain.model.queuedtask.QueuedTask +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.emitAll +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.take +import org.koin.core.annotation.Singleton +import java.util.* +interface AssignQueuedTaskDecider { + fun findAssignableQueue(consumerId: UUID, numberOfConcurrent: Int): Flow +} +@Singleton +class AssignQueuedTaskDeciderImpl( + private val consumerRepository: ConsumerRepository, + private val queueStore: QueueStore +) : AssignQueuedTaskDecider { + override fun findAssignableQueue(consumerId: UUID, numberOfConcurrent: Int): Flow { + return flow { + val consumer = consumerRepository.findById(consumerId) + ?: throw RecordNotFoundException("Consumer not found. id: $consumerId") + emitAll( + queueStore.findByTaskNameInAndIsActiveIsTrueAndOrderByPriority( + consumer.tasks, + numberOfConcurrent + ).take(numberOfConcurrent) + ) + } + + } + +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/ConsumerService.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/ConsumerService.kt new file mode 100644 index 00000000..81156832 --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/ConsumerService.kt @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.service + +import dev.usbharu.owl.broker.domain.model.consumer.Consumer +import dev.usbharu.owl.broker.domain.model.consumer.ConsumerRepository +import org.koin.core.annotation.Singleton +import org.slf4j.LoggerFactory +import java.util.* + +interface ConsumerService { + suspend fun registerConsumer(registerConsumerRequest: RegisterConsumerRequest): UUID +} + +@Singleton +class ConsumerServiceImpl(private val consumerRepository: ConsumerRepository) : ConsumerService { + override suspend fun registerConsumer(registerConsumerRequest: RegisterConsumerRequest): UUID { + val id = UUID.randomUUID() + + consumerRepository.save( + Consumer( + id, + registerConsumerRequest.name, + registerConsumerRequest.hostname, + registerConsumerRequest.tasks + ) + ) + + logger.info( + "Register a new Consumer. name: {} hostname: {} tasks: {}", + registerConsumerRequest.name, + registerConsumerRequest.hostname, + registerConsumerRequest.tasks.size + ) + + return id + } + + companion object { + private val logger = LoggerFactory.getLogger(ConsumerServiceImpl::class.java) + } +} + +data class RegisterConsumerRequest( + val name: String, + val hostname: String, + val tasks: List +) \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/DefaultPropertySerializerFactory.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/DefaultPropertySerializerFactory.kt new file mode 100644 index 00000000..b1caaf51 --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/DefaultPropertySerializerFactory.kt @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.service + +import dev.usbharu.owl.common.property.* +import org.koin.core.annotation.Singleton + +@Singleton(binds = [PropertySerializerFactory::class]) +class DefaultPropertySerializerFactory : + CustomPropertySerializerFactory( + setOf( + IntegerPropertySerializer(), + StringPropertyValueSerializer(), + DoublePropertySerializer(), + BooleanPropertySerializer(), + LongPropertySerializer(), + FloatPropertySerializer(), + ) + ) \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/ProducerService.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/ProducerService.kt new file mode 100644 index 00000000..1c803a02 --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/ProducerService.kt @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.service + +import dev.usbharu.owl.broker.domain.model.producer.Producer +import dev.usbharu.owl.broker.domain.model.producer.ProducerRepository +import org.koin.core.annotation.Singleton +import org.slf4j.LoggerFactory +import java.time.Instant +import java.util.* + +interface ProducerService { + suspend fun registerProducer(producer: RegisterProducerRequest):UUID +} + +@Singleton +class ProducerServiceImpl(private val producerRepository: ProducerRepository) : ProducerService { + override suspend fun registerProducer(producer: RegisterProducerRequest): UUID { + + val id = UUID.randomUUID() + + val saveProducer = Producer( + id = id, + name = producer.name, + hostname = producer.hostname, + registeredTask = emptyList(), + createdAt = Instant.now() + ) + + producerRepository.save(saveProducer) + + logger.info("Register a new Producer. name: {} hostname: {}",saveProducer.name,saveProducer.hostname) + return id + } + + companion object{ + private val logger = LoggerFactory.getLogger(ProducerServiceImpl::class.java) + } +} + +data class RegisterProducerRequest( + val name: String, + val hostname: String +) \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/QueueScanner.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/QueueScanner.kt new file mode 100644 index 00000000..5102571a --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/QueueScanner.kt @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.service + +import dev.usbharu.owl.broker.domain.model.queuedtask.QueuedTask +import kotlinx.coroutines.currentCoroutineContext +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.emitAll +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.isActive +import org.koin.core.annotation.Singleton +import java.time.Instant + +interface QueueScanner { + fun startScan(): Flow +} + +@Singleton +class QueueScannerImpl(private val queueStore: QueueStore) : QueueScanner { + override fun startScan(): Flow { + return flow { + while (currentCoroutineContext().isActive) { + emitAll(scanQueue()) + delay(1000) + } + } + } + + private fun scanQueue(): Flow { + return queueStore.findByQueuedAtBeforeAndIsActiveIsTrue(Instant.now().minusSeconds(10)) + } + +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/QueueStore.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/QueueStore.kt new file mode 100644 index 00000000..2630915a --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/QueueStore.kt @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.service + +import dev.usbharu.owl.broker.domain.model.queuedtask.QueuedTask +import dev.usbharu.owl.broker.domain.model.queuedtask.QueuedTaskRepository +import kotlinx.coroutines.flow.Flow +import org.koin.core.annotation.Singleton +import java.time.Instant + +interface QueueStore { + suspend fun enqueue(queuedTask: QueuedTask) + suspend fun enqueueAll(queuedTaskList: List) + + suspend fun dequeue(queuedTask: QueuedTask) + suspend fun dequeueAll(queuedTaskList: List) + fun findByTaskNameInAndIsActiveIsTrueAndOrderByPriority(tasks: List, limit: Int): Flow + + fun findByQueuedAtBeforeAndIsActiveIsTrue(instant: Instant): Flow +} + +@Singleton +class QueueStoreImpl(private val queuedTaskRepository: QueuedTaskRepository) : QueueStore { + override suspend fun enqueue(queuedTask: QueuedTask) { + queuedTaskRepository.save(queuedTask) + } + + override suspend fun enqueueAll(queuedTaskList: List) { + queuedTaskList.forEach { enqueue(it) } + } + + override suspend fun dequeue(queuedTask: QueuedTask) { + queuedTaskRepository.findByTaskIdAndAssignedConsumerIsNullAndUpdate(queuedTask.task.id, queuedTask) + } + + override suspend fun dequeueAll(queuedTaskList: List) { + return queuedTaskList.forEach { dequeue(it) } + } + + override fun findByTaskNameInAndIsActiveIsTrueAndOrderByPriority( + tasks: List, + limit: Int + ): Flow { + return queuedTaskRepository.findByTaskNameInAndIsActiveIsTrueAndOrderByPriority(tasks, limit) + } + + override fun findByQueuedAtBeforeAndIsActiveIsTrue(instant: Instant): Flow { + return queuedTaskRepository.findByQueuedAtBeforeAndIsActiveIsTrue(instant) + } + +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/QueuedTaskAssigner.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/QueuedTaskAssigner.kt new file mode 100644 index 00000000..4f0678fe --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/QueuedTaskAssigner.kt @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.service + +import dev.usbharu.owl.broker.domain.exception.service.QueueCannotDequeueException +import dev.usbharu.owl.broker.domain.model.queuedtask.QueuedTask +import kotlinx.coroutines.flow.* +import org.koin.core.annotation.Singleton +import org.slf4j.LoggerFactory +import java.time.Instant +import java.util.* + +interface QueuedTaskAssigner { + fun ready(consumerId: UUID, numberOfConcurrent: Int): Flow +} + +@Singleton +class QueuedTaskAssignerImpl( + private val taskManagementService: TaskManagementService, + private val queueStore: QueueStore +) : QueuedTaskAssigner { + override fun ready(consumerId: UUID, numberOfConcurrent: Int): Flow { + return flow { + taskManagementService.findAssignableTask(consumerId, numberOfConcurrent) + .onEach { + val assignTask = assignTask(it, consumerId) + + if (assignTask != null) { + emit(assignTask) + } + } + .catch { logger.warn("Failed to assign task {}", consumerId, it) } + .collect() + } + } + + private suspend fun assignTask(queuedTask: QueuedTask, consumerId: UUID): QueuedTask? { + return try { + + val assignedTaskQueue = + queuedTask.copy(assignedConsumer = consumerId, assignedAt = Instant.now(), isActive = false) + logger.trace( + "Try assign task: {} id: {} consumer: {}", + queuedTask.task.name, + queuedTask.task.id, + consumerId + ) + + queueStore.dequeue(assignedTaskQueue) + + logger.debug( + "Assign Task. name: {} id: {} attempt: {} consumer: {}", + assignedTaskQueue.task.name, + assignedTaskQueue.task.id, + assignedTaskQueue.attempt, + assignedTaskQueue.assignedConsumer + ) + assignedTaskQueue + } catch (e: QueueCannotDequeueException) { + logger.debug("Failed dequeue queue", e) + return null + } + } + + companion object { + private val logger = LoggerFactory.getLogger(QueuedTaskAssignerImpl::class.java) + } +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/RegisterTaskService.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/RegisterTaskService.kt new file mode 100644 index 00000000..32436a14 --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/RegisterTaskService.kt @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.service + +import dev.usbharu.owl.broker.domain.exception.service.IncompatibleTaskException +import dev.usbharu.owl.broker.domain.model.taskdefinition.TaskDefinition +import dev.usbharu.owl.broker.domain.model.taskdefinition.TaskDefinitionRepository +import org.koin.core.annotation.Singleton +import org.slf4j.LoggerFactory + +interface RegisterTaskService { + suspend fun registerTask(taskDefinition: TaskDefinition) + + suspend fun unregisterTask(name:String) +} + +@Singleton +class RegisterTaskServiceImpl(private val taskDefinitionRepository: TaskDefinitionRepository) : RegisterTaskService { + override suspend fun registerTask(taskDefinition: TaskDefinition) { + val definedTask = taskDefinitionRepository.findByName(taskDefinition.name) + if (definedTask != null) { + logger.debug("Task already defined. name: ${taskDefinition.name}") + if (taskDefinition.propertyDefinitionHash != definedTask.propertyDefinitionHash) { + throw IncompatibleTaskException("Task ${taskDefinition.name} has already been defined, and the parameters are incompatible.") + } + return + } + taskDefinitionRepository.save(taskDefinition) + + logger.info("Register a new task. name: {}",taskDefinition.name) + } + + // todo すでにpublish済みのタスクをどうするか決めさせる + override suspend fun unregisterTask(name: String) { + taskDefinitionRepository.deleteByName(name) + + logger.info("Unregister a task. name: {}",name) + } + + companion object{ + private val logger = LoggerFactory.getLogger(RegisterTaskServiceImpl::class.java) + } +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/TaskManagementService.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/TaskManagementService.kt new file mode 100644 index 00000000..3d801972 --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/TaskManagementService.kt @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.service + +import dev.usbharu.owl.broker.domain.exception.repository.RecordNotFoundException +import dev.usbharu.owl.broker.domain.exception.service.TaskNotRegisterException +import dev.usbharu.owl.broker.domain.model.queuedtask.QueuedTask +import dev.usbharu.owl.broker.domain.model.task.Task +import dev.usbharu.owl.broker.domain.model.task.TaskRepository +import dev.usbharu.owl.broker.domain.model.taskdefinition.TaskDefinitionRepository +import dev.usbharu.owl.broker.domain.model.taskresult.TaskResult +import dev.usbharu.owl.broker.domain.model.taskresult.TaskResultRepository +import dev.usbharu.owl.common.retry.RetryPolicyFactory +import kotlinx.coroutines.* +import kotlinx.coroutines.flow.* +import org.koin.core.annotation.Singleton +import org.slf4j.LoggerFactory +import java.time.Instant +import java.util.* + + +interface TaskManagementService { + + suspend fun startManagement(coroutineScope: CoroutineScope) + fun findAssignableTask(consumerId: UUID, numberOfConcurrent: Int): Flow + + suspend fun queueProcessed(taskResult: TaskResult) + + fun subscribeResult(producerId: UUID): Flow +} + +@Singleton +class TaskManagementServiceImpl( + private val taskScanner: TaskScanner, + private val queueStore: QueueStore, + private val taskDefinitionRepository: TaskDefinitionRepository, + private val assignQueuedTaskDecider: AssignQueuedTaskDecider, + private val retryPolicyFactory: RetryPolicyFactory, + private val taskRepository: TaskRepository, + private val queueScanner: QueueScanner, + private val taskResultRepository: TaskResultRepository +) : TaskManagementService { + + private var taskFlow: Flow = flowOf() + private var queueFlow: Flow = flowOf() + override suspend fun startManagement(coroutineScope: CoroutineScope) { + taskFlow = taskScanner.startScan() + queueFlow = queueScanner.startScan() + + coroutineScope { + listOf( + launch { + taskFlow.onEach { + enqueueTask(it) + }.collect() + }, + launch { + queueFlow.onEach { + timeoutQueue(it) + }.collect() + } + ).joinAll() + } + } + + + override fun findAssignableTask(consumerId: UUID, numberOfConcurrent: Int): Flow { + return assignQueuedTaskDecider.findAssignableQueue(consumerId, numberOfConcurrent) + } + + private suspend fun enqueueTask(task: Task): QueuedTask { + + val definedTask = taskDefinitionRepository.findByName(task.name) + ?: throw TaskNotRegisterException("Task ${task.name} not definition.") + + val queuedTask = QueuedTask( + attempt = task.attempt + 1, + queuedAt = Instant.now(), + task = task, + priority = definedTask.priority, + isActive = true, + timeoutAt = null, + assignedConsumer = null, + assignedAt = null + ) + + val copy = task.copy( + nextRetry = retryPolicyFactory.factory(definedTask.retryPolicy) + .nextRetry(Instant.now(), queuedTask.attempt) + ) + + taskRepository.save(copy) + + queueStore.enqueue(queuedTask) + logger.debug("Enqueue Task. name: {} id: {} attempt: {}", task.name, task.id, queuedTask.attempt) + return queuedTask + } + + private suspend fun timeoutQueue(queuedTask: QueuedTask) { + val timeoutQueue = queuedTask.copy(isActive = false, timeoutAt = Instant.now()) + + queueStore.dequeue(timeoutQueue) + + + val task = taskRepository.findById(timeoutQueue.task.id) + ?: throw RecordNotFoundException("Task not found. id: ${timeoutQueue.task.id}") + val copy = task.copy(attempt = timeoutQueue.attempt) + + logger.warn( + "Queue timed out. name: {} id: {} attempt: {}", + timeoutQueue.task.name, + timeoutQueue.task.id, + timeoutQueue.attempt + ) + taskRepository.save(copy) + } + + override suspend fun queueProcessed(taskResult: TaskResult) { + val task = taskRepository.findById(taskResult.taskId) + ?: throw RecordNotFoundException("Task not found. id: ${taskResult.taskId}") + + val taskDefinition = taskDefinitionRepository.findByName(task.name) + ?: throw TaskNotRegisterException("Task ${task.name} not definition.") + + val completedAt = if (taskResult.success) { + Instant.now() + } else if (taskResult.attempt >= taskDefinition.maxRetry) { + Instant.now() + } else { + null + } + + taskResultRepository.save(taskResult) + + taskRepository.findByIdAndUpdate( + taskResult.taskId, + task.copy(completedAt = completedAt, attempt = taskResult.attempt) + ) + + } + + override fun subscribeResult(producerId: UUID): Flow { + return flow { + + while (currentCoroutineContext().isActive) { + taskRepository + .findByPublishProducerIdAndCompletedAtIsNotNull(producerId) + .onEach { + val results = taskResultRepository.findByTaskId(it.id).toList() + emit( + TaskResults( + it.name, + it.id, + results.any { it.success }, + it.attempt, + results + ) + ) + } + delay(500) + } + + } + + } + + companion object { + private val logger = LoggerFactory.getLogger(TaskManagementServiceImpl::class.java) + } +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/TaskPublishService.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/TaskPublishService.kt new file mode 100644 index 00000000..b6f2efe7 --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/TaskPublishService.kt @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.service + +import dev.usbharu.owl.broker.domain.exception.service.TaskNotRegisterException +import dev.usbharu.owl.broker.domain.model.task.Task +import dev.usbharu.owl.broker.domain.model.task.TaskRepository +import dev.usbharu.owl.broker.domain.model.taskdefinition.TaskDefinitionRepository +import dev.usbharu.owl.common.property.PropertyValue +import dev.usbharu.owl.common.retry.RetryPolicyFactory +import org.koin.core.annotation.Singleton +import org.slf4j.LoggerFactory +import java.time.Instant +import java.util.* + +interface TaskPublishService { + suspend fun publishTask(publishTask: PublishTask): PublishedTask + suspend fun publishTasks(list: List): List +} + +data class PublishTask( + val name: String, + val producerId: UUID, + val properties: Map> +) + +data class PublishedTask( + val name: String, + val id: UUID +) + +@Singleton +class TaskPublishServiceImpl( + private val taskRepository: TaskRepository, + private val taskDefinitionRepository: TaskDefinitionRepository, + private val retryPolicyFactory: RetryPolicyFactory +) : TaskPublishService { + override suspend fun publishTask(publishTask: PublishTask): PublishedTask { + val id = UUID.randomUUID() + + val definition = taskDefinitionRepository.findByName(publishTask.name) + ?: throw TaskNotRegisterException("Task ${publishTask.name} not definition.") + + val published = Instant.now() + val nextRetry = retryPolicyFactory.factory(definition.retryPolicy).nextRetry(published, 0) + + val task = Task( + name = publishTask.name, + id = id, + publishProducerId = publishTask.producerId, + publishedAt = published, + completedAt = null, + attempt = 0, + properties = publishTask.properties, + nextRetry = nextRetry + ) + + taskRepository.save(task) + + logger.debug("Published task #{} name: {}", task.id, task.name) + + return PublishedTask( + name = publishTask.name, + id = id + ) + } + + override suspend fun publishTasks(list: List): List { + + val first = list.first() + + val definition = taskDefinitionRepository.findByName(first.name) + ?: throw TaskNotRegisterException("Task ${first.name} not definition.") + + val published = Instant.now() + + val nextRetry = retryPolicyFactory.factory(definition.retryPolicy).nextRetry(published, 0) + + val tasks = list.map { + Task( + it.name, + UUID.randomUUID(), + first.producerId, + published, + nextRetry, + null, + 0, + it.properties + ) + } + + taskRepository.saveAll(tasks) + + logger.debug("Published {} tasks. name: {}", tasks.size, first.name) + + return tasks.map { PublishedTask(it.name, it.id) } + } + + companion object { + private val logger = LoggerFactory.getLogger(TaskPublishServiceImpl::class.java) + } +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/TaskResults.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/TaskResults.kt new file mode 100644 index 00000000..a61dbb0c --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/TaskResults.kt @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.service + +import dev.usbharu.owl.broker.domain.model.taskresult.TaskResult +import java.util.* + +data class TaskResults( + val name:String, + val id:UUID, + val success:Boolean, + val attempt:Int, + val results: List +) diff --git a/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/TaskScanner.kt b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/TaskScanner.kt new file mode 100644 index 00000000..3204f409 --- /dev/null +++ b/owl/owl-broker/src/main/kotlin/dev/usbharu/owl/broker/service/TaskScanner.kt @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.broker.service + +import dev.usbharu.owl.broker.domain.model.task.Task +import dev.usbharu.owl.broker.domain.model.task.TaskRepository +import kotlinx.coroutines.currentCoroutineContext +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.emitAll +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.isActive +import org.koin.core.annotation.Singleton +import org.slf4j.LoggerFactory +import java.time.Instant + +interface TaskScanner { + + fun startScan(): Flow +} + +@Singleton +class TaskScannerImpl(private val taskRepository: TaskRepository) : + TaskScanner { + + override fun startScan(): Flow = flow { + while (currentCoroutineContext().isActive) { + emitAll(scanTask()) + delay(500) + } + } + + private fun scanTask(): Flow { + return taskRepository.findByNextRetryBeforeAndCompletedAtIsNull(Instant.now()) + } + + companion object { + private val logger = LoggerFactory.getLogger(TaskScannerImpl::class.java) + } +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/proto/consumer.proto b/owl/owl-broker/src/main/proto/consumer.proto new file mode 100644 index 00000000..252d4a27 --- /dev/null +++ b/owl/owl-broker/src/main/proto/consumer.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; +import "uuid.proto"; + +option java_package = "dev.usbharu.owl"; + +message SubscribeTaskRequest { + string name = 1; + string hostname = 2; + repeated string tasks = 3;; +} + +message SubscribeTaskResponse { + UUID id = 1; +} + +service SubscribeTaskService { + rpc SubscribeTask (SubscribeTaskRequest) returns (SubscribeTaskResponse); +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/proto/definition_task.proto b/owl/owl-broker/src/main/proto/definition_task.proto new file mode 100644 index 00000000..6cab5257 --- /dev/null +++ b/owl/owl-broker/src/main/proto/definition_task.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; + +option java_package = "dev.usbharu.owl"; + +import "google/protobuf/empty.proto"; +import "uuid.proto"; + + +message TaskDefinition { + string name = 1; + int32 priority = 2; + int32 max_retry = 3; + int64 timeout_milli = 4; + int64 property_definition_hash = 5; + UUID producer_id = 6; + string retryPolicy = 7; +} + +message TaskDefined { + string task_id = 1; +} + +message TaskUnregister { + string name = 1; + UUID producer_id = 2; +} + +service DefinitionTaskService { + rpc register(TaskDefinition) returns (TaskDefined); + rpc unregister(TaskUnregister) returns (google.protobuf.Empty); +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/proto/producer.proto b/owl/owl-broker/src/main/proto/producer.proto new file mode 100644 index 00000000..b4bbcd7a --- /dev/null +++ b/owl/owl-broker/src/main/proto/producer.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +import "uuid.proto"; + +option java_package = "dev.usbharu.owl"; + +message Producer { + string name = 1; + string hostname = 2; +} + +message RegisterProducerResponse { + UUID id = 1; +} + +service ProducerService { + rpc registerProducer (Producer) returns (RegisterProducerResponse); +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/proto/property.proto b/owl/owl-broker/src/main/proto/property.proto new file mode 100644 index 00000000..138e7e22 --- /dev/null +++ b/owl/owl-broker/src/main/proto/property.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +import "google/protobuf/empty.proto"; + +option java_package = "dev.usbharu.owl"; + +message Property{ + oneof value { + google.protobuf.Empty empty = 1; + string string = 2; + int32 integer = 3; + } +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/proto/publish_task.proto b/owl/owl-broker/src/main/proto/publish_task.proto new file mode 100644 index 00000000..620e6396 --- /dev/null +++ b/owl/owl-broker/src/main/proto/publish_task.proto @@ -0,0 +1,41 @@ +syntax = "proto3"; + +import "google/protobuf/timestamp.proto"; + +import "uuid.proto"; + +option java_package = "dev.usbharu.owl"; + + +message PublishTask { + string name = 1; + google.protobuf.Timestamp publishedAt = 2; + map properties = 3; + UUID producer_id = 4; +} + +message Properties { + map properties = 1; +} + +message PublishTasks { + string name = 1; + google.protobuf.Timestamp publishedAt = 2; + repeated Properties propertiesArray = 3; + UUID producer_id = 4; +} + +message PublishedTask { + string name = 1; + UUID id = 2; +} + +message PublishedTasks { + string name = 1; + repeated UUID id = 2; +} + +service TaskPublishService { + rpc publishTask (PublishTask) returns (PublishedTask); + rpc publishTasks(PublishTasks) returns (PublishedTasks); +} diff --git a/owl/owl-broker/src/main/proto/task.proto b/owl/owl-broker/src/main/proto/task.proto new file mode 100644 index 00000000..48566fdb --- /dev/null +++ b/owl/owl-broker/src/main/proto/task.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; +import "uuid.proto"; +import "google/protobuf/timestamp.proto"; +import "property.proto"; + +option java_package = "dev.usbharu.owl"; + +message ReadyRequest { + int32 number_of_concurrent = 1; + UUID consumer_id = 2; +} + +message TaskRequest { + string name = 1; + UUID id = 2; + int32 attempt = 4; + google.protobuf.Timestamp queuedAt = 5; + map properties = 6; +} + +service AssignmentTaskService { + rpc ready (stream ReadyRequest) returns (stream TaskRequest); +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/proto/task_result.proto b/owl/owl-broker/src/main/proto/task_result.proto new file mode 100644 index 00000000..642f7425 --- /dev/null +++ b/owl/owl-broker/src/main/proto/task_result.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; +import "uuid.proto"; +import "google/protobuf/empty.proto"; +import "property.proto"; + +option java_package = "dev.usbharu.owl"; + +message TaskResult { + UUID id = 1; + bool success = 2; + int32 attempt = 3; + map result = 4; + string message = 5; +} + +service TaskResultService{ + rpc tasKResult(stream TaskResult) returns (google.protobuf.Empty); +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/proto/task_result_producer.proto b/owl/owl-broker/src/main/proto/task_result_producer.proto new file mode 100644 index 00000000..6102a020 --- /dev/null +++ b/owl/owl-broker/src/main/proto/task_result_producer.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; +import "uuid.proto"; +import "task_result.proto"; + +option java_package = "dev.usbharu.owl"; + +message TaskResults { + string name = 1; + UUID id = 2; + bool success = 3; + int32 attempt = 4; + repeated TaskResult results = 5; +} + +service TaskResultSubscribeService { + rpc subscribe(UUID) returns (stream TaskResults); +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/proto/uuid.proto b/owl/owl-broker/src/main/proto/uuid.proto new file mode 100644 index 00000000..26d61001 --- /dev/null +++ b/owl/owl-broker/src/main/proto/uuid.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +option java_package = "dev.usbharu.owl"; + +message UUID { + uint64 most_significant_uuid_bits = 1; + uint64 least_significant_uuid_bits = 2; +} \ No newline at end of file diff --git a/owl/owl-broker/src/main/resources/log4j2.xml b/owl/owl-broker/src/main/resources/log4j2.xml new file mode 100644 index 00000000..31bfafec --- /dev/null +++ b/owl/owl-broker/src/main/resources/log4j2.xml @@ -0,0 +1,40 @@ + + + + + + + %d{yyyy/MM/dd HH:mm:ss.SSS} [%t] %-6p %c{10} | %m%n + + + + + ${format1} + + + + + + + + + + + + + + \ No newline at end of file diff --git a/owl/owl-common/build.gradle.kts b/owl/owl-common/build.gradle.kts new file mode 100644 index 00000000..58cc5412 --- /dev/null +++ b/owl/owl-common/build.gradle.kts @@ -0,0 +1,21 @@ +plugins { + kotlin("jvm") +} + +group = "dev.usbharu" +version = "1.0-SNAPSHOT" + +repositories { + mavenCentral() +} + +dependencies { + testImplementation("org.jetbrains.kotlin:kotlin-test") +} + +tasks.test { + useJUnitPlatform() +} +kotlin { + jvmToolchain(17) +} \ No newline at end of file diff --git a/owl/owl-common/owl-common-serialize-jackson/build.gradle.kts b/owl/owl-common/owl-common-serialize-jackson/build.gradle.kts new file mode 100644 index 00000000..5eed5b43 --- /dev/null +++ b/owl/owl-common/owl-common-serialize-jackson/build.gradle.kts @@ -0,0 +1,23 @@ +plugins { + kotlin("jvm") +} + +group = "dev.usbharu" +version = "0.0.1" + +repositories { + mavenCentral() +} + +dependencies { + implementation(project(":owl-common")) + testImplementation(kotlin("test")) + implementation(libs.bundles.jackson) +} + +tasks.test { + useJUnitPlatform() +} +kotlin { + jvmToolchain(21) +} \ No newline at end of file diff --git a/owl/owl-common/owl-common-serialize-jackson/src/main/kotlin/dev/usbharu/Main.kt b/owl/owl-common/owl-common-serialize-jackson/src/main/kotlin/dev/usbharu/Main.kt new file mode 100644 index 00000000..64eb428e --- /dev/null +++ b/owl/owl-common/owl-common-serialize-jackson/src/main/kotlin/dev/usbharu/Main.kt @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu + +fun main() { + println("Hello World!") +} \ No newline at end of file diff --git a/owl/owl-common/owl-common-serialize-jackson/src/main/kotlin/dev/usbharu/owl/common/property/ObjectPropertyValue.kt b/owl/owl-common/owl-common-serialize-jackson/src/main/kotlin/dev/usbharu/owl/common/property/ObjectPropertyValue.kt new file mode 100644 index 00000000..6583d4f1 --- /dev/null +++ b/owl/owl-common/owl-common-serialize-jackson/src/main/kotlin/dev/usbharu/owl/common/property/ObjectPropertyValue.kt @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.common.property + +import com.fasterxml.jackson.databind.ObjectMapper + +class ObjectPropertyValue(override val value: Any) : PropertyValue() { + override val type: PropertyType + get() = PropertyType.string +} + +class ObjectPropertySerializer(private val objectMapper: ObjectMapper) : PropertySerializer { + override fun isSupported(propertyValue: PropertyValue<*>): Boolean { + return propertyValue is ObjectPropertyValue + } + + override fun isSupported(string: String): Boolean { + return string.startsWith("jackson:") + } + + override fun serialize(propertyValue: PropertyValue<*>): String { + return "jackson:" + propertyValue.value!!::class.qualifiedName + ":" + objectMapper.writeValueAsString( + propertyValue.value + ) + } + + override fun deserialize(string: String): PropertyValue { + return ObjectPropertyValue( + objectMapper.readValue( + string.substringAfter("jackson:").substringAfter(":"), + Class.forName(string.substringAfter("jackson:").substringBefore(":")) + ) + ) + + } +} \ No newline at end of file diff --git a/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/ReflectionUtils.kt b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/ReflectionUtils.kt new file mode 100644 index 00000000..f0a6ff90 --- /dev/null +++ b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/ReflectionUtils.kt @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.common + +import java.lang.reflect.Field + +val Class<*>.allFields: List + get() = if (superclass != null) { + superclass.allFields + declaredFields + } else { + declaredFields.toList() + }.map { it.trySetAccessible();it } \ No newline at end of file diff --git a/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/BooleanPropertyValue.kt b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/BooleanPropertyValue.kt new file mode 100644 index 00000000..b595f31c --- /dev/null +++ b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/BooleanPropertyValue.kt @@ -0,0 +1,33 @@ +package dev.usbharu.owl.common.property + +/** + * Boolean型のプロパティ + * + * @property value プロパティ + */ +class BooleanPropertyValue(override val value: Boolean) : PropertyValue() { + override val type: PropertyType + get() = PropertyType.binary +} + +/** + * [BooleanPropertyValue]のシリアライザー + * + */ +class BooleanPropertySerializer : PropertySerializer { + override fun isSupported(propertyValue: PropertyValue<*>): Boolean { + return propertyValue.value is Boolean + } + + override fun isSupported(string: String): Boolean { + return string.startsWith("bool:") + } + + override fun serialize(propertyValue: PropertyValue<*>): String { + return "bool:" + propertyValue.value.toString() + } + + override fun deserialize(string: String): PropertyValue { + return BooleanPropertyValue(string.replace("bool:", "").toBoolean()) + } +} \ No newline at end of file diff --git a/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/CustomPropertySerializerFactory.kt b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/CustomPropertySerializerFactory.kt new file mode 100644 index 00000000..00d7a3f3 --- /dev/null +++ b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/CustomPropertySerializerFactory.kt @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.common.property + +/** + * [Set]でカスタマイズできる[PropertySerializerFactory] + * + * @property propertySerializers [PropertySerializer]の[Set] + */ +open class CustomPropertySerializerFactory(private val propertySerializers: Set>) : + PropertySerializerFactory { + override fun factory(propertyValue: PropertyValue): PropertySerializer { + return propertySerializers.firstOrNull { it.isSupported(propertyValue) } as PropertySerializer? + ?: throw IllegalArgumentException("PropertySerializer not found: $propertyValue") + } + + override fun factory(string: String): PropertySerializer<*> { + return propertySerializers.first { it.isSupported(string) } + } +} \ No newline at end of file diff --git a/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/DoublePropertyValue.kt b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/DoublePropertyValue.kt new file mode 100644 index 00000000..c201cbaa --- /dev/null +++ b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/DoublePropertyValue.kt @@ -0,0 +1,33 @@ +package dev.usbharu.owl.common.property + +/** + * Double型のプロパティ + * + * @property value プロパティ + */ +class DoublePropertyValue(override val value: Double) : PropertyValue() { + override val type: PropertyType + get() = PropertyType.number +} + +/** + * [DoublePropertyValue]のシリアライザー + * + */ +class DoublePropertySerializer : PropertySerializer { + override fun isSupported(propertyValue: PropertyValue<*>): Boolean { + return propertyValue.value is Double + } + + override fun isSupported(string: String): Boolean { + return string.startsWith("double:") + } + + override fun serialize(propertyValue: PropertyValue<*>): String { + return "double:" + propertyValue.value.toString() + } + + override fun deserialize(string: String): PropertyValue { + return DoublePropertyValue(string.replace("double:", "").toDouble()) + } +} \ No newline at end of file diff --git a/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/FloatPropertyValue.kt b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/FloatPropertyValue.kt new file mode 100644 index 00000000..0f18c832 --- /dev/null +++ b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/FloatPropertyValue.kt @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.common.property + +class FloatPropertyValue(override val value: Float) : PropertyValue() { + override val type: PropertyType + get() = PropertyType.number +} + +/** + * [FloatPropertyValue]のシリアライザー + * + */ +class FloatPropertySerializer : PropertySerializer { + override fun isSupported(propertyValue: PropertyValue<*>): Boolean { + return propertyValue.value is Float + } + + override fun isSupported(string: String): Boolean { + return string.startsWith("float:") + } + + override fun serialize(propertyValue: PropertyValue<*>): String { + return "float:" + propertyValue.value.toString() + } + + override fun deserialize(string: String): PropertyValue { + return FloatPropertyValue(string.replace("float:", "").toFloat()) + } +} \ No newline at end of file diff --git a/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/IntegerPropertyValue.kt b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/IntegerPropertyValue.kt new file mode 100644 index 00000000..9b49c39c --- /dev/null +++ b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/IntegerPropertyValue.kt @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.common.property + +/** + * Integer型のプロパティ + * + * @property value プロパティ + */ +class IntegerPropertyValue(override val value: Int) : PropertyValue() { + override val type: PropertyType + get() = PropertyType.number +} + +/** + * [IntegerPropertyValue]のシリアライザー + * + */ +class IntegerPropertySerializer : PropertySerializer { + override fun isSupported(propertyValue: PropertyValue<*>): Boolean { + return propertyValue.value is Int + } + + override fun isSupported(string: String): Boolean { + return string.startsWith("int32:") + } + + override fun serialize(propertyValue: PropertyValue<*>): String { + return "int32:" + propertyValue.value.toString() + } + + override fun deserialize(string: String): PropertyValue { + return IntegerPropertyValue(string.replace("int32:", "").toInt()) + } +} \ No newline at end of file diff --git a/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/LongPropertyValue.kt b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/LongPropertyValue.kt new file mode 100644 index 00000000..660b0b69 --- /dev/null +++ b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/LongPropertyValue.kt @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.common.property + +class LongPropertyValue(override val value: Long) : PropertyValue() { + + override val type: PropertyType + get() = PropertyType.number +} + +/** + * [LongPropertyValue]のシリアライザー + * + */ +class LongPropertySerializer : PropertySerializer { + override fun isSupported(propertyValue: PropertyValue<*>): Boolean { + return propertyValue.value is Long + } + + override fun isSupported(string: String): Boolean { + return string.startsWith("int64:") + } + + override fun serialize(propertyValue: PropertyValue<*>): String { + return "int64:" + propertyValue.value.toString() + } + + override fun deserialize(string: String): PropertyValue { + return LongPropertyValue(string.replace("int64:", "").toLong()) + } +} \ No newline at end of file diff --git a/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/PropertySerializeException.kt b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/PropertySerializeException.kt new file mode 100644 index 00000000..4acc597d --- /dev/null +++ b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/PropertySerializeException.kt @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.common.property + +class PropertySerializeException : RuntimeException { + constructor() : super() + constructor(message: String?) : super(message) + constructor(message: String?, cause: Throwable?) : super(message, cause) + constructor(cause: Throwable?) : super(cause) + constructor(message: String?, cause: Throwable?, enableSuppression: Boolean, writableStackTrace: Boolean) : super( + message, + cause, + enableSuppression, + writableStackTrace + ) +} \ No newline at end of file diff --git a/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/PropertySerializeUtils.kt b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/PropertySerializeUtils.kt new file mode 100644 index 00000000..817f3d24 --- /dev/null +++ b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/PropertySerializeUtils.kt @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.common.property + +/** + * [PropertySerializer]のユーティリティークラス + */ +object PropertySerializeUtils { + /** + * Stringと[PropertyValue]の[Map]から[PropertyValue]をシリアライズし、StringとStringの[Map]として返します + * + * @param serializerFactory シリアライズに使用する[PropertySerializerFactory] + * @param properties シリアライズする[Map] + * @return Stringとシリアライズ済みの[PropertyValue]の[Map] + */ + fun serialize( + serializerFactory: PropertySerializerFactory, + properties: Map>, + ): Map { + return properties.map { + try { + it.key to serializerFactory.factory(it.value).serialize(it.value) + } catch (e: Exception) { + throw PropertySerializeException("Failed to serialize property in ${serializerFactory.javaClass}", e) + } + }.toMap() + } + + /** + * Stringとシリアライズ済みの[PropertyValue]の[Map]からシリアライズ済みの[PropertyValue]をデシリアライズし、Stringと[PropertyValue]の[Map]として返します + * + * @param serializerFactory デシリアライズに使用する[PropertySerializerFactory] + * @param properties デシリアライズする[Map] + * @return Stringと[PropertyValue]の[Map] + */ + fun deserialize( + serializerFactory: PropertySerializerFactory, + properties: Map, + ): Map> { + return properties.map { + try { + it.key to serializerFactory.factory(it.value).deserialize(it.value) + } catch (e: Exception) { + throw PropertySerializeException("Failed to deserialize property in ${serializerFactory.javaClass}", e) + } + }.toMap() + } +} \ No newline at end of file diff --git a/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/PropertySerializer.kt b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/PropertySerializer.kt new file mode 100644 index 00000000..950bd9f4 --- /dev/null +++ b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/PropertySerializer.kt @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.common.property + +/** + * [PropertyValue]をシリアライズ・デシリアライズします + * + * @param T [PropertyValue]の型 + */ +interface PropertySerializer { + /** + * [PropertyValue]をサポートしているかを確認します + * + * @param propertyValue 確認する[PropertyValue] + * @return サポートしている場合true + */ + fun isSupported(propertyValue: PropertyValue<*>): Boolean + + /** + * シリアライズ済みの[PropertyValue]から[PropertyValue]をサポートしているかを確認します + * + * @param string 確認するシリアライズ済みの[PropertyValue] + * @return サポートしている場合true + */ + fun isSupported(string: String): Boolean + + /** + * [PropertyValue]をシリアライズします + * + * @param propertyValue シリアライズする[PropertyValue] + * @return シリアライズ済みの[PropertyValue] + */ + fun serialize(propertyValue: PropertyValue<*>): String + + /** + * デシリアライズします + * + * @param string シリアライズ済みの[PropertyValue] + * @return デシリアライズされた[PropertyValue] + */ + fun deserialize(string: String): PropertyValue +} \ No newline at end of file diff --git a/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/PropertySerializerFactory.kt b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/PropertySerializerFactory.kt new file mode 100644 index 00000000..9983d6cf --- /dev/null +++ b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/PropertySerializerFactory.kt @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.common.property + +/** + * [PropertyValue]のシリアライザーのファクトリ + * + */ +interface PropertySerializerFactory { + /** + * [PropertyValue]からシリアライザーを作成します + * + * @param T [PropertyValue]の型 + * @param propertyValue シリアライザーを作成する[PropertyValue] + * @return 作成されたシリアライザー + */ + fun factory(propertyValue: PropertyValue): PropertySerializer + + /** + * シリアライズ済みの[PropertyValue]からシリアライザーを作成します + * + * @param string シリアライズ済みの[PropertyValue] + * @return 作成されたシリアライザー + */ + fun factory(string: String): PropertySerializer<*> +} \ No newline at end of file diff --git a/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/PropertyType.kt b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/PropertyType.kt new file mode 100644 index 00000000..4259c62f --- /dev/null +++ b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/PropertyType.kt @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.common.property + +/** + * プロパティの型 + * + */ +enum class PropertyType { + /** + * 数字 + * + */ + number, + + /** + * 文字列 + * + */ + string, + + /** + * バイナリ + * + */ + binary +} \ No newline at end of file diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobQueueParentService.kt b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/PropertyValue.kt similarity index 54% rename from src/main/kotlin/dev/usbharu/hideout/core/service/job/JobQueueParentService.kt rename to owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/PropertyValue.kt index c93c6b61..d04ca229 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobQueueParentService.kt +++ b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/PropertyValue.kt @@ -14,19 +14,26 @@ * limitations under the License. */ -package dev.usbharu.hideout.core.service.job +package dev.usbharu.owl.common.property -import dev.usbharu.hideout.core.external.job.HideoutJob -import kjob.core.Job -import kjob.core.dsl.ScheduleContext -import org.springframework.stereotype.Service +/** + * プロパティで使用される値 + * + * @param T プロパティの型 + */ +abstract class PropertyValue { + /** + * プロパティ + */ + abstract val value: T -@Service -interface JobQueueParentService { + /** + * プロパティの型 + */ + abstract val type: PropertyType + override fun toString(): String { + return "PropertyValue(value=$value, type=$type)" + } - fun init(jobDefines: List) - @Deprecated("use type safe → scheduleTypeSafe") - suspend fun schedule(job: J, block: ScheduleContext.(J) -> Unit = {}) - suspend fun > scheduleTypeSafe(job: J, jobProps: T) -} +} \ No newline at end of file diff --git a/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/StringPropertyValue.kt b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/StringPropertyValue.kt new file mode 100644 index 00000000..5b4cbaa1 --- /dev/null +++ b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/property/StringPropertyValue.kt @@ -0,0 +1,33 @@ +package dev.usbharu.owl.common.property + +/** + * String型のプロパティ + * + * @property value プロパティ + */ +class StringPropertyValue(override val value: String) : PropertyValue() { + override val type: PropertyType + get() = PropertyType.string +} + +/** + * [StringPropertyValue]のシリアライザー + * + */ +class StringPropertyValueSerializer : PropertySerializer { + override fun isSupported(propertyValue: PropertyValue<*>): Boolean { + return propertyValue.value is String + } + + override fun isSupported(string: String): Boolean { + return string.startsWith("str:") + } + + override fun serialize(propertyValue: PropertyValue<*>): String { + return "str:" + propertyValue.value + } + + override fun deserialize(string: String): PropertyValue { + return StringPropertyValue(string.replace("str:", "")) + } +} \ No newline at end of file diff --git a/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/retry/ExponentialRetryPolicy.kt b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/retry/ExponentialRetryPolicy.kt new file mode 100644 index 00000000..b34cacf5 --- /dev/null +++ b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/retry/ExponentialRetryPolicy.kt @@ -0,0 +1,17 @@ +package dev.usbharu.owl.common.retry + +import java.time.Instant +import kotlin.math.pow +import kotlin.math.roundToLong + +/** + * 指数関数的に待機時間が増えるリトライポリシー + * `firstRetrySeconds x attempt ^ 2 - firstRetrySeconds` + * + * @property firstRetrySeconds + */ +class ExponentialRetryPolicy(private val firstRetrySeconds: Int = 30) : RetryPolicy { + override fun nextRetry(now: Instant, attempt: Int): Instant = + now.plusSeconds(firstRetrySeconds.times((2.0).pow(attempt).roundToLong()) - firstRetrySeconds) + +} \ No newline at end of file diff --git a/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/retry/RetryPolicy.kt b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/retry/RetryPolicy.kt new file mode 100644 index 00000000..da6e4ec0 --- /dev/null +++ b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/retry/RetryPolicy.kt @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.common.retry + +import java.time.Instant + +/** + * リトライポリシー + * + */ +interface RetryPolicy { + /** + * 次のリトライ時刻を返します。 + * + * [attempt]を負の値にしてはいけません + * + * @param now 現在の時刻 + * @param attempt 試行回数 + * @return 次のリトライ時刻 + */ + fun nextRetry(now: Instant, attempt: Int): Instant +} \ No newline at end of file diff --git a/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/retry/RetryPolicyFactory.kt b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/retry/RetryPolicyFactory.kt new file mode 100644 index 00000000..6948e7bf --- /dev/null +++ b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/retry/RetryPolicyFactory.kt @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.common.retry + + +import org.slf4j.LoggerFactory + +interface RetryPolicyFactory { + fun factory(name: String): RetryPolicy +} + +class DefaultRetryPolicyFactory(private val map: Map) : RetryPolicyFactory { + override fun factory(name: String): RetryPolicy { + return map[name] ?: throwException(name) + } + + private fun throwException(name: String): Nothing { + logger.warn("RetryPolicy not found. name: {}", name) + throw RetryPolicyNotFoundException("RetryPolicy not found. name: $name") + } + + companion object { + private val logger = LoggerFactory.getLogger(RetryPolicyFactory::class.java) + } +} \ No newline at end of file diff --git a/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/retry/RetryPolicyNotFoundException.kt b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/retry/RetryPolicyNotFoundException.kt new file mode 100644 index 00000000..dba37f35 --- /dev/null +++ b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/retry/RetryPolicyNotFoundException.kt @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.common.retry + +class RetryPolicyNotFoundException : RuntimeException { + constructor() : super() + constructor(message: String?) : super(message) + constructor(message: String?, cause: Throwable?) : super(message, cause) + constructor(cause: Throwable?) : super(cause) + constructor(message: String?, cause: Throwable?, enableSuppression: Boolean, writableStackTrace: Boolean) : super( + message, + cause, + enableSuppression, + writableStackTrace + ) +} \ No newline at end of file diff --git a/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/task/PropertyDefinition.kt b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/task/PropertyDefinition.kt new file mode 100644 index 00000000..cbc96b0b --- /dev/null +++ b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/task/PropertyDefinition.kt @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.common.task + +import dev.usbharu.owl.common.property.PropertyType + +/** + * プロパティ定義 + * + * @property map プロパティ名とプロパティタイプの[Map] + */ +class PropertyDefinition(val map: Map) : Map by map { + /** + * プロパティ定義のハッシュを求めます + * + * ハッシュ値はプロパティ名とプロパティタイプ名を結合したものを結合し、各文字のUTF-16コードと31を掛け続けたものです。 + * + * @return + */ + fun hash(): Long { + var hash = 1L + map.map { it.key + it.value.name }.joinToString("").map { hash *= it.code * 31 } + return hash + } + + +} diff --git a/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/task/PublishedTask.kt b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/task/PublishedTask.kt new file mode 100644 index 00000000..a0f944e5 --- /dev/null +++ b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/task/PublishedTask.kt @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.common.task + +import java.time.Instant +import java.util.* + +/** + * 公開済みのタスク + * + * @param T タスク + * @property task タスク + * @property id タスクのID + * @property published 公開された時刻 + */ +data class PublishedTask( + val task: T, + val id: UUID, + val published: Instant +) \ No newline at end of file diff --git a/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/task/Task.kt b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/task/Task.kt new file mode 100644 index 00000000..f29d5d2d --- /dev/null +++ b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/task/Task.kt @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.common.task + +/** + * タスク + * + */ +open class Task \ No newline at end of file diff --git a/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/task/TaskDefinition.kt b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/task/TaskDefinition.kt new file mode 100644 index 00000000..5cced498 --- /dev/null +++ b/owl/owl-common/src/main/kotlin/dev/usbharu/owl/common/task/TaskDefinition.kt @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.common.task + +import dev.usbharu.owl.common.allFields +import dev.usbharu.owl.common.property.* + +/** + * タスク定義 + * + * @param T タスク + */ +interface TaskDefinition { + /** + * タスク名 + */ + val name: String + get() = type.simpleName + + /** + * 優先度 + */ + val priority: Int + get() = 0 + + /** + * 最大リトライ数 + */ + val maxRetry: Int + get() = 5 + + /** + * リトライポリシー名 + * + * ポリシーの解決は各Brokerに依存しています + */ + val retryPolicy: String + get() = "" + + /** + * タスク実行時のタイムアウト(ミリ秒) + */ + val timeoutMilli: Long + get() = 1000 + + /** + * プロパティ定義 + */ + val propertyDefinition: PropertyDefinition + get() { + val mapValues = type.allFields.associate { it.name to it.type }.mapValues { + when { + it.value === Int::class.java -> PropertyType.number + it.value === String::class.java -> PropertyType.string + it.value === Long::class.java -> PropertyType.number + it.value === Double::class.java -> PropertyType.number + it.value === Float::class.java -> PropertyType.number + else -> PropertyType.binary + } + } + return PropertyDefinition(mapValues) + } + + /** + * [Task]の[Class] + */ + val type: Class + + /** + * タスクをシリアライズします. + * プロパティのシリアライズと混同しないようにしてください。 + * @param task シリアライズするタスク + * @return シリアライズされたタスク + */ + fun serialize(task: T): Map> { + return type.allFields.associateBy { it.name }.mapValues { + when { + it.value.type === Int::class.java -> IntegerPropertyValue(it.value.getInt(task)) + it.value.type === String::class.java -> StringPropertyValue(it.value.get(task) as String) + it.value.type === Long::class.java -> LongPropertyValue(it.value.getLong(task)) + it.value.type === Double::class.java -> DoublePropertyValue(it.value.getDouble(task)) + it.value.type === Float::class.java -> FloatPropertyValue(it.value.getFloat(task)) + it.value.type === Boolean::class.java -> BooleanPropertyValue(it.value.getBoolean(task)) + else -> throw IllegalArgumentException("Unsupported type ${it.value} in ${task.javaClass.name}") + } + } + } + + /** + * タスクをデシリアライズします。 + * プロパティのデシリアライズと混同しないようにしてください + * @param value デシリアライズするタスク + * @return デシリアライズされたタスク + */ + fun deserialize(value: Map>): T { + + val task = try { + type.getDeclaredConstructor().newInstance() + } catch (e: Exception) { + throw IllegalArgumentException("Unable to deserialize value $value for type ${type.name}", e) + } + + type.allFields.associateBy { it.name }.mapValues { + when { + it.value.type === Int::class.java -> it.value.setInt(task, value.getValue(it.key).value as Int) + it.value.type === Double::class.java -> it.value.setDouble(task, value.getValue(it.key).value as Double) + it.value.type === Float::class.java -> it.value.setFloat(task, value.getValue(it.key).value as Float) + it.value.type === String::class.java -> it.value.set(task, value.getValue(it.key).value as String) + it.value.type === Long::class.java -> it.value.setLong(task, value.getValue(it.key).value as Long) + else -> throw IllegalArgumentException("Unsupported type ${it.value} in ${task.javaClass.name}") + } + } + + return task + } +} \ No newline at end of file diff --git a/owl/owl-common/src/test/kotlin/dev/usbharu/owl/common/retry/ExponentialRetryPolicyTest.kt b/owl/owl-common/src/test/kotlin/dev/usbharu/owl/common/retry/ExponentialRetryPolicyTest.kt new file mode 100644 index 00000000..c1a1dc2e --- /dev/null +++ b/owl/owl-common/src/test/kotlin/dev/usbharu/owl/common/retry/ExponentialRetryPolicyTest.kt @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.common.retry + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import java.time.Instant + +class ExponentialRetryPolicyTest { + @Test + fun exponential0() { + val nextRetry = ExponentialRetryPolicy().nextRetry(Instant.ofEpochSecond(300), 0) + + assertEquals(Instant.ofEpochSecond(300), nextRetry) + } + + @Test + fun exponential1() { + val nextRetry = ExponentialRetryPolicy().nextRetry(Instant.ofEpochSecond(300), 1) + assertEquals(Instant.ofEpochSecond(330), nextRetry) + } +} \ No newline at end of file diff --git a/owl/owl-consumer/build.gradle.kts b/owl/owl-consumer/build.gradle.kts new file mode 100644 index 00000000..abe00b93 --- /dev/null +++ b/owl/owl-consumer/build.gradle.kts @@ -0,0 +1,54 @@ +plugins { + kotlin("jvm") + id("com.google.protobuf") version "0.9.4" +} + +group = "dev.usbharu" +version = "0.0.1" + +repositories { + mavenCentral() +} + +dependencies { + testImplementation("org.jetbrains.kotlin:kotlin-test") + implementation("io.grpc:grpc-kotlin-stub:1.4.1") + implementation("io.grpc:grpc-protobuf:1.63.0") + implementation("com.google.protobuf:protobuf-kotlin:4.26.1") + implementation("io.grpc:grpc-netty:1.63.0") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1") + implementation(project(":owl-common")) + protobuf(files(project(":owl-broker").dependencyProject.projectDir.toString() + "/src/main/proto")) +} + +tasks.test { + useJUnitPlatform() +} +kotlin { + jvmToolchain(17) +} + +protobuf { + protoc { + artifact = "com.google.protobuf:protoc:4.26.1" + } + plugins { + create("grpc") { + artifact = "io.grpc:protoc-gen-grpc-java:1.63.0" + } + create("grpckt") { + artifact = "io.grpc:protoc-gen-grpc-kotlin:1.4.1:jdk8@jar" + } + } + generateProtoTasks { + all().forEach { + it.plugins { + create("grpc") + create("grpckt") + } + it.builtins { + create("kotlin") + } + } + } +} \ No newline at end of file diff --git a/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/AbstractTaskRunner.kt b/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/AbstractTaskRunner.kt new file mode 100644 index 00000000..e1a5125e --- /dev/null +++ b/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/AbstractTaskRunner.kt @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.consumer + +import dev.usbharu.owl.common.task.Task +import dev.usbharu.owl.common.task.TaskDefinition + +abstract class AbstractTaskRunner>(private val taskDefinition: D) : TaskRunner { + override val name: String + get() = taskDefinition.name + + override suspend fun run(taskRequest: TaskRequest): TaskResult { + val deserialize = taskDefinition.deserialize(taskRequest.properties) + return typedRun(deserialize, taskRequest) + } + + abstract suspend fun typedRun(typedParam: T, taskRequest: TaskRequest): TaskResult + +} \ No newline at end of file diff --git a/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/Consumer.kt b/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/Consumer.kt new file mode 100644 index 00000000..56ac00c7 --- /dev/null +++ b/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/Consumer.kt @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.consumer + +import dev.usbharu.owl.* +import dev.usbharu.owl.Uuid.UUID +import dev.usbharu.owl.common.property.PropertySerializeUtils +import dev.usbharu.owl.common.property.PropertySerializerFactory +import kotlinx.coroutines.* +import kotlinx.coroutines.flow.* +import org.slf4j.LoggerFactory +import java.time.Instant +import kotlin.math.max + +/** + * Consumer + * + * @property subscribeTaskStub + * @property assignmentTaskStub + * @property taskResultStub + * @property runnerMap + * @property propertySerializerFactory + * @constructor + * TODO + * + * @param consumerConfig + */ +class Consumer( + private val subscribeTaskStub: SubscribeTaskServiceGrpcKt.SubscribeTaskServiceCoroutineStub, + private val assignmentTaskStub: AssignmentTaskServiceGrpcKt.AssignmentTaskServiceCoroutineStub, + private val taskResultStub: TaskResultServiceGrpcKt.TaskResultServiceCoroutineStub, + taskRunnerLoader: TaskRunnerLoader, + private val propertySerializerFactory: PropertySerializerFactory, + consumerConfig: ConsumerConfig, +) { + + private lateinit var consumerId: UUID + + private lateinit var coroutineScope: CoroutineScope + + private val concurrent = MutableStateFlow(consumerConfig.concurrent) + private val processing = MutableStateFlow(0) + + private val runnerMap = taskRunnerLoader.load() + + /** + * Consumerを初期化します + * + * @param name Consumer名 + * @param hostname Consumerのホスト名 + */ + suspend fun init(name: String, hostname: String) { + logger.info("Initialize Consumer name: {} hostname: {}", name, hostname) + logger.debug("Registered Tasks: {}", runnerMap.keys) + consumerId = subscribeTaskStub.subscribeTask(subscribeTaskRequest { + this.name = name + this.hostname = hostname + this.tasks.addAll(runnerMap.keys) + }).id + logger.info("Success initialize consumer. ConsumerID: {}", consumerId) + } + + /** + * タスクの受付を開始します + * + */ + suspend fun start() { + coroutineScope = CoroutineScope(Dispatchers.Default) + coroutineScope { + while (isActive) { + try { + taskResultStub + .tasKResult(flow { + assignmentTaskStub + .ready(flow { + requestTask() + }).onEach { + logger.info("Start Task name: {} id: {}", it.name, it.id) + processing.update { it + 1 } + + try { + val taskResult = runnerMap.getValue(it.name).run( + TaskRequest( + it.name, + java.util.UUID( + it.id.mostSignificantUuidBits, + it.id.leastSignificantUuidBits + ), + it.attempt, + Instant.ofEpochSecond(it.queuedAt.seconds, it.queuedAt.nanos.toLong()), + PropertySerializeUtils.deserialize( + propertySerializerFactory, + it.propertiesMap + ) + ) + ) + + emit(taskResult { + this.success = taskResult.success + this.attempt = it.attempt + this.id = it.id + this.result.putAll( + PropertySerializeUtils.serialize( + propertySerializerFactory, taskResult.result + ) + ) + this.message = taskResult.message + }) + logger.info( + "Success execute task. name: {} success: {}", + it.name, + taskResult.success + ) + logger.debug("TRACE RESULT {}", taskResult) + } catch (e: CancellationException) { + logger.warn("Cancelled execute task.", e) + emit(taskResult { + this.success = false + this.attempt = it.attempt + this.id = it.id + this.message = e.localizedMessage + }) + throw e + } catch (e: Exception) { + logger.warn("Failed execute task. name: {} id: {}", it.name, it.id, e) + emit(taskResult { + this.success = false + this.attempt = it.attempt + this.id = it.id + this.message = e.localizedMessage + }) + } finally { + logger.debug(" Task name: {} id: {}", it.name, it.id) + processing.update { it - 1 } + concurrent.update { + if (it < 64) { + it + 1 + } else { + 64 + } + } + } + }.flowOn(Dispatchers.Default).collect() + }) + } catch (e: CancellationException) { + throw e + } catch (e: Exception) { + logger.warn("Consumer error", e) + } + + delay(1000) + } + } + } + + private suspend fun FlowCollector.requestTask() { + while (coroutineScope.isActive) { + val andSet = concurrent.getAndUpdate { 0 } + + + if (andSet != 0) { + logger.debug("Request {} tasks.", andSet) + try { + emit(readyRequest { + this.consumerId = this@Consumer.consumerId + this.numberOfConcurrent = andSet + }) + } catch (e: CancellationException) { + throw e + } catch (e: Exception) { + logger.warn("Failed request task.", e) + } + continue + } + delay(100) + + concurrent.update { + ((64 - it) - processing.value).coerceIn(0, 64 - max(0, processing.value)) + } + } + } + + /** + * タスクの受付を停止します + * + */ + fun stop() { + logger.info("Stop Consumer. consumerID: {}", consumerId) + coroutineScope.cancel() + } + + companion object { + private val logger = LoggerFactory.getLogger(Consumer::class.java) + } +} \ No newline at end of file diff --git a/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/ConsumerConfig.kt b/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/ConsumerConfig.kt new file mode 100644 index 00000000..a4609e51 --- /dev/null +++ b/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/ConsumerConfig.kt @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.consumer + +/** + * Consumerの構成 + * + * @property concurrent Consumerのワーカーの同時実行数 + */ +data class ConsumerConfig( + val concurrent: Int +) diff --git a/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/Main.kt b/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/Main.kt new file mode 100644 index 00000000..31fba291 --- /dev/null +++ b/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/Main.kt @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.consumer + +import kotlinx.coroutines.runBlocking + +fun main() { + val standaloneConsumer = StandaloneConsumer() + + runBlocking { + standaloneConsumer.init() + standaloneConsumer.start() + } + +} \ No newline at end of file diff --git a/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/ServiceLoaderTaskRunnerLoader.kt b/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/ServiceLoaderTaskRunnerLoader.kt new file mode 100644 index 00000000..a34fc37b --- /dev/null +++ b/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/ServiceLoaderTaskRunnerLoader.kt @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.consumer + +import java.util.* + +class ServiceLoaderTaskRunnerLoader : TaskRunnerLoader { + private val taskRunnerMap = ServiceLoader + .load(TaskRunner::class.java) + .associateBy { it.name } + + override fun load(): Map { + return taskRunnerMap + } +} \ No newline at end of file diff --git a/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/StandaloneConsumer.kt b/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/StandaloneConsumer.kt new file mode 100644 index 00000000..34f75a05 --- /dev/null +++ b/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/StandaloneConsumer.kt @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.consumer + +import dev.usbharu.owl.AssignmentTaskServiceGrpcKt +import dev.usbharu.owl.SubscribeTaskServiceGrpcKt +import dev.usbharu.owl.TaskResultServiceGrpcKt +import dev.usbharu.owl.common.property.CustomPropertySerializerFactory +import dev.usbharu.owl.common.property.PropertySerializerFactory +import io.grpc.ManagedChannelBuilder +import java.nio.file.Path + +/** + * 単独で起動できるConsumer + * + * @property config Consumerの起動構成 + * @property propertySerializerFactory [dev.usbharu.owl.common.property.PropertyValue]のシリアライザーのファクトリ + */ +class StandaloneConsumer( + private val config: StandaloneConsumerConfig, + private val propertySerializerFactory: PropertySerializerFactory, + taskRunnerLoader: TaskRunnerLoader, +) { + constructor( + path: Path, + propertySerializerFactory: PropertySerializerFactory = CustomPropertySerializerFactory( + emptySet() + ), + taskRunnerLoader: TaskRunnerLoader = ServiceLoaderTaskRunnerLoader(), + ) : this(StandaloneConsumerConfigLoader.load(path), propertySerializerFactory, taskRunnerLoader) + + constructor( + string: String, + propertySerializerFactory: PropertySerializerFactory = CustomPropertySerializerFactory(emptySet()), + taskRunnerLoader: TaskRunnerLoader = ServiceLoaderTaskRunnerLoader(), + ) : this(Path.of(string), propertySerializerFactory, taskRunnerLoader) + + constructor( + propertySerializerFactory: PropertySerializerFactory = CustomPropertySerializerFactory(emptySet()), + taskRunnerLoader: TaskRunnerLoader = ServiceLoaderTaskRunnerLoader(), + ) : this( + Path.of(StandaloneConsumer::class.java.getClassLoader().getResource("consumer.properties").toURI()), + propertySerializerFactory, + taskRunnerLoader + ) + + private val channel = ManagedChannelBuilder.forAddress(config.address, config.port) + .usePlaintext() + .build() + + private val subscribeStub = SubscribeTaskServiceGrpcKt.SubscribeTaskServiceCoroutineStub(channel) + private val assignmentTaskStub = AssignmentTaskServiceGrpcKt.AssignmentTaskServiceCoroutineStub(channel) + private val taskResultStub = TaskResultServiceGrpcKt.TaskResultServiceCoroutineStub(channel) + + private val consumer = Consumer( + subscribeTaskStub = subscribeStub, + assignmentTaskStub = assignmentTaskStub, + taskResultStub = taskResultStub, + taskRunnerLoader = taskRunnerLoader, + propertySerializerFactory = propertySerializerFactory, + consumerConfig = ConsumerConfig(config.concurrency), + ) + + /** + * Consumerを初期化します + * + */ + suspend fun init() { + consumer.init(config.name, config.hostname) + } + + /** + * Consumerのワーカーを起動し、タスクの受付を開始します。 + * + * シャットダウンフックに[stop]が登録されます。 + */ + suspend fun start() { + consumer.start() + Runtime.getRuntime().addShutdownHook(Thread { + consumer.stop() + }) + } + + /** + * Consumerを停止します + * + */ + fun stop() { + consumer.stop() + } + +} \ No newline at end of file diff --git a/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/StandaloneConsumerConfig.kt b/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/StandaloneConsumerConfig.kt new file mode 100644 index 00000000..ff31dde8 --- /dev/null +++ b/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/StandaloneConsumerConfig.kt @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.consumer + +/** + * 単独で起動できるConsumerの構成 + * + * @property address brokerのアドレス + * @property port brokerのポート + * @property name Consumerの名前 + * @property hostname Consumerのホスト名 + * @property concurrency ConsumerのWorkerの最大同時実行数 + */ +data class StandaloneConsumerConfig( + val address: String, + val port: Int, + val name: String, + val hostname: String, + val concurrency: Int, +) diff --git a/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/StandaloneConsumerConfigLoader.kt b/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/StandaloneConsumerConfigLoader.kt new file mode 100644 index 00000000..d11bda43 --- /dev/null +++ b/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/StandaloneConsumerConfigLoader.kt @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.consumer + +import java.nio.file.Files +import java.nio.file.Path +import java.util.* + +/** + * 単独で起動できるConsumerの構成のローダー + */ +object StandaloneConsumerConfigLoader { + /** + * [Path]から構成を読み込みます + * + * @param path 読み込むパス + * @return 読み込まれた構成 + */ + fun load(path: Path): StandaloneConsumerConfig { + val properties = Properties() + + properties.load(Files.newInputStream(path)) + + val address = properties.getProperty("address") + val port = properties.getProperty("port").toInt() + val name = properties.getProperty("name") + val hostname = properties.getProperty("hostname") + val concurrency = properties.getProperty("concurrency").toInt() + + return StandaloneConsumerConfig(address, port, name, hostname, concurrency) + } +} \ No newline at end of file diff --git a/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/TaskRequest.kt b/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/TaskRequest.kt new file mode 100644 index 00000000..006856f2 --- /dev/null +++ b/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/TaskRequest.kt @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.consumer + +import dev.usbharu.owl.common.property.PropertyValue +import java.time.Instant +import java.util.* + +/** + * タスクをConsumerに要求します + * + * @property name タスク名 + * @property id タスクID + * @property attempt 試行回数 + * @property queuedAt タスクがキューに入れられた時間 + * @property properties タスクに渡されたパラメータ + */ +data class TaskRequest( + val name:String, + val id:UUID, + val attempt:Int, + val queuedAt: Instant, + val properties:Map> +) diff --git a/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/TaskResult.kt b/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/TaskResult.kt new file mode 100644 index 00000000..07d4bd9f --- /dev/null +++ b/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/TaskResult.kt @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.consumer + +import dev.usbharu.owl.common.property.PropertyValue + +/** + * タスクの実行結果 + * + * @property success 成功したらtrue + * @property result タスクの実行結果のMap + * @property message その他メッセージ + */ +data class TaskResult( + val success: Boolean, + val result: Map>, + val message: String, +) { + companion object { + fun ok(result: Map> = emptyMap()): TaskResult { + return TaskResult(true, result, "") + } + } +} \ No newline at end of file diff --git a/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/TaskRunner.kt b/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/TaskRunner.kt new file mode 100644 index 00000000..613b0166 --- /dev/null +++ b/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/TaskRunner.kt @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.consumer + +/** + * タスクを実行するランナー + * + */ +interface TaskRunner { + /** + * 実行するタスク名 + */ + val name: String + + /** + * タスクを実行する + * + * @param taskRequest 実行するタスク + * @return タスク実行結果 + */ + suspend fun run(taskRequest: TaskRequest): TaskResult +} \ No newline at end of file diff --git a/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/TaskRunnerLoader.kt b/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/TaskRunnerLoader.kt new file mode 100644 index 00000000..2581e5de --- /dev/null +++ b/owl/owl-consumer/src/main/kotlin/dev/usbharu/owl/consumer/TaskRunnerLoader.kt @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.consumer + +interface TaskRunnerLoader { + fun load(): Map +} \ No newline at end of file diff --git a/owl/owl-consumer/src/main/resources/consumer.properties b/owl/owl-consumer/src/main/resources/consumer.properties new file mode 100644 index 00000000..05da7435 --- /dev/null +++ b/owl/owl-consumer/src/main/resources/consumer.properties @@ -0,0 +1,20 @@ +# +# Copyright (C) 2024 usbharu +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +address=localhost +port=50051 +name=owl +hostname=localhost +concurrency=10 \ No newline at end of file diff --git a/owl/owl-producer/owl-producer-api/build.gradle.kts b/owl/owl-producer/owl-producer-api/build.gradle.kts new file mode 100644 index 00000000..2a5f96bc --- /dev/null +++ b/owl/owl-producer/owl-producer-api/build.gradle.kts @@ -0,0 +1,21 @@ +plugins { + kotlin("jvm") +} + +group = "dev.usbharu" +version = "0.0.1" + +repositories { + mavenCentral() +} + +dependencies { + api(project(":owl-common")) +} + +tasks.test { + useJUnitPlatform() +} +kotlin { + jvmToolchain(17) +} \ No newline at end of file diff --git a/owl/owl-producer/owl-producer-api/src/main/kotlin/dev/usbharu/owl/producer/api/OwlProducer.kt b/owl/owl-producer/owl-producer-api/src/main/kotlin/dev/usbharu/owl/producer/api/OwlProducer.kt new file mode 100644 index 00000000..7ece4505 --- /dev/null +++ b/owl/owl-producer/owl-producer-api/src/main/kotlin/dev/usbharu/owl/producer/api/OwlProducer.kt @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.producer.api + +import dev.usbharu.owl.common.task.PublishedTask +import dev.usbharu.owl.common.task.Task +import dev.usbharu.owl.common.task.TaskDefinition + +/** + * タスクを発生させるクライアント + * + */ +interface OwlProducer { + + /** + * Producerを開始します + * + */ + suspend fun start() + + /** + * タスク定義を登録します + * + * @param T 登録するタスク + * @param taskDefinition 登録するタスクの定義 + */ + suspend fun registerTask(taskDefinition: TaskDefinition) + + /** + * タスクを公開します。タスクは定義済みである必要があります。 + * + * @param T 公開するタスク + * @param task タスクの詳細 + * @return 公開されたタスク + */ + suspend fun publishTask(task: T): PublishedTask + + suspend fun stop() +} diff --git a/owl/owl-producer/owl-producer-api/src/main/kotlin/dev/usbharu/owl/producer/api/OwlProducerBuilder.kt b/owl/owl-producer/owl-producer-api/src/main/kotlin/dev/usbharu/owl/producer/api/OwlProducerBuilder.kt new file mode 100644 index 00000000..0678266e --- /dev/null +++ b/owl/owl-producer/owl-producer-api/src/main/kotlin/dev/usbharu/owl/producer/api/OwlProducerBuilder.kt @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.producer.api + +/** + * [OwlProducer]を作成するビルダー + * + * @param P 作成する[OwlProducer] + * @param T [OwlProducer]の構成 + */ +interface OwlProducerBuilder

{ + /** + * 現在の構成を返します + * + * @return 現在の構成 + */ + fun config(): T + + /** + * 構成を適用します + * + * @param owlProducerConfig 適用する構成 + */ + fun apply(owlProducerConfig: T) + + /** + * 適用されている構成を使用して[OwlProducer]のインスタンスを作成します。 + * + * @return 作成された[OwlProducer] + */ + fun build(): P +} \ No newline at end of file diff --git a/owl/owl-producer/owl-producer-api/src/main/kotlin/dev/usbharu/owl/producer/api/OwlProducerBuilderConfig.kt b/owl/owl-producer/owl-producer-api/src/main/kotlin/dev/usbharu/owl/producer/api/OwlProducerBuilderConfig.kt new file mode 100644 index 00000000..efedddf0 --- /dev/null +++ b/owl/owl-producer/owl-producer-api/src/main/kotlin/dev/usbharu/owl/producer/api/OwlProducerBuilderConfig.kt @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.producer.api + +/** + * [OwlProducerBuilder]と[OwlProducerConfig]を使用して[OwlProducer]のインスタンスを作成します。 + * + * @param P 作成する[OwlProducer] + * @param T 作成に使用する[OwlProducerBuilder] + * @param C 構成 + * @param owlProducerBuilder 作成に使用する[OwlProducerBuilder] + * @param configBlock 構成 + */ +fun

, C : OwlProducerConfig> OWL( + owlProducerBuilder: T, + configBlock: C.() -> Unit = {}, +): P { + owlProducerBuilder.apply(owlProducerBuilder.config().apply { configBlock() }) + return owlProducerBuilder.build() +} \ No newline at end of file diff --git a/owl/owl-producer/owl-producer-api/src/main/kotlin/dev/usbharu/owl/producer/api/OwlProducerConfig.kt b/owl/owl-producer/owl-producer-api/src/main/kotlin/dev/usbharu/owl/producer/api/OwlProducerConfig.kt new file mode 100644 index 00000000..9334b0fd --- /dev/null +++ b/owl/owl-producer/owl-producer-api/src/main/kotlin/dev/usbharu/owl/producer/api/OwlProducerConfig.kt @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.producer.api + +/** + * [OwlProducer]の構成 + * + */ +interface OwlProducerConfig \ No newline at end of file diff --git a/owl/owl-producer/owl-producer-default/build.gradle.kts b/owl/owl-producer/owl-producer-default/build.gradle.kts new file mode 100644 index 00000000..570eed3c --- /dev/null +++ b/owl/owl-producer/owl-producer-default/build.gradle.kts @@ -0,0 +1,55 @@ +plugins { + kotlin("jvm") + id("com.google.protobuf") version "0.9.4" +} + +group = "dev.usbharu" +version = "0.0.1" + +repositories { + mavenCentral() +} + +dependencies { + testImplementation("org.jetbrains.kotlin:kotlin-test") + api(project(":owl-producer:owl-producer-api")) + implementation("io.grpc:grpc-kotlin-stub:1.4.1") + implementation("io.grpc:grpc-protobuf:1.63.0") + implementation("com.google.protobuf:protobuf-kotlin:4.26.1") + implementation("io.grpc:grpc-netty:1.63.0") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1") + implementation(project(":owl-common")) + protobuf(files(project(":owl-broker").dependencyProject.projectDir.toString() + "/src/main/proto")) +} + +tasks.test { + useJUnitPlatform() +} +kotlin { + jvmToolchain(17) +} + +protobuf { + protoc { + artifact = "com.google.protobuf:protoc:4.26.1" + } + plugins { + create("grpc") { + artifact = "io.grpc:protoc-gen-grpc-java:1.63.0" + } + create("grpckt") { + artifact = "io.grpc:protoc-gen-grpc-kotlin:1.4.1:jdk8@jar" + } + } + generateProtoTasks { + all().forEach { + it.plugins { + create("grpc") + create("grpckt") + } + it.builtins { + create("kotlin") + } + } + } +} \ No newline at end of file diff --git a/owl/owl-producer/owl-producer-default/src/main/kotlin/dev/usbharu/owl/producer/defaultimpl/DefaultOwlProducer.kt b/owl/owl-producer/owl-producer-default/src/main/kotlin/dev/usbharu/owl/producer/defaultimpl/DefaultOwlProducer.kt new file mode 100644 index 00000000..e4a1dfd4 --- /dev/null +++ b/owl/owl-producer/owl-producer-default/src/main/kotlin/dev/usbharu/owl/producer/defaultimpl/DefaultOwlProducer.kt @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.producer.defaultimpl + +import com.google.protobuf.timestamp +import dev.usbharu.owl.* +import dev.usbharu.owl.Uuid.UUID +import dev.usbharu.owl.common.property.PropertySerializeUtils +import dev.usbharu.owl.common.task.PublishedTask +import dev.usbharu.owl.common.task.Task +import dev.usbharu.owl.common.task.TaskDefinition +import dev.usbharu.owl.producer.api.OwlProducer +import java.time.Instant + +class DefaultOwlProducer(private val defaultOwlProducerConfig: DefaultOwlProducerConfig) : OwlProducer { + + lateinit var producerId: UUID + lateinit var producerServiceCoroutineStub: ProducerServiceGrpcKt.ProducerServiceCoroutineStub + lateinit var defineTaskServiceCoroutineStub: DefinitionTaskServiceGrpcKt.DefinitionTaskServiceCoroutineStub + lateinit var taskPublishServiceCoroutineStub: TaskPublishServiceGrpcKt.TaskPublishServiceCoroutineStub + val map = mutableMapOf, TaskDefinition<*>>() + override suspend fun start() { + producerServiceCoroutineStub = + ProducerServiceGrpcKt.ProducerServiceCoroutineStub(defaultOwlProducerConfig.channel) + producerId = producerServiceCoroutineStub.registerProducer(producer { + this.name = defaultOwlProducerConfig.name + this.hostname = defaultOwlProducerConfig.hostname + }).id + + defineTaskServiceCoroutineStub = + DefinitionTaskServiceGrpcKt.DefinitionTaskServiceCoroutineStub(defaultOwlProducerConfig.channel) + + taskPublishServiceCoroutineStub = + TaskPublishServiceGrpcKt.TaskPublishServiceCoroutineStub(defaultOwlProducerConfig.channel) + } + + + override suspend fun registerTask(taskDefinition: TaskDefinition) { + defineTaskServiceCoroutineStub.register(taskDefinition { + this.producerId = this@DefaultOwlProducer.producerId + this.name = taskDefinition.name + this.maxRetry = taskDefinition.maxRetry + this.priority = taskDefinition.priority + this.retryPolicy = taskDefinition.retryPolicy + this.timeoutMilli = taskDefinition.timeoutMilli + this.propertyDefinitionHash = taskDefinition.propertyDefinition.hash() + }) + } + + override suspend fun publishTask(task: T): PublishedTask { + val taskDefinition = map.getValue(task::class.java) as TaskDefinition + val properties = PropertySerializeUtils.serialize( + defaultOwlProducerConfig.propertySerializerFactory, + taskDefinition.serialize(task) + ) + val now = Instant.now() + val publishTask = taskPublishServiceCoroutineStub.publishTask( + dev.usbharu.owl.publishTask { + this.producerId = this@DefaultOwlProducer.producerId + + this.publishedAt = timestamp { + this.seconds = now.epochSecond + this.nanos = now.nano + } + this.name = taskDefinition.name + this.properties.putAll(properties) + } + ) + + return PublishedTask( + task, + java.util.UUID(publishTask.id.mostSignificantUuidBits, publishTask.id.leastSignificantUuidBits), + now + ) + } + + override suspend fun stop() { + defaultOwlProducerConfig.channel.shutdownNow() + } +} \ No newline at end of file diff --git a/owl/owl-producer/owl-producer-default/src/main/kotlin/dev/usbharu/owl/producer/defaultimpl/DefaultOwlProducerBuilder.kt b/owl/owl-producer/owl-producer-default/src/main/kotlin/dev/usbharu/owl/producer/defaultimpl/DefaultOwlProducerBuilder.kt new file mode 100644 index 00000000..4e45e9f4 --- /dev/null +++ b/owl/owl-producer/owl-producer-default/src/main/kotlin/dev/usbharu/owl/producer/defaultimpl/DefaultOwlProducerBuilder.kt @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.producer.defaultimpl + +import dev.usbharu.owl.producer.api.OwlProducerBuilder +import io.grpc.ManagedChannelBuilder + +class DefaultOwlProducerBuilder : OwlProducerBuilder { + + var config: DefaultOwlProducerConfig = config() + + override fun config(): DefaultOwlProducerConfig { + val defaultOwlProducerConfig = DefaultOwlProducerConfig() + + with(defaultOwlProducerConfig) { + channel = ManagedChannelBuilder.forAddress("localhost", 50051).usePlaintext().build() + } + + return defaultOwlProducerConfig + } + + override fun build(): DefaultOwlProducer { + return DefaultOwlProducer( + config + ) + } + + override fun apply(owlProducerConfig: DefaultOwlProducerConfig) { + this.config = owlProducerConfig + } +} + +val DEFAULT by lazy { DefaultOwlProducerBuilder() } \ No newline at end of file diff --git a/owl/owl-producer/owl-producer-default/src/main/kotlin/dev/usbharu/owl/producer/defaultimpl/DefaultOwlProducerConfig.kt b/owl/owl-producer/owl-producer-default/src/main/kotlin/dev/usbharu/owl/producer/defaultimpl/DefaultOwlProducerConfig.kt new file mode 100644 index 00000000..1f955677 --- /dev/null +++ b/owl/owl-producer/owl-producer-default/src/main/kotlin/dev/usbharu/owl/producer/defaultimpl/DefaultOwlProducerConfig.kt @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.producer.defaultimpl + +import dev.usbharu.owl.common.property.PropertySerializerFactory +import dev.usbharu.owl.producer.api.OwlProducerConfig +import io.grpc.Channel +import io.grpc.ManagedChannel + +/** + * デフォルトの[dev.usbharu.owl.producer.api.OwlProducer]の構成 + * + */ +class DefaultOwlProducerConfig : OwlProducerConfig { + /** + * gRPCで使用する[Channel] + */ + lateinit var channel: ManagedChannel + + /** + * プロデューサー名 + */ + lateinit var name: String + + /** + * プロデューサーのホスト名 + */ + lateinit var hostname: String + + /** + * [dev.usbharu.owl.common.property.PropertyValue]のシリアライズに使用するファクトリ + */ + lateinit var propertySerializerFactory: PropertySerializerFactory +} \ No newline at end of file diff --git a/owl/owl-producer/owl-producer-embedded/build.gradle.kts b/owl/owl-producer/owl-producer-embedded/build.gradle.kts new file mode 100644 index 00000000..da6dd7ab --- /dev/null +++ b/owl/owl-producer/owl-producer-embedded/build.gradle.kts @@ -0,0 +1,26 @@ +plugins { + kotlin("jvm") +} + +group = "dev.usbharu" +version = "0.0.1" + +repositories { + mavenCentral() +} + +dependencies { + testImplementation(kotlin("test")) + implementation(project(":owl-producer:owl-producer-api")) + implementation(project(":owl-broker")) + implementation(platform("io.insert-koin:koin-bom:3.5.6")) + implementation("io.insert-koin:koin-core") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1") +} + +tasks.test { + useJUnitPlatform() +} +kotlin { + jvmToolchain(17) +} \ No newline at end of file diff --git a/owl/owl-producer/owl-producer-embedded/src/main/kotlin/dev/usbharu/owl/producer/embedded/EmbeddedGrpcOwlProducer.kt b/owl/owl-producer/owl-producer-embedded/src/main/kotlin/dev/usbharu/owl/producer/embedded/EmbeddedGrpcOwlProducer.kt new file mode 100644 index 00000000..477363a3 --- /dev/null +++ b/owl/owl-producer/owl-producer-embedded/src/main/kotlin/dev/usbharu/owl/producer/embedded/EmbeddedGrpcOwlProducer.kt @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.producer.embedded + +import dev.usbharu.owl.broker.OwlBrokerApplication +import dev.usbharu.owl.common.retry.RetryPolicyFactory +import dev.usbharu.owl.common.task.PublishedTask +import dev.usbharu.owl.common.task.Task +import dev.usbharu.owl.common.task.TaskDefinition +import dev.usbharu.owl.producer.api.OwlProducer +import org.koin.core.Koin +import org.koin.core.context.GlobalContext.startKoin +import org.koin.dsl.module +import org.koin.ksp.generated.defaultModule + +class EmbeddedGrpcOwlProducer( + private val config: EmbeddedGrpcOwlProducerConfig, +) : OwlProducer { + + private lateinit var application: Koin + + override suspend fun start() { + application = startKoin { + printLogger() + + val module = module { + single { + config.retryPolicyFactory + } + } + modules(module, defaultModule, config.moduleContext.module()) + }.koin + + application.get().start(config.port.toInt()) + } + + override suspend fun registerTask(taskDefinition: TaskDefinition) { + config.owlProducer.registerTask(taskDefinition) + } + + override suspend fun publishTask(task: T): PublishedTask { + return config.owlProducer.publishTask(task) + } + + override suspend fun stop() { + config.owlProducer.stop() + } +} \ No newline at end of file diff --git a/owl/owl-producer/owl-producer-embedded/src/main/kotlin/dev/usbharu/owl/producer/embedded/EmbeddedGrpcOwlProducerBuilder.kt b/owl/owl-producer/owl-producer-embedded/src/main/kotlin/dev/usbharu/owl/producer/embedded/EmbeddedGrpcOwlProducerBuilder.kt new file mode 100644 index 00000000..be8b04c2 --- /dev/null +++ b/owl/owl-producer/owl-producer-embedded/src/main/kotlin/dev/usbharu/owl/producer/embedded/EmbeddedGrpcOwlProducerBuilder.kt @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.producer.embedded + +import dev.usbharu.owl.producer.api.OwlProducerBuilder + +class EmbeddedGrpcOwlProducerBuilder : OwlProducerBuilder { + private var config = config() + + override fun config(): EmbeddedGrpcOwlProducerConfig { + return EmbeddedGrpcOwlProducerConfig() + } + + override fun build(): EmbeddedGrpcOwlProducer { + return EmbeddedGrpcOwlProducer( + config + ) + } + + override fun apply(owlProducerConfig: EmbeddedGrpcOwlProducerConfig) { + this.config = owlProducerConfig + } +} + +val EMBEDDED_GRPC by lazy { EmbeddedGrpcOwlProducerBuilder() } \ No newline at end of file diff --git a/owl/owl-producer/owl-producer-embedded/src/main/kotlin/dev/usbharu/owl/producer/embedded/EmbeddedGrpcOwlProducerConfig.kt b/owl/owl-producer/owl-producer-embedded/src/main/kotlin/dev/usbharu/owl/producer/embedded/EmbeddedGrpcOwlProducerConfig.kt new file mode 100644 index 00000000..1efe8bbe --- /dev/null +++ b/owl/owl-producer/owl-producer-embedded/src/main/kotlin/dev/usbharu/owl/producer/embedded/EmbeddedGrpcOwlProducerConfig.kt @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.producer.embedded + +import dev.usbharu.owl.broker.ModuleContext +import dev.usbharu.owl.common.retry.RetryPolicyFactory +import dev.usbharu.owl.producer.api.OwlProducer +import dev.usbharu.owl.producer.api.OwlProducerConfig + +class EmbeddedGrpcOwlProducerConfig : OwlProducerConfig { + lateinit var moduleContext: ModuleContext + lateinit var retryPolicyFactory: RetryPolicyFactory + lateinit var port: String + lateinit var owlProducer: OwlProducer +} \ No newline at end of file diff --git a/owl/owl-producer/owl-producer-embedded/src/main/kotlin/dev/usbharu/owl/producer/embedded/EmbeddedOwlProducer.kt b/owl/owl-producer/owl-producer-embedded/src/main/kotlin/dev/usbharu/owl/producer/embedded/EmbeddedOwlProducer.kt new file mode 100644 index 00000000..032f3255 --- /dev/null +++ b/owl/owl-producer/owl-producer-embedded/src/main/kotlin/dev/usbharu/owl/producer/embedded/EmbeddedOwlProducer.kt @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.producer.embedded + +import dev.usbharu.owl.broker.OwlBrokerApplication +import dev.usbharu.owl.broker.domain.exception.InvalidRepositoryException +import dev.usbharu.owl.broker.domain.model.producer.ProducerRepository +import dev.usbharu.owl.broker.service.* +import dev.usbharu.owl.common.property.PropertySerializerFactory +import dev.usbharu.owl.common.retry.RetryPolicyFactory +import dev.usbharu.owl.common.task.PublishedTask +import dev.usbharu.owl.common.task.Task +import dev.usbharu.owl.common.task.TaskDefinition +import dev.usbharu.owl.producer.api.OwlProducer +import org.koin.core.Koin +import org.koin.core.context.GlobalContext +import org.koin.core.context.GlobalContext.startKoin +import org.koin.dsl.module +import org.koin.ksp.generated.defaultModule +import java.time.Instant +import java.util.* +import dev.usbharu.owl.broker.domain.model.taskdefinition.TaskDefinition as BrokerTaskDefinition + +class EmbeddedOwlProducer( + private val embeddedOwlProducerConfig: EmbeddedOwlProducerConfig, +) : OwlProducer { + + private lateinit var producerId: UUID + + private lateinit var application: Koin + + private lateinit var brokerApplication: OwlBrokerApplication + + private val taskMap: MutableMap, TaskDefinition<*>> = mutableMapOf() + + override suspend fun start() { + GlobalContext.stopKoin() + application = startKoin { + printLogger() + + val module = module { + single { + embeddedOwlProducerConfig.retryPolicyFactory + } + single { + embeddedOwlProducerConfig.propertySerializerFactory + } + } + modules(defaultModule, module, embeddedOwlProducerConfig.moduleContext.module()) + }.koin + + application.getOrNull() + ?: throw InvalidRepositoryException("Repository not found. Install owl-broker-mongodb, etc. on the classpath") + + val producerService = application.get() + + producerId = producerService.registerProducer( + RegisterProducerRequest( + embeddedOwlProducerConfig.name, + embeddedOwlProducerConfig.name + ) + ) + + brokerApplication = application.get() + brokerApplication.start(embeddedOwlProducerConfig.port.toInt()) + } + + override suspend fun registerTask(taskDefinition: TaskDefinition) { + application.get() + .registerTask( + BrokerTaskDefinition( + name = taskDefinition.name, + priority = taskDefinition.priority, + maxRetry = taskDefinition.maxRetry, + timeoutMilli = taskDefinition.timeoutMilli, + propertyDefinitionHash = taskDefinition.propertyDefinition.hash(), + retryPolicy = taskDefinition.retryPolicy + ) + ) + + taskMap[taskDefinition.type] = taskDefinition + } + + override suspend fun publishTask(task: T): PublishedTask { + + val taskDefinition = taskMap.getValue(task::class.java) as TaskDefinition + + val publishTask = application.get().publishTask( + PublishTask( + taskDefinition.name, + producerId, + taskDefinition.serialize(task) + ) + ) + + return PublishedTask( + task, + publishTask.id, + Instant.now() + ) + } + + override suspend fun stop() { + brokerApplication.stop() + } +} \ No newline at end of file diff --git a/owl/owl-producer/owl-producer-embedded/src/main/kotlin/dev/usbharu/owl/producer/embedded/EmbeddedOwlProducerBuilder.kt b/owl/owl-producer/owl-producer-embedded/src/main/kotlin/dev/usbharu/owl/producer/embedded/EmbeddedOwlProducerBuilder.kt new file mode 100644 index 00000000..e92b6fc9 --- /dev/null +++ b/owl/owl-producer/owl-producer-embedded/src/main/kotlin/dev/usbharu/owl/producer/embedded/EmbeddedOwlProducerBuilder.kt @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.producer.embedded + +import dev.usbharu.owl.broker.EmptyModuleContext +import dev.usbharu.owl.common.retry.DefaultRetryPolicyFactory +import dev.usbharu.owl.common.retry.ExponentialRetryPolicy +import dev.usbharu.owl.producer.api.OwlProducerBuilder + +class EmbeddedOwlProducerBuilder : OwlProducerBuilder { + var config: EmbeddedOwlProducerConfig = config() + + override fun config(): EmbeddedOwlProducerConfig { + val embeddedOwlProducerConfig = EmbeddedOwlProducerConfig() + + with(embeddedOwlProducerConfig) { + moduleContext = EmptyModuleContext + retryPolicyFactory = DefaultRetryPolicyFactory(mapOf("" to ExponentialRetryPolicy())) + name = "embedded-owl-producer" + port = "50051" + } + + return embeddedOwlProducerConfig + } + + override fun build(): EmbeddedOwlProducer { + return EmbeddedOwlProducer( + config + ) + } + + override fun apply(owlProducerConfig: EmbeddedOwlProducerConfig) { + this.config = owlProducerConfig + } + +} + +val EMBEDDED by lazy { EmbeddedOwlProducerBuilder() } \ No newline at end of file diff --git a/owl/owl-producer/owl-producer-embedded/src/main/kotlin/dev/usbharu/owl/producer/embedded/EmbeddedOwlProducerConfig.kt b/owl/owl-producer/owl-producer-embedded/src/main/kotlin/dev/usbharu/owl/producer/embedded/EmbeddedOwlProducerConfig.kt new file mode 100644 index 00000000..61e60220 --- /dev/null +++ b/owl/owl-producer/owl-producer-embedded/src/main/kotlin/dev/usbharu/owl/producer/embedded/EmbeddedOwlProducerConfig.kt @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.owl.producer.embedded + +import dev.usbharu.owl.broker.ModuleContext +import dev.usbharu.owl.common.property.CustomPropertySerializerFactory +import dev.usbharu.owl.common.retry.RetryPolicyFactory +import dev.usbharu.owl.producer.api.OwlProducerConfig + +class EmbeddedOwlProducerConfig : OwlProducerConfig { + lateinit var moduleContext: ModuleContext + lateinit var retryPolicyFactory: RetryPolicyFactory + lateinit var propertySerializerFactory: CustomPropertySerializerFactory + lateinit var name: String + lateinit var port: String +} diff --git a/owl/settings.gradle.kts b/owl/settings.gradle.kts new file mode 100644 index 00000000..b78e970f --- /dev/null +++ b/owl/settings.gradle.kts @@ -0,0 +1,27 @@ +plugins { + id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" +} +dependencyResolutionManagement { + repositories { + mavenCentral() + } + + versionCatalogs { + create("libs") { + from(files("../libs.versions.toml")) + } + } +} +rootProject.name = "owl" +include("owl-common") +include("owl-producer:owl-producer-api") +findProject(":owl-producer:owl-producer-api")?.name = "owl-producer-api" +include("owl-broker") +include("owl-broker:owl-broker-mongodb") +findProject(":owl-broker:owl-broker-mongodb")?.name = "owl-broker-mongodb" +include("owl-producer:owl-producer-default") +findProject(":owl-producer:owl-producer-default")?.name = "owl-producer-default" +include("owl-consumer") +include("owl-producer:owl-producer-embedded") +include("owl-common:owl-common-serialize-jackson") +findProject(":owl-common:owl-common-serialize-jackson")?.name = "owl-common-serialize-jackson" diff --git a/renovate.json b/renovate.json new file mode 100644 index 00000000..5db72dd6 --- /dev/null +++ b/renovate.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended" + ] +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 76167ae3..c2d9aa85 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1 +1,35 @@ -rootProject.name = "hideout" \ No newline at end of file +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" +} +rootProject.name = "hideout" + +includeBuild("hideout-core") +includeBuild("hideout-worker") + +dependencyResolutionManagement { + repositories { + mavenCentral() + } + + versionCatalogs { + create("libs") { + from(files("libs.versions.toml")) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Block.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Block.kt deleted file mode 100644 index 5a3c12a9..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Block.kt +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.activitypub.domain.model - -import com.fasterxml.jackson.annotation.JsonProperty -import dev.usbharu.hideout.activitypub.domain.model.objects.Object - -open class Block( - override val actor: String, - override val id: String, - @JsonProperty("object") val apObject: String -) : - Object(listOf("Block")), HasId, HasActor { - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - if (!super.equals(other)) return false - - other as Block - - if (actor != other.actor) return false - if (id != other.id) return false - if (apObject != other.apObject) return false - - return true - } - - override fun hashCode(): Int { - var result = super.hashCode() - result = 31 * result + actor.hashCode() - result = 31 * result + id.hashCode() - result = 31 * result + apObject.hashCode() - return result - } - - override fun toString(): String { - return "Block(" + - "actor='$actor', " + - "id='$id', " + - "apObject='$apObject'" + - ")" + - " ${super.toString()}" - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/block/APDeliverBlockJobProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/block/APDeliverBlockJobProcessor.kt deleted file mode 100644 index b91b41b8..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/block/APDeliverBlockJobProcessor.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.activitypub.service.activity.block - -import dev.usbharu.hideout.activitypub.service.common.APRequestService -import dev.usbharu.hideout.application.external.Transaction -import dev.usbharu.hideout.core.domain.model.actor.ActorRepository -import dev.usbharu.hideout.core.external.job.DeliverBlockJob -import dev.usbharu.hideout.core.external.job.DeliverBlockJobParam -import dev.usbharu.hideout.core.service.job.JobProcessor -import org.springframework.stereotype.Service - -/** - * ブロックアクティビティ配送を処理します - */ -@Service -class APDeliverBlockJobProcessor( - private val apRequestService: APRequestService, - private val actorRepository: ActorRepository, - private val transaction: Transaction, - private val deliverBlockJob: DeliverBlockJob -) : JobProcessor { - override suspend fun process(param: DeliverBlockJobParam): Unit = transaction.transaction { - val signer = actorRepository.findById(param.signer) - apRequestService.apPost( - param.inbox, - param.reject, - signer - ) - apRequestService.apPost( - param.inbox, - param.block, - signer - ) - } - - override fun job(): DeliverBlockJob = deliverBlockJob -} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/block/APSendBlockService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/block/APSendBlockService.kt deleted file mode 100644 index 923770c5..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/block/APSendBlockService.kt +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.activitypub.service.activity.block - -import dev.usbharu.hideout.activitypub.domain.model.Block -import dev.usbharu.hideout.activitypub.domain.model.Follow -import dev.usbharu.hideout.activitypub.domain.model.Reject -import dev.usbharu.hideout.application.config.ApplicationConfig -import dev.usbharu.hideout.core.domain.model.actor.Actor -import dev.usbharu.hideout.core.external.job.DeliverBlockJob -import dev.usbharu.hideout.core.external.job.DeliverBlockJobParam -import dev.usbharu.hideout.core.service.job.JobQueueParentService -import org.springframework.stereotype.Service - -interface APSendBlockService { - suspend fun sendBlock(actor: Actor, target: Actor) -} - -@Service -class ApSendBlockServiceImpl( - private val applicationConfig: ApplicationConfig, - private val jobQueueParentService: JobQueueParentService, - private val deliverBlockJob: DeliverBlockJob -) : APSendBlockService { - override suspend fun sendBlock(actor: Actor, target: Actor) { - val blockJobParam = DeliverBlockJobParam( - actor.id, - Block( - actor.url, - "${applicationConfig.url}/block/${actor.id}/${target.id}", - target.url - ), - Reject( - actor.url, - "${applicationConfig.url}/reject/${actor.id}/${target.id}", - Follow( - apObject = actor.url, - actor = target.url - ) - ), - target.inbox - ) - jobQueueParentService.scheduleTypeSafe(deliverBlockJob, blockJobParam) - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/block/BlockActivityPubProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/block/BlockActivityPubProcessor.kt deleted file mode 100644 index 5a5ac1d4..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/block/BlockActivityPubProcessor.kt +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.activitypub.service.activity.block - -import dev.usbharu.hideout.activitypub.domain.model.Block -import dev.usbharu.hideout.activitypub.service.common.AbstractActivityPubProcessor -import dev.usbharu.hideout.activitypub.service.common.ActivityPubProcessContext -import dev.usbharu.hideout.activitypub.service.common.ActivityType -import dev.usbharu.hideout.application.external.Transaction -import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException -import dev.usbharu.hideout.core.domain.model.actor.ActorRepository -import dev.usbharu.hideout.core.service.relationship.RelationshipService -import org.springframework.stereotype.Service - -/** - * ブロックアクティビティを処理します - */ -@Service -class BlockActivityPubProcessor( - private val relationshipService: RelationshipService, - private val actorRepository: ActorRepository, - transaction: Transaction -) : - AbstractActivityPubProcessor(transaction) { - override suspend fun internalProcess(activity: ActivityPubProcessContext) { - val user = actorRepository.findByUrl(activity.activity.actor) - ?: throw UserNotFoundException.withUrl(activity.activity.actor) - val target = actorRepository.findByUrl(activity.activity.apObject) ?: throw UserNotFoundException.withUrl( - activity.activity.apObject - ) - relationshipService.block(user.id, target.id) - } - - override fun isSupported(activityType: ActivityType): Boolean = activityType == ActivityType.Block - - override fun type(): Class = Block::class.java -} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobProcessor.kt deleted file mode 100644 index 0feaf7e5..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobProcessor.kt +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.activitypub.service.activity.follow - -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue -import dev.usbharu.hideout.activitypub.domain.model.Follow -import dev.usbharu.hideout.activitypub.service.objects.user.APUserService -import dev.usbharu.hideout.application.external.Transaction -import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException -import dev.usbharu.hideout.core.domain.model.actor.ActorRepository -import dev.usbharu.hideout.core.external.job.ReceiveFollowJob -import dev.usbharu.hideout.core.external.job.ReceiveFollowJobParam -import dev.usbharu.hideout.core.service.job.JobProcessor -import dev.usbharu.hideout.core.service.relationship.RelationshipService -import org.slf4j.LoggerFactory -import org.springframework.stereotype.Service - -@Service -class APReceiveFollowJobProcessor( - private val transaction: Transaction, - private val apUserService: APUserService, - private val objectMapper: ObjectMapper, - private val relationshipService: RelationshipService, - private val actorRepository: ActorRepository -) : - JobProcessor { - override suspend fun process(param: ReceiveFollowJobParam) = transaction.transaction { - apUserService.fetchPerson(param.actor, param.targetActor) - val follow = objectMapper.readValue(param.follow) - - logger.info("START Follow from: {} to {}", param.targetActor, param.actor) - - val targetEntity = - actorRepository.findByUrl(param.targetActor) ?: throw UserNotFoundException.withUrl(param.targetActor) - val followActorEntity = - actorRepository.findByUrl(follow.actor) ?: throw UserNotFoundException.withUrl(follow.actor) - - relationshipService.followRequest(followActorEntity.id, targetEntity.id) - - logger.info("SUCCESS Follow from: {} to: {}", param.targetActor, param.actor) - } - - override fun job(): ReceiveFollowJob = ReceiveFollowJob - - companion object { - private val logger = LoggerFactory.getLogger(APReceiveFollowJobProcessor::class.java) - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApReactionJobProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApReactionJobProcessor.kt deleted file mode 100644 index 7762964f..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApReactionJobProcessor.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.activitypub.service.activity.like - -import dev.usbharu.hideout.activitypub.domain.model.Like -import dev.usbharu.hideout.activitypub.service.common.APRequestService -import dev.usbharu.hideout.application.config.ApplicationConfig -import dev.usbharu.hideout.application.external.Transaction -import dev.usbharu.hideout.core.domain.model.actor.ActorRepository -import dev.usbharu.hideout.core.external.job.DeliverReactionJob -import dev.usbharu.hideout.core.external.job.DeliverReactionJobParam -import dev.usbharu.hideout.core.service.job.JobProcessor -import org.springframework.stereotype.Service - -@Service -class ApReactionJobProcessor( - private val apRequestService: APRequestService, - private val applicationConfig: ApplicationConfig, - private val transaction: Transaction, - private val actorRepository: ActorRepository -) : JobProcessor { - override suspend fun process(param: DeliverReactionJobParam): Unit = transaction.transaction { - val signer = actorRepository.findByUrl(param.actor) - - apRequestService.apPost( - param.inbox, - Like( - actor = param.actor, - apObject = param.postUrl, - id = "${applicationConfig.url}/liek/note/${param.id}", - content = param.reaction - ), - signer - ) - } - - override fun job(): DeliverReactionJob = DeliverReactionJob -} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApRemoveReactionJobProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApRemoveReactionJobProcessor.kt deleted file mode 100644 index eb67b754..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApRemoveReactionJobProcessor.kt +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.activitypub.service.activity.like - -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue -import dev.usbharu.hideout.activitypub.domain.model.Like -import dev.usbharu.hideout.activitypub.domain.model.Undo -import dev.usbharu.hideout.activitypub.service.common.APRequestService -import dev.usbharu.hideout.application.config.ApplicationConfig -import dev.usbharu.hideout.application.external.Transaction -import dev.usbharu.hideout.core.domain.model.actor.ActorRepository -import dev.usbharu.hideout.core.external.job.DeliverRemoveReactionJob -import dev.usbharu.hideout.core.external.job.DeliverRemoveReactionJobParam -import dev.usbharu.hideout.core.service.job.JobProcessor -import org.springframework.stereotype.Service -import java.time.Instant - -@Service -class ApRemoveReactionJobProcessor( - private val transaction: Transaction, - private val objectMapper: ObjectMapper, - private val apRequestService: APRequestService, - private val applicationConfig: ApplicationConfig, - private val actorRepository: ActorRepository -) : JobProcessor { - override suspend fun process(param: DeliverRemoveReactionJobParam): Unit = transaction.transaction { - val like = objectMapper.readValue(param.like) - - val signer = actorRepository.findByUrl(param.actor) - - apRequestService.apPost( - param.inbox, - Undo( - actor = param.actor, - apObject = like, - id = "${applicationConfig.url}/undo/like/${param.id}", - published = Instant.now().toString() - ), - signer - ) - } - - override fun job(): DeliverRemoveReactionJob = DeliverRemoveReactionJob -} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/ApNoteJobProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/ApNoteJobProcessor.kt deleted file mode 100644 index 0ad6e898..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/ApNoteJobProcessor.kt +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.activitypub.service.objects.note - -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue -import dev.usbharu.hideout.activitypub.domain.model.Create -import dev.usbharu.hideout.activitypub.service.common.APRequestService -import dev.usbharu.hideout.application.external.Transaction -import dev.usbharu.hideout.core.domain.model.actor.ActorRepository -import dev.usbharu.hideout.core.external.job.DeliverPostJob -import dev.usbharu.hideout.core.external.job.DeliverPostJobParam -import dev.usbharu.hideout.core.service.job.JobProcessor -import org.slf4j.LoggerFactory -import org.springframework.stereotype.Service - -@Service -class ApNoteJobProcessor( - private val transaction: Transaction, - private val objectMapper: ObjectMapper, - private val apRequestService: APRequestService, - private val actorRepository: ActorRepository -) : JobProcessor { - override suspend fun process(param: DeliverPostJobParam) { - val create = objectMapper.readValue(param.create) - transaction.transaction { - val signer = actorRepository.findByUrl(param.actor) - - logger.debug("CreateNoteJob: actor: {} create: {} inbox: {}", param.actor, create, param.inbox) - - apRequestService.apPost( - param.inbox, - create, - signer - ) - } - } - - override fun job(): DeliverPostJob = DeliverPostJob - - companion object { - private val logger = LoggerFactory.getLogger(ApNoteJobProcessor::class.java) - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/application/config/JobQueueRunner.kt b/src/main/kotlin/dev/usbharu/hideout/application/config/JobQueueRunner.kt deleted file mode 100644 index 65fc9fcc..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/application/config/JobQueueRunner.kt +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.application.config - -import dev.usbharu.hideout.core.external.job.HideoutJob -import dev.usbharu.hideout.core.service.job.JobQueueParentService -import dev.usbharu.hideout.core.service.job.JobQueueWorkerService -import org.slf4j.Logger -import org.slf4j.LoggerFactory -import org.springframework.boot.ApplicationArguments -import org.springframework.boot.ApplicationRunner -import org.springframework.stereotype.Component - -@Component -class JobQueueRunner( - private val jobQueueParentService: JobQueueParentService, - private val jobs: List> -) : - ApplicationRunner { - override fun run(args: ApplicationArguments?) { - LOGGER.info("Init job queue. ${jobs.size}") - jobQueueParentService.init(jobs) - } - - companion object { - val LOGGER: Logger = LoggerFactory.getLogger(JobQueueRunner::class.java) - } -} - -@Component -class JobQueueWorkerRunner( - private val jobQueueWorkerService: JobQueueWorkerService, -) : ApplicationRunner { - override fun run(args: ApplicationArguments?) { - LOGGER.info("Init job queue worker.") - jobQueueWorkerService.init>(emptyList()) - } - - companion object { - val LOGGER: Logger = LoggerFactory.getLogger(JobQueueWorkerRunner::class.java) - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverAcceptJob.kt b/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverAcceptJob.kt deleted file mode 100644 index 3c8c4b6c..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverAcceptJob.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.core.external.job - -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue -import dev.usbharu.hideout.activitypub.domain.model.Accept -import kjob.core.dsl.ScheduleContext -import kjob.core.job.JobProps -import org.springframework.stereotype.Component - -data class DeliverAcceptJobParam( - val accept: Accept, - val inbox: String, - val signer: Long -) - -@Component -class DeliverAcceptJob(private val objectMapper: ObjectMapper) : - HideoutJob("DeliverAcceptJob") { - - val accept = string("accept") - val inbox = string("inbox") - val signer = long("signer") - - override fun convert(value: DeliverAcceptJobParam): ScheduleContext.(DeliverAcceptJob) -> Unit = { - props[accept] = objectMapper.writeValueAsString(value.accept) - props[inbox] = value.inbox - props[signer] = value.signer - } - - override fun convert(props: JobProps): DeliverAcceptJobParam { - return DeliverAcceptJobParam( - objectMapper.readValue(props[accept]), - props[inbox], - props[signer] - ) - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverBlockJob.kt b/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverBlockJob.kt deleted file mode 100644 index 3d7f8c54..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverBlockJob.kt +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.core.external.job - -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue -import dev.usbharu.hideout.activitypub.domain.model.Block -import dev.usbharu.hideout.activitypub.domain.model.Reject -import kjob.core.dsl.ScheduleContext -import kjob.core.job.JobProps -import org.springframework.beans.factory.annotation.Qualifier -import org.springframework.stereotype.Component - -/** - * ブロックアクティビティ配送のジョブパラメーター - * - * @property signer ブロック操作を行ったユーザーid - * @property block 配送するブロックアクティビティ - * @property reject 配送するフォロー解除アクティビティ - * @property inbox 配送先url - */ -data class DeliverBlockJobParam( - val signer: Long, - val block: Block, - val reject: Reject, - val inbox: String -) - -/** - * ブロックアクティビティ配送のジョブ - */ -@Component -class DeliverBlockJob(@Qualifier("activitypub") private val objectMapper: ObjectMapper) : - HideoutJob("DeliverBlockJob") { - - val block = string("block") - val reject = string("reject") - val inbox = string("inbox") - val signer = long("signer") - - override fun convert(value: DeliverBlockJobParam): ScheduleContext.(DeliverBlockJob) -> Unit = { - props[block] = objectMapper.writeValueAsString(value.block) - props[reject] = objectMapper.writeValueAsString(value.reject) - props[inbox] = value.inbox - props[signer] = value.signer - } - - override fun convert(props: JobProps): DeliverBlockJobParam = DeliverBlockJobParam( - signer = props[signer], - block = objectMapper.readValue(props[block]), - reject = objectMapper.readValue(props[reject]), - inbox = props[inbox] - ) -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverDeleteJob.kt b/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverDeleteJob.kt deleted file mode 100644 index d5c1576c..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverDeleteJob.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.core.external.job - -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue -import dev.usbharu.hideout.activitypub.domain.model.Delete -import kjob.core.dsl.ScheduleContext -import kjob.core.job.JobProps -import org.springframework.beans.factory.annotation.Qualifier -import org.springframework.stereotype.Component - -data class DeliverDeleteJobParam( - val delete: Delete, - val inbox: String, - val signer: Long -) - -@Component -class DeliverDeleteJob(@Qualifier("activitypub") private val objectMapper: ObjectMapper) : - HideoutJob("DeliverDeleteJob") { - - val delete = string("delete") - val inbox = string("inbox") - val signer = long("signer") - - override fun convert(value: DeliverDeleteJobParam): ScheduleContext.(DeliverDeleteJob) -> Unit = { - props[delete] = objectMapper.writeValueAsString(value.delete) - props[inbox] = value.inbox - props[signer] = value.signer - } - - override fun convert(props: JobProps): DeliverDeleteJobParam = DeliverDeleteJobParam( - objectMapper.readValue(props[delete]), - props[inbox], - props[signer] - ) -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverRejectJob.kt b/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverRejectJob.kt deleted file mode 100644 index a57b3093..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverRejectJob.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.core.external.job - -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue -import dev.usbharu.hideout.activitypub.domain.model.Reject -import kjob.core.dsl.ScheduleContext -import kjob.core.job.JobProps -import org.springframework.beans.factory.annotation.Qualifier -import org.springframework.stereotype.Component - -data class DeliverRejectJobParam( - val reject: Reject, - val inbox: String, - val signer: Long -) - -@Component -class DeliverRejectJob(@Qualifier("activitypub") private val objectMapper: ObjectMapper) : - HideoutJob("DeliverRejectJob") { - val reject = string("reject") - val inbox = string("inbox") - val signer = long("signer") - - override fun convert(value: DeliverRejectJobParam): ScheduleContext.(DeliverRejectJob) -> Unit = - { - props[reject] = objectMapper.writeValueAsString(value.reject) - props[inbox] = value.inbox - props[signer] = value.signer - } - - override fun convert(props: JobProps): DeliverRejectJobParam = DeliverRejectJobParam( - objectMapper.readValue(props[reject]), - props[inbox], - props[signer] - ) -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverUndoJob.kt b/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverUndoJob.kt deleted file mode 100644 index a2f5c8d7..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverUndoJob.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.core.external.job - -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue -import dev.usbharu.hideout.activitypub.domain.model.Undo -import kjob.core.dsl.ScheduleContext -import kjob.core.job.JobProps -import org.springframework.beans.factory.annotation.Qualifier -import org.springframework.stereotype.Component - -data class DeliverUndoJobParam( - val undo: Undo, - val inbox: String, - val signer: Long -) - -@Component -class DeliverUndoJob(@Qualifier("activitypub") private val objectMapper: ObjectMapper) : - HideoutJob("DeliverUndoJob") { - - val undo = string("undo") - val inbox = string("inbox") - val signer = long("signer") - - override fun convert(value: DeliverUndoJobParam): ScheduleContext.(DeliverUndoJob) -> Unit = { - props[undo] = objectMapper.writeValueAsString(value.undo) - props[inbox] = value.inbox - props[signer] = value.signer - } - - override fun convert(props: JobProps): DeliverUndoJobParam { - return DeliverUndoJobParam( - objectMapper.readValue(props[undo]), - props[inbox], - props[signer] - ) - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt b/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt deleted file mode 100644 index 69737d3f..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.core.external.job - -import dev.usbharu.hideout.activitypub.service.common.ActivityType -import kjob.core.Job -import kjob.core.Prop -import kjob.core.dsl.ScheduleContext -import kjob.core.job.JobProps -import org.springframework.stereotype.Component - -abstract class HideoutJob>(name: String) : Job(name) { - abstract fun convert(value: @UnsafeVariance T): ScheduleContext<@UnsafeVariance R>.(@UnsafeVariance R) -> Unit - fun convertUnsafe(props: JobProps<*>): T = convert(props as JobProps) - abstract fun convert(props: JobProps<@UnsafeVariance R>): T -} - -data class ReceiveFollowJobParam( - val actor: String, - val follow: String, - val targetActor: String -) - -@Component -object ReceiveFollowJob : HideoutJob("ReceiveFollowJob") { - val actor: Prop = string("actor") - val follow: Prop = string("follow") - val targetActor: Prop = string("targetActor") - - override fun convert(value: ReceiveFollowJobParam): ScheduleContext.(ReceiveFollowJob) -> Unit = { - props[follow] = value.follow - props[actor] = value.actor - props[targetActor] = value.targetActor - } - - override fun convert(props: JobProps): ReceiveFollowJobParam = ReceiveFollowJobParam( - actor = props[actor], - follow = props[follow], - targetActor = props[targetActor] - ) -} - -data class DeliverPostJobParam( - val create: String, - val inbox: String, - val actor: String -) - -@Component -object DeliverPostJob : HideoutJob("DeliverPostJob") { - val create = string("create") - val inbox = string("inbox") - val actor = string("actor") - override fun convert(value: DeliverPostJobParam): ScheduleContext.(DeliverPostJob) -> Unit = { - props[create] = value.create - props[inbox] = value.inbox - props[actor] = value.actor - } - - override fun convert(props: JobProps): DeliverPostJobParam = DeliverPostJobParam( - create = props[create], - inbox = props[inbox], - actor = props[actor] - ) -} - -data class DeliverReactionJobParam( - val reaction: String, - val postUrl: String, - val actor: String, - val inbox: String, - val id: String -) - -@Component -object DeliverReactionJob : HideoutJob("DeliverReactionJob") { - val reaction: Prop = string("reaction") - val postUrl: Prop = string("postUrl") - val actor: Prop = string("actor") - val inbox: Prop = string("inbox") - val id: Prop = string("id") - override fun convert( - value: DeliverReactionJobParam - ): ScheduleContext.(DeliverReactionJob) -> Unit = - { - props[reaction] = value.reaction - props[postUrl] = value.postUrl - props[actor] = value.actor - props[inbox] = value.inbox - props[id] = value.id - } - - override fun convert(props: JobProps): DeliverReactionJobParam = DeliverReactionJobParam( - props[reaction], - props[postUrl], - props[actor], - props[inbox], - props[id] - ) -} - -data class DeliverRemoveReactionJobParam( - val id: String, - val inbox: String, - val actor: String, - val like: String -) - -@Component -object DeliverRemoveReactionJob : - HideoutJob("DeliverRemoveReactionJob") { - val id: Prop = string("id") - val inbox: Prop = string("inbox") - val actor: Prop = string("actor") - val like: Prop = string("like") - - override fun convert( - value: DeliverRemoveReactionJobParam - ): ScheduleContext.(DeliverRemoveReactionJob) -> Unit = - { - props[id] = value.id - props[inbox] = value.inbox - props[actor] = value.actor - props[like] = value.like - } - - override fun convert(props: JobProps): DeliverRemoveReactionJobParam = - DeliverRemoveReactionJobParam( - id = props[id], - inbox = props[inbox], - actor = props[actor], - like = props[like] - ) -} - -data class InboxJobParam( - val json: String, - val type: ActivityType, - val httpRequest: String, - val headers: String -) - -@Component -object InboxJob : HideoutJob("InboxJob") { - val json = string("json") - val type = string("type") - val httpRequest = string("http_request") - val headers = string("headers") - - override fun convert(value: InboxJobParam): ScheduleContext.(InboxJob) -> Unit = { - props[json] = value.json - props[type] = value.type.name - props[httpRequest] = value.httpRequest - props[headers] = value.headers - } - - override fun convert(props: JobProps): InboxJobParam = InboxJobParam( - props[json], - ActivityType.valueOf(props[type]), - props[httpRequest], - props[headers] - ) -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/ExposedJobRepository.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/ExposedJobRepository.kt deleted file mode 100644 index 50c60379..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/ExposedJobRepository.kt +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.core.infrastructure.kjobexposed - -import kjob.core.job.JobProgress -import kjob.core.job.JobSettings -import kjob.core.job.JobStatus -import kjob.core.job.ScheduledJob -import kjob.core.repository.JobRepository -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.asFlow -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.* -import org.jetbrains.exposed.dao.id.LongIdTable -import org.jetbrains.exposed.sql.* -import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq -import org.jetbrains.exposed.sql.SqlExpressionBuilder.inList -import org.jetbrains.exposed.sql.SqlExpressionBuilder.plus -import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction -import org.jetbrains.exposed.sql.transactions.transaction -import java.time.Clock -import java.time.Instant -import java.util.* - -class ExposedJobRepository( - private val database: Database, - private val tableName: String, - private val clock: Clock, - private val json: Json -) : - JobRepository { - - class Jobs(tableName: String) : LongIdTable(tableName) { - val status = text("status") - val runAt = long("runAt").nullable() - val statusMessage = text("statusMessage").nullable() - val retries = integer("retries") - val kjobId = char("kjobId", 36).nullable() - val createdAt = long("createdAt") - val updatedAt = long("updatedAt") - val jobId = text("jobId") - val name = text("name") - val properties = text("properties").nullable() - val step = integer("step") - val max = integer("max").nullable() - val startedAt = long("startedAt").nullable() - val completedAt = long("completedAt").nullable() - } - - val jobs: Jobs = Jobs(tableName) - - fun createTable() { - transaction(database) { - SchemaUtils.create(jobs) - } - } - - @Suppress("InjectDispatcher") - suspend fun query(block: suspend () -> T): T = newSuspendedTransaction(Dispatchers.IO) { block() } - - override suspend fun completeProgress(id: String): Boolean { - val now = Instant.now(clock).toEpochMilli() - return query { - jobs.update({ jobs.id eq id.toLong() }) { - it[jobs.completedAt] = now - it[jobs.updatedAt] = now - } == 1 - } - } - - override suspend fun exist(jobId: String): Boolean { - return query { - jobs.selectAll().where(jobs.jobId eq jobId).empty().not() - } - } - - @Suppress("SuspendFunWithFlowReturnType") - override suspend fun findNext(names: Set, status: Set, limit: Int): Flow { - return query { - jobs.selectAll().where( - jobs.status.inList(list = status.map { it.name }) - .and(if (names.isEmpty()) Op.TRUE else jobs.name.inList(names)) - ).limit(limit) - .map { it.toScheduledJob() }.asFlow() - } - } - - override suspend fun get(id: String): ScheduledJob? { - val single = query { jobs.selectAll().where(jobs.id eq id.toLong()).singleOrNull() } ?: return null - return single.toScheduledJob() - } - - override suspend fun reset(id: String, oldKjobId: UUID?): Boolean { - return query { - jobs.update({ - jobs.id eq id.toLong() and if (oldKjobId == null) { - jobs.kjobId.isNull() - } else { - jobs.kjobId eq oldKjobId.toString() - } - }) { - it[jobs.status] = JobStatus.CREATED.name - it[jobs.statusMessage] = null - it[jobs.kjobId] = null - it[jobs.step] = 0 - it[jobs.max] = null - it[jobs.startedAt] = null - it[jobs.completedAt] = null - it[jobs.updatedAt] = Instant.now(clock).toEpochMilli() - } == 1 - } - } - - override suspend fun save(jobSettings: JobSettings, runAt: Instant?): ScheduledJob { - val now = Instant.now(clock) - val scheduledJob = - ScheduledJob( - id = "", - status = JobStatus.CREATED, - runAt = runAt, - statusMessage = null, - retries = 0, - kjobId = null, - createdAt = now, - updatedAt = now, - settings = jobSettings, - progress = JobProgress(0) - ) - val id = query { - jobs.insert { - it[jobs.status] = scheduledJob.status.name - it[jobs.createdAt] = scheduledJob.createdAt.toEpochMilli() - it[jobs.updatedAt] = scheduledJob.updatedAt.toEpochMilli() - it[jobs.jobId] = scheduledJob.settings.id - it[jobs.name] = scheduledJob.settings.name - it[jobs.properties] = scheduledJob.settings.properties.stringify() - it[jobs.runAt] = scheduledJob.runAt?.toEpochMilli() - it[jobs.statusMessage] = null - it[jobs.retries] = 0 - it[jobs.kjobId] = null - it[jobs.step] = 0 - it[jobs.max] = null - it[jobs.startedAt] = null - it[jobs.completedAt] = null - }[jobs.id].value - } - return scheduledJob.copy(id = id.toString()) - } - - override suspend fun setProgressMax(id: String, max: Long): Boolean { - val now = Instant.now(clock).toEpochMilli() - return query { - jobs.update({ jobs.id eq id.toLong() }) { - it[jobs.max] = max.toInt() - it[jobs.updatedAt] = now - } == 1 - } - } - - override suspend fun startProgress(id: String): Boolean { - val now = Instant.now(clock).toEpochMilli() - return query { - jobs.update({ jobs.id eq id.toLong() }) { - it[jobs.startedAt] = now - it[jobs.updatedAt] = now - } == 1 - } - } - - override suspend fun stepProgress(id: String, step: Long): Boolean { - val now = Instant.now(clock).toEpochMilli() - return query { - jobs.update({ jobs.id eq id.toLong() }) { - it[jobs.step] = jobs.step + step.toInt() - it[jobs.updatedAt] = now - } == 1 - } - } - - override suspend fun update( - id: String, - oldKjobId: UUID?, - kjobId: UUID?, - status: JobStatus, - statusMessage: String?, - retries: Int - ): Boolean { - return query { - jobs.update({ - (jobs.id eq id.toLong()) and if (oldKjobId == null) { - jobs.kjobId.isNull() - } else { - jobs.kjobId eq oldKjobId.toString() - } - }) { - it[jobs.status] = status.name - it[jobs.retries] = retries - it[jobs.updatedAt] = Instant.now(clock).toEpochMilli() - it[jobs.id] = id.toLong() - it[jobs.statusMessage] = statusMessage - it[jobs.kjobId] = kjobId.toString() - } == 1 - } - } - - @Suppress("CyclomaticComplexMethod") - private fun String?.parseJsonMap(): Map { - this ?: return emptyMap() - return json.parseToJsonElement(this).jsonObject.mapValues { (_, el) -> - if (el is JsonObject) { - val t = el["t"]?.run { jsonPrimitive.content } ?: error("Cannot get jsonPrimitive") - val value = el["v"]?.jsonArray ?: error("Cannot get jsonArray") - when (t) { - "s" -> value.map { it.jsonPrimitive.content } - "d" -> value.map { it.jsonPrimitive.double } - "l" -> value.map { it.jsonPrimitive.long } - "i" -> value.map { it.jsonPrimitive.int } - "b" -> value.map { it.jsonPrimitive.boolean } - else -> error("Unknown type prefix '$t'") - }.toList() - } else { - val content = el.jsonPrimitive.content - val t = content.substringBefore(':') - val value = content.substringAfter(':') - when (t) { - "s" -> value - "d" -> value.toDouble() - "l" -> value.toLong() - "i" -> value.toInt() - "b" -> value.toBoolean() - else -> error("Unknown type prefix '$t'") - } - } - } - } - - @Suppress("CyclomaticComplexMethod") - private fun Map.stringify(): String? { - if (isEmpty()) { - return null - } - - @Suppress("UNCHECKED_CAST") - fun listSerialize(value: List<*>): JsonElement { - return if (value.isEmpty()) { - buildJsonObject { - put("t", "s") - putJsonArray("v") {} - } - } else { - val (t, values) = when (val item = value.first()) { - is Double -> "d" to (value as List).map(::JsonPrimitive) - is Long -> "l" to (value as List).map(::JsonPrimitive) - is Int -> "i" to (value as List).map(::JsonPrimitive) - is String -> "s" to (value as List).map(::JsonPrimitive) - is Boolean -> "b" to (value as List).map(::JsonPrimitive) - else -> error("Cannot serialize unsupported list property value: $item") - } - buildJsonObject { - put("t", t) - put("v", JsonArray(values)) - } - } - } - - fun createJsonPrimitive(string: String, value: Any) = JsonPrimitive("$string:$value") - - val jsonObject = JsonObject( - mapValues { (_, value) -> - when (value) { - is List<*> -> listSerialize(value) - is Double -> createJsonPrimitive("d", value) - is Long -> createJsonPrimitive("l", value) - is Int -> createJsonPrimitive("i", value) - is String -> createJsonPrimitive("s", value) - is Boolean -> createJsonPrimitive("b", value) - else -> error("Cannot serialize unsupported property value: $value") - } - } - ) - return json.encodeToString(jsonObject) - } - - private fun ResultRow.toScheduledJob(): ScheduledJob { - val single = this - - return ScheduledJob( - id = single[jobs.id].value.toString(), - status = JobStatus.valueOf(single[jobs.status]), - runAt = single[jobs.runAt]?.let { Instant.ofEpochMilli(it) }, - statusMessage = single[jobs.statusMessage], - retries = single[jobs.retries], - kjobId = single[jobs.kjobId]?.let { - try { - @Suppress("SwallowedException") - UUID.fromString(it) - } catch (ignored: IllegalArgumentException) { - null - } - }, - createdAt = Instant.ofEpochMilli(single[jobs.createdAt]), - updatedAt = Instant.ofEpochMilli(single[jobs.updatedAt]), - settings = JobSettings( - id = single[jobs.jobId], - name = single[jobs.name], - properties = single[jobs.properties].parseJsonMap() - ), - progress = JobProgress( - step = single[jobs.step].toLong(), - max = single[jobs.max]?.toLong(), - startedAt = single[jobs.startedAt]?.let { Instant.ofEpochMilli(it) }, - completedAt = single[jobs.completedAt]?.let { Instant.ofEpochMilli(it) } - ) - ) - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/ExposedKJob.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/ExposedKJob.kt deleted file mode 100644 index b2f5c49d..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/ExposedKJob.kt +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.core.infrastructure.kjobexposed - -import kjob.core.BaseKJob -import kjob.core.KJob -import kjob.core.KJobFactory -import kotlinx.coroutines.runBlocking -import org.jetbrains.exposed.sql.Database -import java.time.Clock - -class ExposedKJob(config: Configuration) : BaseKJob(config) { - - private val database: Database = config.connectionDatabase ?: Database.connect( - requireNotNull(config.connectionString), - requireNotNull(config.driverClassName) - ) - - override val jobRepository: ExposedJobRepository - get() = ExposedJobRepository(database, config.jobTableName, Clock.systemUTC(), config.json) - - override val lockRepository: ExposedLockRepository - get() = ExposedLockRepository(database, config, clock) - - override fun start(): KJob { - jobRepository.createTable() - lockRepository.createTable() - return super.start() - } - - override fun shutdown(): Unit = runBlocking { - super.shutdown() - lockRepository.clearExpired() - } - - companion object : KJobFactory { - override fun create(configure: Configuration.() -> Unit): KJob = ExposedKJob(Configuration().apply(configure)) - } - - class Configuration : BaseKJob.Configuration() { - var connectionString: String? = null - var driverClassName: String? = null - var connectionDatabase: Database? = null - - var jobTableName: String = "kjobJobs" - - var lockTableName: String = "kjobLocks" - - var expireLockInMinutes: Long = 5L - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/ExposedLockRepository.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/ExposedLockRepository.kt deleted file mode 100644 index f087f224..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/ExposedLockRepository.kt +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.core.infrastructure.kjobexposed - -import kjob.core.job.Lock -import kjob.core.repository.LockRepository -import kotlinx.coroutines.Dispatchers -import org.jetbrains.exposed.dao.id.UUIDTable -import org.jetbrains.exposed.sql.* -import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq -import org.jetbrains.exposed.sql.SqlExpressionBuilder.greater -import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction -import org.jetbrains.exposed.sql.transactions.transaction -import java.time.Clock -import java.time.Instant -import java.util.* -import kotlin.time.Duration.Companion.minutes - -class ExposedLockRepository( - private val database: Database, - private val config: ExposedKJob.Configuration, - private val clock: Clock -) : LockRepository { - - class Locks(tableName: String) : UUIDTable(tableName) { - val updatedAt = long("updatedAt") - val expiresAt = long("expiresAt") - } - - val locks: Locks = Locks(config.lockTableName) - - fun createTable() { - transaction(database) { - SchemaUtils.create(locks) - } - } - - @Suppress("InjectDispatcher") - suspend fun query(block: suspend () -> T): T = newSuspendedTransaction(Dispatchers.IO) { block() } - - override suspend fun exists(id: UUID): Boolean { - val now = Instant.now(clock) - return query { - locks.selectAll().where(locks.id eq id and locks.expiresAt.greater(now.toEpochMilli())).empty().not() - } - } - - override suspend fun ping(id: UUID): Lock { - val now = Instant.now(clock) - val expiresAt = now.plusSeconds(config.expireLockInMinutes.minutes.inWholeSeconds) - val lock = Lock(id, now) - query { - if (locks.selectAll().where(locks.id eq id).limit(1) - .map { Lock(it[locks.id].value, Instant.ofEpochMilli(it[locks.expiresAt])) }.isEmpty() - ) { - locks.insert { - it[locks.id] = id - it[locks.updatedAt] = now.toEpochMilli() - it[locks.expiresAt] = expiresAt.toEpochMilli() - } - } else { - locks.update({ locks.id eq id }) { - it[locks.updatedAt] = now.toEpochMilli() - it[locks.expiresAt] = expiresAt.toEpochMilli() - } - } - } - return lock - } - - suspend fun clearExpired() { - val now = Instant.now(clock).toEpochMilli() - query { - locks.deleteWhere { locks.expiresAt greater now } - } - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/KJobJobQueueParentService.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/KJobJobQueueParentService.kt deleted file mode 100644 index 68ace348..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/KJobJobQueueParentService.kt +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.core.infrastructure.kjobexposed - -import dev.usbharu.hideout.core.external.job.HideoutJob -import dev.usbharu.hideout.core.service.job.JobQueueParentService -import kjob.core.Job -import kjob.core.KJob -import kjob.core.dsl.ScheduleContext -import kjob.core.kjob -import org.jetbrains.exposed.sql.transactions.TransactionManager -import org.slf4j.LoggerFactory -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty -import org.springframework.stereotype.Service - -@Service -@ConditionalOnProperty(name = ["hideout.use-mongodb"], havingValue = "false", matchIfMissing = true) -class KJobJobQueueParentService : JobQueueParentService { - - private val logger = LoggerFactory.getLogger(this::class.java) - - val kjob: KJob by lazy { - kjob(ExposedKJob) { - connectionDatabase = TransactionManager.defaultDatabase - isWorker = false - }.start() - } - - override fun init(jobDefines: List) = Unit - - @Deprecated("use type safe → scheduleTypeSafe") - override suspend fun schedule(job: J, block: ScheduleContext.(J) -> Unit) { - logger.debug("schedule job={}", job.name) - kjob.schedule(job, block) - } - - override suspend fun > scheduleTypeSafe(job: J, jobProps: T) { - logger.debug("SCHEDULE Job: {}", job.name) - logger.trace("Job props: {}", jobProps) - val convert: ScheduleContext.(J) -> Unit = job.convert(jobProps) - kjob.schedule(job, convert) - logger.debug("SUCCESS Schedule Job: {}", job.name) - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/KJobJobQueueWorkerService.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/KJobJobQueueWorkerService.kt deleted file mode 100644 index d8df6469..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/KJobJobQueueWorkerService.kt +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.core.infrastructure.kjobexposed - -import dev.usbharu.hideout.core.external.job.HideoutJob -import dev.usbharu.hideout.core.service.job.JobProcessor -import dev.usbharu.hideout.core.service.job.JobQueueWorkerService -import kjob.core.dsl.JobContextWithProps -import kjob.core.dsl.JobRegisterContext -import kjob.core.dsl.KJobFunctions -import kjob.core.kjob -import org.jetbrains.exposed.sql.transactions.TransactionManager -import org.slf4j.MDC -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty -import org.springframework.stereotype.Service - -@Service -@ConditionalOnProperty(name = ["hideout.use-mongodb"], havingValue = "false", matchIfMissing = true) -class KJobJobQueueWorkerService(private val jobQueueProcessorList: List>) : JobQueueWorkerService { - - val kjob by lazy { - kjob(ExposedKJob) { - connectionDatabase = TransactionManager.defaultDatabase - nonBlockingMaxJobs = 10 - blockingMaxJobs = 10 - jobExecutionPeriodInSeconds = 1 - }.start() - } - - override fun > init( - defines: - List>.(R) -> KJobFunctions>>> - ) { - defines.forEach { job -> - kjob.register(job.first, job.second) - } - - for (jobProcessor in jobQueueProcessorList) { - kjob.register(jobProcessor.job()) { - execute { - @Suppress("TooGenericExceptionCaught") - try { - MDC.put("x-job-id", this.jobId) - val param = it.convertUnsafe(props) - jobProcessor.process(param) - } catch (e: Exception) { - logger.warn("FAILED Execute Job. job name: {} job id: {}", it.name, this.jobId, e) - throw e - } finally { - MDC.remove("x-job-id") - } - } - } - } - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobmongodb/KJobMongoJobQueueWorkerService.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobmongodb/KJobMongoJobQueueWorkerService.kt deleted file mode 100644 index dc5c15e1..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobmongodb/KJobMongoJobQueueWorkerService.kt +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.core.infrastructure.kjobmongodb - -import com.mongodb.reactivestreams.client.MongoClient -import dev.usbharu.hideout.core.external.job.HideoutJob -import dev.usbharu.hideout.core.service.job.JobProcessor -import dev.usbharu.hideout.core.service.job.JobQueueWorkerService -import kjob.core.dsl.JobContextWithProps -import kjob.core.dsl.JobRegisterContext -import kjob.core.dsl.KJobFunctions -import kjob.core.job.JobExecutionType -import kjob.core.kjob -import kjob.mongo.Mongo -import kotlinx.coroutines.CancellationException -import org.slf4j.MDC -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty -import org.springframework.stereotype.Service - -@Service -@ConditionalOnProperty(name = ["hideout.use-mongodb"], havingValue = "true", matchIfMissing = false) -class KJobMongoJobQueueWorkerService( - private val mongoClient: MongoClient, - private val jobQueueProcessorList: List> -) : JobQueueWorkerService, AutoCloseable { - val kjob by lazy { - kjob(Mongo) { - client = mongoClient - nonBlockingMaxJobs = 10 - blockingMaxJobs = 10 - jobExecutionPeriodInSeconds = 1 - maxRetries = 3 - defaultJobExecutor = JobExecutionType.NON_BLOCKING - }.start() - } - - override fun > init( - defines: - List>.(R) -> KJobFunctions>>> - ) { - defines.forEach { job -> - kjob.register(job.first, job.second) - } - for (jobProcessor in jobQueueProcessorList) { - kjob.register(jobProcessor.job()) { - execute { - @Suppress("TooGenericExceptionCaught") - try { - MDC.put("x-job-id", this.jobId) - val param = it.convertUnsafe(props) - jobProcessor.process(param) - } catch (e: CancellationException) { - throw e - } catch (e: Exception) { - logger.warn("FAILED Excute Job. job name: {} job id: {}", it.name, this.jobId, e) - throw e - } finally { - MDC.remove("x-job-id") - } - }.onError { - logger.warn("FAILED Excute Job. job name: {} job id: {}", this.jobName, this.jobId, error) - } - } - } - } - - override fun close() { - kjob.shutdown() - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobmongodb/KjobMongoJobQueueParentService.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobmongodb/KjobMongoJobQueueParentService.kt deleted file mode 100644 index b9e49f4c..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobmongodb/KjobMongoJobQueueParentService.kt +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.core.infrastructure.kjobmongodb - -import com.mongodb.reactivestreams.client.MongoClient -import dev.usbharu.hideout.core.external.job.HideoutJob -import dev.usbharu.hideout.core.service.job.JobQueueParentService -import kjob.core.Job -import kjob.core.dsl.ScheduleContext -import kjob.core.kjob -import kjob.mongo.Mongo -import org.slf4j.LoggerFactory -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty -import org.springframework.stereotype.Service - -@Service -@ConditionalOnProperty(name = ["hideout.use-mongodb"], havingValue = "true", matchIfMissing = false) -class KjobMongoJobQueueParentService(private val mongoClient: MongoClient) : JobQueueParentService, AutoCloseable { - private val kjob = kjob(Mongo) { - client = mongoClient - databaseName = "kjob" - jobCollection = "kjob-jobs" - lockCollection = "kjob-locks" - expireLockInMinutes = 5L - isWorker = false - }.start() - - override fun init(jobDefines: List) = Unit - - @Deprecated("use type safe → scheduleTypeSafe") - override suspend fun schedule(job: J, block: ScheduleContext.(J) -> Unit) { - logger.debug("SCHEDULE Job: {}", job.name) - kjob.schedule(job, block) - } - - override suspend fun > scheduleTypeSafe(job: J, jobProps: T) { - logger.debug("SCHEDULE Job: {}", job.name) - logger.trace("Job props: {}", jobProps) - val convert = job.convert(jobProps) - kjob.schedule(job, convert) - logger.debug("SUCCESS Job: {}", job.name) - } - - override fun close() { - kjob.shutdown() - } - - companion object { - private val logger = LoggerFactory.getLogger(KjobMongoJobQueueParentService::class.java) - } -} diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/BlockTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/BlockTest.kt deleted file mode 100644 index 33908843..00000000 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/domain/model/BlockTest.kt +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.activitypub.domain.model - -import com.fasterxml.jackson.module.kotlin.readValue -import dev.usbharu.hideout.application.config.ActivityPubConfig -import org.assertj.core.api.Assertions.assertThat -import org.intellij.lang.annotations.Language -import org.junit.jupiter.api.Test -import org.springframework.boot.test.json.BasicJsonTester - -class BlockTest { - @Test - fun blockDeserializeTest() { - @Language("JSON") val json = """{ - "@context" : [ "https://www.w3.org/ns/activitystreams", "https://w3id.org/security/v1", { - "manuallyApprovesFollowers" : "as:manuallyApprovesFollowers", - "sensitive" : "as:sensitive", - "Hashtag" : "as:Hashtag", - "quoteUrl" : "as:quoteUrl", - "toot" : "http://joinmastodon.org/ns#", - "Emoji" : "toot:Emoji", - "featured" : "toot:featured", - "discoverable" : "toot:discoverable", - "schema" : "http://schema.org#", - "PropertyValue" : "schema:PropertyValue", - "value" : "schema:value", - "misskey" : "https://misskey-hub.net/ns#", - "_misskey_content" : "misskey:_misskey_content", - "_misskey_quote" : "misskey:_misskey_quote", - "_misskey_reaction" : "misskey:_misskey_reaction", - "_misskey_votes" : "misskey:_misskey_votes", - "_misskey_summary" : "misskey:_misskey_summary", - "isCat" : "misskey:isCat", - "vcard" : "http://www.w3.org/2006/vcard/ns#" - } ], - "type" : "Block", - "id" : "https://misskey.usbharu.dev/blocks/9myf6e40vm", - "actor" : "https://misskey.usbharu.dev/users/97ws8y3rj6", - "object" : "https://test-hideout.usbharu.dev/users/test-user2" -} -""" - - val objectMapper = ActivityPubConfig().objectMapper() - - val block = objectMapper.readValue(json) - - val expected = Block( - "https://misskey.usbharu.dev/users/97ws8y3rj6", - "https://misskey.usbharu.dev/blocks/9myf6e40vm", - "https://test-hideout.usbharu.dev/users/test-user2" - ).apply { context = listOf("https://www.w3.org/ns/activitystreams", "https://w3id.org/security/v1") } - assertThat(block).isEqualTo(expected) - } - - @Test - fun blockSerializeTest() { - val basicJsonTester = BasicJsonTester(javaClass) - - val block = Block( - "https://misskey.usbharu.dev/users/97ws8y3rj6", - "https://misskey.usbharu.dev/blocks/9myf6e40vm", - "https://test-hideout.usbharu.dev/users/test-user2" - ).apply { context = listOf("https://www.w3.org/ns/activitystreams", "https://w3id.org/security/v1") } - - val objectMapper = ActivityPubConfig().objectMapper() - - val writeValueAsString = objectMapper.writeValueAsString(block) - - val from = basicJsonTester.from(writeValueAsString) - assertThat(from).extractingJsonPathStringValue("$.actor") - .isEqualTo("https://misskey.usbharu.dev/users/97ws8y3rj6") - assertThat(from).extractingJsonPathStringValue("$.id") - .isEqualTo("https://misskey.usbharu.dev/blocks/9myf6e40vm") - assertThat(from).extractingJsonPathStringValue("$.object") - .isEqualTo("https://test-hideout.usbharu.dev/users/test-user2") - assertThat(from).extractingJsonPathStringValue("$.type").isEqualTo("Block") - - } -} diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APDeliverAcceptJobProcessorTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APDeliverAcceptJobProcessorTest.kt deleted file mode 100644 index 30f59887..00000000 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APDeliverAcceptJobProcessorTest.kt +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.activitypub.service.activity.accept - -import dev.usbharu.hideout.activitypub.domain.model.Accept -import dev.usbharu.hideout.activitypub.domain.model.Follow -import dev.usbharu.hideout.activitypub.service.common.APRequestService -import dev.usbharu.hideout.core.domain.model.actor.ActorRepository -import dev.usbharu.hideout.core.external.job.DeliverAcceptJob -import dev.usbharu.hideout.core.external.job.DeliverAcceptJobParam -import kotlinx.coroutines.test.runTest -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -import org.mockito.InjectMocks -import org.mockito.Mock -import org.mockito.Spy -import org.mockito.junit.jupiter.MockitoExtension -import org.mockito.kotlin.* -import utils.TestTransaction -import utils.UserBuilder - -@ExtendWith(MockitoExtension::class) -class APDeliverAcceptJobProcessorTest { - - @Mock - private lateinit var apRequestService: APRequestService - - @Mock - private lateinit var actorRepository: ActorRepository - - @Mock - private lateinit var deliverAcceptJob: DeliverAcceptJob - - @Spy - private val transaction = TestTransaction - - @InjectMocks - private lateinit var apDeliverAcceptJobProcessor: APDeliverAcceptJobProcessor - - @Test - fun `process apPostが発行される`() = runTest { - val user = UserBuilder.localUserOf() - - whenever(actorRepository.findById(eq(1))).doReturn(user) - - val accept = Accept( - apObject = Follow( - apObject = "https://example.com", - actor = "https://remote.example.com" - ), - actor = "https://example.com" - ) - val param = DeliverAcceptJobParam( - accept = accept, - "https://remote.example.com", - 1 - ) - - apDeliverAcceptJobProcessor.process(param) - - verify(apRequestService, times(1)).apPost(eq("https://remote.example.com"), eq(accept), eq(user)) - } - - @Test - fun `job DeliverAcceptJobが返ってくる`() { - val actual = apDeliverAcceptJobProcessor.job() - - assertThat(actual).isEqualTo(deliverAcceptJob) - - } -} diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApSendAcceptServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApSendAcceptServiceImplTest.kt deleted file mode 100644 index b3b8e79b..00000000 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApSendAcceptServiceImplTest.kt +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.activitypub.service.activity.accept - -import dev.usbharu.hideout.activitypub.domain.model.Accept -import dev.usbharu.hideout.activitypub.domain.model.Follow -import dev.usbharu.hideout.core.external.job.DeliverAcceptJob -import dev.usbharu.hideout.core.external.job.DeliverAcceptJobParam -import dev.usbharu.hideout.core.service.job.JobQueueParentService -import kotlinx.coroutines.test.runTest -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -import org.mockito.InjectMocks -import org.mockito.Mock -import org.mockito.junit.jupiter.MockitoExtension -import org.mockito.kotlin.eq -import org.mockito.kotlin.times -import org.mockito.kotlin.verify -import utils.UserBuilder - -@ExtendWith(MockitoExtension::class) -class ApSendAcceptServiceImplTest { - - @Mock - private lateinit var jobQueueParentService: JobQueueParentService - - @Mock - private lateinit var deliverAcceptJob: DeliverAcceptJob - - @InjectMocks - private lateinit var apSendAcceptServiceImpl: ApSendAcceptServiceImpl - - @Test - fun `sendAccept DeliverAcceptJobが発行される`() = runTest { - val user = UserBuilder.localUserOf() - val remoteUser = UserBuilder.remoteUserOf() - - apSendAcceptServiceImpl.sendAcceptFollow(user, remoteUser) - - val deliverAcceptJobParam = DeliverAcceptJobParam( - Accept(apObject = Follow(apObject = user.url, actor = remoteUser.url), actor = user.url), - remoteUser.inbox, - user.id - ) - verify(jobQueueParentService, times(1)).scheduleTypeSafe(eq(deliverAcceptJob), eq(deliverAcceptJobParam)) - } -} diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/block/APDeliverBlockJobProcessorTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/block/APDeliverBlockJobProcessorTest.kt deleted file mode 100644 index 2b7ba4d0..00000000 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/block/APDeliverBlockJobProcessorTest.kt +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.activitypub.service.activity.block - -import dev.usbharu.hideout.activitypub.domain.model.Block -import dev.usbharu.hideout.activitypub.domain.model.Follow -import dev.usbharu.hideout.activitypub.domain.model.Reject -import dev.usbharu.hideout.activitypub.service.common.APRequestService -import dev.usbharu.hideout.core.domain.model.actor.ActorRepository -import dev.usbharu.hideout.core.external.job.DeliverBlockJob -import dev.usbharu.hideout.core.external.job.DeliverBlockJobParam -import kotlinx.coroutines.test.runTest -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -import org.mockito.InjectMocks -import org.mockito.Mock -import org.mockito.Spy -import org.mockito.junit.jupiter.MockitoExtension -import org.mockito.kotlin.* -import utils.TestTransaction -import utils.UserBuilder - -@ExtendWith(MockitoExtension::class) -class APDeliverBlockJobProcessorTest { - - @Mock - private lateinit var apRequestService: APRequestService - - @Mock - private lateinit var actorRepository: ActorRepository - - @Spy - private val transaction = TestTransaction - - @Mock - private lateinit var deliverBlockJob: DeliverBlockJob - - @InjectMocks - private lateinit var apDeliverBlockJobProcessor: APDeliverBlockJobProcessor - - @Test - fun `process rejectとblockがapPostされる`() = runTest { - val user = UserBuilder.localUserOf() - whenever(actorRepository.findById(eq(user.id))).doReturn(user) - - - val block = Block( - actor = user.url, - "https://example.com/block", - apObject = "https://remote.example.com" - ) - val reject = Reject( - actor = user.url, - "https://example.com/reject/follow", - apObject = Follow( - apObject = user.url, - actor = "https://remote.example.com" - ) - ) - val param = DeliverBlockJobParam( - user.id, - block, - reject, - "https://remote.example.com" - ) - - - apDeliverBlockJobProcessor.process(param) - - verify(apRequestService, times(1)).apPost(eq("https://remote.example.com"), eq(block), eq(user)) - verify(apRequestService, times(1)).apPost(eq("https://remote.example.com"), eq(reject), eq(user)) - } - - @Test - fun `job deliverBlockJobが返ってくる`() { - val actual = apDeliverBlockJobProcessor.job() - assertThat(actual).isEqualTo(deliverBlockJob) - } -} diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateServiceImplTest.kt deleted file mode 100644 index 74377eff..00000000 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateServiceImplTest.kt +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.activitypub.service.activity.create - -import com.fasterxml.jackson.databind.ObjectMapper -import dev.usbharu.hideout.activitypub.domain.model.Note -import dev.usbharu.hideout.activitypub.query.NoteQueryService -import dev.usbharu.hideout.activitypub.service.objects.note.APNoteServiceImpl -import dev.usbharu.hideout.application.config.ActivityPubConfig -import dev.usbharu.hideout.application.config.ApplicationConfig -import dev.usbharu.hideout.core.domain.model.actor.ActorRepository -import dev.usbharu.hideout.core.external.job.DeliverPostJob -import dev.usbharu.hideout.core.query.FollowerQueryService -import dev.usbharu.hideout.core.service.job.JobQueueParentService -import kotlinx.coroutines.test.runTest -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -import org.mockito.InjectMocks -import org.mockito.Mock -import org.mockito.Spy -import org.mockito.junit.jupiter.MockitoExtension -import org.mockito.kotlin.* -import utils.PostBuilder -import utils.UserBuilder -import java.net.URL -import java.time.Instant - -@ExtendWith(MockitoExtension::class) -class ApSendCreateServiceImplTest { - - @Mock - private lateinit var followerQueryService: FollowerQueryService - - @Spy - private val objectMapper: ObjectMapper = ActivityPubConfig().objectMapper() - - @Mock - private lateinit var jobQueueParentService: JobQueueParentService - - @Mock - private lateinit var actorRepository: ActorRepository - - @Mock - private lateinit var noteQueryService: NoteQueryService - - @Spy - private val applicationConfig: ApplicationConfig = ApplicationConfig(URL("https://example.com")) - - @InjectMocks - private lateinit var apSendCreateServiceImpl: ApSendCreateServiceImpl - - @Test - fun `createNote 正常なPostでCreateのジョブを発行できる`() = runTest { - val post = PostBuilder.of() - val user = UserBuilder.localUserOf(id = post.actorId) - val note = Note( - id = post.apId, - attributedTo = user.url, - content = post.text, - published = Instant.ofEpochMilli(post.createdAt).toString(), - to = listOfNotNull(APNoteServiceImpl.public, user.followers), - sensitive = post.sensitive, - cc = listOfNotNull(APNoteServiceImpl.public, user.followers), - inReplyTo = null - ) - val followers = listOf( - UserBuilder.remoteUserOf(), - UserBuilder.remoteUserOf(), - UserBuilder.remoteUserOf() - ) - - whenever(followerQueryService.findFollowersById(eq(post.actorId))).doReturn(followers) - whenever(actorRepository.findById(eq(post.actorId))).doReturn(user) - whenever(noteQueryService.findById(eq(post.id))).doReturn(note to post) - - apSendCreateServiceImpl.createNote(post) - - verify(jobQueueParentService, times(followers.size)).schedule(eq(DeliverPostJob), any()) - } -} diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionServiceImplTest.kt deleted file mode 100644 index 5bed662e..00000000 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionServiceImplTest.kt +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2024 usbharu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.usbharu.hideout.activitypub.service.activity.like - - -import dev.usbharu.hideout.application.service.id.TwitterSnowflakeIdGenerateService -import dev.usbharu.hideout.core.domain.model.actor.ActorRepository -import dev.usbharu.hideout.core.domain.model.emoji.UnicodeEmoji -import dev.usbharu.hideout.core.domain.model.post.PostRepository -import dev.usbharu.hideout.core.domain.model.reaction.Reaction -import dev.usbharu.hideout.core.external.job.DeliverReactionJob -import dev.usbharu.hideout.core.external.job.DeliverRemoveReactionJob -import dev.usbharu.hideout.core.query.FollowerQueryService -import dev.usbharu.hideout.core.service.job.JobQueueParentService -import kotlinx.coroutines.test.runTest -import org.junit.jupiter.api.Test -import org.mockito.kotlin.* -import utils.JsonObjectMapper.objectMapper -import utils.PostBuilder -import utils.UserBuilder - -class APReactionServiceImplTest { - @Test - fun `reaction リアクションするとフォロワーの数だけ配送ジョブが作成される`() = runTest { - - val user = UserBuilder.localUserOf() - val post = PostBuilder.of() - - val postQueryService = mock { - onBlocking { findById(eq(post.id)) } doReturn post - } - val followerQueryService = mock { - onBlocking { findFollowersById(eq(user.id)) } doReturn listOf( - UserBuilder.localUserOf(), - UserBuilder.localUserOf(), - UserBuilder.localUserOf() - ) - } - val jobQueueParentService = mock() - val actorRepository = mock { - onBlocking { findById(eq(user.id)) }.doReturn(user) - } - val apReactionServiceImpl = APReactionServiceImpl( - jobQueueParentService = jobQueueParentService, - actorRepository = actorRepository, - followerQueryService = followerQueryService, - postRepository = postQueryService, - objectMapper = objectMapper - ) - - apReactionServiceImpl.reaction( - Reaction( - id = TwitterSnowflakeIdGenerateService.generateId(), - emoji = UnicodeEmoji("❤"), - postId = post.id, - actorId = user.id - ) - ) - - verify(jobQueueParentService, times(3)).schedule(eq(DeliverReactionJob), any()) - } - - @Test - fun `removeReaction リアクションを削除するとフォロワーの数だけ配送ジョブが作成される`() = runTest { - - val user = UserBuilder.localUserOf() - val post = PostBuilder.of() - - val postQueryService = mock { - onBlocking { findById(eq(post.id)) } doReturn post - } - val followerQueryService = mock { - onBlocking { findFollowersById(eq(user.id)) } doReturn listOf( - UserBuilder.localUserOf(), - UserBuilder.localUserOf(), - UserBuilder.localUserOf() - ) - } - val jobQueueParentService = mock() - val actorRepository = mock { - onBlocking { findById(eq(user.id)) }.doReturn(user) - } - val apReactionServiceImpl = APReactionServiceImpl( - jobQueueParentService = jobQueueParentService, - actorRepository = actorRepository, - followerQueryService = followerQueryService, - postRepository = postQueryService, - objectMapper = objectMapper - ) - - apReactionServiceImpl.removeReaction( - Reaction( - id = TwitterSnowflakeIdGenerateService.generateId(), - emoji = UnicodeEmoji("❤"), - postId = post.id, - actorId = user.id - ) - ) - - verify(jobQueueParentService, times(3)).schedule(eq(DeliverRemoveReactionJob), any()) - } -}