216 lines
9.3 KiB
Kotlin
216 lines
9.3 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.ApplicationAuthenticationConfigurator
|
|
import dev.inmo.postssystem.features.files.common.*
|
|
import dev.inmo.postssystem.features.files.common.storage.*
|
|
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.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.ExposedKeyValuesRepo
|
|
import dev.inmo.postssystem.features.common.common.*
|
|
import dev.inmo.postssystem.features.common.server.Qualifiers
|
|
import dev.inmo.postssystem.features.content.common.*
|
|
import dev.inmo.postssystem.features.content.server.ServerContentStorageAggregator
|
|
import dev.inmo.postssystem.features.content.server.storage.*
|
|
import dev.inmo.postssystem.features.posts.server.*
|
|
import dev.inmo.postssystem.features.publication.server.PublicationManager
|
|
import dev.inmo.postssystem.services.posts.server.*
|
|
import io.ktor.server.application.pluginOrNull
|
|
import io.ktor.server.application.log
|
|
import io.ktor.server.routing.Route
|
|
import io.ktor.server.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.core.qualifier.named
|
|
import org.koin.dsl.*
|
|
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)
|
|
|
|
return module {
|
|
singleWithRandomQualifier<ContentSerializersModuleConfigurator.Element> { OtherContentSerializerModuleConfigurator }
|
|
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() } }
|
|
}
|
|
}
|
|
|
|
singleWithBinds { config }
|
|
singleWithBinds { get<Config>().databaseConfig }
|
|
singleWithBinds { get<Config>().authConfig }
|
|
singleWithBinds(Qualifiers.filesFolderQualifier) { get<Config>().filesFolderFile }
|
|
singleWithBinds(Qualifiers.commonFilesFolderQualifier) { File(get<Config>().filesFolderFile, "common").apply { mkdirs() } }
|
|
|
|
singleWithBinds { get<DatabaseConfig>().database }
|
|
singleWithBinds { ExposedUsersStorage(get()) }
|
|
singleWithBinds { exposedUsersAuthenticator(get(), get()) }
|
|
|
|
factory<KeyValuesRolesOriginalRepo>(Qualifiers.usersRolesKeyValueFactoryQualifier) { (tableName: String) ->
|
|
ExposedKeyValuesRepo(get(), { text("subject") }, { text("role") }, tableName)
|
|
}
|
|
single {
|
|
RolesManagerRoleStorage(get(Qualifiers.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
|
|
|
|
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>>())
|
|
)
|
|
}
|
|
|
|
singleWithBinds<FilesStorage> {
|
|
val metasRepo = MetasKeyValueRepo(
|
|
get(),
|
|
ExposedKeyValueRepo(get(), { text("fileid") }, { text("metaInfo") }, "CommonFilesMetaInfoTable")
|
|
)
|
|
DefaultFilesStorage(
|
|
DiskReadFilesStorage(get(Qualifiers.commonFilesFolderQualifier), metasRepo),
|
|
WriteDistFilesStorage(get(Qualifiers.commonFilesFolderQualifier), metasRepo)
|
|
)
|
|
}
|
|
|
|
// Routing configurators
|
|
singleWithBinds { FilesRoutingConfigurator(get(), null) }
|
|
singleWithBinds { StatusRoutingConfigurator }
|
|
singleWithBinds { UsersStorageServerRoutesConfigurator(get()) }
|
|
singleWithBinds { RolesStorageReadServerRoutesConfigurator<Role>(get(), RoleSerializer) }
|
|
singleWithBinds { RolesManagerRolesStorageServerRoutesConfigurator(get()) }
|
|
singleWithBinds { ServerPostsServiceRoutingConfigurator(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()) }
|
|
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) {
|
|
pluginOrNull(Routing) ?.print()
|
|
}
|
|
}
|
|
}
|
|
|
|
config.modules.forEach {
|
|
it.apply { load(configJsonElement) }
|
|
}
|
|
}
|
|
}
|