Tudo que precisa saber para integrar seu Azure Service Bus a sua Azure Function com Factory Pattern e Typescript
Bem-vindo ao sexto capítulo da nossa série emocionante sobre como integrar Azure Functions com serviços do Azure utilizando os poderosos princípios SOLID! Já exploramos como conectar o Azure Storage, Azure Key Vault e o Azure Web PubSub. Agora, prepare-se para mergulhar no fascinante mundo do Azure Service Bus! 📬
O Que é o Azure Service Bus?
O Azure Service Bus é uma plataforma de mensagens totalmente gerenciada que permite a comunicação entre diferentes partes de um sistema distribuído, como aplicações em nuvem, serviços e dispositivos. Ele oferece uma solução robusta para integrar sistemas e garantir a entrega confiável de mensagens.
Principais Componentes do Azure Service Bus
1. Filas (Queues)
As filas no Azure Service Bus permitem uma comunicação assíncrona entre diferentes partes de uma aplicação. As mensagens são armazenadas em uma fila até que o destinatário esteja pronto para processá-las, garantindo uma entrega ordenada e confiável.
2. Tópicos e Assinaturas (Topics and Subscriptions)
Os tópicos permitem um modelo de publicação e assinatura (pub/sub), onde as mensagens publicadas em um tópico são entregues a várias assinaturas. Cada assinatura pode aplicar filtros para receber apenas as mensagens relevantes, permitindo um roteamento flexível.
3. Regras e Filtros (Rules and Filters)
As assinaturas podem utilizar regras e filtros para definir critérios específicos de roteamento de mensagens. Isso permite uma personalização avançada sobre quais mensagens são entregues a quais assinaturas.
Vantagens do Azure Service Bus
1. Entrega Confiável
O Azure Service Bus garante a entrega de mensagens com durabilidade e tolerância a falhas. Ele armazena mensagens de forma persistente até que sejam processadas com sucesso pelo receptor.
2. Escalabilidade
Com capacidade de escalabilidade horizontal, o Azure Service Bus pode lidar com grandes volumes de mensagens e transações, suportando sistemas de qualquer tamanho.
3. Segurança
O Azure Service Bus integra-se com o Microsoft Entra ID e oferece autenticação robusta e controle de acesso, garantindo que apenas usuários e aplicações autorizadas possam enviar e receber mensagens.
4. Flexibilidade
Com suporte para diferentes padrões de comunicação, como filas, tópicos e assinaturas, o Azure Service Bus pode ser adaptado a uma ampla variedade de cenários e arquiteturas de sistema.
Casos de Uso
1. Integração de Sistemas Heterogêneos
O Azure Service Bus facilita a comunicação entre sistemas desenvolvidos em diferentes linguagens e plataformas, proporcionando uma integração fluida e eficiente.
2. Processamento Assíncrono
Permite o desacoplamento de componentes de uma aplicação, onde as tarefas podem ser enfileiradas e processadas de forma assíncrona, melhorando a eficiência e a resiliência do sistema.
3. Roteamento de Mensagens Complexas
Com tópicos e assinaturas, o Azure Service Bus pode gerenciar cenários complexos de roteamento de mensagens, garantindo que as informações corretas sejam entregues aos destinatários corretos.
O Azure Service Bus é uma ferramenta poderosa para a comunicação e integração de sistemas distribuídos, oferecendo entrega confiável, escalabilidade, segurança e flexibilidade. Seja para integrar sistemas heterogêneos, gerenciar processamento assíncrono ou lidar com roteamento complexo de mensagens, o Azure Service Bus é uma escolha robusta e eficiente para soluções de mensageria na nuvem.
Passo 1: Configuração do Ambiente
Antes de começar, certifique-se de ter as seguintes dependências instaladas:
npm install @azure/identity @azure/service-bus
OBS: Caso precise ver os Passos 1 ao 3 veja o artigo anterior sobre o tema:
Passo 4: Arquitetura com Provedores de Credenciais
Agora, vamos criar uma fábrica para instanciar o ServiceBusClient
usando nosso CredentialProvider
.
import { ServiceBusClient } from "@azure/service-bus";
/**
* Factory for creating instances of ServiceBusClient.
*/
class ServiceBusClientFactory {
private fullyQualifiedNamespace: string;
private credentialProvider: CredentialProvider;
/**
* Creates a new instance of ServiceBusClientFactory.
* @param {string} fullyQualifiedNamespace - The fully qualified namespace of the Azure Service Bus.
* @param {CredentialProvider} credentialProvider - The credential provider to be used.
*/
constructor(fullyQualifiedNamespace: string, credentialProvider: CredentialProvider) {
this.fullyQualifiedNamespace = fullyQualifiedNamespace;
this.credentialProvider = credentialProvider;
}
/**
* Creates an instance of ServiceBusClient.
* @returns {ServiceBusClient} A configured instance of ServiceBusClient.
*/
createServiceBusClient(): ServiceBusClient {
const credential = this.credentialProvider.getCredential();
return new ServiceBusClient(this.fullyQualifiedNamespace, credential);
}
}
Passo 5: Utilizando a Fábrica em uma Azure Function
Vamos integrar tudo isso em uma Azure Function, mostrando cada método de autenticação.
Exemplo 1: Azure Function com Managed Identity Atribuída ao Sistema
import { AzureFunction, Context, HttpRequest } from "@azure/functions";
import { ServiceBusClientFactory } from "./ServiceBusClientFactory";
import { SystemAssignedManagedIdentityCredentialProvider } from "./SystemAssignedManagedIdentityCredentialProvider";
/**
* Azure Function using System-Assigned Managed Identity.
* @param {Context} context - The function context.
* @param {HttpRequest} req - The HTTP request.
* @returns {Promise<void>} A promise that resolves when the function is complete.
*/
const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
const fullyQualifiedNamespace = process.env.AZURE_SERVICEBUS_FULLYQUALIFIEDNAMESPACE;
const credentialProvider = new SystemAssignedManagedIdentityCredentialProvider();
const serviceClientFactory = new ServiceBusClientFactory(fullyQualifiedNamespace, credentialProvider);
const serviceClient = serviceClientFactory.createServiceBusClient();
// Use the serviceClient for operations with Service Bus
context.res = {
body: "Azure Function using System-Assigned Managed Identity for Access to Service Bus"
};
};
export default httpTrigger;
Exemplo 2: Azure Function com Managed Identity Atribuída ao Usuário
import { AzureFunction, Context, HttpRequest } from "@azure/functions";
import { ServiceBusClientFactory } from "./ServiceBusClientFactory";
import { UserAssignedManagedIdentityCredentialProvider } from "./UserAssignedManagedIdentityCredentialProvider";
/**
* Azure Function using User-Assigned Managed Identity.
* @param {Context} context - The function context.
* @param {HttpRequest} req - The HTTP request.
* @returns {Promise<void>} A promise that resolves when the function is complete.
*/
const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
const fullyQualifiedNamespace = process.env.AZURE_SERVICEBUS_FULLYQUALIFIEDNAMESPACE;
const clientId = process.env.AZURE_SERVICEBUS_CLIENTID;
const credentialProvider = new UserAssignedManagedIdentityCredentialProvider(clientId);
const serviceClientFactory = new ServiceBusClientFactory(fullyQualifiedNamespace, credentialProvider);
const serviceClient = serviceClientFactory.createServiceBusClient();
// Use the serviceClient for operations with Service Bus
context.res = {
body: "Azure Function using User-Assigned Managed Identity for Access to Service Bus"
};
};
export default httpTrigger;
Exemplo 3: Azure Function com Service Principal
import { AzureFunction, Context, HttpRequest } from "@azure/functions";
import { ServiceBusClientFactory } from "./ServiceBusClientFactory";
import { ServicePrincipalCredentialProvider } from "./ServicePrincipalCredentialProvider";
/**
* Azure Function using Service Principal.
* @param {Context} context - The function context.
* @param {HttpRequest} req - The HTTP request.
* @returns {Promise<void>} A promise that resolves when the function is complete.
*/
const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
const fullyQualifiedNamespace = process.env.AZURE_SERVICEBUS_FULLYQUALIFIEDNAMESPACE;
const tenantId = process.env.AZURE_SERVICEBUS_TENANTID;
const clientId = process.env.AZURE_SERVICEBUS_CLIENTID;
const clientSecret = process.env.AZURE_SERVICEBUS_CLIENTSECRET;
const credentialProvider = new ServicePrincipalCredentialProvider(tenantId, clientId, clientSecret);
const serviceClientFactory = new ServiceBusClientFactory(fullyQualifiedNamespace, credentialProvider);
const serviceClient = serviceClientFactory.createServiceBusClient();
// Use the serviceClient for operations with Service Bus
context.res = {
body: "Azure Function using Service Principal for Access to Service Bus"
};
};
export default httpTrigger;
Conclusão
🎉 Você aprendeu como configurar Azure Functions para acessar o Azure Service Bus utilizando várias técnicas de autenticação e aplicando os princípios SOLID e Clean Code! Nossa abordagem modular e escalável facilita a manutenção e o aprimoramento do código.