add information about content client provider to readme

This commit is contained in:
InsanusMokrassar 2022-03-18 00:04:04 +06:00
parent 1dafe0a679
commit 709e7a8583
11 changed files with 122 additions and 56 deletions

26
features/common/README.md Normal file
View File

@ -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
```

View File

@ -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")
}

View File

@ -3,6 +3,6 @@ package dev.inmo.postssystem.features.common.server.sessions
import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonObject
import org.koin.core.module.Module import org.koin.core.module.Module
interface ModuleLoader { interface ServerModuleLoader {
fun Module.load(config: JsonObject) fun Module.load(config: JsonObject)
} }

View File

@ -35,3 +35,14 @@ For example, you want to create content named `MyFormat`. To do this, you must p
```kotlin ```kotlin
singleWithRandomQualifier<ContentSerializersModuleConfigurator.Element> { MyFormatContentSerializerModuleConfigurator } singleWithRandomQualifier<ContentSerializersModuleConfigurator.Element> { 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

View File

@ -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
)
}
}
}

View File

@ -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<ContentSerializersModuleConfigurator.Element> { TextContentSerializerModuleConfigurator }
singleWithRandomQualifier {
ServerContentStorageWrapper(
TextServerContentStorage(get()),
TextContent::class
)
}
}
}

View File

@ -2,11 +2,11 @@ package dev.inmo.postssystem.publicators.simple.server
import dev.inmo.micro_utils.ktor.server.configurators.ApplicationRoutingConfigurator import dev.inmo.micro_utils.ktor.server.configurators.ApplicationRoutingConfigurator
import dev.inmo.postssystem.features.common.common.singleWithRandomQualifier 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 kotlinx.serialization.json.JsonObject
import org.koin.core.module.Module import org.koin.core.module.Module
class SimplePublicationTriggerLoader : ModuleLoader { class SimplePublicationTriggerLoaderServer : ServerModuleLoader {
override fun Module.load(config: JsonObject) { override fun Module.load(config: JsonObject) {
singleWithRandomQualifier<ApplicationRoutingConfigurator.Element> { singleWithRandomQualifier<ApplicationRoutingConfigurator.Element> {
SimplePublicatorRoutingConfigurator( SimplePublicatorRoutingConfigurator(

View File

@ -1,6 +1,6 @@
package dev.inmo.postssystem.server 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.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import java.io.File import java.io.File
@ -25,7 +25,7 @@ data class Config(
val modules by lazy { val modules by lazy {
modulesClassPaths.mapNotNull { moduleClassPath -> modulesClassPaths.mapNotNull { moduleClassPath ->
runCatching { runCatching {
Class.forName(moduleClassPath).constructors.firstOrNull { it.parameterCount == 0 } ?.newInstance() as ModuleLoader Class.forName(moduleClassPath).constructors.firstOrNull { it.parameterCount == 0 } ?.newInstance() as ServerModuleLoader
}.onFailure { }.onFailure {
println("Unable to load $moduleClassPath") println("Unable to load $moduleClassPath")
it.printStackTrace() it.printStackTrace()

View File

@ -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.keyvalue.ExposedKeyValueRepo
import dev.inmo.micro_utils.repos.exposed.onetomany.ExposedOneToManyKeyValueRepo import dev.inmo.micro_utils.repos.exposed.onetomany.ExposedOneToManyKeyValueRepo
import dev.inmo.postssystem.features.common.common.* 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.common.*
import dev.inmo.postssystem.features.content.server.ServerContentStorageAggregator 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.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.posts.server.*
import dev.inmo.postssystem.features.publication.server.PublicationManager 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.services.posts.server.*
import dev.inmo.postssystem.targets.telegram.publication.server.PublicationTargetTelegram
import io.ktor.application.featureOrNull import io.ktor.application.featureOrNull
import io.ktor.application.log import io.ktor.application.log
import io.ktor.routing.Route 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.parameter.ParametersHolder
import org.koin.core.qualifier.StringQualifier import org.koin.core.qualifier.StringQualifier
import org.koin.dsl.* import org.koin.dsl.*
import org.w3c.dom.Text
import java.io.File import java.io.File
private fun Route.print() { private fun Route.print() {
@ -77,18 +70,8 @@ fun getDIModule(
val configJsonElement = configJson.decodeFromString(JsonObject.serializer(), File(args.first()).readText()) val configJsonElement = configJson.decodeFromString(JsonObject.serializer(), File(args.first()).readText())
val config = configJson.decodeFromJsonElement(Config.serializer(), configJsonElement) 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 { return module {
singleWithRandomQualifier<ContentSerializersModuleConfigurator.Element> { OtherContentSerializerModuleConfigurator } singleWithRandomQualifier<ContentSerializersModuleConfigurator.Element> { OtherContentSerializerModuleConfigurator }
singleWithRandomQualifier<ContentSerializersModuleConfigurator.Element> { TextContentSerializerModuleConfigurator }
singleWithRandomQualifier<SerializersModuleConfigurator.Element> { ContentSerializersModuleConfigurator(getAll()) } singleWithRandomQualifier<SerializersModuleConfigurator.Element> { ContentSerializersModuleConfigurator(getAll()) }
single { SerializersModuleConfigurator(getAll()) } single { SerializersModuleConfigurator(getAll()) }
@ -110,34 +93,34 @@ fun getDIModule(
singleWithBinds { config } singleWithBinds { config }
singleWithBinds { get<Config>().databaseConfig } singleWithBinds { get<Config>().databaseConfig }
singleWithBinds { get<Config>().authConfig } singleWithBinds { get<Config>().authConfig }
singleWithBinds(filesFolderQualifier) { get<Config>().filesFolderFile } singleWithBinds(Qualifiers.filesFolderQualifier) { get<Config>().filesFolderFile }
singleWithBinds(commonFilesFolderQualifier) { get<Config>().commonFilesFolder } singleWithBinds(Qualifiers.commonFilesFolderQualifier) { get<Config>().commonFilesFolder }
singleWithBinds(binaryFilesFolderQualifier) { get<Config>().binaryFilesFolder } singleWithBinds(Qualifiers.binaryFilesFolderQualifier) { get<Config>().binaryFilesFolder }
singleWithBinds { get<DatabaseConfig>().database } singleWithBinds { get<DatabaseConfig>().database }
singleWithBinds(originalFilesMetasKeyValueRepoQualifier) { singleWithBinds(Qualifiers.originalFilesMetasKeyValueRepoQualifier) {
ExposedKeyValueRepo(get(), { text("fileid") }, { text("metaInfo") }, "FileIdsToMetas") ExposedKeyValueRepo(get(), { text("fileid") }, { text("metaInfo") }, "FileIdsToMetas")
} }
singleWithBinds(binaryOriginalFilesMetasKeyValueRepoQualifier) { singleWithBinds(Qualifiers.binaryOriginalFilesMetasKeyValueRepoQualifier) {
ExposedKeyValueRepo(get(), { text("fileid") }, { text("metaInfo") }, "BinaryContentFileIdsToMetas") ExposedKeyValueRepo(get(), { text("fileid") }, { text("metaInfo") }, "BinaryContentFileIdsToMetas")
} }
singleWithBinds(commonFilesMetasKeyValueRepoQualifier) { singleWithBinds(Qualifiers.commonFilesMetasKeyValueRepoQualifier) {
MetasKeyValueRepo( MetasKeyValueRepo(
get(), get(),
get(originalFilesMetasKeyValueRepoQualifier) get(Qualifiers.originalFilesMetasKeyValueRepoQualifier)
) )
} }
single<ReadFilesStorage> { DiskReadFilesStorage(get(commonFilesFolderQualifier), get(commonFilesMetasKeyValueRepoQualifier)) } single<ReadFilesStorage> { DiskReadFilesStorage(get(Qualifiers.commonFilesFolderQualifier), get(Qualifiers.commonFilesMetasKeyValueRepoQualifier)) }
single<WriteFilesStorage> { WriteDistFilesStorage(get(commonFilesFolderQualifier), get(commonFilesMetasKeyValueRepoQualifier)) } single<WriteFilesStorage> { WriteDistFilesStorage(get(Qualifiers.commonFilesFolderQualifier), get(Qualifiers.commonFilesMetasKeyValueRepoQualifier)) }
single<FilesStorage> { DefaultFilesStorage(get(), get()) } single<FilesStorage> { DefaultFilesStorage(get(), get()) }
singleWithBinds { ExposedUsersStorage(get()) } singleWithBinds { ExposedUsersStorage(get()) }
singleWithBinds { exposedUsersAuthenticator(get(), get()) } singleWithBinds { exposedUsersAuthenticator(get(), get()) }
factory<KeyValuesRolesOriginalRepo>(usersRolesKeyValueFactoryQualifier) { (tableName: String) -> factory<KeyValuesRolesOriginalRepo>(Qualifiers.usersRolesKeyValueFactoryQualifier) { (tableName: String) ->
ExposedOneToManyKeyValueRepo(get(), { text("subject") }, { text("role") }, tableName) ExposedOneToManyKeyValueRepo(get(), { text("subject") }, { text("role") }, tableName)
} }
single { single {
RolesManagerRoleStorage(get(usersRolesKeyValueFactoryQualifier) { ParametersHolder(mutableListOf("rolesManager")) }) RolesManagerRoleStorage(get(Qualifiers.usersRolesKeyValueFactoryQualifier) { ParametersHolder(mutableListOf("rolesManager")) })
} }
single<RolesStorage<RolesManagerRole>>(StringQualifier("RolesManagerRoleStorage")) { get<RolesManagerRoleStorage>() } single<RolesStorage<RolesManagerRole>>(StringQualifier("RolesManagerRoleStorage")) { get<RolesManagerRoleStorage>() }
singleWithBinds { singleWithBinds {
@ -156,29 +139,16 @@ fun getDIModule(
factory<CoroutineScope> { baseScope.LinkedSupervisorScope() } factory<CoroutineScope> { baseScope.LinkedSupervisorScope() }
// Content storages // Content storages
val binaryStorageFilesQualifier = StringQualifier("binaryContentFiles") singleWithBinds(Qualifiers.binaryFilesMetasKeyValueRepoQualifier) {
singleWithBinds(binaryFilesMetasKeyValueRepoQualifier) {
MetasKeyValueRepo( MetasKeyValueRepo(
get(), get(),
get(binaryOriginalFilesMetasKeyValueRepoQualifier) get(Qualifiers.binaryOriginalFilesMetasKeyValueRepoQualifier)
) )
} }
single<FilesStorage>(binaryStorageFilesQualifier) { single<FilesStorage>(Qualifiers.binaryStorageFilesQualifier) {
DefaultFilesStorage( DefaultFilesStorage(
DiskReadFilesStorage(get(binaryFilesFolderQualifier), get(binaryFilesMetasKeyValueRepoQualifier)), DiskReadFilesStorage(get(Qualifiers.binaryFilesFolderQualifier), get(Qualifiers.binaryFilesMetasKeyValueRepoQualifier)),
WriteDistFilesStorage(get(binaryFilesFolderQualifier), get(binaryFilesMetasKeyValueRepoQualifier)) WriteDistFilesStorage(get(Qualifiers.binaryFilesFolderQualifier), get(Qualifiers.binaryFilesMetasKeyValueRepoQualifier))
)
}
singleWithRandomQualifier {
ServerContentStorageWrapper(
BinaryServerContentStorage(get(binaryStorageFilesQualifier)),
BinaryContent::class
)
}
singleWithRandomQualifier {
ServerContentStorageWrapper(
TextServerContentStorage(get()),
TextContent::class
) )
} }

View File

@ -7,8 +7,10 @@
"filesFolder": "/tmp/files", "filesFolder": "/tmp/files",
"debugMode": true, "debugMode": true,
"modules": [ "modules": [
"dev.inmo.postssystem.targets.telegram.loader.server.TelegramTargetModuleLoader", "dev.inmo.postssystem.features.content.text.server.TextContentServerModuleLoader",
"dev.inmo.postssystem.publicators.simple.server.SimplePublicationTriggerLoader" "dev.inmo.postssystem.features.content.binary.server.BinaryContentServerModuleLoader",
"dev.inmo.postssystem.targets.telegram.loader.server.TelegramTargetServerModuleLoader",
"dev.inmo.postssystem.publicators.simple.server.SimplePublicationTriggerLoaderServer"
], ],
"telegram": { "telegram": {
"botToken": "YOUR BOT TOKEN", "botToken": "YOUR BOT TOKEN",

View File

@ -1,7 +1,7 @@
package dev.inmo.postssystem.targets.telegram.loader.server package dev.inmo.postssystem.targets.telegram.loader.server
import dev.inmo.postssystem.features.common.common.singleWithRandomQualifier 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.content.common.ContentSerializersModuleConfigurator
import dev.inmo.postssystem.features.publication.server.PublicationTarget import dev.inmo.postssystem.features.publication.server.PublicationTarget
import dev.inmo.postssystem.targets.telegram.content.polls.common.PollContent 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 * Expects to get a config from a field "telegram" of your config
*/ */
class TelegramTargetModuleLoader : ModuleLoader { class TelegramTargetServerModuleLoader : ServerModuleLoader {
override fun Module.load(config: JsonObject) { override fun Module.load(config: JsonObject) {
val configJson = config["telegram"] val configJson = config["telegram"]