Olá a todos! Aqui está – nosso último post da série Quarkus! (A propósito, assista ao nosso webinar
В
Desde a versão 0.17.0,
Supõe-se que você já tenha implantado o AMQ Online na plataforma OpenShift (caso contrário, consulte
Para começar, criaremos um aplicativo Quarkus que será um sistema simples de processamento de pedidos usando mensagens reativas. Esta aplicação incluirá um gerador de pedidos que envia pedidos para uma fila de mensagens em um intervalo fixo, bem como um processador de pedidos que processará as mensagens da fila e gerará confirmações visíveis no navegador.
Depois de criarmos o aplicativo, mostraremos como incorporar a configuração do sistema de mensagens no aplicativo e usar o AMQ Online para provisionar os recursos necessários no sistema.
Aplicativo Quarkus
Nosso aplicativo Quarkus roda em OpenShift e é uma versão modificada do programa
Gerador de pedidos
O gerador simplesmente envia monotonicamente IDs de pedidos crescentes para o endereço de “pedidos” a cada 5 segundos.
@ApplicationScoped
public class OrderGenerator {
private int orderId = 1;
@Outgoing("orders")
public Flowable<Integer> generate() {
return Flowable.interval(5, TimeUnit.SECONDS)
.map(tick -> orderId++);
}
}
Processador de pedidos
O manipulador de pedidos é ainda mais simples, apenas retorna um ID de confirmação para o endereço de “confirmações”.
@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;
}
}
Recursos de confirmação
O recurso de confirmação é um endpoint HTTP para listar as confirmações geradas pela nossa aplicação.
@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;
}
}
Fixação
Para se conectar ao AMQ Online, nosso aplicativo precisará de alguns dados de configuração, a saber: configuração do conector Quarkus, informações do endpoint AMQP e credenciais do cliente. É claro que é melhor manter todos os dados de configuração em um só lugar, mas iremos separá-los deliberadamente para mostrar as opções possíveis de configuração do aplicativo Quarkus.
Conectores
A configuração do conector pode ser fornecida em tempo de compilação usando um arquivo de propriedades do aplicativo:
mp.messaging.outgoing.orders.connector=smallrye-amqp
mp.messaging.incoming.orders.connector=smallrye-amqp
Para simplificar, usaremos apenas uma fila de mensagens para o endereço de “pedidos”. E o endereço de “confirmações” em nossa aplicação utilizará uma fila na memória.
Ponto de extremidade AMQP
Em tempo de compilação, o nome do host e o número da porta do endpoint AMQP são desconhecidos, portanto, devem ser injetados. O endpoint pode ser definido no configmap criado pelo AMQ Online, portanto iremos defini-lo através de variáveis de ambiente no manifesto da aplicação:
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
Credenciais
O token da conta de serviço pode ser usado para autenticar nosso aplicativo no OpenShift. Para fazer isso, primeiro você deve criar um ConfigSource personalizado que lerá o token de autenticação do sistema de arquivos do pod:
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);
}
}
Construir e implantar o aplicativo
Como a aplicação deve ser compilada em um arquivo executável, é necessária uma máquina virtual GraalVM. Para obter detalhes sobre como configurar um ambiente para isso, consulte as instruções correspondentes em
Então, seguindo as instruções ali fornecidas, você precisa baixar o código-fonte, construir e implantar nosso aplicativo:
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
Após esses comandos, o aplicativo será implantado, mas não será iniciado até que configuremos os recursos de mensagens necessários no AMQ Online.
Configurando o sistema de mensagens
Agora só falta definir os recursos que nossa aplicação necessita no sistema de mensagens. Para fazer isso, é necessário criar: 1) um espaço de endereço para inicializar o terminal do sistema de mensagens; 2) endereço para configurar os endereços que utilizamos na aplicação; 3) Mensagens ao usuário para definir credenciais do cliente.
Espaço de endereço
Um objeto AddressSpace no AMQ Online é um grupo de endereços que compartilham pontos de extremidade de conexão e políticas de autenticação e autorização. Ao criar um espaço de endereço, é possível especificar como os terminais do sistema de mensagens serão expostos:
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
Endereço
Os endereços são usados para enviar e receber mensagens. Cada endereço possui um tipo, que determina sua semântica, bem como um plano, que especifica a quantidade de recursos a serem reservados. O endereço pode ser determinado, por exemplo, assim:
apiVersion: enmasse.io/v1beta1
kind: Address
metadata:
name: quarkus-example.orders
spec:
address: orders
type: queue
plan: brokered-queue
Usuário de mensagens
Para garantir que apenas aplicativos confiáveis possam enviar e receber mensagens em seus endereços, você deve criar um usuário no sistema de mensagens. Para aplicativos executados em um cluster, os clientes podem ser autenticados usando uma conta de serviço OpenShift. O usuário "serviceaccount" pode ser definido, por exemplo, assim:
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"]
Permissões para configurar o aplicativo
Para que o AMQ Online crie o configmap que usamos para incorporar as informações do endpoint AMQP, Role e RoleBinding devem ser definidos:
---
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
Como aplicar configurações
Você pode aplicar a configuração do sistema de mensagens assim:
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
Verificação de aplicação
Para ter certeza de que a aplicação foi iniciada, primeiro vamos verificar se os endereços correspondentes foram criados e estão ativos:
until [[ `oc get address quarkus-example.prices -o jsonpath='{.status.phase}'` == "Active" ]]; do echo "Not yet ready"; sleep 5; done
Então vamos verificar a URL da rota da aplicação (basta abrir este endereço no navegador):
echo "http://$(oc get route quarkus-example-client -o jsonpath='{.spec.host}')/prices.html"
O navegador deve mostrar que os tickets são atualizados periodicamente à medida que as mensagens são enviadas e recebidas pelo AMQ Online.
Resumindo
Portanto, escrevemos um aplicativo Quarkus que usa AMQP para mensagens, configuramos o aplicativo para ser executado na plataforma Red Hat OpenShift e implementamos sua configuração com base na configuração AMQ Online. Em seguida, criamos os manifestos necessários para inicializar o sistema de mensagens do nosso aplicativo.
Isso conclui a série sobre Quarkus, mas tem muita coisa nova e interessante pela frente, fique ligado!
Fonte: habr.com