Skip to content

Commit 77e45d3

Browse files
author
Oleksandr Dzhychko
committed
feat(model-server): add endpoint /about
Show the server version in the endpoint. Link to the endpoint in the title bar.
1 parent d4298ba commit 77e45d3

File tree

19 files changed

+283
-36
lines changed

19 files changed

+283
-36
lines changed

build-logic/build.gradle.kts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,29 @@
11
plugins {
22
`kotlin-dsl`
33
}
4+
5+
dependencies {
6+
// This should ideally be `compileOnly` and not `implementation`.
7+
// The compiled `build-logic` should not bundle the plugin code.
8+
// The project applying code from "build-logic" should add the plugins themselves.
9+
//
10+
// But using `compileOnly` we run into https://github.com/gradle/gradle/issues/23709
11+
// This is indirectly related to applying any settings plugin in our root "settings.gradle.kts".
12+
// ```
13+
// plugins {
14+
// id("modelix-repositories")
15+
// }
16+
// ```
17+
// Applying any settings plugin causes an `InstrumentingVisitableURLClassLoader` to be added as class loader.
18+
// It results in throwing "java.lang.NoClassDefFoundError: org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper`.
19+
//
20+
// We therefore use `implementation` as a workaround and bundle the plugin code with "build-logic".
21+
//
22+
// Because we use `implementation` and not `compileOnly` only,
23+
// they must not add any of the Kotlin Gradle plugins again in the applying projects.
24+
// This means we must not call `alias(libs.plugins.kotlin.multiplatform)`
25+
// and `alias(libs.plugins.kotlin.jvm), which tries to add them again as plugins.
26+
// We just have to call `kotlin("multiplatform")` and `kotlin("jvm")` which just enables the plugins,
27+
// but uses the plugin code bundled with `build-logic`.
28+
implementation(libs.kotlin.gradlePlugin)
29+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright (c) 2024.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.modelix
18+
19+
import org.gradle.api.Project
20+
import org.gradle.kotlin.dsl.configure
21+
import org.gradle.kotlin.dsl.get
22+
import org.gradle.kotlin.dsl.withType
23+
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
24+
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
25+
import org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformPluginWrapper
26+
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper
27+
28+
/**
29+
* Causes code containing the Modelix version to be generated and used in a Kotlin project.
30+
* The Kotlin project can be a JVM or Multiplatform project.
31+
*/
32+
fun Project.registerVersionGenerationTask(packageName: String) {
33+
val packagePath = packageName.replace('.', '/')
34+
35+
val generateVersionVariable = tasks.register("generateVersionVariable") {
36+
doLast {
37+
val fileContent = buildString {
38+
appendLine("package $packageName")
39+
appendLine()
40+
appendLine("""const val MODELIX_VERSION: String = "$version"""")
41+
if (project.name == "modelql-core") {
42+
appendLine("""@Deprecated("Use the new MODELIX_VERSION", replaceWith = ReplaceWith("MODELIX_VERSION"))""")
43+
appendLine("const val modelqlVersion: String = MODELIX_VERSION")
44+
}
45+
}
46+
val outputDir = layout.buildDirectory.dir("version_gen/$packagePath").get().asFile
47+
outputDir.mkdirs()
48+
outputDir.resolve("Version.kt").writeText(fileContent)
49+
}
50+
}
51+
52+
// Generate version constant for Kotlin JVM projects
53+
plugins.withType<KotlinPluginWrapper> {
54+
extensions.configure<KotlinJvmProjectExtension> {
55+
sourceSets["main"].kotlin.srcDir(layout.buildDirectory.dir("version_gen"))
56+
}
57+
58+
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().all {
59+
dependsOn(generateVersionVariable)
60+
}
61+
}
62+
63+
// Generate version constant for Kotlin Multiplatform projects
64+
plugins.withType<KotlinMultiplatformPluginWrapper> {
65+
extensions.configure<KotlinMultiplatformExtension> {
66+
sourceSets.commonMain {
67+
kotlin.srcDir(layout.buildDirectory.dir("version_gen"))
68+
}
69+
}
70+
71+
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().all {
72+
dependsOn(generateVersionVariable)
73+
}
74+
75+
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompileCommon>().all {
76+
dependsOn(generateVersionVariable)
77+
}
78+
}
79+
}

build.gradle.kts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ buildscript {
2020
plugins {
2121
`maven-publish`
2222
`version-catalog`
23-
alias(libs.plugins.kotlin.multiplatform) apply false
2423
alias(libs.plugins.kotlin.serialization) apply false
2524
alias(libs.plugins.gitVersion)
2625
alias(libs.plugins.spotless) apply false

bulk-model-sync-gradle-test/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616

1717
plugins {
18-
alias(libs.plugins.kotlin.jvm)
18+
kotlin("jvm")
1919
id("org.modelix.bulk-model-sync")
2020
}
2121

bulk-model-sync-lib/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
plugins {
2-
alias(libs.plugins.kotlin.multiplatform)
2+
kotlin("multiplatform")
33
}
44

55
kotlin {

gradle/libs.versions.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ kotlin-serialization-yaml = { group = "com.charleskorn.kaml", name = "kaml", ver
4949
kotlin-logging = { group = "io.github.microutils", name = "kotlin-logging", version = "3.0.5" }
5050
kotlin-collections-immutable = { group = "org.jetbrains.kotlinx", name = "kotlinx-collections-immutable", version = "0.3.7" }
5151
kotlin-datetime = { group = "org.jetbrains.kotlinx", name = "kotlinx-datetime", version = "0.6.0" }
52+
kotlin-gradlePlugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" }
5253

5354
kotlin-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "kotlinCoroutines" }
5455
kotlin-coroutines-swing = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-swing", version.ref = "kotlinCoroutines" }

model-api-gen-gradle-test/kotlin-generation/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
plugins {
2-
alias(libs.plugins.kotlin.jvm)
2+
kotlin("jvm")
33
id("org.modelix.model-api-gen") apply false
44
}
55

model-server-lib/src/main/kotlin/org/modelix/model/server/light/LightModelServer.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ import org.modelix.model.server.api.SetPropertyOpData
6767
import org.modelix.model.server.api.SetReferenceOpData
6868
import org.modelix.model.server.api.VersionData
6969
import org.modelix.model.server.api.buildModelQuery
70-
import org.modelix.modelql.core.modelqlVersion
70+
import org.modelix.modelql.core.MODELIX_VERSION
7171
import org.modelix.modelql.server.ModelQLServer
7272
import java.time.Duration
7373
import java.util.*
@@ -202,7 +202,7 @@ class LightModelServer @JvmOverloads constructor(val port: Int, val rootNodeProv
202202
}
203203
}
204204
get("/version") {
205-
call.respondText(modelqlVersion ?: "unknown")
205+
call.respondText(MODELIX_VERSION)
206206
}
207207
get("/health") {
208208
val output = StringBuilder()

model-server-openapi/specifications/model-server-operative.yaml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,22 @@ paths:
3939
default:
4040
$ref: '#/components/responses/GeneralError'
4141

42+
/about:
43+
get:
44+
operationId: getAboutInformation
45+
x-modelix-media-type-handlers:
46+
- v1:
47+
- 'application/x.modelix.about+json;version=1'
48+
tags:
49+
- about
50+
responses:
51+
"200":
52+
description: Response with information about the model server.
53+
content:
54+
'application/x.modelix.about+json;version=1':
55+
schema:
56+
$ref: "#/components/schemas/AboutV1"
57+
4258
components:
4359
responses:
4460
Healthy:
@@ -110,3 +126,13 @@ components:
110126
e.g. by adding a fragment identifier or sub-path to the problem type.
111127
May be used to locate the root of this problem in the source code.
112128
example: '/some/uri-reference#specific-occurrence-context'
129+
130+
AboutV1:
131+
x-modelix-media-type: 'application/x.modelix.about+json;version=1'
132+
description: Information about the model server
133+
type: object
134+
properties:
135+
version:
136+
type: string
137+
required:
138+
- version

model-server/build.gradle.kts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
22
import com.github.jengelman.gradle.plugins.shadow.transformers.PropertiesFileTransformer
33
import io.gitlab.arturbosch.detekt.Detekt
4+
import org.modelix.registerVersionGenerationTask
45
import org.openapitools.generator.gradle.plugin.tasks.GenerateTask
56

67
plugins {
@@ -270,3 +271,5 @@ openApiFiles.forEach {
270271
tasks.withType<Detekt> {
271272
exclude("**/org/modelix/api/**")
272273
}
274+
275+
project.registerVersionGenerationTask("org.modelix.model.server")

0 commit comments

Comments
 (0)