diff --git a/features/common/README.md b/features/common/README.md new file mode 100644 index 00000000..4c24ffb9 --- /dev/null +++ b/features/common/README.md @@ -0,0 +1,26 @@ +# Common + +In that readme will be stored several notes about working with common parts in all your modules + +## ModuleLoader + +This module has been created to allow your plugins to load dynamically after build of the server and client + +### Server + +To declare your module loader you should create **_class_** realization of `ServerModuleLoader` and put the classname of that +realization into the `modules` section as a string. + +### Client + +On the client side you also should create your own realization of `ModuleLoader`, but instead of some config you will +need to create some `private val` property on the top level in your `ModuleLoader` realization file. Example: + +```kotlin + +object SomeModuleLoader : ModuleLoader { + // body +} + +private val someModuleLoaderProperty = AdditionalModules.addModule(SomeModuleLoader) // that is important part +``` diff --git a/features/common/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/common/server/sessions/Qualifiers.kt b/features/common/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/common/server/sessions/Qualifiers.kt new file mode 100644 index 00000000..de374e5f --- /dev/null +++ b/features/common/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/common/server/sessions/Qualifiers.kt @@ -0,0 +1,15 @@ +package dev.inmo.postssystem.features.common.server.sessions + +import org.koin.core.qualifier.StringQualifier + +object Qualifiers { + val binaryFilesFolderQualifier = StringQualifier("binaryFilesFolder") + val originalFilesMetasKeyValueRepoQualifier = StringQualifier("OriginalFilesMetaKV") + val binaryOriginalFilesMetasKeyValueRepoQualifier = StringQualifier("BinaryOriginalFilesMetaKV") + val commonFilesMetasKeyValueRepoQualifier = StringQualifier("CommonFilesMetaKV") + val binaryFilesMetasKeyValueRepoQualifier = StringQualifier("BinaryFilesMetaKV") + val filesFolderQualifier = StringQualifier("rootFilesFolder") + val commonFilesFolderQualifier = StringQualifier("commonFilesFolder") + val usersRolesKeyValueFactoryQualifier = StringQualifier("usersRolesKeyValueFactory") + val binaryStorageFilesQualifier = StringQualifier("binaryContentFiles") +} diff --git a/features/common/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/common/server/sessions/ModuleLoader.kt b/features/common/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/common/server/sessions/ServerModuleLoader.kt similarity index 85% rename from features/common/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/common/server/sessions/ModuleLoader.kt rename to features/common/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/common/server/sessions/ServerModuleLoader.kt index ee1c2f10..d3e2ee87 100644 --- a/features/common/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/common/server/sessions/ModuleLoader.kt +++ b/features/common/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/common/server/sessions/ServerModuleLoader.kt @@ -3,6 +3,6 @@ package dev.inmo.postssystem.features.common.server.sessions import kotlinx.serialization.json.JsonObject import org.koin.core.module.Module -interface ModuleLoader { +interface ServerModuleLoader { fun Module.load(config: JsonObject) } diff --git a/features/content/README.md b/features/content/README.md index e5bfee12..30abf30a 100644 --- a/features/content/README.md +++ b/features/content/README.md @@ -35,3 +35,14 @@ For example, you want to create content named `MyFormat`. To do this, you must p ```kotlin singleWithRandomQualifier { MyFormatContentSerializerModuleConfigurator } ``` + +## Client + +**Currently, this information is actual only for JS (browser) clients. Other client platforms will be added later** + +Besides, you may (and it is strongly recommended to) create your own client `ContentClientProvider` realization. +This realization will contain all main functions for drawing of content on the client side. + +## Server + +On the server side it is required to diff --git a/features/content/binary/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/content/binary/server/BinaryContentServerModuleLoader.kt b/features/content/binary/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/content/binary/server/BinaryContentServerModuleLoader.kt new file mode 100644 index 00000000..a4a7f73d --- /dev/null +++ b/features/content/binary/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/content/binary/server/BinaryContentServerModuleLoader.kt @@ -0,0 +1,20 @@ +package dev.inmo.postssystem.features.content.binary.server + +import dev.inmo.postssystem.features.common.common.singleWithRandomQualifier +import dev.inmo.postssystem.features.common.server.sessions.Qualifiers +import dev.inmo.postssystem.features.common.server.sessions.ServerModuleLoader +import dev.inmo.postssystem.features.content.common.BinaryContent +import dev.inmo.postssystem.features.content.server.ServerContentStorageWrapper +import kotlinx.serialization.json.JsonObject +import org.koin.core.module.Module + +class BinaryContentServerModuleLoader : ServerModuleLoader { + override fun Module.load(config: JsonObject) { + singleWithRandomQualifier { + ServerContentStorageWrapper( + BinaryServerContentStorage(get(Qualifiers.binaryStorageFilesQualifier)), + BinaryContent::class + ) + } + } +} diff --git a/features/content/text/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/content/text/server/TextContentServerModuleLoader.kt b/features/content/text/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/content/text/server/TextContentServerModuleLoader.kt new file mode 100644 index 00000000..bcc327b3 --- /dev/null +++ b/features/content/text/server/src/jvmMain/kotlin/dev/inmo/postssystem/features/content/text/server/TextContentServerModuleLoader.kt @@ -0,0 +1,22 @@ +package dev.inmo.postssystem.features.content.text.server + +import dev.inmo.postssystem.features.common.common.singleWithRandomQualifier +import dev.inmo.postssystem.features.common.server.sessions.ServerModuleLoader +import dev.inmo.postssystem.features.content.common.ContentSerializersModuleConfigurator +import dev.inmo.postssystem.features.content.server.ServerContentStorageWrapper +import dev.inmo.postssystem.features.content.text.common.TextContent +import dev.inmo.postssystem.features.content.text.common.TextContentSerializerModuleConfigurator +import kotlinx.serialization.json.JsonObject +import org.koin.core.module.Module + +class TextContentServerModuleLoader : ServerModuleLoader { + override fun Module.load(config: JsonObject) { + singleWithRandomQualifier { TextContentSerializerModuleConfigurator } + singleWithRandomQualifier { + ServerContentStorageWrapper( + TextServerContentStorage(get()), + TextContent::class + ) + } + } +} diff --git a/publicators/simple/server/src/jvmMain/kotlin/dev/inmo/postssystem/publicators/simple/server/SimplePublicationTriggerLoader.kt b/publicators/simple/server/src/jvmMain/kotlin/dev/inmo/postssystem/publicators/simple/server/SimplePublicationTriggerLoaderServer.kt similarity index 78% rename from publicators/simple/server/src/jvmMain/kotlin/dev/inmo/postssystem/publicators/simple/server/SimplePublicationTriggerLoader.kt rename to publicators/simple/server/src/jvmMain/kotlin/dev/inmo/postssystem/publicators/simple/server/SimplePublicationTriggerLoaderServer.kt index b36deb7e..abc0b0fa 100644 --- a/publicators/simple/server/src/jvmMain/kotlin/dev/inmo/postssystem/publicators/simple/server/SimplePublicationTriggerLoader.kt +++ b/publicators/simple/server/src/jvmMain/kotlin/dev/inmo/postssystem/publicators/simple/server/SimplePublicationTriggerLoaderServer.kt @@ -2,11 +2,11 @@ package dev.inmo.postssystem.publicators.simple.server import dev.inmo.micro_utils.ktor.server.configurators.ApplicationRoutingConfigurator import dev.inmo.postssystem.features.common.common.singleWithRandomQualifier -import dev.inmo.postssystem.features.common.server.sessions.ModuleLoader +import dev.inmo.postssystem.features.common.server.sessions.ServerModuleLoader import kotlinx.serialization.json.JsonObject import org.koin.core.module.Module -class SimplePublicationTriggerLoader : ModuleLoader { +class SimplePublicationTriggerLoaderServer : ServerModuleLoader { override fun Module.load(config: JsonObject) { singleWithRandomQualifier { SimplePublicatorRoutingConfigurator( diff --git a/server/src/main/java/dev/inmo/postssystem/server/Config.kt b/server/src/main/java/dev/inmo/postssystem/server/Config.kt index 7c798b1a..cb73f270 100644 --- a/server/src/main/java/dev/inmo/postssystem/server/Config.kt +++ b/server/src/main/java/dev/inmo/postssystem/server/Config.kt @@ -1,6 +1,6 @@ package dev.inmo.postssystem.server -import dev.inmo.postssystem.features.common.server.sessions.ModuleLoader +import dev.inmo.postssystem.features.common.server.sessions.ServerModuleLoader import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import java.io.File @@ -25,7 +25,7 @@ data class Config( val modules by lazy { modulesClassPaths.mapNotNull { moduleClassPath -> runCatching { - Class.forName(moduleClassPath).constructors.firstOrNull { it.parameterCount == 0 } ?.newInstance() as ModuleLoader + Class.forName(moduleClassPath).constructors.firstOrNull { it.parameterCount == 0 } ?.newInstance() as ServerModuleLoader }.onFailure { println("Unable to load $moduleClassPath") it.printStackTrace() diff --git a/server/src/main/java/dev/inmo/postssystem/server/DI.kt b/server/src/main/java/dev/inmo/postssystem/server/DI.kt index 9ca2d5fc..3186bfc9 100644 --- a/server/src/main/java/dev/inmo/postssystem/server/DI.kt +++ b/server/src/main/java/dev/inmo/postssystem/server/DI.kt @@ -25,19 +25,13 @@ import dev.inmo.micro_utils.ktor.server.createKtorServer import dev.inmo.micro_utils.repos.exposed.keyvalue.ExposedKeyValueRepo import dev.inmo.micro_utils.repos.exposed.onetomany.ExposedOneToManyKeyValueRepo import dev.inmo.postssystem.features.common.common.* -import dev.inmo.postssystem.features.content.binary.server.BinaryServerContentStorage +import dev.inmo.postssystem.features.common.server.sessions.Qualifiers import dev.inmo.postssystem.features.content.common.* import dev.inmo.postssystem.features.content.server.ServerContentStorageAggregator -import dev.inmo.postssystem.features.content.server.ServerContentStorageWrapper import dev.inmo.postssystem.features.content.server.storage.* -import dev.inmo.postssystem.features.content.text.common.TextContent -import dev.inmo.postssystem.features.content.text.common.TextContentSerializerModuleConfigurator -import dev.inmo.postssystem.features.content.text.server.TextServerContentStorage import dev.inmo.postssystem.features.posts.server.* import dev.inmo.postssystem.features.publication.server.PublicationManager -import dev.inmo.postssystem.features.publication.server.PublicationTarget import dev.inmo.postssystem.services.posts.server.* -import dev.inmo.postssystem.targets.telegram.publication.server.PublicationTargetTelegram import io.ktor.application.featureOrNull import io.ktor.application.log import io.ktor.routing.Route @@ -56,7 +50,6 @@ import org.koin.core.module.Module import org.koin.core.parameter.ParametersHolder import org.koin.core.qualifier.StringQualifier import org.koin.dsl.* -import org.w3c.dom.Text import java.io.File private fun Route.print() { @@ -77,18 +70,8 @@ fun getDIModule( val configJsonElement = configJson.decodeFromString(JsonObject.serializer(), File(args.first()).readText()) val config = configJson.decodeFromJsonElement(Config.serializer(), configJsonElement) - val originalFilesMetasKeyValueRepoQualifier = StringQualifier("OriginalFilesMetaKV") - val binaryOriginalFilesMetasKeyValueRepoQualifier = StringQualifier("BinaryOriginalFilesMetaKV") - val commonFilesMetasKeyValueRepoQualifier = StringQualifier("CommonFilesMetaKV") - val binaryFilesMetasKeyValueRepoQualifier = StringQualifier("BinaryFilesMetaKV") - val filesFolderQualifier = StringQualifier("rootFilesFolder") - val commonFilesFolderQualifier = StringQualifier("commonFilesFolder") - val binaryFilesFolderQualifier = StringQualifier("binaryFilesFolder") - val usersRolesKeyValueFactoryQualifier = StringQualifier("usersRolesKeyValueFactory") - return module { singleWithRandomQualifier { OtherContentSerializerModuleConfigurator } - singleWithRandomQualifier { TextContentSerializerModuleConfigurator } singleWithRandomQualifier { ContentSerializersModuleConfigurator(getAll()) } single { SerializersModuleConfigurator(getAll()) } @@ -110,34 +93,34 @@ fun getDIModule( singleWithBinds { config } singleWithBinds { get().databaseConfig } singleWithBinds { get().authConfig } - singleWithBinds(filesFolderQualifier) { get().filesFolderFile } - singleWithBinds(commonFilesFolderQualifier) { get().commonFilesFolder } - singleWithBinds(binaryFilesFolderQualifier) { get().binaryFilesFolder } + singleWithBinds(Qualifiers.filesFolderQualifier) { get().filesFolderFile } + singleWithBinds(Qualifiers.commonFilesFolderQualifier) { get().commonFilesFolder } + singleWithBinds(Qualifiers.binaryFilesFolderQualifier) { get().binaryFilesFolder } singleWithBinds { get().database } - singleWithBinds(originalFilesMetasKeyValueRepoQualifier) { + singleWithBinds(Qualifiers.originalFilesMetasKeyValueRepoQualifier) { ExposedKeyValueRepo(get(), { text("fileid") }, { text("metaInfo") }, "FileIdsToMetas") } - singleWithBinds(binaryOriginalFilesMetasKeyValueRepoQualifier) { + singleWithBinds(Qualifiers.binaryOriginalFilesMetasKeyValueRepoQualifier) { ExposedKeyValueRepo(get(), { text("fileid") }, { text("metaInfo") }, "BinaryContentFileIdsToMetas") } - singleWithBinds(commonFilesMetasKeyValueRepoQualifier) { + singleWithBinds(Qualifiers.commonFilesMetasKeyValueRepoQualifier) { MetasKeyValueRepo( get(), - get(originalFilesMetasKeyValueRepoQualifier) + get(Qualifiers.originalFilesMetasKeyValueRepoQualifier) ) } - single { DiskReadFilesStorage(get(commonFilesFolderQualifier), get(commonFilesMetasKeyValueRepoQualifier)) } - single { WriteDistFilesStorage(get(commonFilesFolderQualifier), get(commonFilesMetasKeyValueRepoQualifier)) } + single { DiskReadFilesStorage(get(Qualifiers.commonFilesFolderQualifier), get(Qualifiers.commonFilesMetasKeyValueRepoQualifier)) } + single { WriteDistFilesStorage(get(Qualifiers.commonFilesFolderQualifier), get(Qualifiers.commonFilesMetasKeyValueRepoQualifier)) } single { DefaultFilesStorage(get(), get()) } singleWithBinds { ExposedUsersStorage(get()) } singleWithBinds { exposedUsersAuthenticator(get(), get()) } - factory(usersRolesKeyValueFactoryQualifier) { (tableName: String) -> + factory(Qualifiers.usersRolesKeyValueFactoryQualifier) { (tableName: String) -> ExposedOneToManyKeyValueRepo(get(), { text("subject") }, { text("role") }, tableName) } single { - RolesManagerRoleStorage(get(usersRolesKeyValueFactoryQualifier) { ParametersHolder(mutableListOf("rolesManager")) }) + RolesManagerRoleStorage(get(Qualifiers.usersRolesKeyValueFactoryQualifier) { ParametersHolder(mutableListOf("rolesManager")) }) } single>(StringQualifier("RolesManagerRoleStorage")) { get() } singleWithBinds { @@ -156,29 +139,16 @@ fun getDIModule( factory { baseScope.LinkedSupervisorScope() } // Content storages - val binaryStorageFilesQualifier = StringQualifier("binaryContentFiles") - singleWithBinds(binaryFilesMetasKeyValueRepoQualifier) { + singleWithBinds(Qualifiers.binaryFilesMetasKeyValueRepoQualifier) { MetasKeyValueRepo( get(), - get(binaryOriginalFilesMetasKeyValueRepoQualifier) + get(Qualifiers.binaryOriginalFilesMetasKeyValueRepoQualifier) ) } - single(binaryStorageFilesQualifier) { + single(Qualifiers.binaryStorageFilesQualifier) { DefaultFilesStorage( - DiskReadFilesStorage(get(binaryFilesFolderQualifier), get(binaryFilesMetasKeyValueRepoQualifier)), - WriteDistFilesStorage(get(binaryFilesFolderQualifier), get(binaryFilesMetasKeyValueRepoQualifier)) - ) - } - singleWithRandomQualifier { - ServerContentStorageWrapper( - BinaryServerContentStorage(get(binaryStorageFilesQualifier)), - BinaryContent::class - ) - } - singleWithRandomQualifier { - ServerContentStorageWrapper( - TextServerContentStorage(get()), - TextContent::class + DiskReadFilesStorage(get(Qualifiers.binaryFilesFolderQualifier), get(Qualifiers.binaryFilesMetasKeyValueRepoQualifier)), + WriteDistFilesStorage(get(Qualifiers.binaryFilesFolderQualifier), get(Qualifiers.binaryFilesMetasKeyValueRepoQualifier)) ) } diff --git a/server/test.config.json b/server/test.config.json index f466f907..acb91b87 100644 --- a/server/test.config.json +++ b/server/test.config.json @@ -7,8 +7,10 @@ "filesFolder": "/tmp/files", "debugMode": true, "modules": [ - "dev.inmo.postssystem.targets.telegram.loader.server.TelegramTargetModuleLoader", - "dev.inmo.postssystem.publicators.simple.server.SimplePublicationTriggerLoader" + "dev.inmo.postssystem.features.content.text.server.TextContentServerModuleLoader", + "dev.inmo.postssystem.features.content.binary.server.BinaryContentServerModuleLoader", + "dev.inmo.postssystem.targets.telegram.loader.server.TelegramTargetServerModuleLoader", + "dev.inmo.postssystem.publicators.simple.server.SimplePublicationTriggerLoaderServer" ], "telegram": { "botToken": "YOUR BOT TOKEN", diff --git a/targets/telegram/loader/server/src/jvmMain/kotlin/dev/inmo/postssystem/targets/telegram/loader/server/TelegramTargetModuleLoader.kt b/targets/telegram/loader/server/src/jvmMain/kotlin/dev/inmo/postssystem/targets/telegram/loader/server/TelegramTargetServerModuleLoader.kt similarity index 92% rename from targets/telegram/loader/server/src/jvmMain/kotlin/dev/inmo/postssystem/targets/telegram/loader/server/TelegramTargetModuleLoader.kt rename to targets/telegram/loader/server/src/jvmMain/kotlin/dev/inmo/postssystem/targets/telegram/loader/server/TelegramTargetServerModuleLoader.kt index ac1967ff..770e1afe 100644 --- a/targets/telegram/loader/server/src/jvmMain/kotlin/dev/inmo/postssystem/targets/telegram/loader/server/TelegramTargetModuleLoader.kt +++ b/targets/telegram/loader/server/src/jvmMain/kotlin/dev/inmo/postssystem/targets/telegram/loader/server/TelegramTargetServerModuleLoader.kt @@ -1,7 +1,7 @@ package dev.inmo.postssystem.targets.telegram.loader.server import dev.inmo.postssystem.features.common.common.singleWithRandomQualifier -import dev.inmo.postssystem.features.common.server.sessions.ModuleLoader +import dev.inmo.postssystem.features.common.server.sessions.ServerModuleLoader import dev.inmo.postssystem.features.content.common.ContentSerializersModuleConfigurator import dev.inmo.postssystem.features.publication.server.PublicationTarget import dev.inmo.postssystem.targets.telegram.content.polls.common.PollContent @@ -16,7 +16,7 @@ import org.koin.core.qualifier.StringQualifier /** * Expects to get a config from a field "telegram" of your config */ -class TelegramTargetModuleLoader : ModuleLoader { +class TelegramTargetServerModuleLoader : ServerModuleLoader { override fun Module.load(config: JsonObject) { val configJson = config["telegram"]