266 lines
12 KiB
Kotlin
266 lines
12 KiB
Kotlin
package dev.inmo.postssystem.server
|
|
|
|
import dev.inmo.postssystem.features.auth.server.AuthenticationRoutingConfigurator
|
|
import dev.inmo.postssystem.features.auth.server.SessionAuthenticationConfigurator
|
|
import dev.inmo.postssystem.features.auth.server.tokens.*
|
|
import dev.inmo.postssystem.features.common.server.sessions.ApplicationAuthenticationConfigurator
|
|
import dev.inmo.postssystem.features.files.common.*
|
|
import dev.inmo.postssystem.features.files.common.storage.*
|
|
import dev.inmo.postssystem.features.files.common.storage.WriteFilesStorage
|
|
import dev.inmo.postssystem.features.files.server.FilesRoutingConfigurator
|
|
import dev.inmo.postssystem.features.roles.common.*
|
|
import dev.inmo.postssystem.features.roles.common.keyvalue.KeyValuesRolesOriginalRepo
|
|
import dev.inmo.postssystem.features.roles.manager.common.RolesManagerRole
|
|
import dev.inmo.postssystem.features.roles.manager.common.RolesManagerRoleStorage
|
|
import dev.inmo.postssystem.features.roles.manager.server.RolesManagerRolesChecker
|
|
import dev.inmo.postssystem.features.roles.manager.server.RolesManagerRolesStorageServerRoutesConfigurator
|
|
import dev.inmo.postssystem.features.roles.server.*
|
|
import dev.inmo.postssystem.features.status.server.StatusRoutingConfigurator
|
|
import dev.inmo.postssystem.features.users.common.ExposedUsersStorage
|
|
import dev.inmo.postssystem.features.users.server.UsersStorageServerRoutesConfigurator
|
|
import dev.inmo.micro_utils.coroutines.LinkedSupervisorScope
|
|
import dev.inmo.micro_utils.ktor.server.UnifiedRouter
|
|
import dev.inmo.micro_utils.ktor.server.configurators.*
|
|
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.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
|
|
import io.ktor.routing.Routing
|
|
import io.ktor.server.engine.ApplicationEngine
|
|
import io.ktor.server.netty.Netty
|
|
import kotlinx.coroutines.CoroutineScope
|
|
import kotlinx.coroutines.Dispatchers
|
|
import kotlinx.serialization.BinaryFormat
|
|
import kotlinx.serialization.StringFormat
|
|
import kotlinx.serialization.cbor.Cbor
|
|
import kotlinx.serialization.json.*
|
|
import kotlinx.serialization.modules.SerializersModule
|
|
import org.jetbrains.exposed.sql.Database
|
|
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() {
|
|
println(this)
|
|
children.forEach {
|
|
it.print()
|
|
}
|
|
}
|
|
|
|
|
|
fun getDIModule(
|
|
vararg args: String,
|
|
baseScope: CoroutineScope = CoroutineScope(Dispatchers.IO)
|
|
): Module {
|
|
val configJson = Json {
|
|
ignoreUnknownKeys = true
|
|
}
|
|
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<ContentSerializersModuleConfigurator.Element> { OtherContentSerializerModuleConfigurator }
|
|
singleWithRandomQualifier<ContentSerializersModuleConfigurator.Element> { TextContentSerializerModuleConfigurator }
|
|
singleWithRandomQualifier<SerializersModuleConfigurator.Element> { ContentSerializersModuleConfigurator(getAll()) }
|
|
single { SerializersModuleConfigurator(getAll()) }
|
|
|
|
single {
|
|
Json {
|
|
ignoreUnknownKeys = true
|
|
serializersModule = SerializersModule { get<SerializersModuleConfigurator>().apply { invoke() } }
|
|
}
|
|
}
|
|
single<StringFormat> { get<Json>() }
|
|
single<BinaryFormat> {
|
|
Cbor {
|
|
serializersModule = SerializersModule { get<SerializersModuleConfigurator>().apply { invoke() } }
|
|
}
|
|
}
|
|
|
|
single { UnifiedRouter(get()) }
|
|
|
|
singleWithBinds { config }
|
|
singleWithBinds { get<Config>().databaseConfig }
|
|
singleWithBinds { get<Config>().authConfig }
|
|
singleWithBinds(filesFolderQualifier) { get<Config>().filesFolderFile }
|
|
singleWithBinds(commonFilesFolderQualifier) { get<Config>().commonFilesFolder }
|
|
singleWithBinds(binaryFilesFolderQualifier) { get<Config>().binaryFilesFolder }
|
|
|
|
singleWithBinds { get<DatabaseConfig>().database }
|
|
singleWithBinds(originalFilesMetasKeyValueRepoQualifier) {
|
|
ExposedKeyValueRepo(get(), { text("fileid") }, { text("metaInfo") }, "FileIdsToMetas")
|
|
}
|
|
singleWithBinds(binaryOriginalFilesMetasKeyValueRepoQualifier) {
|
|
ExposedKeyValueRepo(get(), { text("fileid") }, { text("metaInfo") }, "BinaryContentFileIdsToMetas")
|
|
}
|
|
singleWithBinds(commonFilesMetasKeyValueRepoQualifier) {
|
|
MetasKeyValueRepo(
|
|
get(),
|
|
get(originalFilesMetasKeyValueRepoQualifier)
|
|
)
|
|
}
|
|
single<ReadFilesStorage> { DiskReadFilesStorage(get(commonFilesFolderQualifier), get(commonFilesMetasKeyValueRepoQualifier)) }
|
|
single<WriteFilesStorage> { WriteDistFilesStorage(get(commonFilesFolderQualifier), get(commonFilesMetasKeyValueRepoQualifier)) }
|
|
single<FilesStorage> { DefaultFilesStorage(get(), get()) }
|
|
singleWithBinds { ExposedUsersStorage(get()) }
|
|
singleWithBinds { exposedUsersAuthenticator(get(), get()) }
|
|
|
|
factory<KeyValuesRolesOriginalRepo>(usersRolesKeyValueFactoryQualifier) { (tableName: String) ->
|
|
ExposedOneToManyKeyValueRepo(get(), { text("subject") }, { text("role") }, tableName)
|
|
}
|
|
single {
|
|
RolesManagerRoleStorage(get(usersRolesKeyValueFactoryQualifier) { ParametersHolder(mutableListOf("rolesManager")) })
|
|
}
|
|
single<RolesStorage<RolesManagerRole>>(StringQualifier("RolesManagerRoleStorage")) { get<RolesManagerRoleStorage>() }
|
|
singleWithBinds {
|
|
RolesStorageHolder(
|
|
RolesManagerRole::class,
|
|
get<RolesManagerRoleStorage>()
|
|
)
|
|
}
|
|
singleWithBinds<RolesStorage<Role>> { RolesAggregator(getAll()) }
|
|
|
|
single(createdAtStart = true) { PublicationManager(getAll(), get(), get(), get()) }
|
|
|
|
// Roles checkers
|
|
single<RolesChecker<Role>>(StringQualifier(RolesManagerRolesChecker.key)) { RolesManagerRolesChecker }
|
|
|
|
factory<CoroutineScope> { baseScope.LinkedSupervisorScope() }
|
|
|
|
// Content storages
|
|
val binaryStorageFilesQualifier = StringQualifier("binaryContentFiles")
|
|
singleWithBinds(binaryFilesMetasKeyValueRepoQualifier) {
|
|
MetasKeyValueRepo(
|
|
get(),
|
|
get(binaryOriginalFilesMetasKeyValueRepoQualifier)
|
|
)
|
|
}
|
|
single<FilesStorage>(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
|
|
)
|
|
}
|
|
|
|
single<ServerContentStorage<Content>> { ServerContentStorageAggregator(getAll(), get()) } binds arrayOf(
|
|
ServerReadContentStorage::class,
|
|
ServerWriteContentStorage::class
|
|
)
|
|
|
|
// Posts storage
|
|
single<ServerPostsStorage> { ExposedServerPostsStorage(get()) } binds arrayOf(
|
|
ServerReadPostsStorage::class,
|
|
ServerWritePostsStorage::class
|
|
)
|
|
|
|
singleWithBinds {
|
|
ServerPostsService(
|
|
DefaultExposedReadPostsService(get<ServerPostsStorage>()),
|
|
DefaultWritePostsService(get<ServerPostsStorage>(), get<ServerContentStorage<Content>>())
|
|
)
|
|
}
|
|
|
|
// Routing configurators
|
|
singleWithBinds { FilesRoutingConfigurator(get(), null, get()) }
|
|
singleWithBinds { StatusRoutingConfigurator }
|
|
singleWithBinds { UsersStorageServerRoutesConfigurator(get(), get()) }
|
|
singleWithBinds { RolesStorageReadServerRoutesConfigurator<Role>(get(), RoleSerializer, get()) }
|
|
singleWithBinds { RolesManagerRolesStorageServerRoutesConfigurator(get(), get()) }
|
|
singleWithBinds { ServerPostsServiceRoutingConfigurator(get(), get(), get(), get()) }
|
|
|
|
singleWithBinds { ClientStaticRoutingConfiguration("web") }
|
|
singleWithBinds {
|
|
RolesAuthenticationConfigurator<Role>(
|
|
get(),
|
|
get(),
|
|
getAll()
|
|
)
|
|
}
|
|
|
|
// Session and auth configurators
|
|
singleWithBinds { SessionAuthenticationConfigurator(get<AuthConfig>().sessionAge) }
|
|
singleWithBinds {
|
|
DefaultAuthTokensService(
|
|
get<Database>(),
|
|
get(),
|
|
get(),
|
|
get<AuthConfig>().sessionAge,
|
|
get()
|
|
)
|
|
}
|
|
singleWithBinds { AuthenticationRoutingConfigurator(get(), get(), get()) }
|
|
singleWithBinds { NotFoundStatusPageRedirectToIndex("/") }
|
|
|
|
if (config.debugMode) {
|
|
single<ApplicationRoutingConfigurator.Element>(StringQualifier("Tracer")) { ApplicationRoutingConfigurator.Element {(this as Routing).trace { application.log.trace(it.buildText()) } } }
|
|
}
|
|
|
|
singleWithBinds { ApplicationRoutingConfigurator(getAllDistinct()) }
|
|
singleWithBinds { ApplicationCachingHeadersConfigurator(getAllDistinct()) }
|
|
singleWithBinds { ApplicationSessionsConfigurator(getAllDistinct()) }
|
|
singleWithBinds { StatusPagesConfigurator(getAllDistinct()) }
|
|
singleWithBinds { ApplicationAuthenticationConfigurator(getAllDistinct()) }
|
|
singleWithBinds { WebSocketsConfigurator }
|
|
|
|
factory<ApplicationEngine> {
|
|
val config = get<Config>()
|
|
createKtorServer(
|
|
Netty,
|
|
config.host,
|
|
config.port
|
|
) {
|
|
getAllDistinct<KtorApplicationConfigurator>().also(::println).forEach {
|
|
it.apply { configure() }
|
|
}
|
|
if (config.debugMode) {
|
|
featureOrNull(Routing) ?.print()
|
|
}
|
|
}
|
|
}
|
|
|
|
config.modules.forEach {
|
|
it.apply { load(configJsonElement) }
|
|
}
|
|
}
|
|
}
|