Kapitel 4. Konfiguration
Diese Arbeit wurde mithilfe von KI übersetzt. Wir freuen uns über dein Feedback und deine Kommentare: translation-feedback@oreilly.com
In diesem Kapitel erfährst du, wie du die Konfigurationsparameter einstellst:
-
Wie man einen Quarkus Dienst konfiguriert
-
Wie man Konfigurationsparameter in den Dienst einfügt
-
Wie man Werte abhängig von der Umgebung anwendet
-
Wie man das Logging-System richtig konfiguriert
-
Wie man Anpassungen für das Konfigurationssystem erstellt
4.1 Konfigurieren der Anwendung mit benutzerdefinierten Eigenschaften
Lösung
Quarkus nutzt eine Reihe von Eclipse MicroProfile-Spezifikationen. Eine davon ist die Configuration-Spezifikation; um die Konfiguration zu vereinfachen, verwendet Quarkus jedoch nur eine Datei für alle Konfigurationen, application.properties, die im Stammverzeichnis des Klassenpfads abgelegt werden muss.
In dieser Datei können Quarkus-Eigenschaften wie die Protokollierung oder der Standardpfad, Quarkus-Erweiterungen wie die Datenquelle oder Kafka oder benutzerdefinierte Eigenschaften, die du für die Anwendung definierst, konfiguriert werden. Du wirst sie alle in diesem Buch kennenlernen, aber in diesem Rezept geht es um die letztere.
Öffne die Datei src/main/resources/application.properties und füge die folgendeEigenschaft hinzu:
greeting.message
=
Hello World
Du kannst den Eigenschaftswert, der in application.properties definiert ist, mit Hilfe der org.eclipse.microprofile.config.inject.ConfigProperty
Annotation in ein Feld einfügen.
Öffne org.acme.quickstart.GreetingResource.java
und gib den Wert der Eigenschaft greeting.message
ein:
@ConfigProperty
(
name
=
"greeting.message"
)
String
message
;
@GET
@Produces
(
MediaType
.
TEXT_PLAIN
)
public
String
hello
(
)
{
return
message
;
}
Injiziert den Wert der Eigenschaft
greeting.message
Platziert Felder im paketgeschützten Bereich
Gibt den konfigurierten Wert zurück
Tipp
Aus Performance-Gründen empfehlen wir dir, bei der Verwendung von GraalVM und Reflection den protected-package-Bereich für Felder zu verwenden, die zur Laufzeit injiziert werden. Du kannst mehr darüber im Quarkus CDI Reference Guide lesen.
Stelle in einem neuen Terminalfenster eine Anfrage an /hello
, um zu sehen, dass die Ausgabemeldung dem konfigurierten Wert in application.properties entspricht:
curl http://localhost:8080/hello
Hello World
Wenn du ein Konfigurationsfeld nicht verpflichtend machen und einen Standardwert angeben möchtest, kannst du das defaultValue
Attribut der @ConfigProperty
Annotation verwenden.
Öffne die Datei org.acme.quickstart.GreetingResource.java
und gib den Wert der Eigenschaft greeting.upper-case
ein:
@ConfigProperty
(
name
=
"greeting.upper-case"
,
defaultValue
=
"true"
)
boolean
upperCase
;
@GET
@Path
(
"/optional"
)
@Produces
(
MediaType
.
TEXT_PLAIN
)
public
String
helloOptional
(
)
{
return
upperCase
?
message
.
toUpperCase
(
)
:
message
;
}
Stelle in einem Terminalfenster eine Anfrage an /hello/optional
, um zu sehen, dass die Ausgabe in Großbuchstaben erfolgt:
curl http://localhost:8080/hello/optional
HELLO WORLD
Eigenschaften mit mehreren Werten werden unterstützt - du musst nur den Feldtyp als einen von Arrays
, java.util.List
oder java.util.Set
definieren, je nach deinen Anforderungen/Präferenzen. Das Trennzeichen für den Eigenschaftswert ist ein Komma (,
) und das Escape-Zeichen ist der Backslash (\
).
Öffne die Datei src/main/resources/application.properties und füge die folgende Eigenschaft mit drei Werten hinzu:
greeting.suffix
=
!!, How are you???
Öffne org.acme.quickstart.GreetingResource.java und injiziere greeting.suffix
Eigenschaftswerte:
@ConfigProperty
(
name
=
"greeting.suffix"
)
List
<
String
>
suffixes
;
@GET
@Path
(
"/list"
)
@Produces
(
MediaType
.
TEXT_PLAIN
)
public
String
helloList
()
{
return
message
+
suffixes
.
get
(
1
);
}
Stelle in einem Terminalfenster eine Anfrage an /hello/list
, um zu sehen, dass die Ausgabemeldung das zweite Suffix enthält:
curl http://localhost:8080/hello/list
Hello World How are you?
Für die Konfiguration der Anwendung wird auch das YAML-Format unterstützt. In diesem Fall heißt die Datei application.yaml oder application.yml.
Um die YAML-Konfigurationsdatei zu verwenden, musst du dieErweiterung config-yaml
hinzufügen:
./mvnw quarkus:add-extension -Dextensions="config-yaml"
Die folgende Konfigurationsdatei wird im Format properties
erstellt:
greeting.message
=
Hello World
%staging.quarkus.http.port
=
8182
quarkus.http.cors
=
true
quarkus.http.cors.methods
=
GET,PUT,POST
Es folgt die Entsprechung im YAML-Format:
greeting
:
message
:
Hello
World
"
%staging
"
:
quarkus
:
http
:
port
:
8182
quarkus
:
http
:
cors
:
~
:
true
methods
:
GET,PUT,POST
Diskussion
Eclipse MicroProfile Configuration verfügt über die folgenden eingebauten Konverter, um einen Konfigurationswert in ein Java-Objekt abzubilden:
-
boolean
undjava.lang.Boolean
; die Werte für wahr sindtrue
,1
,YES
,Y
undON
, während jeder andere Wert alsfalse
-
byte
undjava.lang.Byte
-
short
undjava.lang.Short
-
int
undjava.lang.Integer
-
long
undjava.lang.Long
-
float
undjava.lang.Float
-
double
undjava.lang.Double
-
char
undjava.lang.Character
-
java.lang.Class
basierend auf dem Ergebnis des Aufrufs vonClass.forName
Wenn kein eingebauter oder benutzerdefinierter Konverter vorhanden ist, werden die folgenden Methoden im Zielobjekt überprüft. Wenn ein eingebauter oder benutzerdefinierter Konverter vorhanden ist, wird die Methode discovered/found verwendet, um das Konverter-Objekt zu instanziieren, und das String-Argument wird für die Konvertierung übergeben :
-
Zieltyp hat
public static T of(String)
Methode -
Zieltyp hat
public static T valueOf(String)
Methode -
Der Zieltyp hat einen öffentlichen Konstruktor mit einem
String
Parameter -
Zieltyp hat
public static T parse(CharSequence)
Methode
4.2 Programmgesteuerter Zugriff auf Konfigurationseigenschaften
Lösung
Injiziere die Klasse org.eclipse.microprofile.config.Config
in das Objekt, auf dessen Eigenschaften du programmatisch zugreifen möchtest.
Die Eclipse MicroProfile Configuration Spezifikation ermöglicht es dir, org.eclipse.microprofile.config.Config
zu injizieren, um Eigenschaften programmatisch zu erhalten, anstatt sie direkt mit ConfigProperty
zu injizieren.
Öffne org.acme.quickstart.GreetingResource.java
und injiziere die Klasse Config
:
@Inject
Config
config
;
@GET
@Path
(
"/config"
)
@Produces
(
MediaType
.
TEXT_PLAIN
)
public
String
helloConfig
(
)
{
config
.
getPropertyNames
(
)
.
forEach
(
p
-
>
System
.
out
.
println
(
p
)
)
;
return
config
.
getValue
(
"greeting.message"
,
String
.
class
)
;
}
Verwende die
Inject
CDI-Annotation, um die Instanz zu injizierenDu kannst jetzt auf die Liste der Eigenschaften zugreifen
Die Eigenschaft muss in den endgültigen Typ umgewandelt werden
Du kannst auf die Klasse Config
zugreifen, ohne CDI zu verwenden, indem du die Methode ConfigProvider.getConfig()
aufrufst.
4.3 Externes Überschreiben von Konfigurationswerten
Lösung
Du kannst jede Eigenschaft zur Laufzeit überschreiben, indem du sie als Systemeigenschaft oder Umgebungsvariable setzt.
Mit Quarkus kannst du jede Konfigurationseigenschaft überschreiben, indem du eine Konfigurationals Systemeigenschaft (-Dproperty.name=value
) und/oder als Umgebungsvariable (export PROPERTY_NAME=value
) setzt. Systemeigenschaften haben eine höhere Priorität als Umgebungsvariablen.
Beispiele für die Externalisierung dieser Eigenschaften sind eine Datenbank-URL, ein Benutzername oder ein Passwort, da sie nur in der Zielumgebung bekannt sind. Du musst jedoch wissen, dass es einen Kompromiss gibt, denn je mehr Laufzeiteigenschaften verfügbar sind, desto weniger Vorarbeit kann Quarkus während der Build-Zeit leisten.
Wir verpacken die in Rezept 4.1 verwendete Anwendung und überschreiben die Eigenschaft greeting.message
, indem wir eine Systemeigenschaft setzen:
./mvnw clean package -DskipTests
java -Dgreeting.message=Aloha -jar target/getting-started-1.0-SNAPSHOT-runner.jar
Überprüfe in einem neuen Terminalfenster, ob die Eigenschaft von Hello World
auf Aloha
überschrieben wurde, indem du den Befehl ausführst:
curl localhost:8080/hello
Aloha
Bei Umgebungsvariablen werden drei Namenskonventionen für einen bestimmten Eigenschaftsnamen unterstützt. Das liegt daran, dass einige Betriebssysteme nur Buchstaben und Unterstriche (_
), aber keine anderen Zeichen wie Punkte (.
) zulassen. Um alle möglichen Fälle zu unterstützen, werden die folgenden Regeln verwendet:
-
Genaue Übereinstimmung (
greeting.message
). -
Ersetze nicht-alphanumerische Zeichen durch einen Unterstrich (
greeting_message
). -
Ersetze nicht-alphanumerische Zeichen durch Unterstriche und wandle den Rest in Großbuchstaben um (
GREETING_MESSAGE
).
Hier ist die Datei application.properties:
greeting.message
=
Hello World
Du kannst den Wert mit einer der folgenden Umgebungsvariablennamen überschreiben, da sie alle gleichwertig sind:
export greeting.message=Aloha
export greeting_message=Aloha
export GREETING_MESSAGE=Aloha
Es gibt auch einen speziellen Ort, an dem du die Datei application.properties außerhalb der Anwendung selbst ablegen kannst, und zwar in einem Verzeichnis namens config, in dem die Anwendung läuft. Alle Laufzeiteigenschaften, die in dieser Datei definiert werden, überschreiben die Standardkonfiguration.
Wichtig
config/application.properties funktioniert auch im Entwicklungsmodus, aber du musst sie dem Ausgabeverzeichnis deines Build-Tools hinzufügen, damit es funktioniert (im Fall von Maven das Zielverzeichnis, im Fall von Gradle das Build-Verzeichnis). Du musst dir also darüber im Klaren sein, dass du sie neu erstellen musst, wenn du die Aufgabe clean
ausführst.
Neben den Umgebungsvariablen und der Datei application.properties kannst du auch eine .env-Datei im aktuellen Arbeitsverzeichnis ablegen, um Konfigurationswerte zu überschreiben,die dem Format der Umgebungsvariablenentsprechen (GREETING_MESSAGE=Aloha
).
4.4 Konfigurieren mit Profilen
Lösung
Quarkus unterstützt das Konzept der Konfigurationsprofile. Diese ermöglichen es dir, mehrere Konfigurationswerte für dieselbe Eigenschaft in derselben Datei zu haben und verschiedene Werte zu aktivieren, um sie an die Umgebung anzupassen, in der du den Dienst betreibst.
Die Syntax für Konfigurationsprofile lautet %{profile}.config.key=value
.
Diskutiere
Quarkus kommt mit drei eingebauten Profilen.
- dev
-
Aktiviert, wenn du dich im Entwicklungsmodus befindest (z. B.
quarkus:dev
). - Test
-
Wird bei der Durchführung von Tests aktiviert.
- prod
-
Das Standardprofil, wenn es nicht im Entwicklungs- oder Testmodus läuft; du musst es nicht in application.properties festlegen, da es implizit festgelegt ist.
Öffne die Datei src/main/resources/application.properties und lege fest, dass Quarkus auf Port 8181 im Entwicklungsmodus gestartet wird:
%dev.quarkus.http.port
=
8181
Starten Sie den Dienst nach dieser Änderung, um erneut zu prüfen, ob der abhörende Port 8181 statt des Standardports (8080) ist:
./mvnw compile quarkus:dev
INFO [io.qua.dep.QuarkusAugmentor] (main) Beginning quarkus augmentation
INFO [io.qua.dep.QuarkusAugmentor] (main) Quarkus augmentation completed
in 671ms
INFO [io.quarkus] (main) Quarkus 1.4.1 started in 1.385s. Listening on:
http://0.0.0.0:8181
INFO [io.quarkus] (main) Profile dev activated. Live Coding activated.
INFO [io.quarkus] (main) Installed features:
[cdi, hibernate-validator, resteasy]
Beachte, dass die Abhöradresse jetzthttp://0.0.0.0:8181 lautet und nicht mehr die Standardadresse.
Zum Schluss nimmst du den Port 8080 zurück und entfernst die Zeile %dev.quarkus.http.port=8181
in der Datei application.properties, um sie an den Port anzupassen, der im Rest des Buches verwendet wird.
4.5 Ändern der Logger-Konfiguration
Lösung
Quarkus verwendet ein einheitliches Konfigurationsmodell, bei dem alle Konfigurationseigenschaften in einer Datei gespeichert werden. Im Fall von Quarkus heißt diese Datei application.properties, und du kannst dort viele Aspekte der Protokollierung konfigurieren.
Wenn du zum Beispiel die Protokollierungsstufe ändern möchtest, setzt du quarkus.log.level
einfach auf die minimale Protokollierungsstufe.
Öffne src/main/resources/application.properties und füge den folgenden Inhalt hinzu:
quarkus.log.level
=
DEBUG
Starte nun die Anwendung, um zu sehen, dass eine Menge neuer Logging-Meldungen in der Konsole ausgegeben werden:
./mvnw compile quarkus:dev
...
[INFO] --- quarkus-maven-plugin:0.22.0:dev (default-cli) @ getting-started ---
Listening for transport dt_socket at address: 5005
DEBUG [org.jbo.logging] (main) Logging Provider: \
org.jboss.logging.JBossLogManagerProvider
INFO [io.qua.dep.QuarkusAugmentor] (main) Beginning quarkus augmentation
DEBUG [io.qua.run.con.ConverterSupport] (main) Populate SmallRye config builder
with converter for class java.net.InetSocketAddress of priority 200
DEBUG [io.qua.run.con.ConverterSupport] (main) Populate SmallRye config builder
with converter for class org.wildfly.common.net.CidrAddress of priority 200
Hinweis
Für die Formatierung im Buch mussten wir mehrere Zeilen überspannen; wir haben den Backslash verwendet, um dies anzuzeigen.
Du kannst auch die Speicherung von Protokollen in einer Datei aktivieren, indem du die Eigenschaft quarkus.log.file.enable
verwendest. Die Ausgabe wird standardmäßig in eine Datei namens quarkus.log geschrieben:
quarkus.log.file.enable
=
true
Hinweis
Wenn du in der Entwicklung bist und aus dem Quellverzeichnis heraus arbeitest, befindet sich deine Logging-Datei im Zielverzeichnis.
4.6 Hinzufügen von Anwendungsprotokollen
Lösung
In den meisten Fällen müssen deine Anwendungen ihre eigenen Logging-Meldungen schreiben und sich nicht nur auf die von Quarkus bereitgestellten Standard-Logs verlassen. Anwendungen können jede der unterstützten APIs für das Logging verwenden, und die Logs werden zusammengeführt.
Quarkus unterstützt diese Logging-Bibliotheken:
-
JDK java.util.logging
-
JBoss-Protokollierung
-
SLF4J
-
Apache Commons Logging
Sehen wir uns an, wie man JBoss Logging
zum Protokollieren von Inhalten verwendet. Öffne org.acme.quickstart.GreetingResource.java
und protokolliere eine Nachricht, wenn ein spezieller Endpunkt aufgerufen wird:
private
static
org
.
jboss
.
logging
.
Logger
logger
=
org
.
jboss
.
logging
.
Logger
.
getLogger
(
GreetingResource
.
class
)
;
@GET
@Path
(
"/log"
)
@Produces
(
MediaType
.
TEXT_PLAIN
)
public
String
helloLog
(
)
{
logger
.
info
(
"I said Hello"
)
;
return
"hello"
;
}
Starte jetzt die Anwendung:
./mvnw compile quarkus:dev
Stelle in einem neuen Terminalfenster eine Anfrage an /hello/log
:
curl http://localhost:8080/hello/log
Wenn du das Terminal inspizierst, in dem du Quarkus gestartet hast, siehst du die nächste Logline:
INFO [org.acm.qui.GreetingResource] (executor-thread-1) I said Hello
Diskussion
Eine Konfiguration, die für eine Kategorie gilt, gilt auch für alle Unterkategorien dieser Kategorie, es sei denn, es gibt eine spezifischere passende Unterkategorie-Konfiguration.
Kategorien werden durch den Ort der Klasse repräsentiert (d.h. das Paket oder die Unterpakete,in denen sie definiert sind). Wenn du z.B. die Sicherheitsprotokollierung von Undertowauf Trace-Level einstellen willst, musst du die Eigenschaftquarkus.log.category."io.undertow.request.security".level=TRACE
in application.properties setzen.
In Anlehnung an das vorherige Beispiel wollen wir die Log-Zeilen von Klassen, die sich in org.acme.quickstart
(und Unterklassen) befinden, einschränken, so dass der minimale Log-Level WARNING
ist:
quarkus.log.category."org.acme.quickstart".level
=
WARNING
Wenn du die Anfrage anhttp://localhost:8080/hello/log wiederholst, wird die Logline nicht mehr aufgeschrieben.
4.7 Erweiterte Protokollierung
Lösung
Wenn du mit Microservice-Architekturen und Kubernetes arbeitest, ist das Logging ein wichtiger Punkt, den du berücksichtigen musst, weil jeder Dienst einzeln protokolliert wird; als Entwickler oder Betreiber möchtest du aber vielleicht alle Logs an einem Ort zentralisiert haben, damit sie als Ganzes genutzt werden können.
Quarkus Logging unterstützt auch JSON- und GELF-Ausgaben.
Diese Protokolle können für die maschinelle Verarbeitung im JSON-Format statt im reinen Textformat geschrieben werden, indem du die Erweiterung logging-json
registrierst:
./mvnw quarkus:add-extension -Dextensions="logging-json"
Verwende die GELF-Erweiterung, um Protokolle im GELF-Format zu erstellen und sie entweder über TCP oder UDP zu versenden.
DasGraylog Extended Log Format (GELF) wird von drei der am häufigsten verwendeten zentralen Log-Systeme verstanden :
-
Graylog (MongoDB, Elasticsearch, Graylog)
-
ELK (Elasticsearch, Logstash, Kibana)
-
EFK (Elasticsearch, Fluentd, Kibana)
Um das Logging im GELF-Format zu starten, musst du nur dieErweiterung logging-gelf
hinzufügen:
./mvnw quarkus:add-extension -Dextensions="logging-gelf"
Der Logging-Code ändert sich nicht, also werden die gleichen Schnittstellen verwendet:
private
static
org
.
jboss
.
logging
.
Logger
logger
=
org
.
jboss
.
logging
.
Logger
.
getLogger
(
GreetingResource
.
class
)
;
@GET
@Path
(
"/log"
)
@Produces
(
MediaType
.
TEXT_PLAIN
)
public
String
helloLog
(
)
{
logger
.
info
(
"I said Hello"
)
;
return
"hello"
;
}
Der GELF-Handler muss in application.properties konfiguriert werden:
quarkus.log.handler.gelf.enabled
=
true
quarkus.log.handler.gelf.host
=
localhost
quarkus.log.handler.gelf.port
=
12201
Aktiviert die Erweiterung
Legt den Host fest, an den die Logmeldungen gesendet werden
Legt den Endpunkt-Port fest
Wichtig
Wenn du Logstash (ELK) verwendest, musst du das Input Plug-in aktivieren, das das GELF-Format versteht:
input { gelf { port => 12201 } } output { stdout {} elasticsearch { hosts => ["http://elasticsearch:9200"] } }
Wichtig
Wenn du Fluentd (EFK) verwendest, musst du das Input-Plug-in aktivieren, das das GELF-Format versteht:
<source> type gelf tag example.gelf bind 0.0.0.0 port 12201 </source> <match example.gelf> @type elasticsearch host elasticsearch port 9200 logstash_format true </match>
Diskussion
Quarkus Logging unterstützt standardmäßig auch das Syslog-Format, ohne dass eine Erweiterung hinzugefügt werden muss. Das Syslog-Format kann in Fluentd als Alternative zum GELF-Format in Quarkus verwendet werden:
quarkus.log.syslog.enable
=
true
quarkus.log.syslog.endpoint
=
localhost:5140
quarkus.log.syslog.protocol
=
udp
quarkus.log.syslog.app-name
=
quarkus
quarkus.log.syslog.hostname
=
quarkus-test
Wichtig
Du musst das Input Plug-in aktivieren, das das Syslog-Format in Fluentd versteht:
<source> @type syslog port 5140 bind 0.0.0.0 message_format rfc5424 tag system </source> <match **> @type elasticsearch host elasticsearch port 9200 logstash_format true </match>
Wenn du Kubernetes verwendest, ist der einfachste Weg, sich an der Konsole anzumelden und im Cluster einen zentralen Logmanager zu installieren, der alle Logzeilen sammelt.
4.8 Konfigurieren mit benutzerdefinierten Profilen
Lösung
Bisher hast du gesehen, dass Quarkus mit eingebauten Profilen geliefert wird, so dass du verschiedene Konfigurationswerte für dieselbe Eigenschaft festlegen und sie je nach Umgebung aktivieren kannst. Aber mit Quarkus kannst du auch deine eigenen Profile festlegen.
Du musst nur angeben, welches Profil du aktivieren willst, indem du entweder die Systemeigenschaft quarkus.profile
oder die Umgebungsvariable QUARKUS_PROFILE
verwendest. Wenn beide gesetzt sind, hat die Systemeigenschaft Vorrang vor derUmgebungsvariable.
Dann musst du nur noch die Eigenschaft mit dem Profilnamen erstellen und das aktuelle Profil auf diesen Namen setzen. Lass uns ein neues Staging-Profil erstellen, das den Listening Port von Quarkus überschreibt.
Öffne die Datei src/main/resources/application.properties und stelle ein, dass Quarkus auf Port 8182 gestartet wird, wenn das Profil staging
aktiviert ist:
%staging.quarkus.http.port
=
8182
Starte dann die Anwendung mit aktiviertem staging
Profil:
./mvnw -Dquarkus.profile=staging compile quarkus:dev
INFO [io.qua.dep.QuarkusAugmentor] (main) Beginning quarkus augmentation
INFO [io.qua.dep.QuarkusAugmentor] (main) Quarkus augmentation completed
in 640ms
INFO [io.quarkus] (main) Quarkus 0.23.2 started in 1.300s. Listening on:
http://0.0.0.0:8182
INFO [io.quarkus] (main) Profile staging activated. Live Coding activated.
INFO [io.quarkus] (main) Installed features: [cdi, hibernate-validator,
resteasy]
In diesem Fall wird die Systemeigenschaft verwendet, aber du kannst sie auch über die Umgebungsvariable QUARKUS_PROFILE
setzen.
Diskussion
Wenn du das Laufprofil in Tests festlegen möchtest, musst du nur die Systemeigenschaft quarkus.test.profile
auf das angegebene Profil in deinem Build-Skript setzen - zum Beispiel in Maven:
<groupId>
org.apache.maven.plugins</groupId>
<artifactId>
maven-surefire-plugin</artifactId>
<version>
${surefire-plugin.version}</version>
<configuration>
<systemPropertyVariables>
<quarkus.test.profile>
foo</quarkus.test.profile>
<buildDirectory>
${project.build.directory}</buildDirectory>
</systemPropertyVariables>
</configuration>
oder, in Gradle:
test
{
useJUnitPlatform
()
systemProperty
"quarkus.test.profile"
,
"foo"
}
Außerdem kannst du das Standard-Produktionsprofil ändern. Das in Quarkus eingebaute Profil ist prod
. Wenn du deine Anwendung also ohne Profil ausführst, werden die Werte standardmäßig von diesem Profil übernommen. Du kannst das aber zur Erstellungszeit ändern, sodass dein Profil das Standardprofil ist, wenn die Anwendung läuft, ohne dass du ein Profil angibst.
Das Einzige, was du tun musst, ist, die Anwendung unter Verwendung der Systemeigenschaft quarkus.profile
mit dem Profilwert zu erstellen, den du als Standard festlegen möchtest:
./mvnw package -Pnative -Dquarkus.profile=prod-kubernetes`
./target/getting-started-1.0-runner
4.9 Benutzerdefinierte Quellen erstellen
Lösung
Quarkus nutzt die Eclipse MicroProfile Configuration-Spezifikation, um die gesamte Logik der Konfiguration zu implementieren. Die Spezifikation bietet dieorg.eclipse.microprofile.config.spi.ConfigSource
Java SPI-Schnittstelle, um einebenutzerdefinierte Methode zum Laden von Konfigurationseigenschaften anstelle der von Quarkusbereitgestellten Standardmethode zu implementieren.
Du könntest zum Beispiel Konfigurationseigenschaften aus einer Datenbank, einer XML-Datei oder einer REST-API laden.
Erstellen wir eine einfache In-Memory-Konfigurationsquelle, die die Konfigurationseigenschaften von Map
zur Instanziierungszeit abruft. Erstelle eine neue Klasse namens org.acme.quickstart.InMemoryConfigSource.java
:
package
org
.
acme
.
quickstart
;
import
java.util.HashMap
;
import
java.util.Map
;
import
org.eclipse.microprofile.config.spi.ConfigSource
;
public
class
InMemoryConfigSource
implements
ConfigSource
{
private
Map
<
String
,
String
>
prop
=
new
HashMap
<
>
(
)
;
public
InMemoryConfigSource
(
)
{
prop
.
put
(
"greeting.color"
,
"red"
)
;
}
@Override
public
int
getOrdinal
(
)
{
return
500
;
}
@Override
public
Map
<
String
,
String
>
getProperties
(
)
{
return
prop
;
}
@Override
public
String
getValue
(
String
propertyName
)
{
return
prop
.
get
(
propertyName
)
;
}
@Override
public
String
getName
(
)
{
return
"MemoryConfigSource"
;
}
}
Füllt die Karte mit einer Eigenschaft
Wird verwendet, um die Wichtigkeit der Werte zu bestimmen; die höchste Ordnungszahl hat Vorrang vor der niedrigeren Ordnungszahl
Erhält alle Eigenschaften als
Map
; in diesem Fall ist es direktErmittelt den Wert für eine einzelne Eigenschaft
Gibt den Namen dieser Konfigurationsquelle zurück
Dann musst du diese als Java SPI registrieren. Erstelle den Ordner services unter src/main/resources/META-INF. Als Nächstes erstellst du innerhalb von services eine Datei namens org.eclipse.microprofile.config.spi.ConfigSource mit folgendem Inhalt:
org.acme.quickstart.InMemoryConfigSource
Schließlich kannst du die Klasse org.acme.quickstart.GreetingResource.java
ändern, um diese Eigenschaft zu injizieren:
@ConfigProperty
(
name
=
"greeting.color"
)
String
color
;
@GET
@Path
(
"/color"
)
@Produces
(
MediaType
.
TEXT_PLAIN
)
public
String
color
(
)
{
return
color
;
}
Stelle in einem Terminalfenster eine Anfrage an /hello/color
, um zu sehen, ob die Ausgabemeldung dem konfigurierten Wert in der benutzerdefinierten Quelle entspricht:
curl http://localhost:8080/hello/color
red
Diskussion
Jedes ConfigSource
hat eine bestimmte Ordnungszahl, die verwendet wird, um die Wichtigkeit der Werte aus ConfigSource
festzulegen, wenn mehrere Konfigurationsquellen für dieselbe Anwendung definiert sind. Eine höhere Ordnungszahl ConfigSource
wird über eine ConfigSource
mit einem niedrigeren Wert verwendet. Mit den Vorgaben in der folgenden Liste als Referenz wird eine Systemeigenschaft über alles verwendet, und die Datei application.properties im Verzeichnis src/main/resources wird verwendet, wenn keine anderen ConfigSources
gefunden werden:
-
Systemeigenschaften bis 400
-
Umgebungsvariablen bis 300
-
application.properties im Konfigurationsverzeichnis auf 260
-
application.properties im Projekt auf 250
4.10 Erstellen von benutzerdefinierten Konvertern
Lösung
Du kannst eine Eigenschaft von String
in jede Art von Objekt umwandeln, indem du den org.eclipse.microprofile.config.spi.Converter
Java SPI implementierst.
Quarkus verwendet die Eclipse MicroProfile Configuration Spezifikation, um die gesamte Logik der Konfiguration zu implementieren. Die Spezifikation bietet die org.eclipse.microprofile.config.spi.Converter
Java SPI Schnittstelle, um die Konvertierung von Konfigurationswerten in einen benutzerdefinierten Typ zu implementieren.
Du könntest z.B. einen Prozentwert (z.B. 15%) in einen Percentage
Typ umwandeln, indem du den Prozentwert als double
Typ verpackst.
Erstelle eine neue POJO-Klasse org.acme.quickstart.Percentage.java
:
package
org
.
acme
.
quickstart
;
public
class
Percentage
{
private
double
percentage
;
public
Percentage
(
double
percentage
)
{
this
.
percentage
=
percentage
;
}
public
double
getPercentage
()
{
return
percentage
;
}
}
Und dann erstelle eine Klasse org.acme.quickstart.PercentageConverter.java
, die die Darstellung von String
in Percentage
umwandelt:
package
org
.
acme
.
quickstart
;
import
javax.annotation.Priority
;
import
org.eclipse.microprofile.config.spi.Converter
;
@Priority
(
300
)
public
class
PercentageConverter
implements
Converter
<
Percentage
>
{
@Override
public
Percentage
convert
(
String
value
)
{
String
numeric
=
value
.
substring
(
0
,
value
.
length
(
)
-
1
)
;
return
new
Percentage
(
Double
.
parseDouble
(
numeric
)
/
100
)
;
}
}
Legt die Priorität fest; in diesem speziellen Fall kann sie optional sein
Generischer Typ, der den Typ festlegt, in den konvertiert werden soll
Dann musst du diese als Java SPI registrieren. Erstelle den Ordner services unter src/main/resources/META-INF. Als Nächstes erstellst du im Ordner services eine Datei namensorg.eclipse.microprofile.config.spi.Converter mit folgendem Inhalt:
org.acme.quickstart.PercentageConverter
Dann kannst du die Klasse org.acme.quickstart.GreetingResource.java
ändern, um diese Eigenschaft zu injizieren:
@ConfigProperty
(
name
=
"greeting.vat"
)
Percentage
vat
;
@GET
@Path
(
"/vat"
)
@Produces
(
MediaType
.
TEXT_PLAIN
)
public
String
vat
()
{
return
Double
.
toString
(
vat
.
getPercentage
());
}
Schließlich musst du noch eine neue Eigenschaft in die Datei application.properties in deinem src/main/resources-Verzeichnis einfügen:
greeting.vat
=
21%
Stelle in einem Terminalfenster eine Anfrage an /hello/vat
, um zu sehen, dass die Ausgabemeldung der umgewandelte Bottich als Double ist:
curl http://localhost:8080/hello/vat
0.21
Diskussion
Wenn für einen Konverter keine @Priority
Anmerkung gefunden wird, wird er standardmäßig mit einer Priorität von 100 registriert. Quarkus-Konverter werden mit einer Priorität von 200 registriert. Wenn du also einen Quarkus-Konverter ersetzen willst, solltest du einen höheren Wert verwenden; wenn du keinen Quarkus-Konverter ersetzen musst, ist der Standardwert vollkommen ausreichend.
Eine Liste der Quarkus-Kernkonverter ist in Rezept 4.1 zu finden.
4.11 Konfigurationswerte gruppieren
Lösung
Du kannst gemeinsame Eigenschaften (mit demselben Präfix) mit der Anmerkung @io.quarkus.arc.config.ConfigProperties
gruppieren.
Wenn du in deiner Anwendung Ad-hoc-Konfigurationseigenschaften erstellst, haben diese Eigenschaften in der Regel das gleiche Präfix (z. B. greetings
). Um alle diese Eigenschaften zu injizieren, kannst du die Anmerkung @ConfigProperty
verwenden (wie in Rezept 4.1 gezeigt) oderdu kannst die Anmerkung io.quarkus.arc.config.ConfigProperties
verwenden, umEigenschaften zu gruppieren.
Mit der Datei application.properties:
greeting.message
=
Hello World
greeting.suffix
=
!!, How are you???
implementieren wir eine Klasse, die die Konfigurationseigenschaften mithilfe der io.quarkus.arc.config.ConfigProperties
Annotation in Java-Objekte umwandelt. Erstelle eine neue Klasse org.acme.quickstart.GreetingConfiguration.java
:
package
org
.
acme
.
quickstart
;
import
java.util.List
;
import
java.util.Optional
;
import
javax.validation.constraints.Max
;
import
javax.validation.constraints.Min
;
import
io.quarkus.arc.config.ConfigProperties
;
@ConfigProperties
(
prefix
=
"greeting"
)
public
class
GreetingConfiguration
{
public
String
message
;
public
String
suffix
=
"!"
;
}
Setzt dies als Konfigurations-POJO mit einem gemeinsamen Präfix
Karten der
greeting.message
EigenschaftDer Standardwert für
greeting.suffix
, falls die Eigenschaft nicht gesetzt ist
Eines der wichtigsten Dinge, die im obigen Code zu beachten sind, ist, dass das Attribut prefix
nicht zwingend erforderlich ist. Wenn es nicht gesetzt ist, wird das zu verwendende Präfix durch den Klassennamen bestimmt (wobei der Suffixteil Configuration
entfernt wird). In diesem Fall könnte das Attribut prefix
automatisch zu greeting
aufgelöst werden.
Dann kannst du dieses Konfigurations-POJO injizieren, um die Konfigurationswerte zu verwenden.
Du kannst die Klasse org.acme.quickstart.GreetingResource.java
ändern, um diese Klasse zu injizieren:
@Inject
GreetingConfiguration
greetingConfiguration
;
@GET
@Path
(
"/configurations"
)
@Produces
(
MediaType
.
TEXT_PLAIN
)
public
String
helloConfigurations
(
)
{
return
greetingConfiguration
.
message
+
greetingConfiguration
.
suffix
;
}
In einem Terminalfenster kannst du eine Anfrage an /hello/configurations
stellen, um zu sehen, ob die Konfigurationswerte in Java ausgefüllt sind:
curl http://localhost:8080/hello/configurations
Hello World!!, How are you???
Wie du jetzt siehst, musst du nicht jedes Feld mit @ConfigProperty
annotieren, sondern du brauchst nur die Klassendefinition zu nutzen, um den Eigenschaftsnamen oder den Standardwert zu erhalten.
Diskussion
Außerdem unterstützt Quarkus die Konfiguration von verschachtelten Objekten, so dass du auch Unterkategorien mit Hilfe von inneren Klassen abbilden kannst.
Nehmen wir an, wir fügen eine neue Eigenschaft namens greeting.output.recipients
in der Dateiapplication.properties hinzu:
greeting.output.recipients
=
Ada,Alexandra
Du könntest eine innere Klasse verwenden, um sie im Konfigurationsobjekt abzubilden. Ändere die Klasse org.acme.quickstart.GreetingConfiguration.java
. Füge dann eine neue innere Klasse hinzu, die die Unterkategorie output
repräsentiert, und registriere sie als ein Feld:
public
OutputConfiguration
output
;
public
static
class
OutputConfiguration
{
public
List
<
String
>
recipients
;
}
Dann kannst du auf das Feld greetingConfiguration.output.recipients
zugreifen, um den Wert zu erhalten.Du kannst die Felder auch mit Bean Validation-Annotationen versehen, um beim Start zu überprüfen, ob alle Konfigurationswerte gültig sind. Wenn sie nicht gültig sind, schlägt der Start der Anwendung fehl und die Validierungsfehler werden im Protokoll angezeigt.
4.12 Validierung der Konfigurationswerte
Lösung
Verwende die Bean Validation-Spezifikation, um zu überprüfen, ob ein Eigenschaftswert gültig ist, wenn er mit der @ConfigProperty
-Annotation einer Klasse injiziert wird.
Die Bean Validation Spec ermöglicht es dir, mithilfe von Annotationen Einschränkungen für Objekte festzulegen. Quarkus integriert die Eclipse MicroProfile Configuration Spec mit der Bean Validation Spec, sodass du sie zusammen verwenden kannst, um zu überprüfen, ob ein Konfigurationswert bestimmte Kriterien erfüllt. Diese Überprüfung wird beim Booten durchgeführt und bei einem Verstoß wird eine Fehlermeldung in der Konsole angezeigt und der Bootvorgang abgebrochen.
Als erstes musst du die Quarkus Bean Validation-Abhängigkeit registrieren. Du kannst dies manuell tun, indem du deine pom.xml bearbeitest oder indem du den nächsten Maven-Befehl aus dem Stammverzeichnis des Projekts ausführst:
./mvnw quarkus:add-extension -Dextensions="quarkus-hibernate-validator"
Danach musst du ein Konfigurationsobjekt erstellen, das du im vorherigen Rezept kennengelernt hast. Im nächsten Beispiel wird eine Einschränkung für die Konfigurationseigenschaft greeting.repeat
festgelegt, so dass Wiederholungen außerhalb des Bereichs 1-3 einschließlich nicht eingestellt werden können.
Um den Ganzzahlbereich zu validieren, werden die folgenden Bean Validation Annotations verwendet: javax.validation.constraints.Max
und javax.validation.constraints.Min
. Öffne org.acme.quickstart.GreetingConfiguration.java
und füge Bean Validation Annotations hinzu:
@Min
(
1
)
@Max
(
3
)
public
Integer
repeat
;
Öffne die Datei src/main/resources/application.properties und setze die Konfigurationseigenschaft greeting.repeat
auf 7:
greeting.repeat
=
7
Wenn du die Anwendung startest, wird eine Fehlermeldung angezeigt, die darauf hinweist, dass ein Konfigurationswert gegen eine der definierten Einschränkungen verstößt:
./mvnw compile quarkus:dev
Diskussion
In diesem Beispiel hast du eine kurze Einführung in die Spezifikation der Bean Validation sowie einige Annotationen gesehen, die du zur Validierung von Feldern verwenden kannst. Hibernate Validation und die verwendete Bean-Validation-Implementierung unterstützen jedoch noch weitere Constraints wie @Digits
, @Email
, @NotNull
und @NotBlank
.
Get Quarkus Kochbuch now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.