add information about content client provider to readme

This commit is contained in:
2022-03-18 00:04:04 +06:00
parent 1dafe0a679
commit 709e7a8583
11 changed files with 122 additions and 56 deletions
features
common
README.md
server
src
jvmMain
kotlin
dev
inmo
postssystem
features
content
README.md
binary
server
src
jvmMain
kotlin
dev
inmo
postssystem
features
text
server
src
jvmMain
kotlin
dev
inmo
postssystem
features
publicators/simple/server/src/jvmMain/kotlin/dev/inmo/postssystem/publicators/simple/server
server
src
main
java
dev
inmo
postssystem
test.config.json
targets/telegram/loader/server/src/jvmMain/kotlin/dev/inmo/postssystem/targets/telegram/loader/server

26
features/common/README.md Normal 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
```

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

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

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

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

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

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

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

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

@ -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",

@ -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"]