diff --git a/ClientPart/src/main/kotlin/com/insanusmokrassar/postssystem/core/client/ReadableHttpPostsAPI.kt b/ClientPart/src/main/kotlin/com/insanusmokrassar/postssystem/core/client/ReadableHttpPostsAPI.kt index e3998358..ac9162d8 100644 --- a/ClientPart/src/main/kotlin/com/insanusmokrassar/postssystem/core/client/ReadableHttpPostsAPI.kt +++ b/ClientPart/src/main/kotlin/com/insanusmokrassar/postssystem/core/client/ReadableHttpPostsAPI.kt @@ -1,10 +1,10 @@ package com.insanusmokrassar.postssystem.core.client import com.insanusmokrassar.postssystem.core.api.ReadPostsAPI +import com.insanusmokrassar.postssystem.core.clientserver.common.models.DateTimeRequest import com.insanusmokrassar.postssystem.core.clientserver.common.* import com.insanusmokrassar.postssystem.core.content.ContentId -import com.insanusmokrassar.postssystem.core.post.Post -import com.insanusmokrassar.postssystem.core.post.PostId +import com.insanusmokrassar.postssystem.core.post.* import com.insanusmokrassar.postssystem.core.utils.pagination.Pagination import com.insanusmokrassar.postssystem.core.utils.pagination.PaginationResult import io.ktor.client.HttpClient @@ -13,7 +13,7 @@ import org.joda.time.DateTime class ReadableHttpPostsAPI( private val client: HttpClient = HttpClient(), - private val baseAddress: String + baseAddress: String ) : ReadPostsAPI { private val postByIdAddress = "$baseAddress/$getPostByIdAddress" private val postsByContentIdAddress = "$baseAddress/$getPostsByContentIdAddress" @@ -21,18 +21,29 @@ class ReadableHttpPostsAPI( private val postsByPaginationAddress = "$baseAddress/$getPostsByPaginationAddress" override suspend fun getPostById(id: PostId): Post? { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + return client.post(postByIdAddress) { + body = id + } } override suspend fun getPostsByContent(id: ContentId): List { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + return client.post>(postsByContentIdAddress) { + body = id + } } override suspend fun getPostsByDates(from: DateTime?, to: DateTime?): List { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + return client.post>(postsByDatesAddress) { + body = DateTimeRequest( + from ?.millis, + to ?.millis + ) + } } - override suspend fun getPostsByPagination(pagination: Pagination): PaginationResult { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + override suspend fun getPostsByPagination(pagination: Pagination): PaginationResult { + return client.post>(postsByPaginationAddress) { + body = pagination + } } } \ No newline at end of file diff --git a/ClientPart/src/main/kotlin/com/insanusmokrassar/postssystem/core/client/WritableHttpPostsAPI.kt b/ClientPart/src/main/kotlin/com/insanusmokrassar/postssystem/core/client/WritableHttpPostsAPI.kt index f83bead2..fbcb394a 100644 --- a/ClientPart/src/main/kotlin/com/insanusmokrassar/postssystem/core/client/WritableHttpPostsAPI.kt +++ b/ClientPart/src/main/kotlin/com/insanusmokrassar/postssystem/core/client/WritableHttpPostsAPI.kt @@ -4,7 +4,9 @@ import com.insanusmokrassar.postssystem.core.api.WritePostsAPI import com.insanusmokrassar.postssystem.core.post.* import kotlinx.coroutines.flow.Flow -class WritableHttpPostsAPI : WritePostsAPI { +class WritableHttpPostsAPI( + +) : WritePostsAPI { override val postCreatedFlow: Flow get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates. override val postDeletedFlow: Flow diff --git a/ClientServerCommon/src/main/kotlin/com/insanusmokrassar/postssystem/core/clientserver/common/Paths.kt b/ClientServerCommon/src/main/kotlin/com/insanusmokrassar/postssystem/core/clientserver/common/Paths.kt index 4fd68fcb..b8b9f875 100644 --- a/ClientServerCommon/src/main/kotlin/com/insanusmokrassar/postssystem/core/clientserver/common/Paths.kt +++ b/ClientServerCommon/src/main/kotlin/com/insanusmokrassar/postssystem/core/clientserver/common/Paths.kt @@ -4,3 +4,12 @@ const val getPostByIdAddress = "core/posts/get/id" const val getPostsByContentIdAddress = "core/posts/get/content_id" const val getPostsByDatesAddress = "core/posts/get/dates" const val getPostsByPaginationAddress = "core/posts/get/pagination" + +//class ReadPaths( +// val baseAddress: String +//) { +// val postByIdAddress = "$baseAddress/$getPostByIdAddress" +// val postsByContentIdAddress = "$baseAddress/$getPostsByContentIdAddress" +// val postsByDatesAddress = "$baseAddress/$getPostsByDatesAddress" +// val postsByPaginationAddress = "$baseAddress/$getPostsByPaginationAddress" +//} diff --git a/ClientServerCommon/src/main/kotlin/com/insanusmokrassar/postssystem/core/clientserver/common/models/DateTimeRequest.kt b/ClientServerCommon/src/main/kotlin/com/insanusmokrassar/postssystem/core/clientserver/common/models/DateTimeRequest.kt new file mode 100644 index 00000000..2adfb916 --- /dev/null +++ b/ClientServerCommon/src/main/kotlin/com/insanusmokrassar/postssystem/core/clientserver/common/models/DateTimeRequest.kt @@ -0,0 +1,9 @@ +package com.insanusmokrassar.postssystem.core.clientserver.common.models + +import kotlinx.serialization.Serializable + +@Serializable +data class DateTimeRequest ( + val from: Long?, + val to: Long? +) diff --git a/Core/src/main/kotlin/com/insanusmokrassar/postssystem/core/api/ReadPostsAPI.kt b/Core/src/main/kotlin/com/insanusmokrassar/postssystem/core/api/ReadPostsAPI.kt index bf109326..eb001bce 100644 --- a/Core/src/main/kotlin/com/insanusmokrassar/postssystem/core/api/ReadPostsAPI.kt +++ b/Core/src/main/kotlin/com/insanusmokrassar/postssystem/core/api/ReadPostsAPI.kt @@ -13,5 +13,5 @@ interface ReadPostsAPI { suspend fun getPostsByContent(id: ContentId): List suspend fun getPostsByDates(from: DateTime? = null, to: DateTime? = null): List - suspend fun getPostsByPagination(pagination: Pagination): PaginationResult + suspend fun getPostsByPagination(pagination: Pagination): PaginationResult } \ No newline at end of file diff --git a/Core/src/main/kotlin/com/insanusmokrassar/postssystem/core/post/Post.kt b/Core/src/main/kotlin/com/insanusmokrassar/postssystem/core/post/Post.kt index 12cb975b..f2cec695 100644 --- a/Core/src/main/kotlin/com/insanusmokrassar/postssystem/core/post/Post.kt +++ b/Core/src/main/kotlin/com/insanusmokrassar/postssystem/core/post/Post.kt @@ -1,6 +1,7 @@ package com.insanusmokrassar.postssystem.core.post import com.insanusmokrassar.postssystem.core.content.Content +import kotlinx.serialization.Serializable typealias PostId = String typealias PostContents = List @@ -10,4 +11,11 @@ interface Post { val content: PostContents val meta: PostMetaInfo -} \ No newline at end of file +} + +@Serializable +data class SimplePost( + override val id: PostId, + override val content: PostContents, + override val meta: PostMetaInfo +) : Post diff --git a/ServerPart/build.gradle b/ServerPart/build.gradle new file mode 100644 index 00000000..1142d1e2 --- /dev/null +++ b/ServerPart/build.gradle @@ -0,0 +1,42 @@ +project.version = "0.1.0" +project.group = "com.insanusmokrassar" + +buildscript { + repositories { + mavenLocal() + jcenter() + mavenCentral() + } + + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version" + classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:$gradle_bintray_plugin_version" + } +} + +apply plugin: 'java-library' +apply plugin: 'kotlin' +apply plugin: 'kotlinx-serialization' + +repositories { + mavenLocal() + jcenter() + mavenCentral() + maven { url "https://kotlin.bintray.com/kotlinx" } +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + api project(":Core") + api project(":ClientServerCommon") + + api "io.ktor:ktor-server:$ktor_version" + api "io.ktor:ktor-server-core:$ktor_version" +} + +compileKotlin { + kotlinOptions { + freeCompilerArgs = [ disableImplicitReflectionSerializerAnnotation ] + } +} diff --git a/ServerPart/gradle.properties b/ServerPart/gradle.properties new file mode 100644 index 00000000..35649e7e --- /dev/null +++ b/ServerPart/gradle.properties @@ -0,0 +1 @@ +ktor_version=1.2.4 diff --git a/ServerPart/settings.gradle b/ServerPart/settings.gradle new file mode 100644 index 00000000..c60c2819 --- /dev/null +++ b/ServerPart/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'postssystem.core.server' diff --git a/ServerPart/src/main/kotlin/com/insanusmokrassar/postssystem/core/server/Commons.kt b/ServerPart/src/main/kotlin/com/insanusmokrassar/postssystem/core/server/Commons.kt new file mode 100644 index 00000000..a8357fdd --- /dev/null +++ b/ServerPart/src/main/kotlin/com/insanusmokrassar/postssystem/core/server/Commons.kt @@ -0,0 +1,21 @@ +package com.insanusmokrassar.postssystem.core.server + +import com.insanusmokrassar.postssystem.core.post.Post +import com.insanusmokrassar.postssystem.core.post.SimplePost +import com.insanusmokrassar.postssystem.core.utils.pagination.PaginationResult +import kotlinx.serialization.internal.ArrayListSerializer + + +internal val postsSerializer = ArrayListSerializer(SimplePost.serializer()) +internal val paginationResultSerializer = PaginationResult.serializer(SimplePost.serializer()) + +internal val List.asSimplePostList + get() = map { post -> + post.asSimplePost + } + +internal val Post.asSimplePost + get() = when (this) { + is SimplePost -> this + else -> SimplePost(id, content, meta) + } diff --git a/ServerPart/src/main/kotlin/com/insanusmokrassar/postssystem/core/server/ReadModules.kt b/ServerPart/src/main/kotlin/com/insanusmokrassar/postssystem/core/server/ReadModules.kt new file mode 100644 index 00000000..8816fc7d --- /dev/null +++ b/ServerPart/src/main/kotlin/com/insanusmokrassar/postssystem/core/server/ReadModules.kt @@ -0,0 +1,66 @@ +package com.insanusmokrassar.postssystem.core.server + +import com.insanusmokrassar.postssystem.core.api.ReadPostsAPI +import com.insanusmokrassar.postssystem.core.clientserver.common.* +import com.insanusmokrassar.postssystem.core.clientserver.common.models.DateTimeRequest +import com.insanusmokrassar.postssystem.core.content.ContentId +import com.insanusmokrassar.postssystem.core.post.* +import com.insanusmokrassar.postssystem.core.utils.pagination.PaginationRequest +import com.insanusmokrassar.postssystem.core.utils.pagination.PaginationResult +import io.ktor.application.call +import io.ktor.http.ContentType +import io.ktor.http.HttpStatusCode +import io.ktor.request.receiveOrNull +import io.ktor.response.respond +import io.ktor.response.respondText +import io.ktor.routing.Route +import io.ktor.routing.post +import kotlinx.serialization.json.Json +import org.joda.time.DateTime + +fun Route.includePostsCoreReadModules(readPostsAPI: ReadPostsAPI) { + post(getPostByIdAddress) { + call.receiveOrNull(PostId::class) ?.also { id -> + val post = readPostsAPI.getPostById(id) + post ?.let { + val simplePost = post.asSimplePost + call.respondText(ContentType.Application.Json) { + Json.plain.stringify(SimplePost.serializer(), simplePost) + } + } ?: call.respond(HttpStatusCode.NotFound, "Not found") + } ?: call.respond(HttpStatusCode.BadRequest, "Id of post must be provided as body of request") + } + post(getPostsByContentIdAddress) { + call.receiveOrNull(ContentId::class) ?.also { id -> + val posts = readPostsAPI.getPostsByContent(id) + val simplePosts = posts.asSimplePostList + call.respondText(ContentType.Application.Json) { + Json.plain.stringify(postsSerializer, simplePosts) + } + } ?: call.respond(HttpStatusCode.BadRequest, "Id of content must be provided as body of request") + } + post(getPostsByDatesAddress) { + call.receiveOrNull() ?.also { (from, to) -> + val posts = readPostsAPI.getPostsByDates(from ?.let { DateTime(it) }, to ?.let { DateTime(it) }) + val simplePosts = posts.asSimplePostList + call.respondText(ContentType.Application.Json) { + Json.plain.stringify(postsSerializer, simplePosts) + } + } ?: call.respond(HttpStatusCode.BadRequest, "Object \"DateTimeRequest\" must be provided as body of request") + } + post(getPostsByPaginationAddress) { + call.receiveOrNull() ?.also { pagination -> + val paginationResult = readPostsAPI.getPostsByPagination(pagination).let { + val simplePosts = it.results.asSimplePostList + PaginationResult( + it.page, + it.pagesNumber, + simplePosts + ) + } + call.respondText(ContentType.Application.Json) { + Json.plain.stringify(paginationResultSerializer, paginationResult) + } + } ?: call.respond(HttpStatusCode.BadRequest, "Object \"PaginationRequest\" must be provided as body of request") + } +} diff --git a/settings.gradle b/settings.gradle index f24e9e2f..db678e77 100644 --- a/settings.gradle +++ b/settings.gradle @@ -15,6 +15,7 @@ include 'api' include 'services:webservice' */ -include ':ClientPart' include ':Core' include ':ClientServerCommon' +include ':ClientPart' +include ':ServerPart'