Hallo zusammen! Hier ist er – unser letzter Beitrag in der Quarkus-Reihe! (Sehen Sie sich übrigens unser Webinar an
В
Seit Version 0.17.0,
Es wird davon ausgegangen, dass Sie AMQ Online bereits auf der OpenShift-Plattform bereitgestellt haben (falls nicht, dann siehe
Zunächst erstellen wir eine Quarkus-Anwendung, die ein einfaches Auftragsverarbeitungssystem mit reaktivem Messaging darstellt. Diese Anwendung umfasst einen Bestellgenerator, der in einem festen Intervall Bestellungen an eine Nachrichtenwarteschlange sendet, sowie einen Bestellprozessor, der Nachrichten aus der Warteschlange verarbeitet und im Browser sichtbare Bestätigungen generiert.
Sobald wir die Anwendung erstellt haben, zeigen wir Ihnen, wie Sie die Messaging-Systemkonfiguration in die Anwendung einbetten und AMQ Online verwenden, um die benötigten Ressourcen auf dem System bereitzustellen.
Quarkus-App
Unsere Quarkus-Anwendung läuft auf OpenShift und ist eine modifizierte Version des Programms
Bestellgenerator
Der Generator sendet einfach monoton alle 5 Sekunden wachsende Bestell-IDs an die „Bestellungen“-Adresse.
@ApplicationScoped
public class OrderGenerator {
private int orderId = 1;
@Outgoing("orders")
public Flowable<Integer> generate() {
return Flowable.interval(5, TimeUnit.SECONDS)
.map(tick -> orderId++);
}
}
Auftragsverarbeiter
Der Auftragsabwickler ist sogar noch einfacher, er sendet lediglich eine Bestätigungs-ID an die „Bestätigungs“-Adresse zurück.
@ApplicationScoped
public class OrderProcessor {
@Incoming("orders")
@Outgoing("confirmations")
public Integer process(Integer order) {
// Идентификатор подтверждения равен удвоенному идентификатору заказа <img draggable="false" class="emoji" alt=":-)" src="https://s.w.org/images/core/emoji/11.2.0/svg/1f642.svg">
return order * 2;
}
}
Ressourcen zur Konfirmation
Die Bestätigungsressource ist ein HTTP-Endpunkt zum Auflisten der von unserer Anwendung generierten Bestätigungen.
@Path("/confirmations")
public class ConfirmationResource {
@Inject
@Stream("confirmations") Publisher<Integer> orders;
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "hello";
}
@GET
@Path("/stream")
@Produces(MediaType.SERVER_SENT_EVENTS)
public Publisher<Integer> stream() {
return orders;
}
}
Einstellung
Um eine Verbindung zu AMQ Online herzustellen, benötigt unsere Anwendung einige Konfigurationsdaten, nämlich: Quarkus-Connector-Konfiguration, AMQP-Endpunktinformationen und Client-Anmeldeinformationen. Natürlich ist es besser, alle Konfigurationsdaten an einem Ort aufzubewahren, wir werden sie jedoch bewusst trennen, um die möglichen Optionen zur Konfiguration der Quarkus-Anwendung aufzuzeigen.
Anschlüsse
Die Connector-Konfiguration kann zur Kompilierungszeit mithilfe einer Anwendungseigenschaftendatei bereitgestellt werden:
mp.messaging.outgoing.orders.connector=smallrye-amqp
mp.messaging.incoming.orders.connector=smallrye-amqp
Der Einfachheit halber verwenden wir nur eine Nachrichtenwarteschlange für die Adresse „Bestellungen“. Und die „Bestätigungs“-Adresse in unserer Anwendung verwendet eine Warteschlange im Speicher.
AMQP-Endpunkt
Zur Kompilierungszeit sind der Hostname und die Portnummer für den AMQP-Endpunkt unbekannt und müssen daher eingefügt werden. Der Endpunkt kann in der von AMQ Online erstellten Konfigurationszuordnung festgelegt werden, daher definieren wir ihn über Umgebungsvariablen im Anwendungsmanifest:
spec:
template:
spec:
containers:
- env:
- name: AMQP_HOST
valueFrom:
configMapKeyRef:
name: quarkus-config
key: service.host
- name: AMQP_PORT
valueFrom:
configMapKeyRef:
name: quarkus-config
key: service.port.amqp
Referenzen
Das Dienstkonto-Token kann zur Authentifizierung unserer Anwendung bei OpenShift verwendet werden. Dazu müssen Sie zunächst eine benutzerdefinierte ConfigSource erstellen, die das Authentifizierungstoken aus dem Dateisystem des Pods liest:
public class MessagingCredentialsConfigSource implements ConfigSource {
private static final Set<String> propertyNames;
static {
propertyNames = new HashSet<>();
propertyNames.add("amqp-username");
propertyNames.add("amqp-password");
}
@Override
public Set<String> getPropertyNames() {
return propertyNames;
}
@Override
public Map<String, String> getProperties() {
try {
Map<String, String> properties = new HashMap<>();
properties.put("amqp-username", "@@serviceaccount@@");
properties.put("amqp-password", readTokenFromFile());
return properties;
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
@Override
public String getValue(String key) {
if ("amqp-username".equals(key)) {
return "@@serviceaccount@@";
}
if ("amqp-password".equals(key)) {
try {
return readTokenFromFile();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
return null;
}
@Override
public String getName() {
return "messaging-credentials-config";
}
private static String readTokenFromFile() throws IOException {
return new String(Files.readAllBytes(Paths.get("/var/run/secrets/kubernetes.io/serviceaccount/token")), StandardCharsets.UTF_8);
}
}
Erstellen Sie die Anwendung und stellen Sie sie bereit
Da die Anwendung in eine ausführbare Datei kompiliert werden muss, ist eine virtuelle GraalVM-Maschine erforderlich. Einzelheiten zum Einrichten einer Umgebung hierfür finden Sie in den entsprechenden Anweisungen in
Anschließend müssen Sie den dort gegebenen Anweisungen folgen und die Quelle herunterladen sowie unsere Anwendung erstellen und bereitstellen:
git clone https://github.com/EnMasseProject/enmasse-example-clients
cd enmasse-example-clients/quarkus-example-client
oc new-project myapp
mvn -Pnative -Dfabric8.mode=openshift -Dfabric8.build.strategy=docker package fabric8:build fabric8:resource fabric8:apply
Nach diesen Befehlen wird die Anwendung bereitgestellt, aber erst gestartet, wenn wir die benötigten Messaging-Ressourcen in AMQ Online konfiguriert haben.
Einrichten des Nachrichtensystems
Jetzt müssen wir nur noch die Ressourcen festlegen, die unsere Anwendung im Nachrichtensystem benötigt. Dazu müssen Sie Folgendes erstellen: 1) einen Adressraum zum Initialisieren des Messaging-System-Endpunkts; 2) Adresse zum Konfigurieren der Adressen, die wir in der Anwendung verwenden; 3) Senden Sie dem Benutzer eine Nachricht, um die Anmeldeinformationen des Clients festzulegen.
Adressraum
Ein AddressSpace-Objekt in AMQ Online ist eine Gruppe von Adressen, die Verbindungsendpunkte sowie Authentifizierungs- und Autorisierungsrichtlinien gemeinsam nutzen. Wenn Sie einen Adressraum erstellen, können Sie angeben, wie Messaging-Endpunkte verfügbar gemacht werden:
apiVersion: enmasse.io/v1beta1
kind: AddressSpace
metadata:
name: quarkus-example
spec:
type: brokered
plan: brokered-single-broker
endpoints:
- name: messaging
service: messaging
exports:
- name: quarkus-config
kind: configmap
Адреса
Adressen werden zum Senden und Empfangen von Nachrichten verwendet. Jede Adresse hat einen Typ, der ihre Semantik bestimmt, sowie einen Plan, der die Anzahl der zu reservierenden Ressourcen angibt. Die Adresse kann beispielsweise so ermittelt werden:
apiVersion: enmasse.io/v1beta1
kind: Address
metadata:
name: quarkus-example.orders
spec:
address: orders
type: queue
plan: brokered-queue
Nachrichtenbenutzer
Um sicherzustellen, dass nur vertrauenswürdige Anwendungen Nachrichten an Ihre Adressen senden und empfangen können, müssen Sie im Nachrichtensystem einen Benutzer erstellen. Für Anwendungen, die in einem Cluster ausgeführt werden, können Clients mithilfe eines OpenShift-Dienstkontos authentifiziert werden. Der Benutzer „serviceaccount“ kann beispielsweise so definiert werden:
apiVersion: user.enmasse.io/v1beta1
kind: MessagingUser
metadata:
name: quarkus-example.app
spec:
username: system:serviceaccount:myapp:default
authentication:
type: serviceaccount
authorization:
- operations: ["send", "recv"]
addresses: ["orders"]
Berechtigungen zum Konfigurieren der Anwendung
Damit AMQ Online die Konfigurationszuordnung erstellen kann, die wir zum Einbetten der AMQP-Endpunktinformationen verwendet haben, müssen Role und RoleBinding festgelegt werden:
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: quarkus-config
spec:
rules:
- apiGroups: [ "" ]
resources: [ "configmaps" ]
verbs: [ "create" ]
- apiGroups: [ "" ]
resources: [ "configmaps" ]
resourceNames: [ "quarkus-config" ]
verbs: [ "get", "update", "patch" ]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: quarkus-config
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: quarkus-config
subjects:
- kind: ServiceAccount
name: address-space-controller
namespace: amq-online-infra
So wenden Sie Konfigurationen an
Sie können die Konfiguration des Nachrichtensystems wie folgt anwenden:
cd enmasse-example-clients/quarkus-example-client
oc project myapp
oc apply -f src/main/resources/k8s/addressspace
oc apply -f src/main/resources/k8s/address
Anwendungsüberprüfung
Um sicherzustellen, dass die Anwendung gestartet ist, prüfen wir zunächst, ob die entsprechenden Adressen erstellt wurden und aktiv sind:
until [[ `oc get address quarkus-example.prices -o jsonpath='{.status.phase}'` == "Active" ]]; do echo "Not yet ready"; sleep 5; done
Dann überprüfen wir die URL der Anwendungsroute (öffnen Sie einfach diese Adresse im Browser):
echo "http://$(oc get route quarkus-example-client -o jsonpath='{.spec.host}')/prices.html"
Der Browser sollte anzeigen, dass Tickets regelmäßig aktualisiert werden, wenn Nachrichten von AMQ Online gesendet und empfangen werden.
Zusammenfassend
Deshalb haben wir eine Quarkus-Anwendung geschrieben, die AMQP für die Nachrichtenübermittlung verwendet, die Anwendung für die Ausführung auf der Red Hat OpenShift-Plattform konfiguriert und ihre Konfiguration basierend auf der AMQ Online-Konfiguration implementiert. Anschließend haben wir die Manifeste erstellt, die zum Initialisieren des Nachrichtensystems für unsere Anwendung erforderlich sind.
Damit ist die Serie über Quarkus abgeschlossen, aber es liegen noch viele neue und interessante Dinge vor uns, bleiben Sie dran!
Source: habr.com