-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
update model and split documentation into multi-step setup
- Loading branch information
Showing
25 changed files
with
675 additions
and
150 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,68 @@ | ||
import documentation.generateApplicationDescription | ||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile | ||
import org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES | ||
|
||
plugins { | ||
id("org.springframework.boot") version "3.2.3" | ||
id("io.spring.dependency-management") version "1.1.4" | ||
kotlin("jvm") version "1.9.22" | ||
kotlin("plugin.spring") version "1.9.22" | ||
id("org.springframework.boot") version "3.2.3" | ||
id("io.spring.dependency-management") version "1.1.4" | ||
kotlin("jvm") version "1.9.22" | ||
kotlin("plugin.spring") version "1.9.22" | ||
} | ||
|
||
group = "com.example" | ||
version = "0.0.1-SNAPSHOT" | ||
|
||
java { | ||
sourceCompatibility = JavaVersion.VERSION_17 | ||
sourceCompatibility = JavaVersion.VERSION_17 | ||
} | ||
|
||
repositories { | ||
mavenCentral() | ||
mavenCentral() | ||
} | ||
|
||
dependencyManagement { | ||
imports { | ||
mavenBom("org.jetbrains.kotlin:kotlin-bom:1.9.22") | ||
mavenBom(BOM_COORDINATES) | ||
} | ||
} | ||
|
||
dependencies { | ||
implementation("org.springframework.boot:spring-boot-starter") | ||
implementation("org.jetbrains.kotlin:kotlin-reflect") | ||
implementation("com.fasterxml.jackson.core:jackson-annotations") | ||
implementation("com.fasterxml.jackson.core:jackson-core") | ||
implementation("com.fasterxml.jackson.core:jackson-databind") | ||
implementation("com.fasterxml.jackson.module:jackson-module-kotlin") | ||
testImplementation("org.springframework.boot:spring-boot-starter-test") | ||
implementation("org.springframework.boot:spring-boot-starter") | ||
implementation("org.springframework.boot:spring-boot-starter-web") | ||
implementation("org.jetbrains.kotlin:kotlin-reflect") | ||
implementation("com.fasterxml.jackson.core:jackson-annotations") | ||
implementation("com.fasterxml.jackson.core:jackson-core") | ||
implementation("com.fasterxml.jackson.core:jackson-databind") | ||
implementation("com.fasterxml.jackson.module:jackson-module-kotlin") | ||
testImplementation("org.springframework.boot:spring-boot-starter-test") | ||
testImplementation("org.wiremock:wiremock-standalone:3.4.1") | ||
} | ||
|
||
tasks.withType<KotlinCompile> { | ||
kotlinOptions { | ||
freeCompilerArgs += "-Xjsr305=strict" | ||
jvmTarget = "17" | ||
} | ||
kotlinOptions { | ||
freeCompilerArgs += "-Xjsr305=strict" | ||
jvmTarget = "17" | ||
} | ||
} | ||
|
||
tasks.withType<Test> { | ||
useJUnitPlatform() | ||
useJUnitPlatform() | ||
} | ||
|
||
tasks.register("generateApplicationDescription") { | ||
val sourceFolder = File(project.rootDir, "build/architecture-documentation") | ||
val targetFolder = File(project.rootDir, "build/documentation/json") | ||
|
||
inputs.dir(sourceFolder) | ||
outputs.dir(targetFolder) | ||
|
||
dependsOn("test") | ||
doLast { | ||
generateApplicationDescription(sourceFolder, targetFolder, "backend-service-1") | ||
} | ||
} | ||
|
||
tasks.build { | ||
dependsOn("generateApplicationDescription") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
plugins { | ||
kotlin("jvm") version "1.9.22" | ||
} | ||
|
||
repositories { | ||
mavenCentral() | ||
} | ||
|
||
dependencies { | ||
implementation("com.fasterxml.jackson.core:jackson-databind:2.16.1") | ||
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.16.1") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package documentation.model | ||
|
||
// (!) The content of this file is copied from repository to repository. | ||
// It is the model used by the various generation Gradle tasks and is the same for all repositories. | ||
// In a real project this would likely be packaged as library package and distributed using some kind of registry. | ||
|
||
sealed interface Component { | ||
val id: String | ||
val groupId: String? | ||
val systemId: String? | ||
val type: ComponentType? | ||
val distanceFromUs: Distance? | ||
} | ||
|
||
enum class ComponentType { BACKEND, FRONTEND, DATABASE } | ||
enum class Distance { OWNED, CLOSE, DISTANT } | ||
|
||
data class Application( | ||
override val id: String, | ||
override val groupId: String?, | ||
override val systemId: String?, | ||
override val type: ComponentType?, | ||
override val distanceFromUs: Distance?, | ||
val dependents: List<Dependent> = emptyList(), | ||
val dependencies: List<Dependency> = emptyList(), | ||
) : Component | ||
|
||
data class Dependent( | ||
override val id: String, | ||
override val groupId: String?, | ||
override val systemId: String?, | ||
override val type: ComponentType?, | ||
override val distanceFromUs: Distance?, | ||
) : Component | ||
|
||
data class Dependency( | ||
override val id: String, | ||
override val groupId: String?, | ||
override val systemId: String?, | ||
override val type: ComponentType?, | ||
override val distanceFromUs: Distance?, | ||
val httpEndpoints: List<HttpEndpoint> = emptyList(), | ||
) : Component | ||
|
||
data class HttpEndpoint(val method: String, val path: String) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package documentation | ||
|
||
import com.fasterxml.jackson.annotation.JsonInclude.Include | ||
import com.fasterxml.jackson.databind.DeserializationFeature | ||
import com.fasterxml.jackson.databind.SerializationFeature | ||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper | ||
import com.fasterxml.jackson.module.kotlin.readValue | ||
import documentation.model.Application | ||
import documentation.model.Dependency | ||
import documentation.model.Dependent | ||
import documentation.model.HttpEndpoint | ||
import java.io.File | ||
import kotlin.reflect.KClass | ||
|
||
private val objectMapper = jacksonObjectMapper() | ||
.setSerializationInclusion(Include.NON_EMPTY) | ||
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) | ||
.enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL) | ||
.enable(SerializationFeature.INDENT_OUTPUT) | ||
|
||
fun generateApplicationDescription(sourceFolder: File, targetFolder: File, applicationId: String) { | ||
val baseApplicationDescription = loadBaseApplicationDescription(sourceFolder, applicationId) | ||
val dependents = loadDependents(sourceFolder) | ||
val dependencies = loadDependencies(sourceFolder) | ||
|
||
val applicationDescription = baseApplicationDescription.copy(dependents = dependents, dependencies = dependencies) | ||
|
||
val file = File(targetFolder, applicationDescription.id + ".json") | ||
objectMapper.writeValue(file, applicationDescription) | ||
} | ||
|
||
private fun loadBaseApplicationDescription(sourceFolder: File, applicationId: String): Application { | ||
val file = File(sourceFolder, "$applicationId.json") | ||
check(file.isFile) { "File not found: $file" } | ||
return objectMapper.readValue<Application>(file) | ||
} | ||
|
||
private fun loadDependents(sourceFolder: File): List<Dependent> = | ||
listJsonFilesInFolder(File(sourceFolder, "dependents")) | ||
.map { file -> loadDependent(file) } | ||
|
||
private fun loadDependent(file: File): Dependent { | ||
return objectMapper.readValue<Dependent>(file) | ||
} | ||
|
||
private fun loadDependencies(sourceFolder: File): List<Dependency> = | ||
listJsonFilesInFolder(File(sourceFolder, "dependencies")) | ||
.map { file -> loadDependency(file) } | ||
|
||
private fun loadDependency(file: File): Dependency { | ||
val dependency = objectMapper.readValue<Dependency>(file) | ||
|
||
var httpEndpoints = emptyList<HttpEndpoint>() | ||
|
||
val httpEndpointsFile = File(file.parentFile, "http-endpoints/${dependency.id}.jsonl") | ||
if (httpEndpointsFile.isFile) { | ||
httpEndpoints = loadFromJsonListFile(httpEndpointsFile, HttpEndpoint::class) | ||
.sortedWith(compareBy(HttpEndpoint::path, HttpEndpoint::method)) | ||
.distinct() | ||
} | ||
|
||
return dependency.copy(httpEndpoints = httpEndpoints) | ||
} | ||
|
||
private fun listJsonFilesInFolder(folder: File): List<File> = | ||
if (folder.isDirectory) { | ||
folder.listFiles()!! | ||
.filter { it.isFile } | ||
.filter { it.extension == "json" } | ||
} else { | ||
emptyList() | ||
} | ||
|
||
private fun <T : Any> loadFromJsonListFile(file: File, clazz: KClass<T>): List<T> = | ||
file.readLines() | ||
.filter(String::isNotBlank) | ||
.map(String::trim) | ||
.map { objectMapper.readValue(it, clazz.java) } |
12 changes: 0 additions & 12 deletions
12
src/main/kotlin/application/documentation/ApplicationDescription.kt
This file was deleted.
Oops, something went wrong.
9 changes: 0 additions & 9 deletions
9
src/main/kotlin/application/documentation/ComponentDescription.kt
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
6 changes: 0 additions & 6 deletions
6
src/main/kotlin/application/documentation/DocumentedDependency.kt
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package application.documentation | ||
|
||
data class ComponentDescription( | ||
val id: String, | ||
val groupId: String? = null, | ||
val systemId: String? = null, | ||
val type: ComponentType, | ||
val distanceFromUs: Distance, | ||
) | ||
|
||
enum class ComponentType { BACKEND, FRONTEND, DATABASE } | ||
enum class Distance { OWNED, CLOSE, EXTERNAL } | ||
|
||
data class HttpEndpoint(val method: String, val path: String) |
This file was deleted.
Oops, something went wrong.
51 changes: 34 additions & 17 deletions
51
src/main/kotlin/application/external/BackendService2Client.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,40 @@ | ||
package application.external | ||
|
||
import application.documentation.ComponentDescription | ||
import application.documentation.ComponentType.BACKEND | ||
import application.documentation.Distance.OWNED | ||
import application.documentation.DocumentedDependency | ||
import org.springframework.stereotype.Component | ||
import org.springframework.boot.context.properties.ConfigurationProperties | ||
import org.springframework.boot.context.properties.EnableConfigurationProperties | ||
import org.springframework.context.annotation.Bean | ||
import org.springframework.context.annotation.Configuration | ||
import org.springframework.web.client.RestClient | ||
import org.springframework.web.client.body | ||
import java.net.URL | ||
|
||
@Component | ||
class BackendService2Client : DocumentedDependency { | ||
class BackendService2Client( | ||
private val client: RestClient | ||
) { | ||
|
||
override val description = ComponentDescription( | ||
id = "backend-service-2", | ||
contextId = "application", | ||
systemId = "platform", | ||
type = BACKEND, | ||
distanceFromUs = OWNED | ||
) | ||
fun getSomething(id: String): String? = | ||
client.get() | ||
.uri { it.path("/bar/{id}").build(mapOf("id" to id)) } | ||
.retrieve() | ||
.body<String>() | ||
} | ||
|
||
@Configuration | ||
@EnableConfigurationProperties(BackendService2Properties::class) | ||
class BackendService2Configuration( | ||
private val properties: BackendService2Properties | ||
) { | ||
|
||
fun getSomething(): String { | ||
TODO("some kind of implementation") | ||
} | ||
@Bean | ||
fun backendService2Client(): BackendService2Client = | ||
BackendService2Client( | ||
client = RestClient.builder() | ||
.baseUrl(properties.baseUrl.toString()) | ||
.build() | ||
) | ||
} | ||
|
||
@ConfigurationProperties("application.external.backends.backend-service-2") | ||
data class BackendService2Properties( | ||
val baseUrl: URL | ||
) |
Oops, something went wrong.