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

Problem

Du möchtest die Quarkus-Anwendung mit benutzerdefinierten Eigenschaften konfigurieren.

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") 1
String message; 2

@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
    return message; 3
}
1

Injiziert den Wert der Eigenschaft greeting.message

2

Platziert Felder im paketgeschützten Bereich

3

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") 1
boolean upperCase;
@GET
@Path("/optional")
@Produces(MediaType.TEXT_PLAIN)
public String helloOptional() {
    return upperCase ? message.toUpperCase() : message;
}
1

Setzt die Standardeinstellung der Eigenschaft greeting.upper-case auf true

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-yamlhinzufü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 1
"%staging": 2
  quarkus:
    http:
      port: 8182
quarkus:
  http:
    cors:
      ~: true 3
      methods: GET,PUT,POST
1

Einfache Eigenschaften werden als Struktur festgelegt

2

Profile werden in Anführungszeichen eingeschlossen unterstützt

3

Wenn es Unterschlüssel gibt, wird ~ verwendet, um sich auf den nicht vorangestellten Teil zu beziehen

Diskussion

Eclipse MicroProfile Configuration verfügt über die folgenden eingebauten Konverter, um einen Konfigurationswert in ein Java-Objekt abzubilden:

  • boolean und java.lang.Boolean; die Werte für wahr sind true, 1, YES, Y und ON, während jeder andere Wert als false

  • byte und java.lang.Byte

  • short und java.lang.Short

  • int und java.lang.Integer

  • long und java.lang.Long

  • float und java.lang.Float

  • double und java.lang.Double

  • char und java.lang.Character

  • java.lang.Class basierend auf dem Ergebnis des Aufrufs von Class.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

Problem

Du möchtest programmatisch auf die Konfigurationseigenschaften zugreifen, anstatt sie mit der org.eclipse.microprofile.config.inject.ConfigPropertyAnnotation zu injizieren.

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 1
Config config;
@GET
@Path("/config")
@Produces(MediaType.TEXT_PLAIN)
public String helloConfig() {
    config.getPropertyNames().forEach( p -> System.out.println(p)); 2

    return config.getValue("greeting.message", String.class); 3
}
1

Verwende die Inject CDI-Annotation, um die Instanz zu injizieren

2

Du kannst jetzt auf die Liste der Eigenschaften zugreifen

3

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

Problem

Du willst jeden Konfigurationswert zur Laufzeit überschreiben.

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:

  1. Genaue Übereinstimmung (greeting.message).

  2. Ersetze nicht-alphanumerische Zeichen durch einen Unterstrich (greeting_message).

  3. 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

Problem

Du möchtest Konfigurationswerte überschreiben, die von der Umgebung abhängen, in der du Quarkus einsetzt.

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

Problem

Du möchtest die Standardkonfiguration für die Protokollierung ändern.

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

Problem

Du möchtest deiner Anwendung Protokollzeilen hinzufügen.

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); 1

@GET
@Path("/log") 2
@Produces(MediaType.TEXT_PLAIN)
public String helloLog() {
    logger.info("I said Hello"); 3
    return "hello";
}
1

Erzeugt die Logger-Instanz

2

Der Endpunkt-Unterpfad ist /log

3

Logs auf der Ebene info

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=TRACEin 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 1
1

Doppelte Anführungszeichen sind obligatorisch, um die Kategorie zu setzen

Wenn du die Anfrage anhttp://localhost:8080/hello/log wiederholst, wird die Logline nicht mehr aufgeschrieben.

4.7 Erweiterte Protokollierung

Problem

Du willst alle deine Dienste zentral protokollieren.

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-gelfhinzufü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); 1

@GET
@Path("/log") 2
@Produces(MediaType.TEXT_PLAIN)
public String helloLog() {
    logger.info("I said Hello"); 3
    return "hello";
}
1

Erzeugt die Logger-Instanz

2

Der Endpunkt-Unterpfad ist /log

3

Logs auf der Ebene info

Der GELF-Handler muss in application.properties konfiguriert werden:

quarkus.log.handler.gelf.enabled=true 1
quarkus.log.handler.gelf.host=localhost 2
quarkus.log.handler.gelf.port=12201 3
1

Aktiviert die Erweiterung

2

Legt den Host fest, an den die Logmeldungen gesendet werden

3

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.

Siehe auch

Um mehr über fortgeschrittene Logging-Themen zu erfahren, besuche die folgende Website:

4.8 Konfigurieren mit benutzerdefinierten Profilen

Problem

Du möchtest unterschiedliche Konfigurationswerte für die von dir erstellten benutzerdefinierten Profile festlegen.

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 1
1

