Merge pull request 'Split the project into three modules for every actors' (#14) from container-split into master
Reviewed-on: #14
This commit is contained in:
commit
34a2b3b2e6
87 changed files with 2288 additions and 337 deletions
39
.gitignore
vendored
39
.gitignore
vendored
|
@ -1,39 +0,0 @@
|
|||
# Gradle
|
||||
.gradle/
|
||||
build/
|
||||
|
||||
# Eclipse
|
||||
.project
|
||||
.classpath
|
||||
.settings/
|
||||
bin/
|
||||
|
||||
# IntelliJ
|
||||
.idea
|
||||
*.ipr
|
||||
*.iml
|
||||
*.iws
|
||||
|
||||
# NetBeans
|
||||
nb-configuration.xml
|
||||
|
||||
# Visual Studio Code
|
||||
.vscode
|
||||
.factorypath
|
||||
|
||||
# OSX
|
||||
.DS_Store
|
||||
|
||||
# Vim
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# patch
|
||||
*.orig
|
||||
*.rej
|
||||
|
||||
# Local environment
|
||||
.env
|
||||
|
||||
# Plugin directory
|
||||
/.quarkus/cli/plugins/
|
8
.idea/.gitignore
vendored
Normal file
8
.idea/.gitignore
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
47
.idea/gradle.xml
Normal file
47
.idea/gradle.xml
Normal file
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$/applications/common" />
|
||||
<option name="gradleJvm" value="openjdk-21" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$/applications/common" />
|
||||
</set>
|
||||
</option>
|
||||
</GradleProjectSettings>
|
||||
<GradleProjectSettings>
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$/applications/consumer" />
|
||||
<option name="gradleJvm" value="openjdk-21" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$/applications/common" />
|
||||
<option value="$PROJECT_DIR$/applications/consumer" />
|
||||
</set>
|
||||
</option>
|
||||
</GradleProjectSettings>
|
||||
<GradleProjectSettings>
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$/applications/converter" />
|
||||
<option name="gradleJvm" value="openjdk-21" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$/applications/common" />
|
||||
<option value="$PROJECT_DIR$/applications/converter" />
|
||||
</set>
|
||||
</option>
|
||||
</GradleProjectSettings>
|
||||
<GradleProjectSettings>
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$/applications/producer" />
|
||||
<option name="gradleJvm" value="openjdk-21" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$/applications/common" />
|
||||
<option value="$PROJECT_DIR$/applications/producer" />
|
||||
</set>
|
||||
</option>
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
25
.idea/jarRepositories.xml
Normal file
25
.idea/jarRepositories.xml
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RemoteRepositoriesConfiguration">
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Maven Central repository" />
|
||||
<option name="url" value="https://repo1.maven.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="jboss.community" />
|
||||
<option name="name" value="JBoss Community repository" />
|
||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="MavenRepo" />
|
||||
<option name="name" value="MavenRepo" />
|
||||
<option name="url" value="https://repo.maven.apache.org/maven2/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="MavenLocal" />
|
||||
<option name="name" value="MavenLocal" />
|
||||
<option name="url" value="file:$MAVEN_REPOSITORY$/" />
|
||||
</remote-repository>
|
||||
</component>
|
||||
</project>
|
6
.idea/kotlinc.xml
Normal file
6
.idea/kotlinc.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="KotlinJpsPluginSettings">
|
||||
<option name="version" value="2.0.0" />
|
||||
</component>
|
||||
</project>
|
13
.idea/misc.xml
Normal file
13
.idea/misc.xml
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="FrameworkDetectionExcludesConfiguration">
|
||||
<file type="web" url="file://$PROJECT_DIR$/applications/common" />
|
||||
<file type="web" url="file://$PROJECT_DIR$/applications/consumer" />
|
||||
<file type="web" url="file://$PROJECT_DIR$/applications/converter" />
|
||||
<file type="web" url="file://$PROJECT_DIR$/applications/producer" />
|
||||
</component>
|
||||
<component name="ProjectRootManager">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
8
.idea/modules.xml
Normal file
8
.idea/modules.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/modules/m1_pe_kafka.iml" filepath="$PROJECT_DIR$/.idea/modules/m1_pe_kafka.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
14
.idea/modules/m1_pe_kafka.iml
Normal file
14
.idea/modules/m1_pe_kafka.iml
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module version="4">
|
||||
<component name="AdditionalModuleElements">
|
||||
<content url="file://$MODULE_DIR$/../.." dumb="true">
|
||||
<excludeFolder url="file://$MODULE_DIR$/../../applications/common/.gradle" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/../../applications/common/build" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/../../applications/consumer/.gradle" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/../../applications/consumer/build" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/../../applications/converter/.gradle" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/../../applications/converter/build" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/../../applications/producer/build" />
|
||||
</content>
|
||||
</component>
|
||||
</module>
|
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
15
.run/Compose.run.xml
Normal file
15
.run/Compose.run.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Compose" type="docker-deploy" factoryName="docker-compose.yml" server-name="Docker">
|
||||
<deployment type="docker-compose.yml">
|
||||
<settings>
|
||||
<option name="envFilePath" value="" />
|
||||
<option name="sourceFilePath" value="docker-compose.yaml" />
|
||||
</settings>
|
||||
</deployment>
|
||||
<method v="2">
|
||||
<option name="Gradle.BeforeRunTask" enabled="true" tasks="build" externalProjectPath="$PROJECT_DIR$/applications/consumer" vmOptions="" scriptParameters="" />
|
||||
<option name="Gradle.BeforeRunTask" enabled="true" tasks="build" externalProjectPath="$PROJECT_DIR$/applications/converter" vmOptions="" scriptParameters="" />
|
||||
<option name="Gradle.BeforeRunTask" enabled="true" tasks="build" externalProjectPath="$PROJECT_DIR$/applications/producer" vmOptions="" scriptParameters="" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
|
@ -1,13 +0,0 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="compose" type="docker-deploy" factoryName="docker-compose.yml" server-name="Docker">
|
||||
<deployment type="docker-compose.yml">
|
||||
<settings>
|
||||
<option name="envFilePath" value="" />
|
||||
<option name="sourceFilePath" value="docker-compose.yaml" />
|
||||
</settings>
|
||||
</deployment>
|
||||
<method v="2">
|
||||
<option name="Gradle.BeforeRunTask" enabled="true" tasks="build" externalProjectPath="$PROJECT_DIR$" vmOptions="" scriptParameters="" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
26
README.md
26
README.md
|
@ -23,26 +23,26 @@ Alternatively, you can build and run the project manually by using
|
|||
[gradle](https://gradle.org/) and launching the application with [docker-compose](https://docs.docker.com/compose/).
|
||||
|
||||
```shell
|
||||
gradlew build
|
||||
# build the modules
|
||||
(cd ./applications/consumer/ && ./gradlew build)
|
||||
(cd ./applications/converter/ && ./gradlew build)
|
||||
(cd ./applications/producer/ && ./gradlew build)
|
||||
# start the docker based on the docker-compose.yaml file
|
||||
docker compose up
|
||||
```
|
||||
|
||||
## Configuration
|
||||
If you wish, you can modify the configuration of the `docker-compose.yaml` file to fit your needs.
|
||||
The configuration can be modified in the [docker-compose.yaml](./docker-compose.yaml) file to fit your needs.
|
||||
|
||||
The container `application` can be easily modified with the following environment variables :
|
||||
|
||||
| Name | Required | Format | Default | Description |
|
||||
|------------------------------|----------|-----------------------------------------------------|--------------------------------------------------------------------|---------------------------------------------------------------|
|
||||
| KAFKA_BOOTSTRAP_SERVERS | true | \<ip>[:port] | / | The Kafka server address |
|
||||
| TOPIC_TEMPERATURE_CELSIUS | false | string of alphanumeric characters, ".", "_" and "-" | temperature-celsius | The name of the Kafka topic for the temperature in Celsius |
|
||||
| TOPIC_TEMPERATURE_FAHRENHEIT | false | string of alphanumeric characters, ".", "_" and "-" | temperature-fahrenheit | The name of the Kafka topic for the temperature in Fahrenheit |
|
||||
| TEMPERATURE_LOCATION | true | \<latitude>, \<longitude> | 49.9, 2.3 ([Amiens, France](https://fr.wikipedia.org/wiki/Amiens)) | The coordinates where to get the temperatures from |
|
||||
You can find a list for each module of the project containing their individual configuration :
|
||||
- [producer](./applications/producer/README.md)
|
||||
- [consumer](./applications/consumer/README.md)
|
||||
- [converter](./applications/converter/README.md)
|
||||
|
||||
## Expectation
|
||||
The `application` container shall print the current temperature at the selected place in Fahrenheit every minute.
|
||||
You can also access this value with the REST api at the `http://localhost:8080/temperature` endpoint.
|
||||
You can also access this value with the REST api at the `http://localhost:8080/v1/temperature` endpoint.
|
||||
|
||||
## References
|
||||
The project use the [Open-Meteo API](https://open-meteo.com/) to fetch the current temperature at the
|
||||
given location.
|
||||
The project use the [Open-Meteo](https://open-meteo.com/) API to fetch the current temperature at the
|
||||
given location.
|
||||
|
|
39
applications/common/.gitignore
vendored
Normal file
39
applications/common/.gitignore
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
# Gradle
|
||||
.gradle/
|
||||
build/
|
||||
|
||||
# Eclipse
|
||||
.project
|
||||
.classpath
|
||||
.settings/
|
||||
bin/
|
||||
|
||||
# IntelliJ
|
||||
.idea
|
||||
*.ipr
|
||||
*.iml
|
||||
*.iws
|
||||
|
||||
# NetBeans
|
||||
nb-configuration.xml
|
||||
|
||||
# Visual Studio Code
|
||||
.vscode
|
||||
.factorypath
|
||||
|
||||
# OSX
|
||||
.DS_Store
|
||||
|
||||
# Vim
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# patch
|
||||
*.orig
|
||||
*.rej
|
||||
|
||||
# Local environment
|
||||
.env
|
||||
|
||||
# Plugin directory
|
||||
/.quarkus/cli/plugins/
|
15
applications/common/README.md
Normal file
15
applications/common/README.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
# Module: Common
|
||||
|
||||
This module contain common code that could be used between the three others modules of the application.
|
||||
|
||||
It implements some errors or some useful functionalities and structure to avoid redefining them in all the modules
|
||||
and making debugging easier by only modifying a single file to fix the corresponding issue everywhere.
|
||||
|
||||
## Build
|
||||
|
||||
This project is built automatically when building the others modules.
|
||||
|
||||
However, you can still build it manually with the following command :
|
||||
```shell
|
||||
./gradlew build
|
||||
```
|
|
@ -1,6 +1,6 @@
|
|||
plugins {
|
||||
kotlin("jvm") version "1.9.23"
|
||||
kotlin("plugin.allopen") version "1.9.23"
|
||||
kotlin("jvm") version "2.0.0"
|
||||
kotlin("plugin.allopen") version "2.0.0"
|
||||
id("io.quarkus")
|
||||
}
|
||||
|
||||
|
@ -14,9 +14,6 @@ val quarkusPlatformArtifactId: String by project
|
|||
val quarkusPlatformVersion: String by project
|
||||
|
||||
dependencies {
|
||||
// language
|
||||
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
||||
|
||||
// quarkus
|
||||
implementation(enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}"))
|
||||
implementation("io.quarkus:quarkus-kotlin")
|
||||
|
@ -27,7 +24,6 @@ dependencies {
|
|||
implementation("io.quarkus:quarkus-kafka-client")
|
||||
implementation("io.quarkus:quarkus-kafka-streams")
|
||||
implementation("io.quarkus:quarkus-messaging-kafka")
|
||||
implementation("io.quarkus:quarkus-rest")
|
||||
implementation("com.squareup.okhttp3:okhttp:4.12.0")
|
||||
implementation("com.google.code.gson:gson:2.8.9")
|
||||
}
|
6
applications/common/gradle.properties
Normal file
6
applications/common/gradle.properties
Normal file
|
@ -0,0 +1,6 @@
|
|||
#Gradle properties
|
||||
quarkusPluginId=io.quarkus
|
||||
quarkusPluginVersion=3.12.0
|
||||
quarkusPlatformGroupId=io.quarkus.platform
|
||||
quarkusPlatformArtifactId=quarkus-bom
|
||||
quarkusPlatformVersion=3.12.0
|
|
@ -1,5 +1,5 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
0
gradlew → applications/common/gradlew
vendored
0
gradlew → applications/common/gradlew
vendored
|
@ -10,4 +10,4 @@ pluginManagement {
|
|||
id(quarkusPluginId) version quarkusPluginVersion
|
||||
}
|
||||
}
|
||||
rootProject.name = "m1_pe_kafka"
|
||||
rootProject.name = "common"
|
|
@ -1,4 +1,4 @@
|
|||
package fr.faraphel.m1_pe_kafka.error
|
||||
package fr.faraphel.common.error
|
||||
|
||||
|
||||
/**
|
|
@ -1,4 +1,4 @@
|
|||
package fr.faraphel.m1_pe_kafka.error.http
|
||||
package fr.faraphel.common.error.http
|
||||
|
||||
import java.io.IOException
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package fr.faraphel.common.temperature
|
||||
|
||||
|
||||
/**
|
||||
* Represent a temperature
|
||||
* Allow to store temperature and convert the units in an easier way
|
||||
* @param value the value of the temperature (Kelvin)
|
||||
*/
|
||||
class Temperature(
|
||||
private val value: Double
|
||||
) {
|
||||
// convert Temperature to Double (Kelvin)
|
||||
val asKelvin: Double
|
||||
get() = this.value
|
||||
// convert Temperature to Double (Celsius)
|
||||
val asCelsius: Double
|
||||
get() = this.value - 275.15
|
||||
// convert Temperature to Double (Fahrenheit)
|
||||
val asFahrenheit: Double
|
||||
get() = ((this.value - 273.15) * 1.8) + 32
|
||||
}
|
|
@ -1,25 +1,6 @@
|
|||
package fr.faraphel.m1_pe_kafka.utils
|
||||
package fr.faraphel.common.temperature
|
||||
|
||||
|
||||
/**
|
||||
* Represent a temperature
|
||||
* Allow to store temperature and convert the units in an easier way
|
||||
* @param value the value of the temperature (Kelvin)
|
||||
*/
|
||||
class Temperature(
|
||||
private val value: Double
|
||||
) {
|
||||
// convert Temperature to Double (Kelvin)
|
||||
val asKelvin: Double
|
||||
get() = this.value
|
||||
// convert Temperature to Double (Celsius)
|
||||
val asCelsius: Double
|
||||
get() = this.value - 275.15
|
||||
// convert Temperature to Double (Fahrenheit)
|
||||
val asFahrenheit: Double
|
||||
get() = ((this.value - 273.15) * 1.8) + 32
|
||||
}
|
||||
|
||||
// convert Double (Kelvin) to Temperature
|
||||
val Double.kelvin: Temperature
|
||||
get() = Temperature(this)
|
39
applications/consumer/.gitignore
vendored
Normal file
39
applications/consumer/.gitignore
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
# Gradle
|
||||
.gradle/
|
||||
build/
|
||||
|
||||
# Eclipse
|
||||
.project
|
||||
.classpath
|
||||
.settings/
|
||||
bin/
|
||||
|
||||
# IntelliJ
|
||||
.idea
|
||||
*.ipr
|
||||
*.iml
|
||||
*.iws
|
||||
|
||||
# NetBeans
|
||||
nb-configuration.xml
|
||||
|
||||
# Visual Studio Code
|
||||
.vscode
|
||||
.factorypath
|
||||
|
||||
# OSX
|
||||
.DS_Store
|
||||
|
||||
# Vim
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# patch
|
||||
*.orig
|
||||
*.rej
|
||||
|
||||
# Local environment
|
||||
.env
|
||||
|
||||
# Plugin directory
|
||||
/.quarkus/cli/plugins/
|
22
applications/consumer/README.md
Normal file
22
applications/consumer/README.md
Normal file
|
@ -0,0 +1,22 @@
|
|||
# Module: Consumer
|
||||
|
||||
This module contain the code responsible for receiving values, displaying them in the container output and hosting
|
||||
the REST API where we can find the latest value received.
|
||||
|
||||
## Build
|
||||
|
||||
This project is built automatically when using [docker-compose](https://docs.docker.com/compose/) at the root.
|
||||
|
||||
However, you can still build it manually with the following command :
|
||||
```shell
|
||||
./gradlew build
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
This module can be easily modified with the following environment variables :
|
||||
|
||||
| Name | Required | Format | Default | Description |
|
||||
|-------------------------|----------|-----------------------------------------------------|---------|---------------------------------------------------|
|
||||
| KAFKA_BOOTSTRAP_SERVERS | true | \<ip>[:port] | / | The Kafka server address |
|
||||
| TEMPERATURE_TOPIC | true | string of alphanumeric characters, ".", "_" and "-" | / | The Kafka topic were the temperature can be found |
|
54
applications/consumer/build.gradle.kts
Normal file
54
applications/consumer/build.gradle.kts
Normal file
|
@ -0,0 +1,54 @@
|
|||
plugins {
|
||||
kotlin("jvm") version "2.0.0"
|
||||
kotlin("plugin.allopen") version "2.0.0"
|
||||
id("io.quarkus")
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
}
|
||||
|
||||
val quarkusPlatformGroupId: String by project
|
||||
val quarkusPlatformArtifactId: String by project
|
||||
val quarkusPlatformVersion: String by project
|
||||
|
||||
dependencies {
|
||||
// common
|
||||
implementation(project(":common"))
|
||||
|
||||
// quarkus
|
||||
implementation(enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}"))
|
||||
implementation("io.quarkus:quarkus-kotlin")
|
||||
implementation("io.quarkus:quarkus-arc")
|
||||
testImplementation("io.quarkus:quarkus-junit5")
|
||||
implementation("io.quarkus:quarkus-rest")
|
||||
|
||||
// libraries
|
||||
implementation("io.quarkus:quarkus-kafka-client")
|
||||
implementation("io.quarkus:quarkus-kafka-streams")
|
||||
implementation("com.google.code.gson:gson:2.8.9")
|
||||
}
|
||||
|
||||
group = "fr.faraphel"
|
||||
version = "1.0-SNAPSHOT"
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_21
|
||||
targetCompatibility = JavaVersion.VERSION_21
|
||||
}
|
||||
|
||||
tasks.withType<Test> {
|
||||
systemProperty("java.util.logging.manager", "org.jboss.logmanager.LogManager")
|
||||
}
|
||||
allOpen {
|
||||
annotation("jakarta.ws.rs.Path")
|
||||
annotation("jakarta.enterprise.context.ApplicationScoped")
|
||||
annotation("jakarta.persistence.Entity")
|
||||
annotation("io.quarkus.test.junit.QuarkusTest")
|
||||
}
|
||||
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
|
||||
kotlinOptions.jvmTarget = JavaVersion.VERSION_21.toString()
|
||||
kotlinOptions.javaParameters = true
|
||||
}
|
6
applications/consumer/gradle.properties
Normal file
6
applications/consumer/gradle.properties
Normal file
|
@ -0,0 +1,6 @@
|
|||
#Gradle properties
|
||||
quarkusPluginId=io.quarkus
|
||||
quarkusPluginVersion=3.12.0
|
||||
quarkusPlatformGroupId=io.quarkus.platform
|
||||
quarkusPlatformArtifactId=quarkus-bom
|
||||
quarkusPlatformVersion=3.12.0
|
BIN
applications/consumer/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
applications/consumer/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
applications/consumer/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
applications/consumer/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
185
applications/consumer/gradlew
vendored
Executable file
185
applications/consumer/gradlew
vendored
Executable file
|
@ -0,0 +1,185 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
104
applications/consumer/gradlew.bat
vendored
Normal file
104
applications/consumer/gradlew.bat
vendored
Normal file
|
@ -0,0 +1,104 @@
|
|||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
17
applications/consumer/settings.gradle.kts
Normal file
17
applications/consumer/settings.gradle.kts
Normal file
|
@ -0,0 +1,17 @@
|
|||
pluginManagement {
|
||||
val quarkusPluginVersion: String by settings
|
||||
val quarkusPluginId: String by settings
|
||||
repositories {
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
mavenLocal()
|
||||
}
|
||||
plugins {
|
||||
id(quarkusPluginId) version quarkusPluginVersion
|
||||
}
|
||||
}
|
||||
rootProject.name = "consumer"
|
||||
|
||||
// Dependencies
|
||||
include(":common")
|
||||
project(":common").projectDir = file("../common")
|
|
@ -7,11 +7,11 @@
|
|||
#
|
||||
# Then, build the image with:
|
||||
#
|
||||
# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/m1_pe_kafka-jvm .
|
||||
# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/consumer-jvm .
|
||||
#
|
||||
# Then run the container using:
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/m1_pe_kafka-jvm
|
||||
# docker run -i --rm -p 8080:8080 quarkus/consumer-jvm
|
||||
#
|
||||
# If you want to include the debug port into your docker image
|
||||
# you will have to expose the debug port (default 5005 being the default) like this : EXPOSE 8080 5005.
|
||||
|
@ -20,7 +20,7 @@
|
|||
#
|
||||
# Then run the container using :
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/m1_pe_kafka-jvm
|
||||
# docker run -i --rm -p 8080:8080 quarkus/consumer-jvm
|
||||
#
|
||||
# This image uses the `run-java.sh` script to run the application.
|
||||
# This scripts computes the command line to execute your Java application, and
|
||||
|
@ -77,7 +77,7 @@
|
|||
# accessed directly. (example: "foo.example.com,bar.example.com")
|
||||
#
|
||||
###
|
||||
FROM registry.access.redhat.com/ubi8/openjdk-21:1.18
|
||||
FROM registry.access.redhat.com/ubi8/openjdk-21:1.19
|
||||
|
||||
ENV LANGUAGE='en_US:en'
|
||||
|
|
@ -7,11 +7,11 @@
|
|||
#
|
||||
# Then, build the image with:
|
||||
#
|
||||
# docker build -f src/main/docker/Dockerfile.legacy-jar -t quarkus/m1_pe_kafka-legacy-jar .
|
||||
# docker build -f src/main/docker/Dockerfile.legacy-jar -t quarkus/consumer-legacy-jar .
|
||||
#
|
||||
# Then run the container using:
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/m1_pe_kafka-legacy-jar
|
||||
# docker run -i --rm -p 8080:8080 quarkus/consumer-legacy-jar
|
||||
#
|
||||
# If you want to include the debug port into your docker image
|
||||
# you will have to expose the debug port (default 5005 being the default) like this : EXPOSE 8080 5005.
|
||||
|
@ -20,7 +20,7 @@
|
|||
#
|
||||
# Then run the container using :
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/m1_pe_kafka-legacy-jar
|
||||
# docker run -i --rm -p 8080:8080 quarkus/consumer-legacy-jar
|
||||
#
|
||||
# This image uses the `run-java.sh` script to run the application.
|
||||
# This scripts computes the command line to execute your Java application, and
|
||||
|
@ -77,7 +77,7 @@
|
|||
# accessed directly. (example: "foo.example.com,bar.example.com")
|
||||
#
|
||||
###
|
||||
FROM registry.access.redhat.com/ubi8/openjdk-21:1.18
|
||||
FROM registry.access.redhat.com/ubi8/openjdk-21:1.19
|
||||
|
||||
ENV LANGUAGE='en_US:en'
|
||||
|
|
@ -7,11 +7,11 @@
|
|||
#
|
||||
# Then, build the image with:
|
||||
#
|
||||
# docker build -f src/main/docker/Dockerfile.native -t quarkus/m1_pe_kafka .
|
||||
# docker build -f src/main/docker/Dockerfile.native -t quarkus/consumer .
|
||||
#
|
||||
# Then run the container using:
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/m1_pe_kafka
|
||||
# docker run -i --rm -p 8080:8080 quarkus/consumer
|
||||
#
|
||||
###
|
||||
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.9
|
|
@ -10,11 +10,11 @@
|
|||
#
|
||||
# Then, build the image with:
|
||||
#
|
||||
# docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/m1_pe_kafka .
|
||||
# docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/consumer .
|
||||
#
|
||||
# Then run the container using:
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/m1_pe_kafka
|
||||
# docker run -i --rm -p 8080:8080 quarkus/consumer
|
||||
#
|
||||
###
|
||||
FROM quay.io/quarkus/quarkus-micro-image:2.0
|
|
@ -0,0 +1,41 @@
|
|||
package fr.faraphel.consumer
|
||||
|
||||
import fr.faraphel.consumer.kafka.Consumer
|
||||
import fr.faraphel.consumer.rest.TemperatureEndpoint
|
||||
import fr.faraphel.common.error.MissingEnvironmentException
|
||||
import io.quarkus.runtime.QuarkusApplication
|
||||
import io.quarkus.runtime.annotations.QuarkusMain
|
||||
import java.time.Instant
|
||||
|
||||
|
||||
@QuarkusMain
|
||||
class Main : QuarkusApplication {
|
||||
override fun run(vararg args: String?): Int {
|
||||
// get the kafka server address
|
||||
val kafkaServer = System.getenv("KAFKA_BOOTSTRAP_SERVERS")
|
||||
?: throw MissingEnvironmentException("KAFKA_BOOTSTRAP_SERVERS")
|
||||
|
||||
// get the topic name
|
||||
val topicTemperature: String = System.getenv("TEMPERATURE_TOPIC")
|
||||
?: throw MissingEnvironmentException("TEMPERATURE_TOPIC")
|
||||
|
||||
// create a consumer that will print the received values in the input topic
|
||||
val consumer = Consumer(
|
||||
server=kafkaServer,
|
||||
topic=topicTemperature
|
||||
) { message ->
|
||||
// clean the values in the record
|
||||
val messageInstant = Instant.ofEpochMilli(message.timestamp())
|
||||
val messageContent = message.value()
|
||||
// print the value
|
||||
println("[${timeFormatter.format(messageInstant)}] ${messageContent}°F")
|
||||
// update the value for the API
|
||||
TemperatureEndpoint.updateData(messageContent, messageInstant)
|
||||
}
|
||||
|
||||
// indefinitely consume new values
|
||||
consumer.consumeForever()
|
||||
|
||||
return 0
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
package fr.faraphel.m1_pe_kafka.kafka
|
||||
|
||||
package fr.faraphel.consumer.kafka
|
||||
|
||||
import org.apache.kafka.clients.consumer.*
|
||||
import org.apache.kafka.common.serialization.DoubleDeserializer
|
||||
|
@ -21,10 +20,10 @@ import kotlin.time.toJavaDuration
|
|||
*/
|
||||
class Consumer(
|
||||
private val server: String,
|
||||
private val identifier: String = "consumer",
|
||||
private val identifier: String = "fr/faraphel/consumer",
|
||||
private val topic: String,
|
||||
private val callback: (ConsumerRecord<String, Double>) -> Unit,
|
||||
) : Thread() {
|
||||
) {
|
||||
private val properties: Properties = Properties().apply {
|
||||
// identifier
|
||||
this[ConsumerConfig.GROUP_ID_CONFIG] = identifier
|
||||
|
@ -49,7 +48,7 @@ class Consumer(
|
|||
val messages: ConsumerRecords<String, Double> = this.consumer.poll(timeout)
|
||||
|
||||
// print them with their timestamp and content
|
||||
messages.forEach { message -> this.callback(message) }
|
||||
messages.forEach(this.callback)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -59,10 +58,4 @@ class Consumer(
|
|||
fun consumeForever(timeout: Duration = 1.seconds.toJavaDuration()) {
|
||||
while (true) this.consume(timeout)
|
||||
}
|
||||
|
||||
/**
|
||||
* Thread entrypoint
|
||||
* @see consumeForever
|
||||
*/
|
||||
override fun run() = this.consumeForever()
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package fr.faraphel.m1_pe_kafka.rest
|
||||
package fr.faraphel.consumer.rest
|
||||
|
||||
import jakarta.ws.rs.GET
|
||||
import jakarta.ws.rs.Path
|
||||
|
@ -9,7 +9,7 @@ import jakarta.ws.rs.Path
|
|||
* Always answer "Pong!"
|
||||
* Can be used to test if the API can be reached
|
||||
*/
|
||||
@Path("ping")
|
||||
@Path("/v1/ping")
|
||||
class PingEndpoint {
|
||||
/**
|
||||
* Handler for a GET request on this endpoint
|
|
@ -0,0 +1,43 @@
|
|||
package fr.faraphel.consumer.rest
|
||||
|
||||
import com.google.gson.Gson
|
||||
import jakarta.ws.rs.GET
|
||||
import jakarta.ws.rs.Path
|
||||
import jakarta.ws.rs.Produces
|
||||
import jakarta.ws.rs.core.MediaType
|
||||
import java.time.Instant
|
||||
|
||||
|
||||
/**
|
||||
* This API endpoint return the latest temperature measured (in Fahrenheit)
|
||||
*/
|
||||
@Path("/v1/temperature")
|
||||
class TemperatureEndpoint {
|
||||
companion object {
|
||||
val jsonParser = Gson() ///< the json parser
|
||||
|
||||
private var temperature: Double? = null ///< the latest temperature value
|
||||
private var time: Instant? = null /// < the time of the latest value
|
||||
|
||||
/**
|
||||
* Setter to update the latest temperature value
|
||||
* @param temperature the new temperature value
|
||||
*/
|
||||
fun updateData(temperature: Double, time: Instant) {
|
||||
this.temperature = temperature
|
||||
this.time = time
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for a GET request on this endpoint
|
||||
* @return the latest temperature measured
|
||||
*/
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
fun get(): String = jsonParser.toJson(mapOf(
|
||||
"value" to temperature,
|
||||
"time" to time?.toEpochMilli(),
|
||||
"unit" to "Fahrenheit"
|
||||
))
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package fr.faraphel.consumer
|
||||
|
||||
import java.time.ZoneId
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
|
||||
// create a time formatter
|
||||
val timeFormatter: DateTimeFormatter = DateTimeFormatter
|
||||
.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")
|
||||
.withZone(ZoneId.systemDefault())
|
5
applications/converter/.dockerignore
Normal file
5
applications/converter/.dockerignore
Normal file
|
@ -0,0 +1,5 @@
|
|||
*
|
||||
!build/*-runner
|
||||
!build/*-runner.jar
|
||||
!build/lib/*
|
||||
!build/quarkus-app/*
|
39
applications/converter/.gitignore
vendored
Normal file
39
applications/converter/.gitignore
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
# Gradle
|
||||
.gradle/
|
||||
build/
|
||||
|
||||
# Eclipse
|
||||
.project
|
||||
.classpath
|
||||
.settings/
|
||||
bin/
|
||||
|
||||
# IntelliJ
|
||||
.idea
|
||||
*.ipr
|
||||
*.iml
|
||||
*.iws
|
||||
|
||||
# NetBeans
|
||||
nb-configuration.xml
|
||||
|
||||
# Visual Studio Code
|
||||
.vscode
|
||||
.factorypath
|
||||
|
||||
# OSX
|
||||
.DS_Store
|
||||
|
||||
# Vim
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# patch
|
||||
*.orig
|
||||
*.rej
|
||||
|
||||
# Local environment
|
||||
.env
|
||||
|
||||
# Plugin directory
|
||||
/.quarkus/cli/plugins/
|
23
applications/converter/README.md
Normal file
23
applications/converter/README.md
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Module: Converter
|
||||
|
||||
This module contain the code responsible for receiving values from a topic, converting them from
|
||||
Celsius temperature to Fahrenheit and send it back into another topic.
|
||||
|
||||
## Build
|
||||
|
||||
This project is built automatically when using [docker-compose](https://docs.docker.com/compose/) at the root.
|
||||
|
||||
However, you can still build it manually with the following command :
|
||||
```shell
|
||||
./gradlew build
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
This module can be easily modified with the following environment variables :
|
||||
|
||||
| Name | Required | Format | Default | Description |
|
||||
|------------------------------|----------|-----------------------------------------------------|---------|-----------------------------------------------------------------|
|
||||
| KAFKA_BOOTSTRAP_SERVERS | true | \<ip>[:port] | / | The Kafka server address |
|
||||
| TEMPERATURE_CELSIUS_TOPIC | true | string of alphanumeric characters, ".", "_" and "-" | / | The Kafka topic were the temperature in celsius can be found |
|
||||
| TEMPERATURE_FAHRENHEIT_TOPIC | true | string of alphanumeric characters, ".", "_" and "-" | / | The Kafka topic were the temperature in fahrenheit can be found |
|
52
applications/converter/build.gradle.kts
Normal file
52
applications/converter/build.gradle.kts
Normal file
|
@ -0,0 +1,52 @@
|
|||
plugins {
|
||||
kotlin("jvm") version "2.0.0"
|
||||
kotlin("plugin.allopen") version "2.0.0"
|
||||
id("io.quarkus")
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
}
|
||||
|
||||
val quarkusPlatformGroupId: String by project
|
||||
val quarkusPlatformArtifactId: String by project
|
||||
val quarkusPlatformVersion: String by project
|
||||
|
||||
dependencies {
|
||||
// common
|
||||
implementation(project(":common"))
|
||||
|
||||
// quarkus
|
||||
implementation(enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}"))
|
||||
implementation("io.quarkus:quarkus-kotlin")
|
||||
implementation("io.quarkus:quarkus-arc")
|
||||
testImplementation("io.quarkus:quarkus-junit5")
|
||||
|
||||
// libraries
|
||||
implementation("io.quarkus:quarkus-kafka-client")
|
||||
implementation("io.quarkus:quarkus-kafka-streams")
|
||||
}
|
||||
|
||||
group = "fr.faraphel"
|
||||
version = "1.0-SNAPSHOT"
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_21
|
||||
targetCompatibility = JavaVersion.VERSION_21
|
||||
}
|
||||
|
||||
tasks.withType<Test> {
|
||||
systemProperty("java.util.logging.manager", "org.jboss.logmanager.LogManager")
|
||||
}
|
||||
allOpen {
|
||||
annotation("jakarta.ws.rs.Path")
|
||||
annotation("jakarta.enterprise.context.ApplicationScoped")
|
||||
annotation("jakarta.persistence.Entity")
|
||||
annotation("io.quarkus.test.junit.QuarkusTest")
|
||||
}
|
||||
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
|
||||
kotlinOptions.jvmTarget = JavaVersion.VERSION_21.toString()
|
||||
kotlinOptions.javaParameters = true
|
||||
}
|
6
applications/converter/gradle.properties
Normal file
6
applications/converter/gradle.properties
Normal file
|
@ -0,0 +1,6 @@
|
|||
#Gradle properties
|
||||
quarkusPluginId=io.quarkus
|
||||
quarkusPluginVersion=3.12.0
|
||||
quarkusPlatformGroupId=io.quarkus.platform
|
||||
quarkusPlatformArtifactId=quarkus-bom
|
||||
quarkusPlatformVersion=3.12.0
|
BIN
applications/converter/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
applications/converter/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
applications/converter/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
applications/converter/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
185
applications/converter/gradlew
vendored
Executable file
185
applications/converter/gradlew
vendored
Executable file
|
@ -0,0 +1,185 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
104
applications/converter/gradlew.bat
vendored
Normal file
104
applications/converter/gradlew.bat
vendored
Normal file
|
@ -0,0 +1,104 @@
|
|||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
17
applications/converter/settings.gradle.kts
Normal file
17
applications/converter/settings.gradle.kts
Normal file
|
@ -0,0 +1,17 @@
|
|||
pluginManagement {
|
||||
val quarkusPluginVersion: String by settings
|
||||
val quarkusPluginId: String by settings
|
||||
repositories {
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
mavenLocal()
|
||||
}
|
||||
plugins {
|
||||
id(quarkusPluginId) version quarkusPluginVersion
|
||||
}
|
||||
}
|
||||
rootProject.name = "converter"
|
||||
|
||||
// Dependencies
|
||||
include(":common")
|
||||
project(":common").projectDir = file("../common")
|
96
applications/converter/src/main/docker/Dockerfile.jvm
Normal file
96
applications/converter/src/main/docker/Dockerfile.jvm
Normal file
|
@ -0,0 +1,96 @@
|
|||
####
|
||||
# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
|
||||
#
|
||||
# Before building the container image run:
|
||||
#
|
||||
# ./gradlew build
|
||||
#
|
||||
# Then, build the image with:
|
||||
#
|
||||
# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/converter-jvm .
|
||||
#
|
||||
# Then run the container using:
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/converter-jvm
|
||||
#
|
||||
# If you want to include the debug port into your docker image
|
||||
# you will have to expose the debug port (default 5005 being the default) like this : EXPOSE 8080 5005.
|
||||
# Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005
|
||||
# when running the container
|
||||
#
|
||||
# Then run the container using :
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/converter-jvm
|
||||
#
|
||||
# This image uses the `run-java.sh` script to run the application.
|
||||
# This scripts computes the command line to execute your Java application, and
|
||||
# includes memory/GC tuning.
|
||||
# You can configure the behavior using the following environment properties:
|
||||
# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class")
|
||||
# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options
|
||||
# in JAVA_OPTS (example: "-Dsome.property=foo")
|
||||
# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is
|
||||
# used to calculate a default maximal heap memory based on a containers restriction.
|
||||
# If used in a container without any memory constraints for the container then this
|
||||
# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio
|
||||
# of the container available memory as set here. The default is `50` which means 50%
|
||||
# of the available memory is used as an upper boundary. You can skip this mechanism by
|
||||
# setting this value to `0` in which case no `-Xmx` option is added.
|
||||
# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This
|
||||
# is used to calculate a default initial heap memory based on the maximum heap memory.
|
||||
# If used in a container without any memory constraints for the container then this
|
||||
# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio
|
||||
# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx`
|
||||
# is used as the initial heap size. You can skip this mechanism by setting this value
|
||||
# to `0` in which case no `-Xms` option is added (example: "25")
|
||||
# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS.
|
||||
# This is used to calculate the maximum value of the initial heap memory. If used in
|
||||
# a container without any memory constraints for the container then this option has
|
||||
# no effect. If there is a memory constraint then `-Xms` is limited to the value set
|
||||
# here. The default is 4096MB which means the calculated value of `-Xms` never will
|
||||
# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096")
|
||||
# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output
|
||||
# when things are happening. This option, if set to true, will set
|
||||
# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true").
|
||||
# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example:
|
||||
# true").
|
||||
# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787").
|
||||
# - CONTAINER_CORE_LIMIT: A calculated core limit as described in
|
||||
# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2")
|
||||
# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024").
|
||||
# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion.
|
||||
# (example: "20")
|
||||
# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking.
|
||||
# (example: "40")
|
||||
# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection.
|
||||
# (example: "4")
|
||||
# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus
|
||||
# previous GC times. (example: "90")
|
||||
# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20")
|
||||
# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100")
|
||||
# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should
|
||||
# contain the necessary JRE command-line options to specify the required GC, which
|
||||
# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC).
|
||||
# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080")
|
||||
# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080")
|
||||
# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be
|
||||
# accessed directly. (example: "foo.example.com,bar.example.com")
|
||||
#
|
||||
###
|
||||
FROM registry.access.redhat.com/ubi8/openjdk-21:1.19
|
||||
|
||||
ENV LANGUAGE='en_US:en'
|
||||
|
||||
|
||||
# We make four distinct layers so if there are application changes the library layers can be re-used
|
||||
COPY --chown=185 build/quarkus-app/lib/ /deployments/lib/
|
||||
COPY --chown=185 build/quarkus-app/*.jar /deployments/
|
||||
COPY --chown=185 build/quarkus-app/app/ /deployments/app/
|
||||
COPY --chown=185 build/quarkus-app/quarkus/ /deployments/quarkus/
|
||||
|
||||
USER 185
|
||||
ENV JAVA_OPTS_APPEND="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
|
||||
ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"
|
||||
|
||||
ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ]
|
||||
|
92
applications/converter/src/main/docker/Dockerfile.legacy-jar
Normal file
92
applications/converter/src/main/docker/Dockerfile.legacy-jar
Normal file
|
@ -0,0 +1,92 @@
|
|||
####
|
||||
# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
|
||||
#
|
||||
# Before building the container image run:
|
||||
#
|
||||
# ./gradlew build -Dquarkus.package.jar.type=legacy-jar
|
||||
#
|
||||
# Then, build the image with:
|
||||
#
|
||||
# docker build -f src/main/docker/Dockerfile.legacy-jar -t quarkus/converter-legacy-jar .
|
||||
#
|
||||
# Then run the container using:
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/converter-legacy-jar
|
||||
#
|
||||
# If you want to include the debug port into your docker image
|
||||
# you will have to expose the debug port (default 5005 being the default) like this : EXPOSE 8080 5005.
|
||||
# Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005
|
||||
# when running the container
|
||||
#
|
||||
# Then run the container using :
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/converter-legacy-jar
|
||||
#
|
||||
# This image uses the `run-java.sh` script to run the application.
|
||||
# This scripts computes the command line to execute your Java application, and
|
||||
# includes memory/GC tuning.
|
||||
# You can configure the behavior using the following environment properties:
|
||||
# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class")
|
||||
# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options
|
||||
# in JAVA_OPTS (example: "-Dsome.property=foo")
|
||||
# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is
|
||||
# used to calculate a default maximal heap memory based on a containers restriction.
|
||||
# If used in a container without any memory constraints for the container then this
|
||||
# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio
|
||||
# of the container available memory as set here. The default is `50` which means 50%
|
||||
# of the available memory is used as an upper boundary. You can skip this mechanism by
|
||||
# setting this value to `0` in which case no `-Xmx` option is added.
|
||||
# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This
|
||||
# is used to calculate a default initial heap memory based on the maximum heap memory.
|
||||
# If used in a container without any memory constraints for the container then this
|
||||
# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio
|
||||
# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx`
|
||||
# is used as the initial heap size. You can skip this mechanism by setting this value
|
||||
# to `0` in which case no `-Xms` option is added (example: "25")
|
||||
# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS.
|
||||
# This is used to calculate the maximum value of the initial heap memory. If used in
|
||||
# a container without any memory constraints for the container then this option has
|
||||
# no effect. If there is a memory constraint then `-Xms` is limited to the value set
|
||||
# here. The default is 4096MB which means the calculated value of `-Xms` never will
|
||||
# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096")
|
||||
# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output
|
||||
# when things are happening. This option, if set to true, will set
|
||||
# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true").
|
||||
# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example:
|
||||
# true").
|
||||
# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787").
|
||||
# - CONTAINER_CORE_LIMIT: A calculated core limit as described in
|
||||
# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2")
|
||||
# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024").
|
||||
# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion.
|
||||
# (example: "20")
|
||||
# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking.
|
||||
# (example: "40")
|
||||
# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection.
|
||||
# (example: "4")
|
||||
# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus
|
||||
# previous GC times. (example: "90")
|
||||
# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20")
|
||||
# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100")
|
||||
# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should
|
||||
# contain the necessary JRE command-line options to specify the required GC, which
|
||||
# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC).
|
||||
# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080")
|
||||
# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080")
|
||||
# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be
|
||||
# accessed directly. (example: "foo.example.com,bar.example.com")
|
||||
#
|
||||
###
|
||||
FROM registry.access.redhat.com/ubi8/openjdk-21:1.19
|
||||
|
||||
ENV LANGUAGE='en_US:en'
|
||||
|
||||
|
||||
COPY build/lib/* /deployments/lib/
|
||||
COPY build/*-runner.jar /deployments/quarkus-run.jar
|
||||
|
||||
USER 185
|
||||
ENV JAVA_OPTS_APPEND="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
|
||||
ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"
|
||||
|
||||
ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ]
|
26
applications/converter/src/main/docker/Dockerfile.native
Normal file
26
applications/converter/src/main/docker/Dockerfile.native
Normal file
|
@ -0,0 +1,26 @@
|
|||
####
|
||||
# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode.
|
||||
#
|
||||
# Before building the container image run:
|
||||
#
|
||||
# ./gradlew build -Dquarkus.native.enabled=true
|
||||
#
|
||||
# Then, build the image with:
|
||||
#
|
||||
# docker build -f src/main/docker/Dockerfile.native -t quarkus/converter .
|
||||
#
|
||||
# Then run the container using:
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/converter
|
||||
#
|
||||
###
|
||||
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.9
|
||||
WORKDIR /work/
|
||||
RUN chown 1001 /work \
|
||||
&& chmod "g+rwX" /work \
|
||||
&& chown 1001:root /work
|
||||
COPY --chown=1001:root build/*-runner /work/application
|
||||
|
||||
USER 1001
|
||||
|
||||
ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"]
|
|
@ -0,0 +1,29 @@
|
|||
####
|
||||
# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode.
|
||||
# It uses a micro base image, tuned for Quarkus native executables.
|
||||
# It reduces the size of the resulting container image.
|
||||
# Check https://quarkus.io/guides/quarkus-runtime-base-image for further information about this image.
|
||||
#
|
||||
# Before building the container image run:
|
||||
#
|
||||
# ./gradlew build -Dquarkus.native.enabled=true
|
||||
#
|
||||
# Then, build the image with:
|
||||
#
|
||||
# docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/converter .
|
||||
#
|
||||
# Then run the container using:
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/converter
|
||||
#
|
||||
###
|
||||
FROM quay.io/quarkus/quarkus-micro-image:2.0
|
||||
WORKDIR /work/
|
||||
RUN chown 1001 /work \
|
||||
&& chmod "g+rwX" /work \
|
||||
&& chown 1001:root /work
|
||||
COPY --chown=1001:root build/*-runner /work/application
|
||||
|
||||
USER 1001
|
||||
|
||||
ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"]
|
|
@ -0,0 +1,41 @@
|
|||
package fr.faraphel.converter
|
||||
|
||||
import fr.faraphel.common.error.MissingEnvironmentException
|
||||
import fr.faraphel.common.temperature.celsius
|
||||
import fr.faraphel.converter.kafka.Converter
|
||||
import io.quarkus.runtime.QuarkusApplication
|
||||
import io.quarkus.runtime.annotations.QuarkusMain
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
import kotlin.time.toJavaDuration
|
||||
|
||||
|
||||
@QuarkusMain
|
||||
class Main : QuarkusApplication {
|
||||
override fun run(vararg args: String?): Int {
|
||||
// get the kafka server address
|
||||
val kafkaServer = System.getenv("KAFKA_BOOTSTRAP_SERVERS")
|
||||
?: throw MissingEnvironmentException("KAFKA_BOOTSTRAP_SERVERS")
|
||||
|
||||
// get the topics names
|
||||
val topicTemperatureCelsius: String = System.getenv("TEMPERATURE_CELSIUS_TOPIC")
|
||||
?: throw MissingEnvironmentException("TEMPERATURE_CELSIUS_TOPIC")
|
||||
val topicTemperatureFahrenheit: String = System.getenv("TEMPERATURE_FAHRENHEIT_TOPIC")
|
||||
?: throw MissingEnvironmentException("TEMPERATURE_FAHRENHEIT_TOPIC")
|
||||
|
||||
// create a converter that will convert values coming from the Celsius topic to the Fahrenheit topic
|
||||
val converter = Converter(
|
||||
server=kafkaServer,
|
||||
inputTopic=topicTemperatureCelsius,
|
||||
outputTopic=topicTemperatureFahrenheit,
|
||||
) { temperature -> temperature.celsius.asFahrenheit }
|
||||
|
||||
// start converting values
|
||||
converter.start()
|
||||
|
||||
// indefinitely wait for the converter to be paused
|
||||
while (!converter.isPaused)
|
||||
Thread.sleep(1.seconds.toJavaDuration())
|
||||
|
||||
return 0
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package fr.faraphel.m1_pe_kafka.kafka
|
||||
package fr.faraphel.converter.kafka
|
||||
|
||||
import org.apache.kafka.common.serialization.Serdes
|
||||
import org.apache.kafka.streams.KafkaStreams
|
||||
|
@ -19,7 +19,7 @@ import java.util.*
|
|||
*/
|
||||
class Converter(
|
||||
private val server: String,
|
||||
private val identifier: String = "converter",
|
||||
private val identifier: String = "fr/faraphel/converter",
|
||||
private val inputTopic: String,
|
||||
private val outputTopic: String,
|
||||
private val converter: (Double) -> Double,
|
||||
|
@ -54,23 +54,30 @@ class Converter(
|
|||
* Start the conversion process
|
||||
* @see KafkaStreams.start
|
||||
*/
|
||||
fun start() = streams.start()
|
||||
fun start() = this.streams.start()
|
||||
|
||||
/**
|
||||
* Pause the conversion process
|
||||
* @see KafkaStreams.pause
|
||||
*/
|
||||
fun pause() = streams.pause()
|
||||
fun pause() = this.streams.pause()
|
||||
|
||||
/**
|
||||
* Resume a paused conversion process
|
||||
* @see KafkaStreams.resume
|
||||
*/
|
||||
fun resume() = streams.resume()
|
||||
fun resume() = this.streams.resume()
|
||||
|
||||
/**
|
||||
* Stop a conversion process
|
||||
* @see KafkaStreams.close
|
||||
*/
|
||||
fun stop() = streams.close()
|
||||
fun stop() = this.streams.close()
|
||||
|
||||
/**
|
||||
* Indicate if the conversion is paused
|
||||
* @see KafkaStreams.isPaused
|
||||
*/
|
||||
val isPaused: Boolean
|
||||
get() = this.streams.isPaused
|
||||
}
|
5
applications/producer/.dockerignore
Normal file
5
applications/producer/.dockerignore
Normal file
|
@ -0,0 +1,5 @@
|
|||
*
|
||||
!build/*-runner
|
||||
!build/*-runner.jar
|
||||
!build/lib/*
|
||||
!build/quarkus-app/*
|
39
applications/producer/.gitignore
vendored
Normal file
39
applications/producer/.gitignore
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
# Gradle
|
||||
.gradle/
|
||||
build/
|
||||
|
||||
# Eclipse
|
||||
.project
|
||||
.classpath
|
||||
.settings/
|
||||
bin/
|
||||
|
||||
# IntelliJ
|
||||
.idea
|
||||
*.ipr
|
||||
*.iml
|
||||
*.iws
|
||||
|
||||
# NetBeans
|
||||
nb-configuration.xml
|
||||
|
||||
# Visual Studio Code
|
||||
.vscode
|
||||
.factorypath
|
||||
|
||||
# OSX
|
||||
.DS_Store
|
||||
|
||||
# Vim
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# patch
|
||||
*.orig
|
||||
*.rej
|
||||
|
||||
# Local environment
|
||||
.env
|
||||
|
||||
# Plugin directory
|
||||
/.quarkus/cli/plugins/
|
23
applications/producer/README.md
Normal file
23
applications/producer/README.md
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Module: Converter
|
||||
|
||||
This module contain the code responsible for getting the current temperature at a given location thanks to the
|
||||
[Open-Meteo](https://open-meteo.com/) API, and sending it into a topic.
|
||||
|
||||
## Build
|
||||
|
||||
This project is built automatically when using [docker-compose](https://docs.docker.com/compose/) at the root.
|
||||
|
||||
However, you can still build it manually with the following command :
|
||||
```shell
|
||||
./gradlew build
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
This module can be easily modified with the following environment variables :
|
||||
|
||||
| Name | Required | Format | Default | Description |
|
||||
|-------------------------|----------|-----------------------------------------------------|---------|--------------------------------------------------------------|
|
||||
| KAFKA_BOOTSTRAP_SERVERS | true | \<ip>[:port] | / | The Kafka server address |
|
||||
| TEMPERATURE_TOPIC | true | string of alphanumeric characters, ".", "_" and "-" | / | The Kafka topic were the temperature in celsius can be found |
|
||||
| TEMPERATURE_LOCATION | true | \<latitude>, \<longitude> | / | The coordinates where to get the temperatures from |
|
53
applications/producer/build.gradle.kts
Normal file
53
applications/producer/build.gradle.kts
Normal file
|
@ -0,0 +1,53 @@
|
|||
plugins {
|
||||
kotlin("jvm") version "2.0.0"
|
||||
kotlin("plugin.allopen") version "2.0.0"
|
||||
id("io.quarkus")
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
}
|
||||
|
||||
val quarkusPlatformGroupId: String by project
|
||||
val quarkusPlatformArtifactId: String by project
|
||||
val quarkusPlatformVersion: String by project
|
||||
|
||||
dependencies {
|
||||
// common
|
||||
implementation(project(":common"))
|
||||
|
||||
// quarkus
|
||||
implementation(enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}"))
|
||||
implementation("io.quarkus:quarkus-kotlin")
|
||||
implementation("io.quarkus:quarkus-arc")
|
||||
testImplementation("io.quarkus:quarkus-junit5")
|
||||
|
||||
// libraries
|
||||
implementation("io.quarkus:quarkus-kafka-client")
|
||||
implementation("com.squareup.okhttp3:okhttp:4.12.0")
|
||||
implementation("com.google.code.gson:gson:2.8.9")
|
||||
}
|
||||
|
||||
group = "fr.faraphel"
|
||||
version = "1.0-SNAPSHOT"
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_21
|
||||
targetCompatibility = JavaVersion.VERSION_21
|
||||
}
|
||||
|
||||
tasks.withType<Test> {
|
||||
systemProperty("java.util.logging.manager", "org.jboss.logmanager.LogManager")
|
||||
}
|
||||
allOpen {
|
||||
annotation("jakarta.ws.rs.Path")
|
||||
annotation("jakarta.enterprise.context.ApplicationScoped")
|
||||
annotation("jakarta.persistence.Entity")
|
||||
annotation("io.quarkus.test.junit.QuarkusTest")
|
||||
}
|
||||
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
|
||||
kotlinOptions.jvmTarget = JavaVersion.VERSION_21.toString()
|
||||
kotlinOptions.javaParameters = true
|
||||
}
|
6
applications/producer/gradle.properties
Normal file
6
applications/producer/gradle.properties
Normal file
|
@ -0,0 +1,6 @@
|
|||
#Gradle properties
|
||||
quarkusPluginId=io.quarkus
|
||||
quarkusPluginVersion=3.12.0
|
||||
quarkusPlatformGroupId=io.quarkus.platform
|
||||
quarkusPlatformArtifactId=quarkus-bom
|
||||
quarkusPlatformVersion=3.12.0
|
BIN
applications/producer/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
applications/producer/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
applications/producer/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
applications/producer/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
185
applications/producer/gradlew
vendored
Executable file
185
applications/producer/gradlew
vendored
Executable file
|
@ -0,0 +1,185 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
104
applications/producer/gradlew.bat
vendored
Normal file
104
applications/producer/gradlew.bat
vendored
Normal file
|
@ -0,0 +1,104 @@
|
|||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
17
applications/producer/settings.gradle.kts
Normal file
17
applications/producer/settings.gradle.kts
Normal file
|
@ -0,0 +1,17 @@
|
|||
pluginManagement {
|
||||
val quarkusPluginVersion: String by settings
|
||||
val quarkusPluginId: String by settings
|
||||
repositories {
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
mavenLocal()
|
||||
}
|
||||
plugins {
|
||||
id(quarkusPluginId) version quarkusPluginVersion
|
||||
}
|
||||
}
|
||||
rootProject.name = "producer"
|
||||
|
||||
// Dependencies
|
||||
include(":common")
|
||||
project(":common").projectDir = file("../common")
|
96
applications/producer/src/main/docker/Dockerfile.jvm
Normal file
96
applications/producer/src/main/docker/Dockerfile.jvm
Normal file
|
@ -0,0 +1,96 @@
|
|||
####
|
||||
# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
|
||||
#
|
||||
# Before building the container image run:
|
||||
#
|
||||
# ./gradlew build
|
||||
#
|
||||
# Then, build the image with:
|
||||
#
|
||||
# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/producer-jvm .
|
||||
#
|
||||
# Then run the container using:
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/producer-jvm
|
||||
#
|
||||
# If you want to include the debug port into your docker image
|
||||
# you will have to expose the debug port (default 5005 being the default) like this : EXPOSE 8080 5005.
|
||||
# Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005
|
||||
# when running the container
|
||||
#
|
||||
# Then run the container using :
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/producer-jvm
|
||||
#
|
||||
# This image uses the `run-java.sh` script to run the application.
|
||||
# This scripts computes the command line to execute your Java application, and
|
||||
# includes memory/GC tuning.
|
||||
# You can configure the behavior using the following environment properties:
|
||||
# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class")
|
||||
# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options
|
||||
# in JAVA_OPTS (example: "-Dsome.property=foo")
|
||||
# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is
|
||||
# used to calculate a default maximal heap memory based on a containers restriction.
|
||||
# If used in a container without any memory constraints for the container then this
|
||||
# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio
|
||||
# of the container available memory as set here. The default is `50` which means 50%
|
||||
# of the available memory is used as an upper boundary. You can skip this mechanism by
|
||||
# setting this value to `0` in which case no `-Xmx` option is added.
|
||||
# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This
|
||||
# is used to calculate a default initial heap memory based on the maximum heap memory.
|
||||
# If used in a container without any memory constraints for the container then this
|
||||
# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio
|
||||
# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx`
|
||||
# is used as the initial heap size. You can skip this mechanism by setting this value
|
||||
# to `0` in which case no `-Xms` option is added (example: "25")
|
||||
# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS.
|
||||
# This is used to calculate the maximum value of the initial heap memory. If used in
|
||||
# a container without any memory constraints for the container then this option has
|
||||
# no effect. If there is a memory constraint then `-Xms` is limited to the value set
|
||||
# here. The default is 4096MB which means the calculated value of `-Xms` never will
|
||||
# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096")
|
||||
# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output
|
||||
# when things are happening. This option, if set to true, will set
|
||||
# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true").
|
||||
# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example:
|
||||
# true").
|
||||
# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787").
|
||||
# - CONTAINER_CORE_LIMIT: A calculated core limit as described in
|
||||
# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2")
|
||||
# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024").
|
||||
# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion.
|
||||
# (example: "20")
|
||||
# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking.
|
||||
# (example: "40")
|
||||
# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection.
|
||||
# (example: "4")
|
||||
# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus
|
||||
# previous GC times. (example: "90")
|
||||
# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20")
|
||||
# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100")
|
||||
# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should
|
||||
# contain the necessary JRE command-line options to specify the required GC, which
|
||||
# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC).
|
||||
# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080")
|
||||
# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080")
|
||||
# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be
|
||||
# accessed directly. (example: "foo.example.com,bar.example.com")
|
||||
#
|
||||
###
|
||||
FROM registry.access.redhat.com/ubi8/openjdk-21:1.19
|
||||
|
||||
ENV LANGUAGE='en_US:en'
|
||||
|
||||
|
||||
# We make four distinct layers so if there are application changes the library layers can be re-used
|
||||
COPY --chown=185 build/quarkus-app/lib/ /deployments/lib/
|
||||
COPY --chown=185 build/quarkus-app/*.jar /deployments/
|
||||
COPY --chown=185 build/quarkus-app/app/ /deployments/app/
|
||||
COPY --chown=185 build/quarkus-app/quarkus/ /deployments/quarkus/
|
||||
|
||||
USER 185
|
||||
ENV JAVA_OPTS_APPEND="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
|
||||
ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"
|
||||
|
||||
ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ]
|
||||
|
92
applications/producer/src/main/docker/Dockerfile.legacy-jar
Normal file
92
applications/producer/src/main/docker/Dockerfile.legacy-jar
Normal file
|
@ -0,0 +1,92 @@
|
|||
####
|
||||
# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
|
||||
#
|
||||
# Before building the container image run:
|
||||
#
|
||||
# ./gradlew build -Dquarkus.package.jar.type=legacy-jar
|
||||
#
|
||||
# Then, build the image with:
|
||||
#
|
||||
# docker build -f src/main/docker/Dockerfile.legacy-jar -t quarkus/producer-legacy-jar .
|
||||
#
|
||||
# Then run the container using:
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/producer-legacy-jar
|
||||
#
|
||||
# If you want to include the debug port into your docker image
|
||||
# you will have to expose the debug port (default 5005 being the default) like this : EXPOSE 8080 5005.
|
||||
# Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005
|
||||
# when running the container
|
||||
#
|
||||
# Then run the container using :
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/producer-legacy-jar
|
||||
#
|
||||
# This image uses the `run-java.sh` script to run the application.
|
||||
# This scripts computes the command line to execute your Java application, and
|
||||
# includes memory/GC tuning.
|
||||
# You can configure the behavior using the following environment properties:
|
||||
# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class")
|
||||
# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options
|
||||
# in JAVA_OPTS (example: "-Dsome.property=foo")
|
||||
# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is
|
||||
# used to calculate a default maximal heap memory based on a containers restriction.
|
||||
# If used in a container without any memory constraints for the container then this
|
||||
# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio
|
||||
# of the container available memory as set here. The default is `50` which means 50%
|
||||
# of the available memory is used as an upper boundary. You can skip this mechanism by
|
||||
# setting this value to `0` in which case no `-Xmx` option is added.
|
||||
# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This
|
||||
# is used to calculate a default initial heap memory based on the maximum heap memory.
|
||||
# If used in a container without any memory constraints for the container then this
|
||||
# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio
|
||||
# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx`
|
||||
# is used as the initial heap size. You can skip this mechanism by setting this value
|
||||
# to `0` in which case no `-Xms` option is added (example: "25")
|
||||
# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS.
|
||||
# This is used to calculate the maximum value of the initial heap memory. If used in
|
||||
# a container without any memory constraints for the container then this option has
|
||||
# no effect. If there is a memory constraint then `-Xms` is limited to the value set
|
||||
# here. The default is 4096MB which means the calculated value of `-Xms` never will
|
||||
# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096")
|
||||
# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output
|
||||
# when things are happening. This option, if set to true, will set
|
||||
# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true").
|
||||
# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example:
|
||||
# true").
|
||||
# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787").
|
||||
# - CONTAINER_CORE_LIMIT: A calculated core limit as described in
|
||||
# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2")
|
||||
# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024").
|
||||
# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion.
|
||||
# (example: "20")
|
||||
# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking.
|
||||
# (example: "40")
|
||||
# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection.
|
||||
# (example: "4")
|
||||
# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus
|
||||
# previous GC times. (example: "90")
|
||||
# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20")
|
||||
# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100")
|
||||
# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should
|
||||
# contain the necessary JRE command-line options to specify the required GC, which
|
||||
# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC).
|
||||
# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080")
|
||||
# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080")
|
||||
# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be
|
||||
# accessed directly. (example: "foo.example.com,bar.example.com")
|
||||
#
|
||||
###
|
||||
FROM registry.access.redhat.com/ubi8/openjdk-21:1.19
|
||||
|
||||
ENV LANGUAGE='en_US:en'
|
||||
|
||||
|
||||
COPY build/lib/* /deployments/lib/
|
||||
COPY build/*-runner.jar /deployments/quarkus-run.jar
|
||||
|
||||
USER 185
|
||||
ENV JAVA_OPTS_APPEND="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
|
||||
ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"
|
||||
|
||||
ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ]
|
26
applications/producer/src/main/docker/Dockerfile.native
Normal file
26
applications/producer/src/main/docker/Dockerfile.native
Normal file
|
@ -0,0 +1,26 @@
|
|||
####
|
||||
# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode.
|
||||
#
|
||||
# Before building the container image run:
|
||||
#
|
||||
# ./gradlew build -Dquarkus.native.enabled=true
|
||||
#
|
||||
# Then, build the image with:
|
||||
#
|
||||
# docker build -f src/main/docker/Dockerfile.native -t quarkus/producer .
|
||||
#
|
||||
# Then run the container using:
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/producer
|
||||
#
|
||||
###
|
||||
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.9
|
||||
WORKDIR /work/
|
||||
RUN chown 1001 /work \
|
||||
&& chmod "g+rwX" /work \
|
||||
&& chown 1001:root /work
|
||||
COPY --chown=1001:root build/*-runner /work/application
|
||||
|
||||
USER 1001
|
||||
|
||||
ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"]
|
|
@ -0,0 +1,29 @@
|
|||
####
|
||||
# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode.
|
||||
# It uses a micro base image, tuned for Quarkus native executables.
|
||||
# It reduces the size of the resulting container image.
|
||||
# Check https://quarkus.io/guides/quarkus-runtime-base-image for further information about this image.
|
||||
#
|
||||
# Before building the container image run:
|
||||
#
|
||||
# ./gradlew build -Dquarkus.native.enabled=true
|
||||
#
|
||||
# Then, build the image with:
|
||||
#
|
||||
# docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/producer .
|
||||
#
|
||||
# Then run the container using:
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/producer
|
||||
#
|
||||
###
|
||||
FROM quay.io/quarkus/quarkus-micro-image:2.0
|
||||
WORKDIR /work/
|
||||
RUN chown 1001 /work \
|
||||
&& chmod "g+rwX" /work \
|
||||
&& chown 1001:root /work
|
||||
COPY --chown=1001:root build/*-runner /work/application
|
||||
|
||||
USER 1001
|
||||
|
||||
ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"]
|
|
@ -0,0 +1,40 @@
|
|||
package fr.faraphel.producer
|
||||
|
||||
import fr.faraphel.common.error.MissingEnvironmentException
|
||||
import fr.faraphel.producer.kafka.TemperatureProducer
|
||||
import io.quarkus.runtime.QuarkusApplication
|
||||
import io.quarkus.runtime.annotations.QuarkusMain
|
||||
|
||||
|
||||
@QuarkusMain
|
||||
class Main : QuarkusApplication {
|
||||
override fun run(vararg args: String?): Int {
|
||||
// get the kafka server address
|
||||
val kafkaServer = System.getenv("KAFKA_BOOTSTRAP_SERVERS")
|
||||
?: throw MissingEnvironmentException("KAFKA_BOOTSTRAP_SERVERS")
|
||||
|
||||
// get the topic name
|
||||
val topicTemperature: String = System.getenv("TEMPERATURE_TOPIC")
|
||||
?: throw MissingEnvironmentException("TEMPERATURE_TOPIC")
|
||||
|
||||
// get the location of the temperature to get
|
||||
val location = System.getenv("TEMPERATURE_LOCATION")
|
||||
?: throw MissingEnvironmentException("TEMPERATURE_LOCATION")
|
||||
|
||||
// parse the location to get the latitude and longitude
|
||||
val (latitude, longitude) = location.split(",").map { coordinate -> coordinate.trim().toDouble() }
|
||||
|
||||
// create a producer that will generate temperature values based on the current temperature.
|
||||
val producer = TemperatureProducer(
|
||||
server=kafkaServer,
|
||||
latitude=latitude,
|
||||
longitude=longitude,
|
||||
topic=topicTemperature
|
||||
)
|
||||
|
||||
// indefinitely produce new temperatures values
|
||||
producer.produceForever()
|
||||
|
||||
return 0
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
package fr.faraphel.m1_pe_kafka.kafka
|
||||
package fr.faraphel.producer.kafka
|
||||
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.JsonObject
|
||||
import fr.faraphel.m1_pe_kafka.error.http.HttpException
|
||||
import fr.faraphel.common.error.http.HttpException
|
||||
import org.apache.kafka.clients.producer.KafkaProducer
|
||||
import org.apache.kafka.clients.producer.ProducerConfig
|
||||
import org.apache.kafka.clients.producer.ProducerRecord
|
||||
|
@ -29,7 +29,7 @@ class TemperatureProducer(
|
|||
private val latitude: Double,
|
||||
private val longitude: Double,
|
||||
private val topic: String,
|
||||
) : Thread() {
|
||||
) {
|
||||
companion object {
|
||||
private val BASE_API_BUILDER: okhttp3.HttpUrl.Builder = okhttp3.HttpUrl.Builder() ///< the Url builder for the API
|
||||
.scheme("https") // use the https protocol
|
||||
|
@ -78,7 +78,7 @@ class TemperatureProducer(
|
|||
val response = httpClient.newCall(this.apiRequest).execute()
|
||||
// check for a successful response
|
||||
if (!response.isSuccessful)
|
||||
// in case of error, raise a http exception
|
||||
// in case of error, raise a http exception
|
||||
throw HttpException(response.code, response.message)
|
||||
|
||||
// parse the response into a map of string to string
|
||||
|
@ -102,13 +102,7 @@ class TemperatureProducer(
|
|||
// produce a data
|
||||
this.produce()
|
||||
// wait for the cooldown
|
||||
sleep(frequency)
|
||||
Thread.sleep(frequency)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Thread entrypoint
|
||||
* @see produceForever
|
||||
*/
|
||||
override fun run() = this.produceForever()
|
||||
}
|
|
@ -27,18 +27,32 @@ services:
|
|||
depends_on:
|
||||
- zookeeper
|
||||
|
||||
# Our application
|
||||
application:
|
||||
# Our producer
|
||||
producer:
|
||||
build:
|
||||
context: .
|
||||
context: ./applications/producer
|
||||
dockerfile: ./src/main/docker/Dockerfile.${QUARKUS_MODE:-jvm}
|
||||
environment:
|
||||
KAFKA_BOOTSTRAP_SERVERS: kafka:9092
|
||||
TEMPERATURE_TOPIC: "temperature-celsius"
|
||||
TEMPERATURE_LOCATION: 49.9, 2.3
|
||||
networks:
|
||||
- kafka
|
||||
depends_on:
|
||||
- kafka
|
||||
|
||||
# Our consumer
|
||||
consumer:
|
||||
build:
|
||||
context: ./applications/consumer
|
||||
dockerfile: ./src/main/docker/Dockerfile.${QUARKUS_MODE:-jvm}
|
||||
ports:
|
||||
- "8080:8080"
|
||||
environment:
|
||||
KAFKA_BOOTSTRAP_SERVERS: kafka:9092
|
||||
TEMPERATURE_LOCATION: 49.9, 2.3
|
||||
TEMPERATURE_TOPIC: "temperature-fahrenheit"
|
||||
healthcheck:
|
||||
test: curl --fail http://localhost:8080/ping
|
||||
test: curl --fail http://localhost:8080/v1/ping
|
||||
start_period: 10s
|
||||
timeout: 5s
|
||||
interval: 60s
|
||||
|
@ -46,9 +60,24 @@ services:
|
|||
networks:
|
||||
- kafka
|
||||
depends_on:
|
||||
- zookeeper
|
||||
- kafka
|
||||
|
||||
# Our converter
|
||||
converter:
|
||||
build:
|
||||
context: ./applications/converter
|
||||
dockerfile: ./src/main/docker/Dockerfile.${QUARKUS_MODE:-jvm}
|
||||
environment:
|
||||
KAFKA_BOOTSTRAP_SERVERS: kafka:9092
|
||||
TEMPERATURE_CELSIUS_TOPIC: "temperature-celsius"
|
||||
TEMPERATURE_FAHRENHEIT_TOPIC: "temperature-fahrenheit"
|
||||
networks:
|
||||
- kafka
|
||||
depends_on:
|
||||
- kafka
|
||||
- producer
|
||||
- consumer
|
||||
|
||||
networks:
|
||||
# the Kafka network
|
||||
kafka:
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
# Gradle properties
|
||||
quarkusPluginId=io.quarkus
|
||||
quarkusPluginVersion=3.11.1
|
||||
quarkusPlatformGroupId=io.quarkus.platform
|
||||
quarkusPlatformArtifactId=quarkus-bom
|
||||
quarkusPlatformVersion=3.11.1
|
||||
|
||||
# Kafka Properties
|
||||
quarkus.analytics.disabled=true
|
||||
quarkus.kafka-streams.bootstrap-servers=${KAFKA_BOOTSTRAP_SERVERS:kafka:9092}
|
||||
kafka.bootstrap.servers=${KAFKA_BOOTSTRAP_SERVERS:kafka:9092}
|
8
m1-PE-Kafka.iml
Normal file
8
m1-PE-Kafka.iml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="GENERAL_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
|
@ -1,109 +0,0 @@
|
|||
package fr.faraphel.m1_pe_kafka
|
||||
|
||||
import fr.faraphel.m1_pe_kafka.error.MissingEnvironmentException
|
||||
import fr.faraphel.m1_pe_kafka.kafka.AdminUtils
|
||||
import fr.faraphel.m1_pe_kafka.kafka.Consumer
|
||||
import fr.faraphel.m1_pe_kafka.kafka.Converter
|
||||
import fr.faraphel.m1_pe_kafka.kafka.TemperatureProducer
|
||||
import fr.faraphel.m1_pe_kafka.rest.TemperatureEndpoint
|
||||
import fr.faraphel.m1_pe_kafka.utils.celsius
|
||||
import io.quarkus.runtime.Quarkus
|
||||
import io.quarkus.runtime.QuarkusApplication
|
||||
import io.quarkus.runtime.annotations.QuarkusMain
|
||||
import java.time.Instant
|
||||
import java.time.ZoneId
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
|
||||
/**
|
||||
* The main class.
|
||||
* Contains the entrypoint of the program.
|
||||
*/
|
||||
@QuarkusMain
|
||||
class Main : QuarkusApplication {
|
||||
/**
|
||||
* The entrypoint of the program
|
||||
* @param args command line arguments
|
||||
* @return the result code of the program
|
||||
* @throws MissingEnvironmentException a required environment variable from the configuration is missing
|
||||
*/
|
||||
override fun run(vararg args: String?): Int {
|
||||
// create a time formatter
|
||||
val timeFormatter = DateTimeFormatter
|
||||
.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")
|
||||
.withZone(ZoneId.systemDefault())
|
||||
|
||||
// get the kafka server address
|
||||
val kafkaServer = System.getenv("KAFKA_BOOTSTRAP_SERVERS")
|
||||
?: throw MissingEnvironmentException("KAFKA_BOOTSTRAP_SERVERS")
|
||||
|
||||
// get the topics name
|
||||
val topicTemperatureCelsius: String = System.getenv("TOPIC_TEMPERATURE_CELSIUS")
|
||||
?: "temperature-celsius"
|
||||
val topicTemperatureFahrenheit: String = System.getenv("TOPIC_TEMPERATURE_FAHRENHEIT")
|
||||
?: "temperature-fahrenheit"
|
||||
|
||||
// create an admin object
|
||||
val admin = AdminUtils(kafkaServer)
|
||||
// create our topics
|
||||
admin.createTopics(topicTemperatureCelsius, topicTemperatureFahrenheit)
|
||||
|
||||
// get the location of the temperature to get
|
||||
val location = System.getenv("TEMPERATURE_LOCATION")
|
||||
?: throw MissingEnvironmentException("TEMPERATURE_LOCATION")
|
||||
|
||||
// parse the location to get the latitude and longitude
|
||||
val (latitude, longitude) = location.split(",").map { coordinate -> coordinate.trim().toDouble() }
|
||||
|
||||
// create a producer that will generate temperature values based on the current temperature at Amiens (France).
|
||||
val producer = TemperatureProducer(
|
||||
server=kafkaServer,
|
||||
latitude=latitude,
|
||||
longitude=longitude,
|
||||
topic=topicTemperatureCelsius
|
||||
)
|
||||
|
||||
// create a converter that will convert values coming from the Celsius topic to the Fahrenheit topic
|
||||
val converter = Converter(
|
||||
server=kafkaServer,
|
||||
inputTopic=topicTemperatureCelsius,
|
||||
outputTopic=topicTemperatureFahrenheit
|
||||
) { temperature -> temperature.celsius.asFahrenheit }
|
||||
|
||||
// create a consumer that will print the received values in the Fahrenheit topic
|
||||
val consumer = Consumer(
|
||||
server=kafkaServer,
|
||||
topic=topicTemperatureFahrenheit
|
||||
) { message ->
|
||||
// format the time of the message to a proper string
|
||||
val time = timeFormatter.format(Instant.ofEpochMilli(message.timestamp()))
|
||||
// print the value
|
||||
println("[${time}] ${message.value()}°F")
|
||||
// update the value for the API
|
||||
TemperatureEndpoint.setTemperature(message.value())
|
||||
}
|
||||
|
||||
// run all the clients
|
||||
producer.start()
|
||||
consumer.start()
|
||||
converter.start()
|
||||
|
||||
// wait for them to finish before closing
|
||||
producer.join()
|
||||
consumer.join()
|
||||
|
||||
// close the converter if the others clients are done
|
||||
converter.stop()
|
||||
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The main function.
|
||||
* Simply call the entrypoint.
|
||||
* Used to run the program directly with Kotlin.
|
||||
*/
|
||||
fun main(args: Array<String>) {
|
||||
Quarkus.run(Main::class.java, *args)
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
package fr.faraphel.m1_pe_kafka.kafka
|
||||
|
||||
import org.apache.kafka.clients.admin.Admin
|
||||
import org.apache.kafka.clients.admin.AdminClientConfig
|
||||
import org.apache.kafka.clients.admin.CreateTopicsResult
|
||||
import org.apache.kafka.clients.admin.NewTopic
|
||||
import java.util.*
|
||||
|
||||
|
||||
/**
|
||||
* A wrapper around KafkaAdminClient to simplify its configuration.
|
||||
* @param server the kafka server address
|
||||
* @param identifier the kafka identifier for the configuration
|
||||
* @see Admin
|
||||
*/
|
||||
class AdminUtils(
|
||||
private val server: String,
|
||||
private val identifier: String = "admin"
|
||||
) {
|
||||
private val adminConfig = Properties().apply {
|
||||
// set the identifier
|
||||
this[AdminClientConfig.CLIENT_ID_CONFIG] = identifier
|
||||
// set the server information
|
||||
this[AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG] = server
|
||||
}
|
||||
|
||||
private val admin = Admin.create(adminConfig)
|
||||
|
||||
/**
|
||||
* Create the topics in the kafka server.
|
||||
* @param topics the names of the topics to create.
|
||||
* @return the result of the operation.
|
||||
* @see Admin.createTopics
|
||||
*/
|
||||
fun createTopics(vararg topics: String): CreateTopicsResult {
|
||||
// convert the topics name into the corresponding operation
|
||||
val operations = topics.map { topic -> NewTopic(topic, 1, 1) }
|
||||
// run the command
|
||||
return this.admin.createTopics(operations)
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
package fr.faraphel.m1_pe_kafka.rest
|
||||
|
||||
import jakarta.ws.rs.GET
|
||||
import jakarta.ws.rs.Path
|
||||
|
||||
|
||||
/**
|
||||
* This API endpoint return the latest temperature measured (in Fahrenheit)
|
||||
*/
|
||||
@Path("temperature")
|
||||
class TemperatureEndpoint {
|
||||
companion object {
|
||||
private var temperature: Double? = null ///< the latest temperature value
|
||||
|
||||
/**
|
||||
* Setter to update the latest temperature value
|
||||
* @param temperature the new temperature value
|
||||
*/
|
||||
fun setTemperature(temperature: Double) {
|
||||
this.temperature = temperature
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for a GET request on this endpoint
|
||||
* @return the latest temperature measured
|
||||
*/
|
||||
@GET
|
||||
fun get(): Double? {
|
||||
return temperature
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
quarkus.kafka-streams.application-id=fr.faraphel.m1_pe_kafka
|
Loading…
Reference in a new issue