Der Befehl wird mit dem Profil prod-kubernetes ausgeführt, das standardmäßig aktiviert ist

4.9 Benutzerdefinierte Quellen erstellen

Problem

Du möchtest die Konfigurationsparameter aus einer anderen Quelle laden, anstatt aus der Datei application.properties.

Lösung

Quarkus nutzt die Eclipse MicroProfile Configuration-Spezifikation, um die gesamte Logik der Konfiguration zu implementieren. Die Spezifikation bietet dieo⁠r⁠g⁠.⁠e⁠c⁠l⁠i⁠p⁠s⁠e⁠.⁠m⁠i⁠c⁠r⁠o⁠p⁠r⁠o⁠f⁠i⁠l⁠e​.⁠c⁠o⁠n⁠f⁠i⁠g⁠.⁠s⁠p⁠i⁠.⁠C⁠o⁠n⁠f⁠i⁠g⁠S⁠o⁠u⁠r⁠c⁠eJava 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() { 1
        prop.put("greeting.color", "red");
    }

    @Override
    public int getOrdinal() { 2
        return 500;
    }

    @Override
    public Map<String, String> getProperties() { 3
        return prop;
    }

    @Override
    public String getValue(String propertyName) { 4
        return prop.get(propertyName);
    }

    @Override
    public String getName() { 5
        return "MemoryConfigSource";
    }

}
1

Füllt die Karte mit einer Eigenschaft

2

Wird verwendet, um die Wichtigkeit der Werte zu bestimmen; die höchste Ordnungszahl hat Vorrang vor der niedrigeren Ordnungszahl

3

Erhält alle Eigenschaften als Map; in diesem Fall ist es direkt

4

Ermittelt den Wert für eine einzelne Eigenschaft

5

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") 1
String color;

@GET
@Path("/color")
@Produces(MediaType.TEXT_PLAIN)
public String color() {
    return color;
}
1

Injiziere den Wert der Eigenschaft, die in der InMemoryConfigSource

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

Problem

Du möchtest einen benutzerdefinierten Konverter implementieren.

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) 1
public class PercentageConverter implements Converter<Percentage> { 2

    @Override
    public Percentage convert(String value) {

        String numeric = value.substring(0, value.length() - 1);
        return new Percentage (Double.parseDouble(numeric) / 100);

    }

}
1

Legt die Priorität fest; in diesem speziellen Fall kann sie optional sein

2

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

Problem

Du willst vermeiden, dass du das gemeinsame Präfix einer Konfigurationseigenschaft immer wieder neu setzt.

Lösung

Du kannst gemeinsame Eigenschaften (mit demselben Präfix) mit der Anmerkung @⁠i⁠o​.⁠q⁠u⁠a⁠r⁠k⁠u⁠s⁠.⁠a⁠r⁠c⁠.⁠c⁠o⁠n⁠f⁠i⁠g⁠.⁠C⁠o⁠n⁠f⁠i⁠g⁠P⁠r⁠o⁠p⁠e⁠r⁠t⁠i⁠e⁠s 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") 1
public class GreetingConfiguration {

    public String message; 2
    public String suffix = "!"; 3
}
1

Setzt dies als Konfigurations-POJO mit einem gemeinsamen Präfix

2

Karten der greeting.message Eigenschaft

3

Der 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 1
GreetingConfiguration greetingConfiguration;

@GET
@Path("/configurations")
@Produces(MediaType.TEXT_PLAIN)
public String helloConfigurations() {
    return greetingConfiguration.message + greetingConfiguration.suffix;
}
1

Die Konfiguration wird mit der CDI @Inject Annotation injiziert

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 @ConfigPropertyannotieren, 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; 1

public static class OutputConfiguration {
    public List<String> recipients;
}
1

Der Name der Unterkategorie ist der Feldname (output)

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

Problem

Du möchtest überprüfen, ob die Konfigurationswerte korrekt sind.

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: j⁠a⁠v⁠a⁠x​.⁠v⁠a⁠l⁠i⁠d⁠a⁠t⁠i⁠o⁠n⁠.⁠c⁠o⁠n⁠s⁠t⁠r⁠a⁠i⁠n⁠t⁠s⁠.⁠M⁠a⁠x und javax.validation.constraints.Min. Öffne org.acme.quickstart.GreetingConfiguration.java und füge Bean Validation Annotations hinzu:

@Min(1) 1
@Max(3) 2
public Integer repeat;
1

Akzeptierter Mindestwert

2

Maximal akzeptierter Wert

Ö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.