Você está na página 1de 393

Computação

sem servidor
do Azure
Livro de receitas Segunda Edição

Receitas para criar e monitorar aplicativos controlados por evento usando


o Azure Functions

www.packt.com
Praveen Kumar Sreeram
Livro de receitas da computação
sem servidor do Azure
Segunda Edição

Receitas para criar e monitorar aplicativos controlados


por evento usando o Azure Functions

Praveen Kumar Sreeram

BIRMINGHAM – MUMBAI
Livro de receitas da computação sem servidor do Azure
Segunda Edição
Copyright © 2018 Packt Publishing

Todos os direitos reservados. Nenhuma parte deste livro pode ser reproduzida,
armazenada em um sistema de recuperação ou transmitida sob qualquer forma
ou por qualquer meio sem a permissão prévia por escrito da editora, exceto no caso
de breves citações incorporadas em artigos críticos ou comentários.

Não se poupou esforços na preparação deste livro para garantir a precisão das
informações apresentadas. No entanto, as informações contidas neste livro são vendidas
sem garantia, expressa ou implícita. O autor, a Packt Publishing e seus revendedores
e distribuidores não serão responsabilizados por quaisquer danos causados ou
supostamente causados de forma direta ou indireta por este livro.

A Packt Publishing empenha-se em fornecer informações de marca registrada sobre


todas as empresas e produtos mencionados neste livro pelo uso adequado de capitais.
No entanto, a Packt Publishing não garante a precisão dessas informações.

Editor de comissionamento: Vijin Boricha


Editor de aquisições: Shrilekha Inani
Editores de desenvolvimento de conteúdo: Nithin George Varghese
Editor técnico: Komal Karne
Editora: Safis Editing
Coordenador de projetos: Drashti Panchal
Revisor: Safis Editing
Indexadores: Mariammal Chettiyar
Gráficos: Tom Scaria
Coordenadora de produção: Aparna Bhagat

Primeira publicação: agosto de 2017


Segunda edição: novembro de 2018

Referência de produção: 1301118

Publicado pela Packt Publishing Ltd.


Livery Place
35 Livery Street
Birmingham B3 2PB, UK.

ISBN 978-1-78961-526-5

www.packtpub.com
Não teria sido possível concluir o livro sem o apoio da minha melhor
metade, minha esposa, Haritha, e do meu lindo anjinho, Rithwika Sreeram
mapt.io

O Mapt é uma biblioteca digital online que lhe oferece acesso total a mais
de 5.000 livros e vídeos, bem como a ferramentas líderes da indústria para
ajudá-lo a planejar seu desenvolvimento pessoal e avançar em sua carreira.
Para obter mais informações, visite nosso site.

Por que se inscrever?


• Gaste menos tempo aprendendo e mais tempo codificando com e-books
e vídeos práticos de mais de 4.000 profissionais da indústria
• Aprenda melhor com planos de habilidade criados especialmente para você
• Receba um e-book ou vídeo gratuito todo mês
• O Mapt é totalmente pesquisável
• Copie e cole, imprima e marque conteúdos

PacktPub.com
Você sabia que a Packt oferece versões e-book de todos os livros publicados,
com arquivos disponíveis em ePub e PDF? Você pode fazer um upgrade para
a versão e-book em www.PacktPub.com e, como cliente de livro impresso, você
tem direito a um desconto na cópia do e-book. Entre em contato conosco pelo
e-mail service@packtpub.com para obter mais detalhes.

Em www.PacktPub.com, você também pode ler uma coleção de artigos técnicos


gratuitamente, inscrever-se em vários boletins informativos grátis e receber
descontos exclusivos e ofertas de livros e e-books da Packt.
Colaboradores

Sobre o autor
Praveen Kumar Sreeram trabalha como arquiteto do Azure, instrutor em uma
MNC líder. Ele tem mais de 14 anos de experiência no campo de desenvolvimento,
análise, design e entrega de aplicativos, incluindo desenvolvimento personalizado para
Web usando ASP.NET e MVC para a criação de aplicativos móveis usando o Xamarin
para domínios, como seguro, telecomunicações e gerenciamento de despesas em fio.
Ele foi reconhecido duas vezes como MVP por um dos principais sites de comunidade
social, CSharpCorner. Ele é um blogueiro ávido que escreve sobre o seu aprendizado
em seu blog chamado Praveen Kumar Sreeram. Seu foco atual é na análise de
problemas de negócios e no fornecimento de soluções técnicas para vários projetos
relacionados ao Microsoft Azure e .NET Core. Sua ID no twitter é @PrawinSreeram.

Primeiramente, gostaria de agradecer à equipe da Packt Publishing,


incluindo Shrilekha Inani, Nithin George Varghese e Komal Karne.

Gostaria de agradecer minha avó, Neelavatamma, meu pai, Kamalakar,


e minha mãe, Seetha, por fazerem parte da minha vida e me darem coragem
o tempo todo.

Gostaria de expressar minha mais profunda gratidão a Bhagyamma


(minha avó), Kamala Kumar (meu tio materno), seus irmãos e ao restante
da família, que têm me apoiado o tempo todo.
Sobre os revisores
Kasam Shaikh, entusiasta do Microsoft Azure, é um profissional experiente com
uma atitude "Poderia ser", com 10 anos de experiência na indústria trabalhando
como arquiteto de nuvem com uma das principais empresas de TI em Mumbai,
Índia. Ele é um arquiteto certificado para o Azure e foi reconhecido como um MVP
por uma comunidade online líder, além de ser palestrante global de IA. Ele foi autor
de livros sobre o Azure Cognitive, Azure Bots e Microsoft Bot Frameworks. Ele lidera
a comunidade do Azure India (AZINDIA), a comunidade online de crescimento mais
rápido de aprendizado do Azure. Ele também é fundador do site Dear Azure.

Em primeiro lugar, gostaria de agradecer a Almighty Allah, minha família


e, especialmente, a minha cara-metade, por me motivarem ao longo de todo
este processo. Sou muito grato a Packt Publishing por acreditar em mim
e por me considerar para esta oportunidade.

Michael Sync (SOE Htike) é um engenheiro sênior que trabalha na Readify na


Austrália. Ele foi um MVP (Microsoft Valuable Professional) por 7 anos. Participou
como palestrante, mentor e ajudante em vários eventos comunitários. Também
é autor e revisor de livros técnicos. Ele publicou dois livros com Manning e revisou
vários livros para diversas editoras. Ele trabalha na indústria de software há mais
de 16 anos.

A Packt está à procura de autores


como você
Se você está interessado em se tornar um autor para a Packt, visite authors.
packtpub.com e candidate-se hoje. Temos trabalhado com milhares de
desenvolvedores e profissionais de tecnologia, assim como você, para ajudá-los
a compartilhar sua visão com a comunidade de tecnologia global. Você pode
fazer uma candidatura geral, candidatar-se para um assunto específico para
o qual estamos recrutando um autor ou enviar a sua própria ideia.
Sumário
Prefácioxiii
Capítulo 1: Desenvolver aplicativos de nuvem usando
associações e gatilhos de função 1
Introdução1
Criar uma API Web de back-end usando gatilhos HTTP 2
Preparação3
Como fazer isso… 3
Como funciona… 8
Consulte também 8
Persistir detalhes de funcionários usando associações
de saída da tabela de Armazenamento do Azure 8
Preparação9
Como fazer isso... 9
Como funciona... 13
Noções básicas sobre a conexão de armazenamento 14
O que é o serviço de armazenamento de Tabelas do Azure? 15
Chave de partição e chave de linha 15
E mais... 15
Salvar as imagens de perfil em Filas usando Associações
de saída de fila 15
Preparação16
Como fazer isso… 16
Como funciona… 18
Armazenar a imagem no Armazenamento de Blobs do Azure 18
Preparação18
Como fazer isso... 18
Como funciona... 20
E mais... 21

[i]
Sumário

Capítulo 2: Trabalhar com notificações usando os serviços


SendGrid e Twilio 23
Introdução23
Enviar uma notificação por email ao administrador de um site
usando o serviço SendGrid 24
Preparação24
Criar uma conta do SendGrid 24
Gerar uma chave de API a partir do portal SendGrid 27
Configurar a chave de API do SendGrid com o aplicativo de Função do Azure 28
Como fazer isso... 28
Criar associação de Fila de Armazenamento para o Gatilho HTTP 29
Criar Gatilho de Fila para processar a mensagem do Gatilho HTTP 30
Criar associação de saída do SendGrid para o Gatilho de Fila 31
Como funciona... 33
E mais 34
Enviar uma notificação por email dinamicamente ao usuário final 34
Preparação34
Como fazer isso... 35
Aceitar o novo Parâmetro de email na função RegisterUser 35
Recuperar as informações de UserProfile no gatilho de SendNotifications 36
Como funciona... 37
E mais... 38
Implementar log de email no Armazenamento de Blobs do Azure 39
Como fazer isso... 39
Como funciona... 41
Modificar o conteúdo do email para incluir um anexo 41
Preparação42
Como fazer isso... 42
Personalizar o nome do arquivo de log usando a interface IBinder 42
Adicionar um anexo ao email 43
Enviar uma notificação por SMS ao usuário final usando o serviço Twilio 44
Preparação45
Como fazer isso... 47
Como funciona... 49
Capítulo 3: Integração perfeita do Azure Functions
com os Serviços do Azure 51
Introdução 51
Usar os Serviços Cognitivos para localizar rostos em imagens 52
Preparação52
Criar uma nova conta da API da Pesquisa Visual Computacional 52
Definir as configurações do aplicativo 53

[ ii ]
Sumário

Como fazer isso... 53


Como funciona... 60
E mais... 60
Interações do Banco de dados SQL do Azure usando o Azure Functions 61
Preparação61
Como fazer isso... 63
Como funciona... 66
Monitorar Tweets com Aplicativos Lógicos e notificar quando
um usuário popular tweetar 66
Preparação67
Como fazer isso... 67
Criar um novo Aplicativo Lógico 67
Criar o Aplicativo Lógico com conectores do Twitter e do Gmail 69
Testar a funcionalidade do Aplicativo Lógico 73
Como funciona... 74
Integrar Aplicativos Lógicos com funções sem servidor 74
Como fazer isso... 75
E mais... 79
Consulte também 80
Auditar dados do Cosmos DB usando gatilhos de feed de alterações 80
Preparação80
Criar uma nova conta do Cosmos DB 81
Criar uma nova coleção do Cosmos DB 81
Como fazer isso... 82
Como funciona... 86
E mais... 86
Capítulo 4: Noções básicas sobre a experiência integrada
de desenvolvedor de Ferramentas do Visual Studio 87
Introdução87
Criação de um aplicativo de função usando o Visual Studio 2017 88
Preparação88
Como fazer isso... 90
Como funciona... 92
E mais... 92
Depuração de C# do Azure Functions em um ambiente local
de preparação usando o Visual Studio 2017 92
Preparação93
Como fazer isso... 93
Como funciona... 97
E mais... 97

[ iii ]
Sumário

Conexão à nuvem de armazenamento do Azure a partir


do ambiente local do Visual Studio 98
Preparação98
Como fazer isso... 98
Como funciona... 102
E mais... 102
Implantação do aplicativo Azure Functions para a Nuvem do Azure
usando o Visual Studio 103
Como fazer isso... 103
E mais... 107
Depuração de um C# do Azure Functions ao vivo, hospedada
no ambiente de Nuvem do Microsoft Azure, usando o Visual Studio 107
Preparação108
Como fazer isso... 108
Implantação do Azure Functions em um contêiner 111
Preparação112
Criando um ACR 113
Como fazer isso... 114
Criação de uma imagem do Docker para o aplicativo de função 115
Como mover a imagem do Docker para o ACR 116
Criação um novo aplicativo de função com o Docker 118
Como funciona... 119
Capítulo 5: Exploração de ferramentas de testes para
a validação do Azure Functions 121
Introdução121
Testes do Azure Functions 122
Preparação122
Como fazer isso... 123
Testes de gatilhos HTTP usando o Postman 123
Testes de um gatilho de blob usando o Gerenciador de Armazenamento do Microsoft 125
Testes do gatilho de fila usando o portal de gerenciamento do Azure 128
E mais... 131
Testes de um Azure Functions em um ambiente de teste
utilizando slots de implantação 131
Como fazer isso... 132
E mais... 139
Testes de carga do Azure Functions usando o Azure DevOps  139
Preparação140
Como fazer isso... 140
E mais... 143
Consulte também 144

[ iv ]
Sumário

Criação e testes locais do Azure Functions usando ferramentas


da CLI do Azure 144
Preparação144
Como fazer isso... 144
Testes e validação da capacidade de resposta do Azure
Functions usando o Application Insights 147
Preparação148
Como fazer isso... 149
Como funciona... 152
E mais... 152
Desenvolvimento de testes de unidade para o Azure Functions
com gatilhos HTTP 152
Preparação153
Como fazer isso... 154
Capítulo 6: Como monitorar e solucionar problemas de serviços
sem servidor no Azure 157
Introdução 157
Solução de problemas do Azure Functions 158
Como fazer isso... 158
Visualização de logs de aplicativos em tempo real 158
Diagnóstico do aplicativo de função inteiro 160
E mais... 161
Integração do Azure Functions com o Application Insights 163
Preparação163
Como fazer isso... 164
Como funciona... 166
E mais... 166
Monitoramento do Azure Functions 166
Como fazer isso... 166
Como funciona... 168
Envio de detalhes de telemetria personalizados para o Application
Insights Analytics 168
Preparação170
Como fazer isso... 170
Criação de uma função do Application Insights 171
Configuração de chaves de acesso 172
Integração e teste de uma consulta do Application Insights 174
Configuração do relatório métrico derivado personalizado 176
Como funciona... 178
Envio de detalhes de telemetria do aplicativo via e-mail 179
Preparação179
Como fazer isso... 180
[v]
Sumário

Como funciona... 182


E mais... 182
Consulte também 182
Integração de dados de monitoramento do Application Insights
em tempo real com Power BI usando o Azure Functions 182
Preparação183
Como fazer isso... 184
Configuração do Power BI com um painel, um conjunto de dados e o URI de envio por push 184
Criação de um Power BI em tempo real do Azure Application Insights — função C# 190
Como funciona... 193
E mais... 193
Capítulo 7: Desenvolver aplicativos confiáveis sem
servidor usando o Durable Functions 195
Introdução 195
Configurar o Durable Functions no Portal de Gerenciamento do Azure 196
Preparação196
Como fazer isso... 197
E mais... 198
Criar um aplicativo Hello World do Durable Functions 199
Preparação199
Como fazer isso... 199
Criar uma função HttpStart no cliente Orchestrator 200
Criar a função do Orchestrator 202
Criar uma função de atividade 204
Como funciona... 205
E mais... 205
Testar e solucionar problemas do Durable Functions 205
Preparação206
Como fazer isso... 206
Implementar aplicativos confiáveis multi-threaded usando
o Durable Functions 208
Preparação208
Como fazer isso... 208
Criar a função do Orchestrator 209
Criar uma função de atividade GetAllCustomers  210
Criar uma função de atividade CreateBARCodeImagesPerCustomer 211
Como funciona... 213
E mais... 213
Capítulo 8: Importação em massa de dados usando
o Azure Durable Functions e o Cosmos DB 215
Introdução 215
Problema de negócios 216
[ vi ]
Sumário

Maneira sem servidor do Durable de implementar uma importação do Excel 217


Carregar dados de funcionários no Armazenamento de Blobs 217
Como fazer isso... 218
Como funciona... 221
E mais... 222
Criar um gatilho de blob 222
Preparação222
Como fazer isso... 226
E mais... 226
Criar o Orquestrador do Durable e acioná-lo para cada
importação do Excel 227
Como fazer isso... 227
Como funciona... 230
E mais... 230
Ler dados do Excel usando funções de atividade 231
Preparação231
Como fazer isso... 232
Ler dados do Armazenamento de Blob 232
Ler dados do Excel do fluxo 233
Criar a função de atividade 234
E mais... 236
Escalar automaticamente a taxa de transferência do Cosmos DB 237
Preparação237
Como fazer isso... 239
E mais... 241
Inserir dados em massa no Cosmos DB 241
Como fazer isso... 241
E mais... 242
Capítulo 9: Implementação de práticas recomendadas para
o Azure Functions 243
Adição de várias mensagens a uma fila usando a função
IAsyncCollector244
Preparação244
Como fazer isso... 245
Como funciona... 247
E mais... 247
Implementação de aplicativos de defesa usando o Azure Functions
e gatilhos de fila 247
Preparação248
Como fazer isso... 248
CreateQueueMessage – aplicativo de console C# 248

[ vii ]
Sumário

Desenvolvimento do Azure Function – gatilho de fila 249


Execução de testes usando o aplicativo de console 250
Como funciona... 251
E mais... 251
Manipulação de ingresso massivo usando Hubs de Eventos para IoT
e outros cenários semelhantes 252
Preparação252
Como fazer isso... 252
Como criar um gatilho de hub de eventos do Azure Function  252
Desenvolvimento de um aplicativo de console que simula dados da IoT  253
Como evitar partidas a frio ao aquecer o aplicativo em intervalos
regulares 256
Preparação256
Como fazer isso... 257
Como criar um gatilho HTTP 257
Como criar um gatilho de timer 257
E mais... 258
Consulte também 258
Como habilitar a autorização para aplicativos de função 258
Preparação258
Como fazer isso... 259
Como funciona... 260
E mais... 260
Controle de acesso ao Azure Functions usando teclas de função 260
Como fazer isso... 261
Como configurar a tecla de função para cada aplicativo 261
Configuração de uma tecla host para todas as funções em um único aplicativo de função 262
E mais... 264
Como proteger o Azure Functions usando o Azure Active Directory 264
Preparação265
Como fazer isso... 265
Configuração do Azure AD para o aplicativo de função 265
Como registrar o aplicativo cliente no Azure AD 266
Como conceder ao aplicativo cliente acesso ao aplicativo de back-end  269
Como testar a funcionalidade de autenticação usando um token JWT 269
Configuração da limitação do Azure Functions usando
o Gerenciamento de API 271
Preparação272
Como fazer isso... 273
Como integrar Azure Functions ao Gerenciamento de API 273
Configuração da limitação de solicitações usando políticas de entrada 276
Como testar a configuração de política de entrada de limite de taxa 278
Como funciona... 279

[ viii ]
Sumário

Como acessar com segurança o Banco de Dados SQL


do Azure Functions usando Identidade de Serviço Gerenciada 280
Preparação280
Como fazer isso... 281
Criação de um aplicativo de função usando o Visual Studio 2017 com
o tempo de execução V1 281
Como criar um SQL Server lógico e um Banco de Dados SQL 284
Como habilitar a identidade de serviço gerenciada 284
E mais... 287
Consulte também 287
Código compartilhado no Azure Functions usando bibliotecas de classe 287
Como fazer isso... 288
Como funciona... 290
E mais... 291
Uso de classes fortemente tipadas no Azure Functions 291
Preparação291
Como fazer isso... 292
Como funciona... 294
E mais... 294
Capítulo 10: Configuração de aplicativos sem servidor
no ambiente de produção 295
Introdução 295
Implantar o Azure Functions usando Run From Package 296
Preparação297
Como fazer isso... 298
Como funciona... 299
E mais... 299
Implantar o Azure Functions usando modelos ARM 299
Preparação299
Como fazer isso... 300
E mais... 303
Configurar o domínio personalizado para o Azure Functions 303
Preparação304
Como fazer isso... 304
Configuração do aplicativo de função com um domínio existente 306
Técnicas para acessar Configurações do Aplicativo 308
Preparação308
Como fazer isso... 308
Acesso a Configurações do Aplicativo e cadeias de conexão no código do Azure Function 308
Configuração do aplicativo – expressões de associação  311

[ ix ]
Sumário

Criar e gerar especificações de API abertas usando o Swagger 311


Preparação312
Como fazer isso... 312
Quebrar APIs grandes em pequenos subconjuntos de APIs
usando proxies 316
Preparação316
Como fazer isso... 317
Criação de microsserviços 318
Criação dos proxies de gateway 318
Teste das URLs de proxy 321
E mais... 321
Consulte também 322
Mover itens de configuração de um ambiente para outro usando recursos 322
Preparação323
Como fazer isso... 324
Capítulo 11: Como implementar e implantar a integração
contínua usando o Azure DevOps 329
Introdução329
Pré-requisitos 330
Integração contínua – criar uma definição de build 331
Preparação332
Como fazer isso... 333
Como funciona... 337
E mais... 338
Integração contínua – enfileirar um build e acioná-lo manualmente 338
Preparação338
Como fazer isso... 339
Configurar e acionar um build automatizado 341
Como fazer isso... 342
Como funciona... 344
E mais... 344
Integração contínua – executar casos de teste de unidade no pipeline 345
Como fazer isso… 346
E mais... 348
Criar uma definição da versão 348
Preparação349
Como fazer isso... 350

[x]
Sumário

Como funciona... 358


E mais... 358
Consulte também 359
Acionar a versão automaticamente 360
Preparação360
Como fazer isso... 360
Como funciona... 362
E mais... 362
Outros livros que você pode gostar 363

[ xi ]
Prefácio

Prefácio
A computação sem servidor é a abstração do gerenciamento de infraestrutura e permite
que os desenvolvedores aumentem o foco na lógica de negócios para que possam oferecer
mais recursos e inovação por ciclo. Ao criar aplicativos sem servidor, você não precisa
investir tempo em provisionamento ou gerenciamento de infraestrutura (por exemplo,
criação de servidores, instalação de atualizações, aplicação de patch do sistema operacional,
gerenciamento de como o aplicativo será escalado). Em vez disso, você usa um conjunto
de serviços de nuvem totalmente gerenciados e altamente escaláveis que cuidam dessa
parte do trabalho.

Os benefícios da computação sem servidor abrangem toda a organização e todo o ciclo


de desenvolvimento:

• Para o desenvolvedor, ela representa o foco total no valor. A criação de


aplicativos sem servidor aumenta a capacidade individual de contribuir
com mais eficácia para o centro do negócio.
• Para a equipe de desenvolvimento, ela significa tempo mais rápido de
lançamento no mercado. Uma abordagem sem servidor agiliza a agregação
de mais valor por ciclo de desenvolvimento.
• Para a organização, ela é um facilitador da inovação proveniente de uma base
sólida. Graças à combinação de capacidade liberada e serviços disruptivos, toda
a organização pode atuar nos primeiros sinais para desenvolver ou diversificar
seu modelo de negócios e cumprir sua agenda de inovação.

Ao falar sobre aplicativos sem servidor, podemos identificar alguns padrões de aplicativos
que valem a pena ser mencionados aqui. Enquanto cada um deles compartilha os benefícios
mencionados acima, eles também têm características específicas e benefícios adicionais que
os tornam únicos e uma opção melhor para determinados cenários. Aqui estão os padrões
de aplicativos sem servidor que podemos observar:

• Aplicativos Web, que hospedam o lado do cliente e back-end em um serviço


totalmente gerenciado que lida com os requisitos de escala automática, segurança
e conformidade, com Serviço de Aplicativo.

[ xiii ]
Prefácio

• Aplicativos direcionados a eventos que usam funções sem servidor, aproveitando


o modelo de programação exclusivo (com base em gatilhos para responder a
eventos e associações para integrar outros serviços) e um modelo de faturamento
de pagamento por execução, com Azure Functions.
• Fluxos de trabalho de código baixo para uma orquestração fácil e rápida de
tarefas combinadas que resolvem um problema de negócios (geralmente
integrando serviços diferentes, tanto na nuvem quanto na infraestrutura local,
para trabalhar em conjunto) sem realmente codificar essas integrações, nem
programar novas APIs ou especificações, com Aplicativos Lógicos.
• Contêineres sem servidor, o que leva os contêineres que você tiver a uma
orquestração de Kubernetes totalmente gerenciada com o Serviço de Kubernetes
do Azure, que pode impulsionar o escalonamento com nós virtuais e Instâncias
de Contêiner do Azure quando o volume de workload for escalado de forma
repentina ou acelerada.

A Microsoft fornece uma solução para a execução fácil de pequenos segmentos de código
na nuvem com o Azure Functions. O Azure Functions fornece soluções para processamento
de dados, integração de sistemas e criação de APIs e microsserviços simples.

O livro começa com receitas de nível intermediário em computação sem servidor,


juntamente com alguns casos de uso sobre os benefícios e os principais recursos do Azure
Functions. Em seguida, exploraremos os principais aspectos do Azure Functions, como os
serviços que ele oferece, como você pode desenvolver e gravar Azure Functions e como
monitorar e solucionar os problemas apresentados.

Prosseguindo, você receberá receitas práticas sobre como integrar o DevOps com o Azure
Functions e como fornecer implantação contínua com o Azure DevOps (anteriormente
Visual Studio Team Services). O livro também fornece etapas e tutoriais práticos com base
em casos de uso sem servidor do mundo real para guiá-lo pela configuração e instalação
de ambientes sem servidor com facilidade. Por último, você verá como gerenciar o Azure
Functions, proporcionando segurança e conformidade de nível empresarial para sua
arquitetura de código sem servidor.

Você também aprenderá como criar rapidamente aplicativos que são confiáveis
e duráveis usando Durable Functions, com um exemplo de caso de uso em tempo
real muito comum.

No fim deste livro, você terá todas as habilidades necessárias para trabalhar com
arquiteturas de código sem servidor, fornecendo entrega contínua aos seus usuários.

A quem este livro se destina


Se você for um administrador de nuvem, arquiteto ou desenvolvedor que deseja
criar sistemas escaláveis e implantar aplicativos sem servidor com o Azure Functions,
o Livro de receitas da computação sem servidor do Azure é para você.

[ xiv ]
Prefácio

Tópicos abordados
Capítulo 1, Desenvolver aplicativos de nuvem usando associações e gatilhos de função, apresenta
como o tempo de execução do Azure Functions fornece modelos que podem ser usados
para integrar rapidamente diferentes serviços do Azure para as necessidades de seus
aplicativos. Ele reduz todo o código de conexão para que você possa se concentrar apenas
na lógica do aplicativo. Neste capítulo, você aprenderá como criar APIs e associações
da Web relacionadas aos Serviços de Armazenamento do Azure.

Capítulo 2, Trabalhar com notificações usando os serviços SendGrid e Twilio, lida com a forma
como a comunicação é um dos aspectos mais críticos de qualquer requisito de negócios.
Neste capítulo, você aprenderá como é fácil conectar seus requisitos de negócios escritos
no Azure Functions com os serviços de comunicação mais populares, como SendGrid
(para email) e Twilio (para SMS).

Capítulo 3, Integração perfeita do Azure Functions com os Serviços do Azure, discute como o
Azure fornece muitos conectores que você pode aproveitar para integrar seus aplicativos
de negócios com outros sistemas com muita facilidade. Neste capítulo, você aprenderá
como integrar o Azure Functions com serviços cognitivos e Aplicativos Lógicos.

Capítulo 4, Noções básicas sobre a experiência integrada de desenvolvedor de Ferramentas


do Visual Studio, ensina como desenvolver o Azure Functions usando o Visual Studio,
que fornece muitos recursos, como IntelliSense, depuração local e remota e a maioria
dos recursos de desenvolvimento regular.

Capítulo 5, Exploração de ferramentas de teste para a validação do Azure Functions, ajuda você
a entender diferentes ferramentas e processos que ajudam a agilizar os processos de
desenvolvimento e controle de qualidade. Você também aprenderá como criar cargas
usando o teste de carga do Azure DevOps (anteriormente, VSTS) e verá como monitorar
a performance do Azure Functions usando os relatórios fornecidos pelo Application
Insights. Por último, você também aprenderá como configurar alertas que notificam
quando os aplicativos não são responsivos.

Capítulo 6, Como monitorar e solucionar problemas de serviços sem servidor no Azure, ensina
como monitorar continuamente os aplicativos, analisar a performance e revisar os logs
para entender se há problemas que os usuários finais estão enfrentando. O Azure fornece
várias ferramentas para atender a todos os requisitos de monitoramento, desde os
estágios de desenvolvimento e manutenção do aplicativo.

Capítulo 7, Como desenvolver aplicativos confiáveis sem servidor usando Durable Functions,
mostra como desenvolver soluções dinâmicas de longa duração em ambientes sem
servidor usando Durable Functions, que tem recursos avançados que foram lançados
como uma extensão para o Azure Functions.

[ xv ]
Prefácio

Capítulo 8, Importação em massa de dados usando o Azure Durable Functions e o Cosmos DB,
ensina como aproveitar o Azure Durable Functions para ler e importar os dados do
armazenamento de Blobs e despejar os dados no Cosmos DB.

Capítulo 9, Implementação de práticas recomendadas para Azure Functions, ensina algumas das
práticas recomendadas que você deve seguir para melhorar a performance e a segurança
enquanto trabalha no Azure Functions.

Capítulo 10, Configuração de aplicativos sem servidor no ambiente de produção, demonstra


como implantar um aplicativo de função de maneira eficiente e copiar/mover as
configurações de maneira mais inteligente para evitar erros humanos. Você também
aprenderá como configurar um domínio personalizado que poderá compartilhar com
seus clientes ou usuários finais no lugar do domínio padrão que é criado como parte
do provisionamento do aplicativo de função.

Capítulo 11, Como implementar e implantar a integração contínua usando o Azure DevOps,
ajuda você a aprender como implementar a integração e entrega contínua do seu
código do Azure Functions com a ajuda do Visual Studio e do Azure DevOps.

Aproveite ao máximo este livro


O conhecimento prévio e a experiência prática com os serviços principais
do Microsoft Azure são necessários.

Download dos arquivos de exemplo de


código
Você pode fazer download dos arquivos de exemplo de código para este livro em sua
conta em http://www.packtpub.com. Se comprou este livro em outro lugar, você
pode visitar http://www.packtpub.com/support e registrar-se para ter os arquivos
enviados por email diretamente para você.

Você pode fazer download dos arquivos de código seguindo as seguintes etapas:

1. Faça logon ou registre-se em http://www.packtpub.com.


2. Selecione a aba SUPPORT.
3. Clique em Downloads de código e Errata.
4. Digite o nome do livro na caixa de Pesquisa e siga as instruções na tela.

[ xvi ]
Prefácio

Assim que o arquivo é baixado, certifique-se de descompactar ou extrair a pasta usando


a versão mais recente do:

• WinRAR / 7-Zip para Windows


• Zipeg / iZip / UnRarX para Mac
• 7-zip / PeaZip para Linux

O pacote de código para o livro também está hospedado no GitHub em


https://github.com/PacktPublishing/Azure-Serverless-Computing-
Cookbook-Second-Edition. Também temos outros pacotes de código em
nosso rico catálogo de manuais e vídeos disponíveis em https://github.com/
PacktPublishing/. Dê uma olhada neles!

Download dos arquivos EPUB/mobi


e exemplo de código
Uma versão EPUB e mobi deste livro está disponível gratuitamente no GitHub.

Download das imagens coloridas


Também fornecemos a você um arquivo de PDF com as imagens coloridas das capturas
de tela/diagramas utilizados neste livro. Você pode fazer download deles aqui:
https://www.packtpub.com/sites/default/files/downloads/9781789615265_
ColorImages.pdf.

Convenções usadas
Existem várias convenções de texto usadas ao longo de todo este livro.

CodeInText: indica palavras de código em texto, nomes de tabela de banco de dados,


nomes de pastas e arquivos, extensões de arquivo, nomes de caminhos, URLs fictícios,
entrada do usuário e usuários do Twitter. Aqui está um exemplo: "Monte o arquivo
de imagem de disco WebStorm-10*.dmg baixado como outro disco em seu sistema".

Um bloco de código é definido da seguinte forma:


using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;

[ xvii ]
Prefácio

Quando desejamos chamar a atenção para uma parte específica de um bloco de código,
as linhas ou itens relevantes são definidos em negrito:
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;

Qualquer entrada de linha de comando ou saída é escrita como segue:


docker tag functionsindocker cookbookregistry.azurecr.io/
functionsindocker:v1

Negrito: indica um novo termo, uma palavra importante ou palavras que você vê na tela,
por exemplo, em menus ou caixas de diálogo, também aparece em texto como este. Aqui
está um exemplo: "Durante a instalação, escolha Desenvolvimento do Azure na seção
Workloads.»

Avisos ou notas importantes aparecem desta


forma.

Dicas e truques aparecem desta forma.

Seções
Neste livro, você encontrará vários títulos que aparecem com frequência (Preparação,
Como fazer isso..., Como funciona..., Há mais... e Consulte também).

Para fornecer instruções claras sobre como concluir uma receita, use estas seções
da seguinte forma:

Preparação
Esta seção informa o que esperar na receita e descreve como configurar qualquer
software ou configuração preliminar necessária para a receita.

Como fazer isso…


Esta seção contém as etapas necessárias para seguir a receita.

[ xviii ]
Prefácio

Como funciona…
Esta seção geralmente consiste em uma explicação detalhada do que aconteceu na seção
anterior.

E mais...
Esta seção consiste em informações adicionais sobre a receita para que você possa
adquira mais conhecimento sobre ela.

Consulte também
Esta seção fornece links úteis para outras informações úteis para a receita.

Entre em contato
Os comentários dos nossos leitores são sempre bem-vindos.

Comentários gerais: enviar email para feedback@packtpub.com e mencionar o título


do livro no assunto de sua mensagem. Se você tiver dúvidas sobre qualquer aspecto deste
livro, envie um email para questions@packtpub.com.

Errata: embora tomemos o máximo de cuidado para garantir a precisão de nosso


conteúdo, erros acontecem. Se você encontrou um erro neste livro, ficaríamos gratos
se você nos relatasse. Visite http://www.packtpub.com/submit-errata, selecione
seu livro, clique no link Formulário de envio de errata e insira os detalhes.

Pirataria: se você se deparar com cópias ilegais de nossas obras em qualquer forma
na Internet, ficaríamos gratos se você nos enviasse o endereço do local ou nome do site.
Entre em contato conosco pelo e-mail copyright@packtpub.com com um link para
o material.

Se você está interessado em se tornar um autor: se há um tópico no qual você


tem experiência e está interessado em escrever ou contribuir para um livro, visite
http://authors.packtpub.com.

[ xix ]
Prefácio

Comentários
Por favor, deixe um comentário. Depois de ler e usar este livro, que tal deixar um
comentário sobre o site no qual você o comprou? Potenciais leitores poderão ver e usar
sua opinião imparcial para fazer decisões de compra, a Packt pode entender o que
você acha sobre nossos produtos e nossos autores podem ver seus comentários sobre
seu livro. Obrigado!

Para obter mais informações sobre o Packt, acesse packtpub.com.

[ xx ]
Desenvolver aplicativos
de nuvem usando associações
e gatilhos de função
Neste capítulo, vamos abordar as seguintes receitas:

• Criar uma API Web de back-end usando gatilhos HTTP


• Persistir detalhes de funcionários usando associações de saída da tabela de
Armazenamento do Azure
• Salvar as imagens de perfil em Filas usando Associações de saída de fila
• Armazenar a imagem no Armazenamento de Blobs do Azure

Introdução
Todo aplicativo de software precisa de componentes de back-end que são responsáveis
por cuidar da lógica de negócios e armazenar os dados em algum tipo de repositório,
como bancos de dados e sistemas de arquivos. Cada um desses componentes de back-
end pode ser desenvolvido usando tecnologias diferentes. A tecnologia sem servidor
do Azure também nos permite desenvolver essas APIs de back-end usando o Azure
Functions.

[1]
Desenvolver aplicativos de nuvem usando associações e gatilhos de função

O Azure Functions fornece muitos modelos prontos para uso que resolvem os problemas
mais comuns, como conectar-se ao armazenamento, criar APIs Web e cortar imagens. Neste
capítulo, aprenderemos a usar esses modelos internos. Além de aprender os conceitos
relacionados à computação sem servidor do Azure, também vamos tentar implementar
uma solução para um problema de domínio básico: a criação de componentes necessários
para qualquer organização gerenciar as informações de funcionários internos.

A seguir, um diagrama simples que ajuda a compreender o que alcançaremos neste


capítulo:

Criar uma API Web de back-end usando


gatilhos HTTP
Usaremos a arquitetura sem servidor do Azure para criar uma API Web usando gatilhos
HTTP. Esses gatilhos HTTP podem ser consumidos por qualquer aplicativo de front-end
que seja capaz de fazer chamadas HTTP.

[2]
Capítulo 1

Preparação
Vamos começar nossa jornada de compreensão da computação sem servidor do Azure
usando o Azure Functions, criando uma API Web de back-end básica que responda
a solicitações HTTP:

• Consulte https://azure.microsoft.com/free/?&wt.mc_id=AID607363_
SEM_8y6Q27AS para criar uma conta gratuita do Azure.
• Visite https://docs.microsoft.com/azure/azure-functions/
functions-create-function-app-portal para entender passo a passo o
processo de criação de um aplicativo de função e https://docs.microsoft.
com/azure/azure-functions/functions-create-first-azure-function
para criar uma função. Ao criar uma função, uma Conta de Armazenamento
também é criada para armazenar todos os arquivos. Lembre-se do nome da
Conta de Armazenamento, pois ela será usada posteriormente nos outros
capítulos.
• Depois de criar o Aplicativo de Função, examine os conceitos básicos de Gatilhos
e Associações que são os conceitos fundamentais de como o Azure Functions
funciona. Eu recomendo que você examine o artigo https://docs.microsoft.
com/azure/azure-functions/functions-triggers-bindings antes de
prosseguir.

Vamos usar o C# como a linguagem de programação em todo


o livro. A maioria das funções é desenvolvida usando o tempo
de execução do Azure Functions V2. No entanto, algumas
receitas ainda não têm suporte no tempo de execução da V2, o
que é mencionado na respectiva receita. Esperamos que, quando
você estiver lendo este livro, a Microsoft já tenha disponibilizado
esses recursos para o tempo de execução da V2 também.

Como fazer isso…


Execute as seguintes etapas:

1. Navegue até a página de listagem do Aplicativo de Função clicando no menu


Aplicativos de Funções, que está disponível no lado esquerdo.
2. Crie uma nova função clicando no ícone +:

[3]
Desenvolver aplicativos de nuvem usando associações e gatilhos de função

3. Você verá a página Azure Functions para .NET – introdução na qual será
solicitado a escolher o tipo de ferramentas que gostaria de usar. Você pode
escolher o que for do seu interesse. Nos primeiros capítulos, usaremos a opção
No Portal na qual é possível criar Funções do Azure com rapidez diretamente
do portal sem nenhuma ferramenta. Posteriormente, nos outros capítulos,
usaremos o Visual Studio e o Azure Functions Core Tools para criar as Funções:

4. Na próxima etapa, selecione Mais modelos e clique em Concluir e exibir


modelos, como mostrado na captura de tela a seguir:

[4]
Capítulo 1

5. Na seção Escolha um modelo abaixo ou acesse o início rápido, escolha Gatilho


HTTP para criar uma nova função de gatilho de HTTP:

[5]
Desenvolver aplicativos de nuvem usando associações e gatilhos de função

6. Forneça um nome significativo. Para este exemplo, usei RegisterUser como


o nome da Função do Azure.
7. No menu suspenso Nível de autorização, escolha a opção Anônimo.
Vamos aprender mais sobre todos os níveis de autorização no Capítulo 9,
Implementar práticas recomendadas para o Azure Functions:

8. Clique no botão Criar para criar a função de gatilho de HTTP.


9. Assim que você criar a função, todos os arquivos de configuração e códigos
necessários serão criados automaticamente e o arquivo run.csx será aberto
para edição do código. Remova o código padrão e substitua-o pelo código
a seguir. Adicionei dois parâmetros (firstname e lastname) que seriam
exibidos na saída quando o Gatilho HTTP fosse acionado:
#r "Newtonsoft.Json"

using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;

public static async Task<IActionResult> Run(


HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a
request.");
string firstname=null,lastname = null;
string requestBody = await new StreamReader(req.Body).
ReadToEndAsync();

dynamic inputJson = JsonConvert.DeserializeObject(requestBody);


firstname = firstname ?? inputJson?.firstname;
lastname = inputJson?.lastname;

return (lastname + firstname) != null


? (ActionResult)new OkObjectResult($"Hello, {firstname + " " +
lastname}")
: new BadRequestObjectResult("Please pass a name on the query" +
"string or in the request body");
}

[6]
Capítulo 1

10. Salve as alterações clicando no botão Salvar disponível logo acima do editor
de código.
11. Vamos tentar testar a função RegisterUser usando o console de Testes.
Clique na guia Testar para abrir o console de Testes:

12. Insira os valores para firstname e lastname na seção Corpo da solicitação:

Selecione POST no menu suspenso Método HTTP.

13. Depois de revisar os parâmetros de entrada, clique no botão Executar disponível


na parte inferior do console de Testes:

[7]
Desenvolver aplicativos de nuvem usando associações e gatilhos de função

14. Se o workload da solicitação de entrada for transmitido corretamente com todos


os parâmetros necessários, você verá um Status 200 OK, e a saída na janela
Saída será conforme mostrado na captura de tela anterior.

Como funciona…
Criamos a primeira Função básica do Azure usando gatilhos HTTP e fizemos
algumas modificações no código padrão. O código apenas aceita os parâmetros
firstname e lastname e imprime o nome do usuário final com uma mensagem
Hello {firstname} {lastname} como resposta. Também aprendemos a testar
a função de gatilho de HTTP diretamente do portal de Gerenciamento do Azure.

Por uma questão de simplicidade, não executei validações


do parâmetro de entrada. Não se esqueça de validar todos
os parâmetros de entrada nos aplicativos em execução no
seu ambiente de produção.

Consulte também
A receita Permitir a autorização para aplicativos de função no Capítulo 9, Implementar práticas
recomendadas para o Azure Functions

Persistir detalhes de funcionários


usando associações de saída da tabela
de Armazenamento do Azure
Na receita anterior, você aprendeu a criar um gatilho de HTTP e aceitar os parâmetros
de entrada. Agora vamos trabalhar em algo interessante, ou seja, onde armazenar
os dados de entrada em um meio persistente. O Azure Functions oferece suporte
ao armazenamento de dados de várias formas. Para este exemplo, armazenaremos
os dados no armazenamento de Tabelas do Azure.

[8]
Capítulo 1

Preparação
Nesta receita, você verá como é fácil integrar um gatilho de HTTP e o serviço de
armazenamento de Tabelas do Azure usando associações de saída. A função de gatilho
de HTTP do Azure recebe os dados de várias fontes e armazena os dados do perfil
do usuário em uma tabela de armazenamento chamada tblUserProfile. Vamos
seguir os pré-requisitos listados abaixo:

• Nesta receita, vamos usar o mesmo gatilho de HTTP que criamos na receita
anterior.
• Vamos usar o Gerenciador de Armazenamento do Azure, que é uma
ferramenta que nos ajuda a trabalhar com os dados armazenados
na conta de Armazenamento do Azure. Faça download dele em
http://storageexplorer.com/.
• Você pode saber mais sobre como se conectar à Conta de Armazenamento
usando o Gerenciador de Armazenamento do Azure em https://docs.
microsoft.com/azure/vs-azure-tools-storage-manage-with-storage-
explorer.

Como fazer isso...


Execute as seguintes etapas:

1. Navegue até a guia Integrar da função de gatilho de HTTP RegisterUser.


2. Clique no botão Nova Saída, selecione Armazenamento de Tabelas do Azure e,
em seguida, clique no botão Selecionar:

[9]
Desenvolver aplicativos de nuvem usando associações e gatilhos de função

3. Você será solicitado a instalar as associações, clique em Instalar, o que levará


alguns minutos. Depois que as associações forem instaladas, escolha as seguintes
configurações das associações de saída do armazenamento de Tabelas do Azure:
°° Nome do parâmetro da tabela: este é o nome do parâmetro que você
usará no método Run da Função do Azure. Para este exemplo, forneça
objUserProfileTable como o valor.
°° Nome da tabela: uma nova tabela no armazenamento de Tabelas do
Azure será criada para persistir os dados. Se a tabela não existir ainda,
o Azure automaticamente criará uma para você! Para este exemplo,
forneça tblUserProfile como o nome da tabela.
°° Conexão da conta de armazenamento: se você não vir a string
de Conexão da conta de armazenamento, clique em nova (conforme
mostrado na captura de tela a seguir) para criar uma nova ou escolher
uma conta de armazenamento existente.
°° As associações de saída do armazenamento de Tabelas do Azure
devem ser conforme mostrado na captura de tela a seguir:

4. Clique em Salvar para salvar as alterações.


5. Navegue até o editor de código clicando no nome da função e cole o código
a seguir. Ele aceita a entrada transmitida pelo usuário final e a salva no
Armazenamento de Tabelas:
#r "Newtonsoft.Json"
#r "Microsoft.WindowsAzure.Storage"

using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using Microsoft.WindowsAzure.Storage.Table;

[ 10 ]
Capítulo 1

public static async Task<IActionResult> Run(


HttpRequest req,
CloudTable objUserProfileTable,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a
request.");
string firstname=null,lastname = null;
string requestBody = await new StreamReader(req.Body).
ReadToEndAsync();
dynamic inputJson = JsonConvert.DeserializeObject(requestBody);
firstname = firstname ?? inputJson?.firstname;
lastname = inputJson?.lastname;
UserProfile objUserProfile = new UserProfile(firstname,
lastname);
TableOperation objTblOperationInsert = TableOperation.
Insert(objUserProfile);
await objUserProfileTable.ExecuteAsync(objTblOperationInsert);
return (lastname + firstname) != null
? (ActionResult)new OkObjectResult($"Hello, {firstname + " " +
lastname}")
: new BadRequestObjectResult("Please pass a name on the query" +
"string or in the request body");
}

class UserProfile : TableEntity


{
public UserProfile(string firstName,string lastName)
{
this.PartitionKey = "p1";
this.RowKey = Guid.NewGuid().ToString();
this.FirstName = firstName;
this.LastName = lastName;
}
UserProfile() { }
public string FirstName { get; set; }
public string LastName { get; set; }
}

[ 11 ]
Desenvolver aplicativos de nuvem usando associações e gatilhos de função

6. Vamos executar a função clicando no botão Executar da guia Testar,


transmitindo os parâmetros firstname e lastname no Corpo da
solicitação:

7. Se tudo correr bem, você receberá uma mensagem Status 200 OK na caixa
Saída, conforme mostrado na captura de tela anterior. Vamos navegar até
o Gerenciador de Armazenamento do Azure e visualizar o armazenamento
de tabelas para ver se a tabela denominada tblUserProfile foi criada
com êxito:

[ 12 ]
Capítulo 1

Como funciona...
O Azure Functions nos permite integrar facilmente a outros serviços do Azure apenas
adicionando uma associação de saída ao gatilho. Para este exemplo, integramos o gatilho
de HTTP à associação de tabelas do Armazenamento do Azure e também configuramos
a conta de Armazenamento do Azure fornecendo a string de conexão de armazenamento
e o nome da tabela de Armazenamento do Azure na qual gostaríamos de criar um
registro para cada uma das solicitações HTTP recebidas pelo gatilho de HTTP.

Também adicionamos mais um parâmetro para lidar com o armazenamento de tabelas,


denominado objUserProfileTable, do tipo CloudTable, para o método Run.
Podemos executar todas as operações no armazenamento de Tabelas do Azure usando
objUserProfileTable.

Os parâmetros de entrada não estão validados no exemplo


de código. No entanto, no seu ambiente de produção, é
importante validá-los antes de armazená-los em qualquer
tipo de meio persistente.

Também criamos um objeto UserProfile, que foi preenchido com os valores recebidos
no objeto de solicitação e, em seguida, transmitido a uma operação de tabela.

Você pode saber mais sobre como lidar com operações no serviço
de armazenamento de Tabelas do Azure em https://docs.
microsoft.com/en-us/azure/storage/storage-dotnet-
how-to-use-tables.

[ 13 ]
Desenvolver aplicativos de nuvem usando associações e gatilhos de função

Noções básicas sobre a conexão de


armazenamento
Quando você criar uma nova conexão de armazenamento (consulte a etapa 3 da seção
Como fazer isso... desta receita), novas Configurações de aplicativo serão criadas:

Você pode navegar até as Configurações de aplicativo clicando no menu Configurações


de aplicativo disponível na seção CONFIGURAÇÕES GERAIS da guia Recursos
da plataforma:

[ 14 ]
Capítulo 1

O que é o serviço de armazenamento de Tabelas do


Azure?
O serviço de armazenamento de Tabelas do Azure é um meio persistente de chave-valor
NoSQL para armazenar dados semiestruturados.

Saiba mais sobre ele em https://azure.microsoft.com/


services/storage/tables/.

Chave de partição e chave de linha


A chave primária da tabela do armazenamento de Tabelas do Azure tem duas partes:

• Chave de partição: os registros do armazenamento de Tabelas do Azure são


classificados e organizados em partições. Todo registro localizado em uma
partição terá a mesma chave de partição (p1 no nosso exemplo).
• Chave de linha: um valor exclusivo deve ser atribuído a cada uma das linhas.

E mais...
A seguir, as primeiras linhas do código nesta receita:
#r "Newtonsoft.json"
#r "Microsoft.WindowsAzure.Storage"

As linhas de código anteriores instruem a função de tempo de execução a incluir uma


referência à biblioteca especificada para o contexto atual.

Salvar as imagens de perfil em Filas


usando Associações de saída de fila
Na receita anterior, você aprendeu a receber dois parâmetros de cadeia de caracteres,
firstname e lastname, no Corpo da solicitação e armazená-los no armazenamento
de Tabelas do Azure. Nesta receita, vamos adicionar um novo parâmetro chamado
ProfilePicUrl para a imagem de perfil do usuário que é acessível publicamente
por meio da Internet. Você aprenderá a receber uma URL de uma imagem e salvá-la
no contêiner de Blob de uma conta de Armazenamento do Azure.

[ 15 ]
Desenvolver aplicativos de nuvem usando associações e gatilhos de função

Talvez você esteja pensando que o parâmetro de entrada ProfilePicUrl poderia ter
sido usado para fazer download da imagem da Internet na receita anterior, Persistir
detalhes de funcionários usando associações de saída da tabela de Armazenamento do Azure. Não
fizemos isso porque o tamanho das imagens de perfil pode ser enorme com a tecnologia
moderna, portanto, o processamento de imagens em tempo real nas solicitações HTTP
pode prejudicar a performance do aplicativo em geral. Por esse motivo, vamos apenas
pegar a URL da imagem de perfil e armazená-la na Fila. Posteriormente, podemos
processar a imagem e armazená-la no Blob.

Preparação
Vamos atualizar o código da função RegisterUser que usamos nas receitas anteriores.

Como fazer isso…


Execute as seguintes etapas:

1. Navegue até a guia Integrar da função de gatilho de HTTP RegisterUser.


2. Clique no botão Nova Saída, selecione Armazenamento de Filas do Azure e,
em seguida, clique no botão Selecionar.
3. Forneça os seguintes parâmetros nas configurações de saída do Armazenamento
de Filas do Azure:
°° Nome do parâmetro da mensagem: defina o nome do parâmetro como
objUserProfileQueueItem, que será usado no método Run
°° Nome da fila: defina o valor do Nome da fila como
userprofileimagesqueue
°° Conexão da conta de armazenamento: selecione a conta de
armazenamento certa no campo Conexão da conta de armazenamento

4. Clique em Salvar para criar a nova associação de saída.


5. Navegue de volta para o editor de código clicando no nome da função
(RegisterUser neste exemplo) ou no arquivo run.csx e faça as alterações
marcadas em negrito no código abaixo:
public static async Task<IActionResult> Run(
HttpRequest req,
CloudTable objUserProfileTable,
IAsyncCollector<string> objUserProfileQueueItem,
ILogger log)
{

....

[ 16 ]
Capítulo 1

string firstname= inputJson.firstname;


string profilePicUrl = inputJson.ProfilePicUrl;
await objUserProfileQueueItem.AddAsync(profilePicUrl);

....
objUserProfileTable.Execute(objTblOperationInsert);
}

6. No código anterior, acrescentamos Associações de Saída de Fila, adicionando


o parâmetro IAsyncCollecter ao método Run e apenas transmitindo a
mensagem necessária ao método AddAsync. As associações de saída salvarão o
ProfilePicUrl na Fila. Agora, clique em Salvar para salvar as alterações de
código no editor de código do arquivo run.csx.
7. Vamos testar o código adicionando outro parâmetro, ProfilePicUrl, ao Corpo
da solicitação e, em seguida, clicar no botão Executar na guia Testar da janela
do editor de código da Função do Azure. A imagem usada no JSON a seguir
pode não existir quando você estiver lendo este livro. Portanto, forneça uma URL
válida da imagem:
{
"firstname": "Bill",
"lastname": "Gates",
"ProfilePicUrl":"https://upload.wikimedia.org/wikipedia/
commons/1/19/Bill_Gates_June_2015.jpg"
}

8. Se tudo correr bem, você verá a mensagem Status 200 OK, em seguida,
a URL da imagem que você transmitiu como um parâmetro de entrada
no Corpo da solicitação será criada como uma Mensagem da fila no
serviço de Fila de Armazenamento do Azure. Vamos navegar até o
Gerenciador de Armazenamento do Azure e visualizar a Fila chamada
userprofileimagesqueue, que é o Nome da fila que fornecemos na etapa 3.
Veja a seguir uma captura de tela da Mensagem da fila que foi criada:

[ 17 ]
Desenvolver aplicativos de nuvem usando associações e gatilhos de função

Como funciona…
Nesta receita, adicionamos a associação de saída da Mensagem da fila e fizemos
as seguintes alterações no código:

• Adicionamos um novo parâmetro denominado out string


objUserProfileQueueItem, que é usado para associar a URL da imagem
de perfil como um conteúdo da Mensagem da fila
• Usamos o método AddAsync do IAsyncCollector para o método Run,
que salva a URL do perfil na Fila como uma Mensagem da fila.

Armazenar a imagem no Armazenamento


de Blobs do Azure
Na receita anterior, armazenamos a URL da imagem na mensagem da fila. Vamos
aprender a acionar uma Função do Azure (Gatilho de Fila) quando um novo item da fila
for adicionado ao serviço de Fila de Armazenamento do Azure. Cada mensagem na Fila
é a URL da imagem de perfil de um usuário, que será processada pelo Azure Functions
e armazenada como um Blob no serviço de Armazenamento de Blobs do Azure.

Preparação
Na receita anterior, aprendemos a criar Associações de saída de fila. Nesta receita, você
vai pegar a URL da Fila, criar uma matriz de bytes e, em seguida, gravá-la em um Blob.

Esta receita é uma continuação das receitas anteriores. Verifique se você as implementou.

Como fazer isso...


Execute as seguintes etapas:

1. Crie uma nova Função do Azure escolhendo o Gatilho do Armazenamento


de Filas do Azure entre os modelos.
2. Fornece os seguintes detalhes depois de escolher o modelo:
°° Nomeie sua função: forneça um nome significativo, como
CreateProfilePictures.

[ 18 ]
Capítulo 1

°° Nome da fila: nome da Fila userprofileimagesqueue. Isso será


monitorado pela Função do Azure. Nossa receita anterior criou um novo
item para cada uma das solicitações válidas que chegaram ao gatilho de
HTTP (chamado RegisterUser) na Fila userprofileimagesqueue.
Para cada nova entrada de uma mensagem da fila nesse Armazenamento
de filas, o gatilho CreateProfilePictures será executado
automaticamente.
°° Conexão da conta de armazenamento: conexão da conta de
armazenamento em que as Filas estão localizadas.

3. Revise todos os detalhes e clique em Criar para criar a nova função.


4. Navegue até a guia Integrar, clique em Nova Saída, escolha Armazenamento
de Blobs do Azure e, em seguida, clique no botão Selecionar.
5. Na seção Saída do Armazenamento de Blobs do Azure, forneça o seguinte:
°° Nome do parâmetro do Blob: defina como outputBlob
°° Caminho: defina como userprofileimagecontainer/{rand-guid}
°° Conexão da conta de armazenamento: escolha a conta de armazenamento
em que gostaria de salvar os Blobs e clique no botão Salvar:

6. Clique no botão Salvar para salvar todas as alterações.


7. Substitua o código padrão do arquivo run.csx da função
CreateProfilePictures pelo código a seguir. Esse código pega a URL da Fila,
cria uma matriz de bytes e, em seguida, grava-a em um Blob:
using System;
public static void Run(Stream outputBlob,string
myQueueItem,
TraceWriter log)
{
byte[] imageData = null;
using (var wc = new System.Net.WebClient())

[ 19 ]
Desenvolver aplicativos de nuvem usando associações e gatilhos de função

{
imageData = wc.DownloadData(myQueueItem);
}
outputBlob.WriteAsync(imageData,0,imageData.Length);
}

8. Clique no botão Salvar para salvar as alterações. Verifique se não há nenhum


erro de compilação na janela Logs:

9. Vamos voltar para a função RegisterUser e testá-la fornecendo os campos


firstname, lastname e ProfilePicUrl como fizemos na receita Salvar
as imagens de perfil em Filas usando Associações de saída de fila.
10. Navegue até o Gerenciador de Armazenamento do Azure e observe o contêiner
de Blob userprofileimagecontainer. Você encontrará um novo Blob:

11. Você pode exibir a imagem em qualquer ferramenta (como MS Paint ou Internet
Explorer).

Como funciona...
Criamos um gatilho de Fila que é executado conforme e quando uma nova mensagem
chega na Fila. Ao encontrar uma nova Mensagem da fila, ele lê a mensagem e, como
sabemos, ela é uma URL de uma imagem de perfil. A função realiza uma solicitação
de cliente Web, faz download dos dados da imagem na forma de uma matriz de bytes e,
em seguida, grava-os no Blob que é configurado como um Blob de saída.

[ 20 ]
Capítulo 1

E mais...
O parâmetro rand-guid gerará um novo GUID e é atribuído ao Blob que é criado
sempre que o gatilho é acionado.

É obrigatório especificar o nome do contêiner de Blob no parâmetro


Path da associação de saída do armazenamento de Blobs ao configurar
a saída do armazenamento de Blobs. O Azure Functions criará um
automaticamente se ele não existir.
Você pode usar Mensagens de fila somente quando quiser armazenar
mensagens de até 64 KB. Se quiser armazenar mensagens maiores
que 64 KB, você precisará usar o Barramento de Serviço do Azure.

[ 21 ]
Trabalhar com notificações
usando os serviços
SendGrid e Twilio
Neste capítulo, vamos ver como:

• Enviar uma notificação por email ao administrador de um site usando


o serviço SendGrid
• Enviar uma notificação por email dinamicamente ao usuário final
• Implementar log de email no Armazenamento de Blobs do Azure
• Modificar o conteúdo do email para incluir um anexo
• Enviar uma notificação por SMS ao usuário final usando o serviço Twilio

Introdução
Para todos os aplicativos de negócios executarem suas operações comerciais
perfeitamente, um dos recursos fundamentais é ter um sistema de comunicação confiável
entre a empresa e seus clientes. O canal de comunicação pode ser bidirecional, enviando
uma mensagem aos administradores que gerenciam o aplicativo ou enviando alertas aos
clientes por email ou SMS para seus celulares.

O Azure pode se integrar a dois serviços de comunicação populares: o SendGrid para


emails e o Twilio para trabalhar com SMS. Neste capítulo, usaremos esses dois serviços
de comunicação para aprender a aproveitar seus serviços básicos a fim de enviar
mensagens entre administradores de negócios e usuários finais.

[ 23 ]
Trabalhar com notificações usando os serviços SendGrid e Twilio

Abaixo está a arquitetura que usaremos para utilizar as associações de saída do SendGrid
e do Twilio com o Gatilho HTTP e o Gatilho de Fila.

Enviar uma notificação por email


ao administrador de um site usando
o serviço SendGrid
Nesta receita, você aprenderá a criar uma associação de saída do SendGrid e enviar
uma notificação por email, com conteúdo estático, ao administrador do site. Nosso caso
de uso envolve apenas um administrador, portanto, vamos codificar o endereço de
email do administrador no campo Endereço do destinatário da associação de saída do
SendGrid (message).

Preparação
Vamos executar as seguintes etapas antes de passar para a próxima seção:

1. Criar uma chave de API de conta do SendGrid a partir do portal de


Gerenciamento do Azure
2. Gerar uma chave de API a partir do portal SendGrid
3. Configurar a chave de API do SendGrid com o aplicativo de Função do Azure

Criar uma conta do SendGrid


Execute as seguintes etapas:

1. Navegue até o portal de Gerenciamento do Azure e crie uma conta de Entrega


de Email do SendGrid procurando por ele no Marketplace, conforme mostrado
na captura de tela a seguir:

[ 24 ]
Capítulo 2

2. Na folha Entrega de Email do SendGrid, clique no botão Criar para navegar até
Criar uma Nova Conta do SendGrid. Selecione gratuito nas opções da Camada
de preços, forneça todos os outros detalhes e, em seguida, clique no botão Criar,
conforme mostrado na captura de tela a seguir:

[ 25 ]
Trabalhar com notificações usando os serviços SendGrid e Twilio

Até o momento da redação deste livro, a conta gratuita do


SendGrid permite enviar 25.000 emails gratuitos por mês.
Se quiser enviar mais emails, você pode obter uma conta
de nível Silver S2 , na qual terá 100.000 emails por mês.

3. Depois que a conta for criada com êxito, navegue até Contas do SendGrid.
Você pode usar a caixa de pesquisa disponível na parte superior, conforme
mostrado na captura de tela a seguir:

4. Navegue até Configurações, escolha Configurações e copie o NOME DE


USUÁRIO e o SERVIDOR DO SMTP da folha Configurações, conforme
mostrado na captura de tela a seguir:

[ 26 ]
Capítulo 2

Gerar uma chave de API a partir do portal SendGrid


Execute as seguintes etapas:

1. Para utilizar a conta do SendGrid no tempo de execução das Funções do


Azure, precisamos fornecer a chave de API do SendGrid como uma entrada
para as Funções do Azure. Você pode gerar uma chave de API a partir do portal
SendGrid. Vamos navegar até o portal SendGrid clicando no botão Gerenciar
na folha Essentials da Conta do SendGrid, como mostrado na captura de tela
a seguir:

2. No portal SendGrid, clique em Chaves de API na seção Configurações do menu


à esquerda, como mostrado na captura de tela a seguir:

3. Na página Chaves de API, clique em Criar Chave de API, conforme mostrado


abaixo:

[ 27 ]
Trabalhar com notificações usando os serviços SendGrid e Twilio

4. Na janela pop-up Criar Chave de API, forneça um nome e escolha Permissões


da Chave de API, em seguida, clique no botão Criar e Exibir.
5. Em instantes, você verá a chave de API. Clique na chave para copiá-la para a área
de transferência, como mostrado na captura de tela a seguir:

Configurar a chave de API do SendGrid com


o aplicativo de Função do Azure
Execute as seguintes etapas:

1. Crie novas Configurações de aplicativo no aplicativo de Função do Azure


navegando até a folha Configurações de aplicativo, na seção Recursos da
plataforma do aplicativo de função, conforme mostrado captura de tela a seguir:

2. Clique no botão Salvar depois de adicionar as Configurações de aplicativo


da etapa anterior.

Como fazer isso...


Nesta seção, vamos fazer o seguinte.

1. Criar associação de Fila de Armazenamento para o Gatilho HTTP


2. Criar Gatilho de Fila para processar a mensagem do Gatilho HTTP
3. Criar associação de saída do SendGrid para o Gatilho de Fila
4. Criar associação de saída do Twilio para o Gatilho de Fila

[ 28 ]
Capítulo 2

Criar associação de Fila de Armazenamento para o


Gatilho HTTP
Execute as seguintes etapas:

1. Navegue até a guia Integrar da função RegisterUser e clique no botão Nova


Saída para adicionar uma nova associação de saída.
2. Escolha Armazenamento de Filas do Azure, clique no botão Selecionar para
adicionar a associação e fornecer os valores mostrados abaixo e, em seguida,
clique no botão Salvar. Pense no Nome da fila (neste caso notificationqueue)
que será usado em instantes.

3. Navegue até o método Run da função RegisterUser e faça as seguintes


alterações destacadas. Adicionamos outra Associação de saída de fila e uma
mensagem vazia para acionar a função de Gatilho de Fila. Por enquanto, não
adicionamos nenhuma mensagem à fila. Vamos fazer alterações no método
NotificationQueueItem.AddAsync(""); na próxima receita do capítulo.

public static async Task<IActionResult> Run(


HttpRequest req,
CloudTable objUserProfileTable,
IAsyncCollector<string> objUserProfileQueueItem,
IAsyncCollector<string> NotificationQueueItem,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed
a request.");
string firstname=null,lastname = null;
...
...
await NotificationQueueItem.AddAsync("");
return (lastname + firstname) != null
? (ActionResult)new OkObjectResult($"Hello, {firstname + "
" + lastname}")
: new BadRequestObjectResult("Please pass a name on the

[ 29 ]
Trabalhar com notificações usando os serviços SendGrid e Twilio

query" +
"string or in the request body");
}

Criar Gatilho de Fila para processar a mensagem


do Gatilho HTTP
1. Crie um Gatilho de Armazenamento de Filas do Azure escolhendo o modelo
mostrado abaixo.

2. Na próxima etapa, forneça todo o nome do Gatilho de Fila e o nome da fila que
precisa ser monitorada para enviar as notificações. Depois de fornecer todos
os detalhes, clique no botão Criar para criar a Função.

[ 30 ]
Capítulo 2

3. Depois de criar a função de Gatilho de Fila, vamos executar a função


RegisterUser para ver se o Gatilho de Fila está sendo invocado. Abra
a função RegisterUser em uma nova guia e teste-a clicando no botão
Executar. Na janela Logs da guia SendNotifications, você verá algo como
o que é mostrado a seguir:

Depois de garantir que o Gatilho de Fila está funcionando conforme o esperado, vamos
criar as associações do SendGrid para enviar o email.

Criar associação de saída do SendGrid para


o Gatilho de Fila
1. Navegue até a guia Integrar da função SendNotifications e clique no botão
Nova Saída para adicionar uma nova associação de saída.
2. Escolha a associação do SendGrid e clique no botão Selecionar para adicioná-la.
3. A próxima etapa é instalar as extensões do SendGrid. Clique no botão Instalar
para instalar as extensões. Pode levar alguns minutos para instalá-las.
4. Forneça os seguintes parâmetros na associação de saída do SendGrid (message):

°° Nome do parâmetro da mensagem: deixe o valor padrão, que é


message. Usaremos esse parâmetro no método Run daqui a pouco.
°° Chave de API do SendGrid: escolha a chave Configurações de
aplicativo que você criou nas Configurações de aplicativo para
armazenar a Chave de API do SendGrid.
°° Endereço do destinatário: forneça o endereço de email do administrador.
°° Endereço do remetente: forneça o endereço de email de onde você quer
enviar o email. Pode ser algo como donotreply@example.com.

[ 31 ]
Trabalhar com notificações usando os serviços SendGrid e Twilio

°° Assunto da mensagem: forneça o assunto que você quer que seja exibido
no assunto do email.
°° Texto da Mensagem: forneça o texto que você quer incluir no corpo
do email.

5. A associação de saída do SendGrid (message) deve ser ter esta aparência depois
do fornecimento de todos os campos:

6. Depois de revisar os valores, clique em Salvar para salvar as alterações.


7. Navegue até o método Run das funções SendNotifications e faça as seguintes
alterações:
°° Adicione uma nova referência para o SendGrid, juntamente com
o namespace SendGrid.Helpers.Mail.
°° Adicione uma nova mensagem de parâmetro de saída do tipo
SendGridMessage.
°° Crie um objeto do tipo SendGridMessage. Veremos como usar esse
objeto na próxima receita.

8. A seguir está o código completo do método Run:


#r "SendGrid"
using System;
using SendGrid.Helpers.Mail;

public static void Run(string myQueueItem,out SendGridMessage


message, ILogger log)
{
log.LogInformation($"C# Queue trigger function processed:

[ 32 ]
Capítulo 2

{myQueueItem}");
message = new SendGridMessage();
}

9. Agora, vamos testar a funcionalidade de envio do email navegando até a função


RegisterUser e enviando uma solicitação com alguns valores de teste,
da seguinte maneira:
{
"firstname": "Bill",
"lastname": "Gates",
"ProfilePicUrl":"https://upload.wikimedia.org/
wikipedia/commons/thumb/1/19/
Bill_Gates_June_2015.jpg/220px-
Bill_Gates_June_2015.jpg"
}

Como funciona...
O objetivo desta receita é enviar uma notificação via email ao administrador, informando
que um novo registro foi criado com êxito.

Usamos uma das associações de saída da Função do Azure, denominada SendGrid,


como um servidor do Protocolo SMTP para enviar nossos emails, codificando as
seguintes propriedades nas associações de saída do SendGrid (message):

• O endereço de email "de"


• O endereço de email "para"
• O assunto do email
• O corpo do email

As associações de saída do SendGrid (message) usarão a chave de API fornecida nas


Configurações de aplicativo para invocar as APIs necessárias da biblioteca do SendGrid
para enviar os emails.

[ 33 ]
Trabalhar com notificações usando os serviços SendGrid e Twilio

E mais
Ao adicionar as associações do SendGrid, você será solicitado a instalar as Extensões,
como mostrado abaixo.

Se não forem exibidas, exclua a associação de saída e recrie-a. Você também pode
instalar as extensões manualmente seguindo as instruções mencionadas no artigo
https://docs.microsoft.com/azure/azure-functions/install-update-
binding-extensions-manual.

Enviar uma notificação por email


dinamicamente ao usuário final
Na receita anterior, codificamos a maioria dos atributos relacionados ao envio de um
email a um administrador, pois havia apenas um administrador. Nesta receita, vamos
modificar a receita anterior para enviar um email Thank you for registration
aos próprios usuários.

Preparação
Verifique se os seguintes itens estão configurados corretamente:

• A conta do SendGrid foi criada e uma chave de API foi gerada no portal
SendGrid.
• Configurações de aplicativo foram criadas nas Configurações de aplicativo
do aplicativo de função.
• A chave Configurações de aplicativo foi configurada nas associações de saída
do SendGrid (message).

[ 34 ]
Capítulo 2

Como fazer isso...


Nesta receita, atualizaremos o código no arquivo run.csx das seguintes Funções
do Azure

• RegisterUser
• SendNotifications

Aceitar o novo Parâmetro de email na função


RegisterUser
Execute as seguintes etapas:

1. Navegue até a função RegisterUser, no arquivo run.csx, adicione uma


nova variável de string que aceite um novo parâmetro de entrada, denominado
email, do objeto request, da seguinte maneira. Além disso, observe que
estamos serializando o objeto UserProfile e armazenando o conteúdo JSON
na Mensagem da fila:
string firstname=null,lastname = null, email = null;
...
...
string email = inputJson.email;
...
...
UserProfile objUserProfile = new UserProfile(firstname,
lastname,email);
...
...
await
NotificationQueueItem.AddAsync(JsonConvert.SerializeObject(objUser
Profile));

2. Atualize o seguinte código destacado para a classe UserProfile e clique no


botão Salvar para salvar as alterações:
public class UserProfile : TableEntity
{
public UserProfile(string firstname,string lastname,
string profilePicUrl,string email)
{
....
....
this.ProfilePicUrl = profilePicUrl;
this.Email = email;
}
....
....
public string ProfilePicUrl {get; set;}

[ 35 ]
Trabalhar com notificações usando os serviços SendGrid e Twilio

public string Email { get; set; }


}

Recuperar as informações de UserProfile no gatilho


de SendNotifications
Execute as seguintes etapas

1. Navegue até a função SendNotifications, no arquivo run.csx, adicione a


referência NewtonSoft.Json e também o namespace.
2. O Gatilho de Fila receberá a entrada na forma de cadeia de caracteres JSON.
Usaremos o método JsonConvert.Deserializeobject para converter a
cadeia de caracteres em um objeto dinâmico para que possamos recuperar
as propriedades individuais. Substitua o código existente pelo código a
seguir no qual estamos preenchendo dinamicamente as propriedades do
SendGridMessage do código.
#r "SendGrid"
#r "Newtonsoft.Json"
using System;
using SendGrid.Helpers.Mail;
using Newtonsoft.Json;

public static void Run(string myQueueItem,


out SendGridMessage message,
ILogger log)
{
log.LogInformation($"C# Queue trigger function processed:
{myQueueItem}");
dynamic inputJson = JsonConvert.DeserializeObject(myQueueItem);
string FirstName=null, LastName=null, Email = null;
FirstName=inputJson.FirstName;
LastName=inputJson.LastName;
Email=inputJson.Email;
log.LogInformation($"Email{inputJson.Email}, {inputJson.FirstName
+ " " + inputJson.LastName}");
message = new SendGridMessage();
message.SetSubject("New User got registered successfully.");
message.SetFrom("donotreply@example.com");
message.AddTo(Email,FirstName + " " + LastName);
message.AddContent("text/html", "Thank you " + FirstName + " " +
LastName +" so much for getting registered to our site.");
}

[ 36 ]
Capítulo 2

3. Vamos executar um teste adicionando um novo email de campo de entrada à


carga de solicitação do teste, da seguinte maneira:
{
"firstname": "Praveen",
"lastname": "Sreeram",
"email":"example@gmail.com",
"ProfilePicUrl":"A Valid url here"
}

4. Esta é a captura de tela do email que recebi:

Como funciona...
Atualizamos o código da função RegisterUser para aceitar outro novo parâmetro,
denominado email.

A função aceita o parâmetro email e envia o email ao usuário final usando a API
do SendGrid. Também configuramos todos os outros parâmetros, como endereço
From, Subject e corpo (conteúdo) no código, de modo que ele seja personalizado
dinamicamente com base nos requisitos.

[ 37 ]
Trabalhar com notificações usando os serviços SendGrid e Twilio

Também podemos limpar os campos nas associações de saída do SendGrid, conforme


mostrado na captura de tela a seguir:

Os valores especificados no código terão precedência sobre


os valores especificados na etapa anterior.

E mais...
Você também pode enviar conteúdo HTML no corpo da mensagem para tornar seu email
mais atraente. A seguir, um exemplo simples, em que acabei de aplicar uma marca de
negrito (<b>) ao nome do usuário final:
message.AddContent("text/html", "Thank you <b>" + FirstName + "</b><b>
" + LastName +" </b>so much for getting registered to our site.");

Abaixo, a captura de tela do email, com o meu nome em negrito:

[ 38 ]
Capítulo 2

Implementar log de email no


Armazenamento de Blobs do Azure
A maioria dos aplicativos de negócios de emails automatizados provavelmente envolverá
o envio de emails contendo notificações, alertas e assim por diante, ao usuário final.
Às vezes, os usuários podem reclamar que não receberam nenhum email, mesmo que
não vejamos nenhum erro no aplicativo ao enviar esses alertas de notificação.

Pode haver vários motivos pelos quais os usuários não receberam o email. Cada
provedor de serviço de email tem filtros de spam diferentes que podem bloquear
os emails da caixa de entrada do usuário final. Mas esses emails podem ter informações
importantes das quais os usuários podem precisar. Faz sentido armazenar o conteúdo
de todos os emails enviados aos usuários finais, para que possamos recuperar os dados
posteriormente, a fim de solucionar quaisquer problemas imprevistos.

Nesta receita, você aprenderá a criar um novo arquivo de log de email com a extensão
.log para cada novo registro. Esse arquivo de log pode ser usado como uma
redundância para os dados armazenados no Armazenamento de tabelas. Você também
aprenderá a armazenar os arquivos de log de email como um Blob em um contêiner
de armazenamento, juntamente com os dados inseridos pelo usuário final durante
o registro.

Como fazer isso...


Execute as seguintes etapas:

1. Navegue até a guia Integrar da função SendNotifications, clique em


Nova Saída e escolha Armazenamento de Blobs do Azure. Você será solicitado
a instalar as Extensões de Armazenamento. Instale-as para continuar.
2. Forneça os parâmetros necessários na seção de saída do Armazenamento
de Blobs do Azure, como mostrado na captura de tela a seguir. Observe
a extensão .log no campo Caminho:

[ 39 ]
Trabalhar com notificações usando os serviços SendGrid e Twilio

3. Navegue até o editor de código do arquivo run.csx da função


SendNotifications e faça as seguintes alterações:
1. Adicione um novo parâmetro outputBlob do tipo TextWriter
ao método Run.
2. Adicione uma nova variável de string chamada emailContent. Essa
variável é usada para enquadrar o conteúdo do email. Também usaremos
a mesma variável para criar o conteúdo do arquivo de log que será
finalmente armazenado no blob.
3. Enquadre o conteúdo do email acrescentando o texto estático necessário
e os parâmetros de entrada recebidos no Corpo da solicitação,
da seguinte maneira:
public static void Run(string myQueueItem,
out SendGridMessage message,
TextWriter outputBlob,
ILogger log)
....
....
string FirstName=null, LastName=null, Email = null;
string emailContent;
....
....
emailContent = "Thank you <b>" + FirstName + " " +
LastName +"</b> for your registration.<br><br>" +
"Below are the details that you have provided
us<br> <br>"+ "<b>First name:</b> " +
FirstName + "<br>" + "<b>Last name:</b> " +
LastName + "<br>" + "<b>Email Address:</b> " +
inputJson.Email + "<br><br> <br>" + "Best Regards," +
"<br>" + "Website Team";
message.AddContent(new
Content("text/html",emailContent));
outputBlob.WriteLine(emailContent);

4. Execute um teste usando a mesma carga de solicitação que usamos na receita


anterior.
5. Depois de executar o teste, o arquivo de log será criado no contêiner denominado
userregistrationemaillogs:

[ 40 ]
Capítulo 2

Como funciona...
Criamos novas associações de saída de Blobs do Azure. Assim que uma nova solicitação
é recebida, o conteúdo do email é criado e gravado em um novo arquivo .log (observe
que você pode usar qualquer outra extensão também) que é armazenado como um Blob
no contêiner especificado no campo Caminho das associações de saída.

Modificar o conteúdo do email para


incluir um anexo
Nesta receita, você aprenderá a enviar um arquivo como um anexo ao usuário registrado.
Em nossa receita anterior, criamos um arquivo de log do conteúdo do email. Enviaremos
o mesmo arquivo como um anexo ao email. No entanto, em aplicações reais, talvez você
não pretenda enviar arquivos de log ao usuário final. Por uma questão de simplicidade,
enviaremos o arquivo de log como um anexo.

Até o momento da redação deste livro, o SendGrid recomenda


que o tamanho do anexo não exceda 10 MB, embora
tecnicamente, seu email possa ter até 20 MB.

[ 41 ]
Trabalhar com notificações usando os serviços SendGrid e Twilio

Preparação
Esta é uma continuação da receita anterior. Se você estiver lendo isto primeiro, veja
as receitas anteriores deste capítulo antes.

Como fazer isso...


Precisaremos executar as seguintes etapas antes de passar para a próxima seção:

1. Faça as alterações no código para criar um arquivo de log com o RowKey


da tabela. Conseguiremos isso usando a interface IBinder.
2. Envie esse arquivo como um anexo ao email.

Personalizar o nome do arquivo de log usando


a interface IBinder
Execute as seguintes etapas:

1. Navegue até o arquivo run.csx da função SendNotifications.


2. Remova o objeto TextWriter e substitua-o pelo associador de variáveis
do tipo IBinder. A seguir, a nova assinatura do método Run com as alterações
destacadas:
#r "SendGrid"
#r "Newtonsoft.Json"
#r "Microsoft.Azure.WebJobs.Extensions.Storage"
using System;
using SendGrid.Helpers.Mail;
using Newtonsoft.Json;
using Microsoft.Azure.WebJobs.Extensions.Storage;
public static void Run(string myQueueItem,
out SendGridMessage message,
IBinder binder,
ILogger log)

3. Removemos o objeto TextWriter. A função outputBlob.


WriteLine(emailContent); não funcionará mais. Vamos substituí-la pelo
código a seguir:
using (var emailLogBloboutput = binder.
Bind<TextWriter>(new
BlobAttribute($"userregistrationemaillogs/
{objInsertedUser.RowKey}.log")))
{
emailLogBloboutput.WriteLine(emailContent);
}

[ 42 ]
Capítulo 2

4. Vamos executar um teste usando a mesma carga de solicitação que usamos nas
receitas anteriores.
5. Você pode ver o arquivo de log de email que é criado usando o RowKey do novo
registro armazenado no armazenamento de Tabelas do Azure, como mostrado
na captura de tela a seguir:

Adicionar um anexo ao email


Execute as seguintes etapas:

1. Adicione o seguinte código ao método Run da função SendNotifications


e salve as alterações clicando no botão Salvar:
message.AddAttachment(FirstName +"_"+LastName+".log",
System.Convert.
ToBase64String(System.Text.Encoding.UTF8.GetBytes(emailContent)),
"text/plain",
"attachment",
"Logs"
);

2. Execute um teste usando a mesma carga de solicitação que usamos nas receitas
anteriores.

[ 43 ]
Trabalhar com notificações usando os serviços SendGrid e Twilio

3. Esta é a captura de tela do email, juntamente com o anexo:

Saiba mais sobre a API do SendGrid em


https://sendgrid.com/docs/API_Reference/api_v3.html

Enviar uma notificação por SMS


ao usuário final usando o serviço Twilio
Na maioria das receitas anteriores deste capítulo, trabalhamos com gatilhos de SendGrid
para enviar emails em diferentes cenários. Nesta receita, você aprenderá a enviar
notificações via SMS, usando uma das principais plataformas de comunicação na nuvem,
denominada Twilio.

Você também pode saber mais sobre o


Twilio em
https://www.twilio.com/.

[ 44 ]
Capítulo 2

Preparação
Para usar a associação de saída de SMS do Twilio (objsmsmessage), precisamos fazer
o seguinte:

1. Crie uma conta de trial do Twilio em https://www.twilio.com/try-twilio.


2. Após a criação bem-sucedida da conta, copie o SID DA CONTA e o TOKEN
DE AUTENTICAÇÃO do Painel do Twilio, como mostrado na captura de tela
a seguir. Vamos criar duas Configurações de aplicativo na folha Configurações
de aplicativo do aplicativo de função para estas duas configurações:

3. Para começar a enviar mensagens, é necessário criar um número ativo no Twilio,


que será usado como o Número do remetente para o envio do SMS. Você pode
criar e gerenciar números no Painel de Números de Telefone. Navegue até
https://www.twilio.com/console/phone-numbers/incoming e clique
no botão Começar, como mostrado na captura de tela a seguir:

[ 45 ]
Trabalhar com notificações usando os serviços SendGrid e Twilio

4. Na página Começar com Números de Telefone, clique em Obter seu primeiro


número de telefone do Twilio, como mostrado na captura de tela a seguir:

5. Assim que obter seu número, ele será listado da seguinte maneira:

6. A etapa final é verificar um número ao qual você gostaria de enviar um SMS.


Você pode ter apenas um número na sua conta de trial. É possível verificar um
número na página Verificada do Twilio, disponível em https://www.twilio.
com/console/phone-numbers/verified. Veja uma captura de tela da lista
de números verificados:

[ 46 ]
Capítulo 2

Como fazer isso...


Execute as seguintes etapas:

1. Navegue até a folha Configurações de aplicativo do aplicativo de função


e adicione duas chaves para armazenar TwilioAccountSID e TwilioAuthToken,
da seguinte maneira:

2. Vá para a guia Integrar da função SendNotifications, clique em Nova Saída


e escolha SMS do Twilio.
3. Clique em Selecionar e forneça os seguintes valores às associações de saída
de SMS do Twilio. Instale as extensões do Twilio. O Número do remetente
é aquele que é gerado no portal do Twilio, que discutimos na seção Preparação
desta receita:

4. Navegue até o editor de código e adicione as seguintes linhas de código,


destacadas em negrito. No código abaixo, codifiquei o Número do destinatário.
No entanto, em cenários reais, você receberia dinamicamente o número
de celular do usuário final e enviaria o SMS via código:
...
...
#r "Twilio"
#r "Microsoft.Azure.WebJobs.Extensions.Twilio"
...
...
using Microsoft.Azure.WebJobs.Extensions.Twilio;
using Twilio.Rest.Api.V2010.Account;
using Twilio.Types;
[ 47 ]
Trabalhar com notificações usando os serviços SendGrid e Twilio

public static void Run(string myQueueItem,


out SendGridMessage message,
IBinder binder,
out CreateMessageOptions objsmsmessage,
ILogger log)
...
...
...
message.AddAttachment(FirstName +"_"+LastName+".log",
System.Convert.ToBase64String(System.Text.Encoding.UTF8.
GetBytes(emailContent)),
"text/plain",
"attachment",
"Logs"
);

objsmsmessage = new CreateMessageOptions(new


PhoneNumber("+91 98492*****"));
objsmsmessage.Body = "Hello.. Thank you for getting
registered.";
}

5. Agora, faça uma execução de teste da função RegisterUser usando a mesma


carga de solicitação.
6. Esta é a captura de tela do SMS que recebi:

[ 48 ]
Capítulo 2

Como funciona...
Criamos uma nova conta do Twilio e copiamos a ID da conta e a chave do aplicativo nas
Configurações de aplicativo do aplicativo de Função do Azure. Essas duas configurações
serão usadas pelo tempo de execução do aplicativo de função para se conectar à API do
Twilio a fim de enviar o SMS.

Por uma questão de simplicidade, codifiquei o número de telefone nas associações


de saída. No entanto, em aplicações reais, você enviaria o SMS ao número de telefone
fornecido pelos usuários finais.

Você pode assistir ao vídeo https://www.youtube.com/watch?v=ndxQXnoDIj8 para


ver uma implementação funcional.

[ 49 ]
Integração perfeita do Azure
Functions com os Serviços
do Azure
Neste capítulo, vamos abordar as seguintes receitas:

• Usar os Serviços Cognitivos para localizar rostos em imagens


• Interações do Banco de dados SQL do Azure usando o Azure Functions
• Monitorar Tweets com Aplicativos Lógicos e notificar quando um usuário
popular tweetar
• Integrar Aplicativos Lógicos com funções sem servidor
• Auditar dados do Cosmos DB usando gatilhos de feed de alterações

Introdução
Um dos principais objetivos do Azure Functions é permitir que os desenvolvedores
se concentrem apenas na lógica e nos requisitos do desenvolvimento de aplicativos
sem se preocupar com o restante.

Como um desenvolvedor ou usuário empresarial, você não consegue criar e desenvolver


seus próprios aplicativos do zero para cada uma das suas necessidades de negócios.
Primeiro, você precisa pesquisar os sistemas existentes para verificar se eles são
adequados para seus requisitos de negócios. Muitas vezes, não é fácil entender as APIs
dos outros sistemas e integrá-las, pois elas foram desenvolvidas por outra pessoa.

[ 51 ]
Integração perfeita do Azure Functions com os Serviços do Azure

O Azure fornece muitos conectores que você pode utilizar para integrar seus aplicativos
de negócios com outros sistemas com muita facilidade.

Neste capítulo, veremos como é fácil integrar os diferentes serviços disponíveis


no ecossistema do Azure.

Usar os Serviços Cognitivos para


localizar rostos em imagens
Aqui, você aprenderá a usar a API da Pesquisa Visual Computacional para detectar
rostos em uma imagem. Vamos localizar rostos, capturar suas coordenadas e salvá-los
em diferentes áreas do Armazenamento de Tabelas do Azure com base no gênero.

Preparação
Para começar, precisamos criar uma API da Pesquisa Visual Computacional e configurar
suas chaves de API para que o Azure Functions (ou qualquer outro programa) possa
acessá-la de maneira programática.

Verifique se você tem o Gerenciador de Armazenamento do Azure instalado e também


se configurou o acesso à área de armazenamento na qual está fazendo upload dos blobs.

Criar uma nova conta da API da Pesquisa Visual


Computacional
Execute as seguintes etapas:

1. Procure visão computacional e clique em Criar.


2. A próxima etapa é fornecer todos os detalhes para criar uma conta da API da
Pesquisa Visual Computacional. No momento da redação deste e-book, a API
da Pesquisa Visual Computacional tinha apenas dois tipos de preço. Eu escolhi
o gratuito, F0, que permite 20 chamadas de API por minuto e é limitado a 5.000
chamadas por mês.

[ 52 ]
Capítulo 3

Definir as configurações do aplicativo


Execute as seguintes etapas:

1. Após a geração da conta da API da Pesquisa Visual Computacional, navegue


até a folha Chaves e escolha uma das seguintes chaves:

2. Navegue até o aplicativo do Azure Functions, defina as Configurações do


aplicativo com o nome Vision_API_Subscription_Key e use qualquer uma
das chaves anteriores como o valor. Essa chave será usada pelo Azure Functions
Runtime para se conectar e consumir a API dos Serviços Cognitivos da Pesquisa
Visual Computacional.
3. Anote o local onde você está criando o serviço de Pesquisa Visual
Computacional. No meu caso, o local escolhido foi a Europa Ocidental.
Quando você está transmitindo as imagens para a API dos Serviços Cognitivos,
é importante garantir que o ponto de extremidade da API comece com o nome do
local. Seria algo assim: https://westeurope.api.cognitive.microsoft.
com/vision/v1.0/analyze?visualFeatures=Faces&language=en.

Como fazer isso...


Execute as seguintes etapas:

1. Crie uma nova função usando um dos modelos padrão chamados de Gatilho
de Armazenamento de Blobs do Azure.

[ 53 ]
Integração perfeita do Azure Functions com os Serviços do Azure

2. Em seguida, é necessário fornecer o nome da Função do Azure junto com


o Caminho e a Conexão da conta de armazenamento. Carregaremos uma
imagem no contêiner do Gatilho de Armazenamento de Blobs do Azure
(imagem) (mencionado no parâmetro Caminho na captura de tela a seguir)
no final desta seção:

Ao criar a função, o modelo cria uma associação de saída da Tabela


de Armazenamento de Blobs e nos permite fornecer o nome do parâmetro
Nome da tabela. No entanto, não é possível atribuir o nome do parâmetro
durante a criação da função. Poderemos alterá-lo depois que ele for criado.
Depois de revisar todos os detalhes, clique no botão Criar para criar a Função
do Azure.
3. Após a criação da função, navegue até a guia Integrar, clique em Nova Saída
e escolha Armazenamento de Tabelas do Azure. Em seguida, clique no botão
Selecionar. Forneça os valores de parâmetro e clique no botão Salvar, como
mostrado na seguinte captura de tela:

[ 54 ]
Capítulo 3

4. Vamos criar outra associação de saída do Armazenamento de Tabelas do Azure


para armazenar todas as informações de mulheres. Para isso, é necessário clicar
no botão Nova Saída na guia Integrar, selecionar Armazenamento de Tabelas
do Azure e clicar no botão Selecionar. Veja como ela ficará após o fornecimento
dos valores de entrada:

5. Depois de revisar todos os detalhes, clique no botão Salvar para criar


a associação de saída do Armazenamento de Tabelas do Azure e armazene
os detalhes sobre as mulheres.

[ 55 ]
Integração perfeita do Azure Functions com os Serviços do Azure

6. Navegue até o editor de código do método Run da função


LocateMaleFemaleFaces. Em seguida, adicione os parâmetros outMaleTable
e outFemaleTable. O código a seguir captura o fluxo de imagens carregado
no blob, que é então transmitido como uma entrada para os Serviços Cognitivos,
que retorna um JSON com todas as informações dos rostos. Após o recebimento
das informações dos rostos, incluindo as coordenadas e os detalhes de gênero,
armazenamos as coordenadas dos rostos no respectivo Armazenamento
de Tabelas usando as associações de saída da tabela:
#r "Newtonsoft.Json"
#r "Microsoft.WindowsAzure.Storage"

using Newtonsoft.Json;
using Microsoft.WindowsAzure.Storage.Table;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
public static async Task Run(Stream myBlob,
string name,
IAsyncCollector<FaceRectangle>
outMaleTable,
IAsyncCollector<FaceRectangle>
outFemaleTable,
ILogger log)
{
log.LogInformation($"C# Blob trigger function Processed blob\n
Name:{name} \n Size: {myBlob.Length} Bytes");
string result = await CallVisionAPI(myBlob);
log.LogInformation(result);
if (String.IsNullOrEmpty(result))
{
return;
}
ImageData imageData = JsonConvert.DeserializeObject<ImageData>
(result);
foreach (Face face in imageData.Faces)
{
var faceRectangle = face.FaceRectangle;
faceRectangle.RowKey = Guid.NewGuid().ToString();
faceRectangle.PartitionKey = "Functions";
faceRectangle.ImageFile = name + ".jpg";
if(face.Gender=="Female")
{
await outFemaleTable.AddAsync(faceRectangle);

[ 56 ]
Capítulo 3

}
Else
{
await outMaleTable.AddAsync(faceRectangle);
}
}
}
static async Task<string> CallVisionAPI(Stream image)
{
using (var client = new HttpClient())
{
var content = new StreamContent(image);
var url = "https://westeurope.api.cognitive.microsoft.com/
vision/v1.0/analyze?visualFeatures=Faces&language=en";
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-
Key", Environment.GetEnvironmentVariable("Vision_API_Subscription_
Key"));
content.Headers.ContentType = new MediaTypeHeaderValue("ap
plication/octet-stream");
var httpResponse = await client.PostAsync(url, content);

if (httpResponse.StatusCode == HttpStatusCode.OK)
{
return await httpResponse.Content.ReadAsStringAsync();
}
}
return null;
}
public class ImageData
{
public List<Face> Faces { get; set; }
}
public class Face
{
public int Age { get; set; }
public string Gender { get; set; }
public FaceRectangle FaceRectangle { get; set; }
}
public class FaceRectangle : TableEntity
{
public string ImageFile { get; set; }
public int Left { get; set; }
public int Top { get; set; }
public int Width { get; set; }
public int Height { get; set; }}

[ 57 ]
Integração perfeita do Azure Functions com os Serviços do Azure

7. Vamos adicionar uma condição (destacada em negrito no código mencionado


na Etapa 10) para verificar o gênero e, com base nele, armazenar as informações
no respectivo Armazenamento de Tabelas.
8. Crie um novo contêiner de blobs chamado images usando o Gerenciador
de Armazenamento do Azure, como mostrado na captura de tela a seguir:

9. Vamos carregar uma imagem com rostos masculinos e femininos no contêiner


chamado images usando o Gerenciador de Armazenamento do Azure, como
mostrado aqui:

[ 58 ]
Capítulo 3

10. A função é acionada assim que você carrega uma imagem. Este é o JSON que
foi registrado no console Logs da função:
{
"requestId":"483566bc-7d4d-45c1-87e2-6f894aaa4c29",
"metadata":{ },
"faces":[
{
"age":31,
"gender":"Female",
"faceRectangle":{
"left":535,
"top":182,
"width":165,
"height":165
}
},
{
"age":33,
"gender":"Male",
"faceRectangle":{
"left":373,
"top":182,
"width":161,
"height":161
}
}
]
}

Se você é um desenvolvedor de front-end com especialização em


tecnologias HTML5 e relacionadas a telas, pode até mesmo desenhar
quadrados que localizam os rostos na imagem usando as informações
fornecidas pelos Serviços Cognitivos.

[ 59 ]
Integração perfeita do Azure Functions com os Serviços do Azure

11. A função também criou duas tabelas de Armazenamento de Tabelas do Azure,


como mostrado aqui:

Como funciona...
Primeiro criamos uma associação de saída do Armazenamento de Tabelas para
armazenar detalhes sobre todos os homens nas fotos. Em seguida, criamos outra
associação de saída do Armazenamento de Tabelas para armazenar os detalhes sobre
todas as mulheres.

Usamos todos os códigos padrão que o modelo do Azure Functions fornece para
armazenar todas as coordenadas dos rostos em uma única tabela. Entretanto, acabamos
de fazer uma pequena alteração para verificar se a pessoa na foto é homem ou mulher
e armazenar os dados com base no resultado.

Lembre-se de que a identificação do gênero correto feita pelas APIs não


é totalmente precisa. Então, você deve ter um mecanismo de fallback em
seus ambientes de produção para gerenciar tais situações.

E mais...
Para invocar a API da Pesquisa Visual Computacional, o código padrãoque o modelo
fornece transmite a imagem que carregamos para o armazenamento de blobs.
Para invocar a chamada de API, os modelos de localizador de rostos transmitem
o parâmetro visualFeatures=Faces, que retorna informações sobre:

• Idade
• Gênero
• Coordenadas dos rostos na foto

[ 60 ]
Capítulo 3

Saiba mais sobre a API da Pesquisa Visual Computacional em https://


docs.microsoft.com/azure/cognitive-services/computer-
vision/home.

Use a função Environment.GetEnvironmentVariable("KeyName") para recuperar


as informações armazenadas nas configurações do aplicativo. Nesse caso, o método
CallVisionAPI usa a função para recuperar a chave, que é essencial para fazer uma
solicitação aos Serviços Cognitivos da Microsoft.

Uma prática recomendada é armazenar todas as chaves e outras


informações confidenciais nas configurações do aplicativo.

ICollector e IAsyncCollector são usadas para inserção em massa


de dados.

Interações do Banco de dados SQL


do Azure usando o Azure Functions
Até agora, você aprendeu a armazenar dados nos serviços de Armazenamento do
Azure, como blobs, filas e tabelas. Todos esses serviços de armazenamento são ótimos
para armazenar dados não estruturados ou semiestruturados. No entanto, talvez seja
necessário armazenar dados em sistemas de gerenciamento de banco de dados relacional,
como um Banco de Dados SQL do Azure.

Aqui, você aprenderá a utilizar a API ADO.NET para se conectar a um Banco de Dados
SQL e inserir dados JSON em uma tabela chamada EmployeeInfo.

Preparação
Navegue até o Portal do Azure e faça o seguinte:

1. Crie um SQL Server lógico com o nome que você escolher. É recomendável
criá-lo no mesmo grupo de recursos em que você colocou o Azure Functions.
2. Crie um Banco de Dados SQL do Azure chamado Cookbookdatabase. Para
fazer isso, escolha Banco de dados em branco no menu suspenso Selecionar
origem da folha do Banco de Dados SQL ao criar o banco de dados.

[ 61 ]
Integração perfeita do Azure Functions com os Serviços do Azure

3. Crie uma regra de firewall para seu endereço IP clicando no botão Definir regra
de firewall na folha Visão geral. Assim, você poderá se conectar aos Bancos
de Dados SQL do Azure usando o SQL Server Management Studio (SSMS).
Se você não tem o SSMS, instale a versão mais recente. Faça download dele
em https://docs.microsoft.com/sql/ssms/download-sql-server-
management-studio-ssms.
4. Clique no link Mostrar cadeias de conexão de banco de dados na folha do
Essentials do Banco de Dados SQL, como mostrado na captura de tela a seguir:

5. Copie a cadeia de conexão da folha a seguir. Substitua os modelos


your_username e your_password pelo seu nome de usuário e senha reais:

[ 62 ]
Capítulo 3

6. Abra o SSMS e conecte-se ao SQL Server lógico do Azure que você criou nas
etapas anteriores.
7. Quando estiver conectado, crie uma nova tabela chamada EmployeeInfo
usando o seguinte esquema:
CREATE TABLE [dbo].[EmployeeInfo](
[PKEmployeeId] [bigint] IDENTITY(1,1) NOT NULL,
[firstname] [varchar](50) NOT NULL,
[lastname] [varchar](50) NULL,
[email] [varchar](50) NOT NULL,
[devicelist] [varchar](max) NULL,
CONSTRAINT [PK_EmployeeInfo] PRIMARY KEY CLUSTERED
(
[PKEmployeeId] ASC
)
)

Como fazer isso...


Execute as seguintes etapas:

1. Navegue até seu aplicativo de função, crie um novo gatilho HTTP usando
o modelo HttpTrigger-CSharp, escolha o Nível de autorização como Anônimo.
2. Navegue até o editor de código de run.csx na função
SaveJSONToAzureSQLDatabase e substitua o código padrão pelo que será
mostrado a seguir. Este código captura os dados que são transmitidos para
o gatilho HTTP e os insere no banco de dados usando a API ADO.Net:
#r "Newtonsoft.Json"
#r "System.Data"

using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using System.Data.SqlClient;
using System.Data;

public static async Task<IActionResult> Run(HttpRequest req,


ILogger log)
{

[ 63 ]
Integração perfeita do Azure Functions com os Serviços do Azure

log.LogInformation("C# HTTP trigger function processed a


request.");

string firstname,lastname, email, devicelist;

string requestBody = await new StreamReader(req.Body).


ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
firstname = data.firstname;
lastname = data.lastname;
email = data.email;
devicelist = data.devicelist;

SqlConnection con =null;


Try
{
string query = "INSERT INTO EmployeeInfo
(firstname,lastname, email, devicelist) " + "VALUES (@firstname,@
lastname, @email, @devicelist) ";

con = new
SqlConnection("Server=tcp:azurecookbooks.database.
windows.net,1433;Initial Catalog=Cookbookdatabase;Persist Security
Info=False;User ID=username;Password=password;MultipleActiveResu
ltSets=False;Encrypt=True;TrustServerCertificate=False;Connection
Timeout=30;");
SqlCommand cmd = new SqlCommand(query, con);
cmd.Parameters.Add("@firstname", SqlDbType.VarChar,
50).Value = firstname;
cmd.Parameters.Add("@lastname", SqlDbType.VarChar,
50)
.Value = lastname;
cmd.Parameters.Add("@email", SqlDbType.VarChar, 50)
.Value = email;
cmd.Parameters.Add("@devicelist", SqlDbType.VarChar)
.Value = devicelist;
con.Open();
cmd.ExecuteNonQuery();
}
catch(Exception ex)
{
log.LogInformation(ex.Message);
}
Finally
{

[ 64 ]
Capítulo 3

if(con!=null)
{
con.Close();
}
}

return (ActionResult)new OkObjectResult($"Successfully


inserted the data.");

Você precisa validar cada um dos parâmetros de entrada. Para simplificar, o código que
valida os parâmetros de entrada não está incluído. Valide cada um dos parâmetros antes
de salvá-los no seu banco de dados. Também é uma prática recomendada armazenar
a cadeia de conexão nas configurações do aplicativo.

3. Vamos executar o gatilho HTTP usando os seguintes dados de teste diretamente


do console de teste do Azure Functions:
{
"firstname": "Praveen",
"lastname": "Kumar",
"email": "praveen@example.com",
"devicelist":
"[
{
'Type' : 'Mobile Phone',
'Company':'Microsoft'
},
{
'Type' : 'Laptop',
'Company':'Lenovo'
}
]"
}

Você precisa validar cada um dos parâmetros de entrada. Para simplificar, o código que
valida os parâmetros de entrada não está incluído. Valide cada um dos parâmetros antes
de salvá-los no seu banco de dados.

[ 65 ]
Integração perfeita do Azure Functions com os Serviços do Azure

4. Um registro foi inserido com êxito, como mostrado na captura de tela a seguir:

Como funciona...
O objetivo aqui era aceitar valores de entrada do usuário e salvá-los em um banco
de dados relacional onde os dados pudessem ser recuperados posteriormente para fins
operacionais. Para isso, usamos o Banco de Dados SQL do Azure, uma oferta de banco
de dados relacional também conhecida como banco de dados como serviço (DBaaS).
Criamos um novo Banco de Dados SQL e regras de firewall com as quais podemos nos
conectar remotamente da estação de trabalho de desenvolvimento local usando o SSMS.
Também criamos uma tabela chamada EmployeeInfo, que pode ser usada para salvar
dados.

Com a API ADO.NET, desenvolvemos um programa simples que se conecta ao Banco


de Dados SQL do Azure e insere dados na tabela EmployeeInfo.

Monitorar Tweets com Aplicativos


Lógicos e notificar quando um usuário
popular tweetar
Um dos meus colegas, que trabalha para um projeto de gestão de queixas sociais,
é responsável por monitorar os problemas que os usuários postam em plataformas
de mídia social, como Facebook, Twitter etc. Ele estava enfrentando um problema
de monitoramento contínuo de Tweets publicados no identificador do Twitter de seu
cliente com hashtags específicas. Sua principal tarefa era responder rapidamente aos
Tweets de usuários com uma quantidade enorme de seguidores, por exemplo, usuários
com mais de 50.000 seguidores. Então, ele estava procurando uma solução para manter
o monitoramento de uma hashtag específica e alertá-lo sempre que um usuário com
mais de 50.000 seguidores tweetar. Assim, sua equipe poderia responder rapidamente
a esse usuário.

[ 66 ]
Capítulo 3

Para simplificar, a condição verificará 200 seguidores, e não 50.000.

Antes de conhecer os Aplicativos Lógicos do Azure, eu pensava que levaria algumas


semanas para aprender, desenvolver, testar e implantar essa solução. Obviamente, levaria
um bom tempo para aprender, entender e consumir a API do Twitter (ou de qualquer
outro canal social) para obter as informações necessárias e criar uma solução completa
que resolvesse o problema.

Felizmente, depois de conhecer os Aplicativos Lógicos e seus conectores prontos para


uso, a criação de uma solução para o problema do meu amigo leva pouco menos
de 10 minutos.

Aqui, você aprenderá a criar um Aplicativo Lógico que se integre com o Twitter
(para monitorar Tweets) e o Gmail (para enviar emails).

Preparação
Para trabalhar com esse método, precisamos de:

• Uma conta válida do Twitter


• Uma conta válida do Gmail

Ao trabalhar com o método, precisaremos autorizar os Aplicativos Lógicos do Azure


a acessar suas contas.

Como fazer isso...


Seguiremos as seguintes etapas:

1. Crie um novo Aplicativo Lógico


2. Projete-o com conectores do Twitter e do Gmail
3. Teste-o tweetando com a hashtag específica

Criar um novo Aplicativo Lógico


Execute as seguintes etapas:

1. Faça logon no Portal de Gerenciamento do Azure, procure aplicativos


lógicos e selecione Aplicativo Lógico.

[ 67 ]
Integração perfeita do Azure Functions com os Serviços do Azure

2. Na folha Criar aplicativo lógico, depois de fornecer o Nome, Grupo de recursos,


Assinatura e Local, clique no botão Criar para criar o Aplicativo Lógico:

[ 68 ]
Capítulo 3

Criar o Aplicativo Lógico com conectores do Twitter


e do Gmail
Execute as seguintes etapas:

1. Depois de criar o Aplicativo Lógico, navegue até Designer de aplicativos lógicos


e escolha Aplicativo Lógico em Branco.
2. Em seguida, você deverá escolher Conectores. Na lista de Conectores, clique
em Twitter. Em seguida, você deverá se conectar ao Twitter fornecendo as
credenciais da sua conta na rede social. Se você já se conectou, verá diretamente
a lista de gatilhos associados ao conector do Twitter, como mostrado na captura
de tela a seguir:

3. Depois de clicar no gatilho do Twitter, você deverá informar o Texto da


pesquisa (por exemplo, hashtags e palavras-chave) e a Frequência com que
o Aplicativo Lógico deverá pesquisar os Tweets. Veja como ficarão os campos
depois que você informar os detalhes:

[ 69 ]
Integração perfeita do Azure Functions com os Serviços do Azure

4. Vamos adicionar uma nova condição. Para isso, é necessário clicar em Próxima
etapa, procurar condição e selecionar a ação Condição, como mostrado
na captura de tela a seguir:

5. A partir da instrução anterior, a tela a seguir será exibida, onde você poderá
escolher os valores para a condição e o que gostaria de adicionar quando
a condição for avaliada como true ou false:

[ 70 ]
Capítulo 3

6. Ao clicar no campo de entrada Escolher um valor, você receberá todos os


parâmetros em que poderia adicionar uma condição. Neste caso, precisamos
escolher Número de seguidores, como mostrado na captura de tela a seguir:

7. Depois de escolher o parâmetro Número de seguidores, crie uma condição


(O número de seguidores é maior ou igual a 200), como mostrado na captura
de tela a seguir:

[ 71 ]
Integração perfeita do Azure Functions com os Serviços do Azure

8. Na seção If true da Condição anterior, procure a conexão do Gmail e selecione


Gmail | Enviar email, como mostrado na captura de tela a seguir:

9. Será solicitado que você faça logon, caso ainda não tenha feito. Forneça suas
credenciais e autorize os Aplicativos Lógicos do Azure a acessar sua conta
do Gmail.
10. Após a autorização, você poderá marcar seu email com Adicionar conteúdo
dinâmico com os parâmetros do Twitter, como mostrado na captura de tela
a seguir:

[ 72 ]
Capítulo 3

Se a opção Número de seguidores não
aparecer na tela, clique no link Mostrar mais.

11. Quando terminar, clique no botão Salvar.

Testar a funcionalidade do Aplicativo Lógico


Execute as seguintes etapas:

1. Vamos publicar um Tweet com a hashtag #AzureFunctions, como mostrado


na captura de tela a seguir.

[ 73 ]
Integração perfeita do Azure Functions com os Serviços do Azure

2. Depois de aproximadamente um minuto, o Aplicativo Lógico será acionado.


Vamos navegar até a folha Visão geral do Aplicativo Lógico e visualizar
o Histórico de execuções:

3. Ótimo! Ele foi acionado duas vezes, e eu recebi os emails. Um deles é mostrado
na captura de tela a seguir:

Como funciona...
Você criou um novo Aplicativo Lógico e escolheu o conector do Twitter para monitorar
os Tweets publicados com a hashtag #AzureFunctions uma vez por minuto. Se houver
Tweets com essa hashtag, ele verificará se o número de seguidores é maior ou igual
a 200. Se o número de seguidores atender à condição, uma nova ação será criada com
um novo conector do Gmail que poderá enviar um email com o conteúdo dinâmico
que está sendo moldado usando os parâmetros do conector do Twitter.

Integrar Aplicativos Lógicos com


funções sem servidor
Você já sabe como integrar conectores diferentes usando Aplicativos Lógicos. Aqui,
implementaremos a mesma solução implementada no método anterior apenas movendo
a lógica condicional que verifica o número de seguidores para o Azure Functions.

[ 74 ]
Capítulo 3

Preparação
Antes de avançar, seguiremos as seguintes etapas:

1. Crie uma conta SendGrid (se já não tiver sido criada), pegue a chave da API
SendGrid e crie uma nova chave nas Configurações do aplicativo de função.
2. Instale o Postman para testar o gatilho HTTP. Você pode fazer download
da ferramenta em https://www.getpostman.com/.

Como fazer isso...


Execute as seguintes etapas:

1. Crie uma nova função escolhendo o gatilho HTTP e chame-a de


ValidateTwitterFollowerCount.
2. Navegue até a guia Integrar e adicione uma nova associação de saída, SendGrid,
clicando no botão Nova Saída:

3. Substitua o código padrão pelo que será mostrado a seguir e clique em Salvar.
Este código apenas verifica o número de seguidores . Se for maior que 200,
ele enviará um email:
#r "Newtonsoft.Json"
#r "SendGrid"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;

[ 75 ]
Integração perfeita do Azure Functions com os Serviços do Azure

using SendGrid.Helpers.Mail;
public static async Task<IActionResult> Run(HttpRequest req, IAsyn
cCollector<SendGridMessage> messages, ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a
request.");

string name = req.Query["name"];

string requestBody = await new StreamReader(req.Body).


ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);

string strTweet = "";


SendGridMessage message = new SendGridMessage();
if(data.followersCount >= 200)
{
strTweet = "Tweet Content" + data.tweettext;

message.SetSubject($"{data.Name} with {data.


followersCount} followers has posted a tweet");
message.SetFrom("donotreply@example.com");
message.AddTo("prawin2k@gmail.com");
message.AddContent("text/html", strTweet);

}
Else
{
message = null;
}
await messages.AddAsync(message);
return (ActionResult)new OkObjectResult($"Hello");
}

4. Teste a função usando o Postman. Para isso, escolha os parâmetros destacados na


captura de tela a seguir. Nas próximas etapas, depois de integrarmos a Função
ValidateTwitterFollowerCount do Azure, todos os parâmetros de entrada a
seguir, como followersCount, tweettext e Name, serão postados pelo conector
do Twitter do Aplicativo Lógico:

[ 76 ]
Capítulo 3

5. Crie um novo Aplicativo Lógico chamado


NotifywhenTweetedbyPopularUserUsingFunctions.
6. Comece a criar o aplicativo com o modelo Aplicativo Lógico em Branco,
escolha o conector do Twitter e configure o Texto da pesquisa, a Frequência
e o Intervalo.
7. Clique em Nova etapa para adicionar uma ação. Na seção Escolher uma ação,
selecione o Azure Functions como um conector, como mostrado na captura
de tela a seguir:

[ 77 ]
Integração perfeita do Azure Functions com os Serviços do Azure

8. Quando você clicar no Azure Functions, serão listados todos os aplicativos


de função do Azure disponíveis, como mostrado na captura de tela a seguir:

9. Clique no aplicativo de função no qual você criou a função


ValidateTwitterFollowerCount. Agora, selecione a função
ValidateTwitterFollowerCount, como mostrado na captura de tela a seguir:

[ 78 ]
Capítulo 3

10. Na próxima etapa, é necessário preparar a entrada JSON que precisa


ser transmitida do Aplicativo Lógico para a função do gatilho HTTP
ValidateTwitterFollowerCount que desenvolvemos. Vamos moldar
a entrada JSON da mesma maneira que fizemos ao testar a função do gatilho
HTTP usando o Postman, como mostrado na captura de tela a seguir (a única
diferença é que os valores, como followersCount, Name e tweettext,
agora são dinâmicos):

11. Depois que você revisar todos os parâmetros que a função


ValidateTwitterFollowerCount espera, clique no botão Salvar
para salvar as alterações.
12. Você pode aguardar alguns minutos ou publicar um Tweet com a hashtag
que configurou no campo de entrada Texto da pesquisa.

E mais...
Se você não visualizar o parâmetro dinâmico pretendido, clique no botão Ver mais,
como mostrado na captura de tela a seguir:

[ 79 ]
Integração perfeita do Azure Functions com os Serviços do Azure

Na função ValidateTwitterFollowerCount do Azure, codificamos


o limite de número de seguidores como 200. Uma prática recomendada
é armazenar esses valores como itens configuráveis nas Configurações
do aplicativo.

Consulte também
• Consulte Enviar uma notificação por email para o usuário final de modo dinâmico
no Capítulo 2, Trabalhar com notificações usando os serviços SendGrid e Twilio

Auditar dados do Cosmos DB usando


gatilhos de feed de alterações
Muitos de vocês já devem ter ouvido falar no Cosmos DB, pois ele se tornou muito
popular, e muitas organizações o utilizam devido aos recursos que ele oferece.

Aqui, aprenderemos sobre a integração do Azure Functions sem servidor com um


banco de dados NoSQL sem servidor no Cosmos DB. Saiba mais sobre o Cosmos DB
em https://docs.microsoft.com/azure/cosmos-db/introduction.

Muitas vezes, pode ser necessário manter logs de alterações de campos, atributos,
documentos e muito mais para fins de auditoria. No mundo dos bancos de dados
relacionais, você pode ter visto desenvolvedores usando gatilhos ou procedimentos
armazenados para implementar esse tipo de funcionalidade de auditoria, na qual
você escreve o código para armazenar dados em uma tabela de auditoria separada.

Aqui, veremos como é fácil concretizar o caso de uso anterior e auditar as coleções
do Cosmos DB escrevendo uma função simples que será acionada sempre que houver
uma alteração em um documento de uma coleção do Cosmos DB.

No mundo dos bancos de dados relacionais, uma coleção é o mesmo que


uma tabela, e um documento é o mesmo que um registro.

Preparação
Para começar, primeiro precisamos:

• Criar uma conta do Cosmos DB


• Criar uma nova coleção do Cosmos DB em que é possível armazenar dados na
forma de documentos

[ 80 ]
Capítulo 3

Criar uma nova conta do Cosmos DB


Navegue até o Portal do Azure e crie uma nova conta do Cosmos DB. Você precisará
fornecer:

• Uma assinatura válida e um grupo de recursos.


• Um nome de conta válido. Isso criará um ponto de extremidade em
<<accountname>>.document.azure.com.
• Uma API — defina como SQL. Assim, você poderá gravar consultas no SQL.
Fique à vontade para testar outras APIs.

Criar uma nova coleção do Cosmos DB


Execute as seguintes etapas:

1. Depois de criar a conta, você precisa criar um novo banco de dados e uma
coleção. Podemos criar ambos em uma única etapa diretamente do Portal.
2. Navegue até a guia Visão geral e clique no botão Adicionar coleção para criar
uma nova coleção:

3. Agora, você será direcionado à guia Data Explorer automaticamente, onde


deverá informar os seguintes detalhes:

Nome do campo Valor Comentário


ID do banco Contêiner de várias coleções
cookbookdatabase
de dados do Cosmos DB.
Nome da coleção em que você
ID da coleção cookbookdatacollection
armazenará os dados.

[ 81 ]
Integração perfeita do Azure Functions com os Serviços do Azure

Nome do campo Valor Comentário


Dependendo dos seus workloads
Capacidade de de produção, poderá ser necessário
Fixa (10 GB)
armazenamento usar a capacidade Ilimitada. Caso
contrário, poderá haver partições.
Capacidade da sua coleção do
Taxa de Cosmos DB. A performance das
transferência leituras e gravações na coleção
400
(400 - 10.000 depende da taxa de transferência
RU/s) configurada ao provisionar a
coleção.
4. Em seguida, clique no botão OK para criar a coleção. Se tudo correr bem, você
verá algo assim na guia Data Explorer da conta do Cosmos DB:

Criamos uma conta do Cosmos DB e uma coleção. Agora, aprenderemos a integrar a


coleção com uma nova Função do Azure e veremos como acioná-la sempre que houver
uma alteração na coleção do Cosmos DB.

Como fazer isso...


Execute as seguintes etapas:

1. Navegue até a conta do Cosmos DB e clique no menu Adicionar Função


do Azure na folha Todas as configurações da conta do Cosmos DB.

[ 82 ]
Capítulo 3

2. Agora, você será direcionado à folha Adicionar Função do Azure, onde escolherá
o aplicativo de função do Azure no qual gostaria de criar uma nova função
(gatilho do Cosmos DB) para ser acionada sempre que houver uma alteração
na coleção. Veja como isso será feito:

[ 83 ]
Integração perfeita do Azure Functions com os Serviços do Azure

3. Depois de revisar os detalhes, clique no botão Salvar (mostrado na captura


de tela anterior) para criar a nova função, que será acionada a cada alteração
feita na coleção. Vamos navegar rapidamente para o aplicativo de função do
Azure (no meu caso, é AzureFunctionCookBookV2) e ver se a nova função
com o nome cookbookdatacollectionTrigger foi criada. Veja uma captura
de tela do meu aplicativo de função:

4. Substitua o código padrão pelo código a seguir do gatilho do Azure Functions


Cosmos DB, que obtém uma lista de todos os documentos que foram atualizados.
O código a seguir apenas imprime o número de documentos que foram
atualizados e o ID do primeiro documento no console Logs:
#r "Microsoft.Azure.DocumentDB.Core"
using System;
using System.Collections.Generic;
using Microsoft.Azure.Documents;

public static void Run(IReadOnlyList<Document> input, ILogger log)


{

[ 84 ]
Capítulo 3

if (input != null && input.Count > 0)


{
log.LogInformation("Documents modified " + input.Count);
log.LogInformation("First document Id " + input[0].Id);
}
}

5. A integração da coleção do Cosmos DB e da Função do Azure foi concluída.


Agora, vamos adicionar um novo documento à coleção e ver como
o gatilho é disparado na ação. Abra uma nova guia (deixando a guia
cookbookdatacollectionTrigger aberta no navegador), navegue até
a coleção e crie um novo documento clicando no botão Novo documento,
como mostrado na captura de tela a seguir:

6. Depois de substituir o JSON padrão (que tem apenas um atributo ID) pelo
JSON que possui os atributos necessários, clique no botão Salvar para salvar
as alterações, navegue rapidamente para a outra guia do navegador, onde
a Função do Azure está aberta, e exiba os logs para ver a saída da função.
Veja a seguir como ficaram meus logs. Acabei de adicionar um valor ao atributo
ID do documento. Ele pode parecer diferente para você, dependendo da
sua estrutura JSON:

[ 85 ]
Integração perfeita do Azure Functions com os Serviços do Azure

Como funciona...
Para integrar o Azure Functions com o Cosmos DB, primeiro criamos uma conta do
Cosmos DB, além de um banco de dados e uma nova coleção nele. Depois que a coleção
foi criada, nós a integramos a partir do Portal do Azure clicando no botão Adicionar
Função do Azure, que está disponível no nível da conta do Cosmos DB. Escolhemos
o aplicativo de função necessário no qual queríamos criar um gatilho do Cosmos DB.
Depois que a integração foi concluída, criamos um exemplo de documento na coleção
do Cosmos DB e, em seguida, verificamos que a função foi acionada automaticamente
para todas as alterações (todas as leituras e gravações, mas não as exclusões) que
fizemos na coleção.

E mais...
Quando você integra o Azure Functions para rastrear alterações do Cosmos DB,
ele cria automaticamente uma nova coleção chamada locações, como mostrado
aqui. Lembre-se de que esse é um custo adicional, pois o custo no Cosmos DB
se baseia nas unidades de solicitação (RUs) alocadas para cada coleção:

É importante observar que o gatilho do Cosmos DB não seria acionado (no momento
da gravação) para nenhuma exclusão na coleção. Ele só é acionado para criações
e atualizações de documentos em uma coleção. Se for importante rastrear as exclusões,
você precisará fazer soft deletes, o que significa definir um atributo como IsDeleted
como true para registros que são excluídos pelo aplicativo e, com base no valor do
atributo isDeleted, implementar sua lógica personalizada no gatilho do Cosmos DB.

A integração que fizemos entre o Azure Functions e o Cosmos DB usa os feeds


de alterações do Cosmos DB. Saiba mais sobre os feeds de alterações aqui:
https://docs.microsoft.com/azure/cosmos-db/change-feed.

Não se esqueça de excluir a conta do Cosmos DB e suas coleções associadas se você


acredita que não as usará mais, pois as coleções são cobradas com base nas RUs alocadas,
mesmo que você não as utilize ativamente.

Se você não conseguir executar essa Função do Azure ou se receber um erro informando
que as extensões do Cosmos DB não estão instaladas, tente criar um novo gatilho
do Azure Cosmos DB, que deverá solicitar a instalação.

[ 86 ]
Noções básicas sobre
a experiência integrada
de desenvolvedor de
Ferramentas do Visual Studio
Neste capítulo, vamos abordar o seguinte:
• Criação de um aplicativo de função usando o Visual Studio 2017
• Depuração de C# do Azure Functions em um ambiente local de preparação
usando o Visual Studio 2017
• Conexão à nuvem de armazenamento do Azure a partir do ambiente
local do Visual Studio
• Implantação do aplicativo Azure Functions para a Nuvem do Azure usando
o Visual Studio
• Depuração de C# do Azure Functions ao vivo, hospedada no ambiente
de Nuvem do Microsoft Azure, usando o Visual Studio
• Implantação do Azure Functions em um contêiner

Introdução
Nos capítulos anteriores, examinamos como criar o Azure Functions diretamente
do Portal de Gerenciamento do Azure. Aqui estão algumas das características:
• Você pode criar rapidamente uma função apenas selecionando um dos modelos
internos fornecidos pelo Tempo de Execução do Azure Functions
• Os desenvolvedores não precisam se preocupar em escrever o código de conexão
e compreender o funcionamento das estruturas
• As alterações de configuração podem ser feitas diretamente na interface
do usuário usando o editor padrão
[ 87 ]
Noções básicas sobre a experiência integrada de desenvolvedor de Ferramentas do Visual Studio

Apesar de todas as vantagens mencionadas, os desenvolvedores podem estranhar


caso estejam acostumados a trabalhar com os ambientes de desenvolvimento integrado
(IDEs) há muito tempo. A equipe da Microsoft apresentou algumas ferramentas que
ajudam os desenvolvedores a integrá-los no Visual Studio para que possam aproveitar
alguns dos recursos críticos do IDE que aceleram seus esforços de desenvolvimento.
Aqui estão alguns deles:

• Os desenvolvedores aproveitam o suporte do IntelliSense


• Você pode depurar o código linha por linha
• Visualize rapidamente os valores das variáveis, enquanto depura o aplicativo
• Integração com sistemas de controle de versão, como o Azure DevOps
(antes, ele era chamado de Visual Studio Team Services (VSTS))

Hoje, no momento que escrevo, as ferramentas do Visual Studio para a função


oferecem suporte à depuração somente para C#. No futuro, a Microsoft provavelmente
disponibilizará esses recursos para outros idiomas.

Você conhecerá alguns dos recursos já citados neste capítulo e verá como integrar
o código com o Azure DevOps no capítulo 11, Como implementar e implantar a integração
contínua usando o Azure DevOps.

Criação de um aplicativo de função


usando o Visual Studio 2017
Nesta receita, você saberá como criar um Azure Functions para seu IDE favorito
no Visual Studio 2017.

Preparação
Você precisa fazer download e instalar as seguintes ferramentas e software:

1. Faça download da versão mais recente do Visual Studio 2017. Você pode fazer
download em https://visualstudio.microsoft.com/downloads/.
2. Durante a instalação, escolha desenvolvimento do Azure na seção Workloads,
conforme mostrado na captura de tela a seguir e clique no botão Instalar:

[ 88 ]
Capítulo 4

3. Navegue até Ferramentas | Extensões e Atualizações e veja se há atualizações


em Ferramentas do Visual Studio para o Azure Functions, conforme mostrado na
seguinte captura de tela:

[ 89 ]
Noções básicas sobre a experiência integrada de desenvolvedor de Ferramentas do Visual Studio

Como fazer isso...


Execute as seguintes etapas:

1. Abra o Visual Studio, escolha Arquivo e clique em Novo Projeto. Na caixa


de diálogo Novo Projeto, nos modelos Instalados, em Visual C#, selecione
Nuvem e, depois, o modelo Azure Functions:

2. Forneça o nome do aplicativo de função. Clique no botão OK para ir para


a próxima etapa. Conforme mostrado na captura de tela a seguir, escolha
Azure Funtions v2 (.NET Core) no menu suspenso, selecione Gatilho HTTP
e clique no botão OK:

[ 90 ]
Capítulo 4

3. Criamos com êxito o aplicativo Azure Functions , juntamente com um gatilho


HTTP (que aceita solicitações da Web e envia uma resposta ao cliente), com
o nome Function1. Sinta-se à vontade para alterar o nome padrão do aplicativo
de função e também certifique-se de criar o aplicativo para fazer download
dos pacotes NuGet necessários, se houver.
4. Depois de criar uma nova função, uma nova classe também será criada, conforme
mostrado na seguinte captura de tela:

Criamos com êxito um novo aplicativo de função acionado por HTTP usando o Visual
Studio 2017.

[ 91 ]
Noções básicas sobre a experiência integrada de desenvolvedor de Ferramentas do Visual Studio

Como funciona...
Ferramentas do Visual Studio para o Azure Functions permitem que os desenvolvedores
utilizem seu IDE favorito, já utilizado há muito tempo. Com as ferramentas do Azure
Function, você pode usar o mesmo conjunto de modelos que o Portal de Gerenciamento
do Azure fornece para criar e integrar rapidamente com os serviços de nuvem sem
escrever códigos de conexão (ou mínimos).

A outra vantagem de usar ferramentas do Visual Studio para funções é que você
não precisa ter uma assinatura do Azure ao vivo. Você pode depurar e testar o Azure
Functions diretamente no ambiente de desenvolvimento local. A CLI do Azure e os
utilitários relacionados nos fornecem a assistência necessária para executar o Azure
Functions.

E mais...
Um dos problemas mais comuns enfrentados pelos desenvolvedores ao desenvolver
qualquer aplicativo no ambiente local é que tudo funciona bem na máquina local, mas não
no ambiente de produção. Os desenvolvedores não precisam se preocupar com isso no
caso do Azure Functions. O tempo de execução do Azure Functions fornecido pelas
ferramentas da CLI do Azure é exatamente igual ao tempo de execução disponível
na Nuvem do Azure.

Observe que você sempre poderá usar e acionar um serviço do Azure


em execução na nuvem, mesmo quando estiver desenvolvendo o Azure
Functions localmente.

Depuração de C# do Azure Functions em


um ambiente local de preparação usando
o Visual Studio 2017
Quando a configuração da criação de nossa função estiver concluída, a próxima etapa
será começar a desenvolver o aplicativo de acordo com suas necessidades. Desenvolver
códigos diariamente não é uma tarefa fácil; desenvolvedores acabam enfrentando todo
tipo de problema técnico. Eles precisam de ferramentas para ajudá-los a identificar
a causa raiz do problema e corrigi-lo para garantir que apresentem a solução. Essas
ferramentas incluem ferramentas de depuração que ajudam os desenvolvedores
a entrar em cada linha do código para exibir os valores da variável e os objetos,
além de obter uma exibição detalhada das exceções.

Nesta receita, você saberá como configurar e depurar o Azure Functions em um ambiente
de desenvolvimento local no Visual Studio.

[ 92 ]
Capítulo 4

Preparação
Faça download e instale a CLI do Azure (caso essas ferramentas não estejam instaladas,
note que o Visual Studio fará download automático delas quando você executar suas
funções a partir do Visual Studio).

Como fazer isso...


Execute as seguintes etapas:

1. Em nossa receita anterior, criamos a função HTTPTrigger usando o Visual


Studio. Vamos compilar o aplicativo clicando em Criar e em Criar Solução.
2. Abra o arquivo HTTPTriggerCSharpFromVS.cs e crie um ponto de interrupção
pressionando a tecla F9, conforme mostrado na seguinte captura de tela:

[ 93 ]
Noções básicas sobre a experiência integrada de desenvolvedor de Ferramentas do Visual Studio

3. Pressione a tecla F5 para começar a depurar a função. Quando você pressionar F5


pela primeira vez, o Visual Studio solicitará que faça download das ferramentas
CLI do Visual Studio se elas ainda não estiverem instaladas. Essas ferramentas
são essenciais para executar um Azure Functions no Visual Studio:

A CLI do Azure Functions foi renomeada como Azure Functions


Core Tools. Saiba mais sobre elas em https://www.npmjs.com/
package/azure-functions-core-tools.

4. Clique em Sim na captura de tela anterior para começar a fazer download das
ferramentas da CLI. O download e a instalação das ferramentas da CLI levarão
alguns minutos.
5. Após a instalação com êxito das ferramentas da CLI do Azure Functions,
um host de trabalho será criado e iniciado. Ele começa a monitorar solicitações
em uma porta específica para todas as funções do nosso aplicativo de função.
Esta é a captura de tela que mostra que o host de trabalho começou a monitorar
as solicitações para o aplicativo de função:

[ 94 ]
Capítulo 4

6. Vamos tentar acessar o aplicativo de função fazendo uma solicitação a


http://localhost:7071 no seu navegador favorito:

[ 95 ]
Noções básicas sobre a experiência integrada de desenvolvedor de Ferramentas do Visual Studio

7. Algo essencial na URL completa do nosso gatilho HTTP é o navegador. Ela deve
ter esta aparência: http://localhost:7071/api/HttpTriggerCsharpFromV
S?name=Praveen Sreeram.
8. Depois de digitar a URL correta do Azure Functions, assim que pressionarmos
a tecla Enter na barra de endereços do navegador, o depurador do Visual Studio
atingirá o ponto de depuração (se você tiver um), conforme mostrado na seguinte
captura de tela:

9. Você também pode exibir os dados de suas variáveis, conforme mostrado na


seguinte captura de tela:

10. Depois de concluir a depuração, você pode clicar na tecla F5 para concluir o
processo de execução, após o qual você verá a resposta de saída no navegador,
conforme mostrado na seguinte captura de tela:

11. O log de execução da função aparecerá no console do host de trabalho, conforme


mostrado na seguinte captura de tela:

[ 96 ]
Capítulo 4

12. Você pode adicionar mais Azure Functions ao aplicativo de função,


se necessário. Na próxima receita, vamos examinar como se conectar
à nuvem de armazenamento do Azure a partir do ambiente local.

Como funciona...
O host de trabalho funciona como um servidor que escuta uma porta específica.
Se houver solicitações para essa porta específica, ele automaticamente cuidará
da execução das solicitações e enviará uma resposta.

O console de host de trabalho fornece os seguintes detalhes:

• O status da execução, juntamente com os dados de solicitação e resposta


• Os detalhes sobre todas as funções disponíveis no aplicativo de função

E mais...
Usando o Visual Studio, você pode criar diretamente funções pré-compiladas. Isso
significa que, quando você cria suas funções, o Visual Studio cria um arquivo .dll
que pode ser indicado em outros aplicativos, assim como você faz com suas classes
regulares. Estas são duas das vantagens de usar funções pré-compiladas:

• As funções pré-compiladas têm melhor performance, já que não precisam


ser compiladas em tempo real
• Você pode converter facilmente suas classes tradicionais em Azure Functions
e consultá-las em outros aplicativos sem problemas

[ 97 ]
Noções básicas sobre a experiência integrada de desenvolvedor de Ferramentas do Visual Studio

Conexão à nuvem de armazenamento


do Azure a partir do ambiente local
do Visual Studio
Nas duas receitas anteriores, você aprendeu como criar e executar o Azure Functions
em um ambiente local. Acionamos a função de um navegador local. No entanto, nesta
receita, você aprenderá a disparar o Azure Functions em seu ambiente local quando
ocorre um evento no Azure. Por exemplo, quando um novo blob é criado em uma conta
de armazenamento do Azure, sua função pode ser disparada na máquina local. Isso ajuda
os desenvolvedores a testar seus aplicativos no início, antes de implantá-los no ambiente
de produção.

Preparação
Execute os seguintes pré-requisitos:

1. Crie uma conta de armazenamento e, em seguida, um contêiner


de blob denominado cookbookfiles, no Azure.
2. Instale o Gerenciador de Armazenamento do Microsoft Azure de
http://storageexplorer.com/.

Como fazer isso...


Execute as seguintes etapas:

1. Abra o aplicativo Azure Functions FunctionAppInVisualStudio no


Visual Studio e, em seguida, adicione uma nova função clicando com o botão
direito no projeto FunctionAppInVisualStudio. Clique em Adicionar
| Nova Função do Azure, que abre um popup. Aqui, no campo de nome,
insira BlobTriggerCSharp e clique no botão Adicionar.
2. Isso abre outro popup, em que você pode fornecer outros parâmetros, como
mostrado na seguinte captura de tela:

[ 98 ]
Capítulo 4

3. Nas configurações de conexão da conta de armazenamento, forneça


AzureWebJobsStorage como o nome da cadeia de conexão e também forneça
o nome do contêiner de blob (no meu caso, ele é cookbookfiles) no campo
de entrada Caminho e, depois, clique no botão OK para criar a nova função
de gatilho de blob. Uma nova função de gatilho de blob é criada, conforme
mostrado nesta captura de tela:

[ 99 ]
Noções básicas sobre a experiência integrada de desenvolvedor de Ferramentas do Visual Studio

4. Se estiver lembrado da receita do capítulo 1, Criar uma API Web de back-end


usando gatilhos HTTP, Desenvolver aplicativos de nuvem usando associações e gatilhos
de função, o portal de gerenciamento do Azure nos permitiu escolher entre uma
conta de armazenamento nova ou existente. No entanto, a caixa de diálogo
anterior não está conectada à sua assinatura do Azure. Portanto, você precisa
navegar até a conta de armazenamento e copiar a cadeia de conexão, que pode ser
encontrada na folha de Chaves de acesso da conta de armazenamento no Portal
de gerenciamento do Azure, conforme mostrado na seguinte captura de tela:

5. Cole a cadeia de conexão no arquivo local.settings.json, que está na


pasta raiz do projeto. Este arquivo é criado quando você cria o aplicativo
de função. Após você adicionar a cadeia de conexão à chave denominada
AzureWebJobsStorage, o arquivo local.settings.json deverá ter esta
aparência na seguinte captura de tela:

6. Abra o arquivo BlobTriggerCSharp.cs e crie um ponto de interrupção,


conforme mostrado na seguinte captura de tela:

[ 100 ]
Capítulo 4

7. Agora pressione a tecla F5 para iniciar o host de trabalho, conforme mostrado


na seguinte captura de tela:

8. Adicionei um novo arquivo de blob usando o Explorador de armazenamento


do Azure, conforme mostrado nesta captura de tela:

[ 101 ]
Noções básicas sobre a experiência integrada de desenvolvedor de Ferramentas do Visual Studio

9. Assim que o blob for adicionado ao contêiner especificado (neste caso, ele é
cookbookfiles), que está na nuvem em um local remoto, o host de trabalho em
execução no meu computador local detectará que um novo blob foi adicionado
e o depurador atingiu a função, como mostrado na seguinte captura de tela:

Como funciona...
Nesta classe BlobTriggerCSharp, o método Run tem os atributos WebJobs com uma
cadeia de conexão (neste caso, ela é AzureWebJobsStorage). Isso orienta o tempo
de execução a referenciar a cadeia de conexão do armazenamento do Azure no arquivo
de configuração de configurações locais com a chave nomeada após a cadeia de
conexão AzureWebJobsStorage. Quando o host de trabalho começa a ser executado,
ele usa a cadeia de conexão e observa os contêineres de contas de armazenamento
que especificamos. Sempre que um novo blob é adicionado ou atualizado, ele dispara
automaticamente o gatilho de blob no ambiente atual.

E mais...
Ao criar o Azure Functions no Portal de gerenciamento do Azure, você precisa criar
gatilhos e associações de saída na guia Integrar de cada Azure Function. No entanto,
quando você cria uma função do IDE do Visual Studio 2017, só pode configurar atributos
WebJobs para atingir isso.

Para saber mais sobre os atributos WebJobs, visite https://docs.


microsoft.com/azure/app-service/webjobs-sdk-get-
started.

[ 102 ]
Capítulo 4

Implantação do aplicativo Azure Functions


para a Nuvem do Azure usando o Visual
Studio
Até agora, nosso aplicativo de função é apenas um aplicativo comum no Visual Studio.
Para implantar o aplicativo de função junto com suas funções, precisamos criar os novos
recursos a seguir ou selecionar os existentes para hospedar o novo aplicativo de função:
• O grupo de recursos
• O plano de serviço de aplicativo
• O aplicativo Azure Functions

Você pode fornecer todos esses detalhes diretamente do Visual Studio sem abrir o Portal
de gerenciamento do Azure. Nesta receita, você aprenderá a fazer isso.

Como fazer isso...


Execute as seguintes etapas:

1. Clique com o botão direito do mouse no projeto e clique no botão Publicar


para abrir a janela publicar.
2. Na janela Publicar, escolha a opção Criar Novo e clique no botão Publicar,
conforme mostrado na seguinte captura de tela:

[ 103 ]
Noções básicas sobre a experiência integrada de desenvolvedor de Ferramentas do Visual Studio

3. Na janela Criar Serviço de Aplicativo, você pode escolher entre os recursos


existentes ou clicar no botão Novo para escolher o novo Grupo de Recursos,
o plano do Serviço de Aplicativo e a Conta de Armazenamento, como mostrado
na seguinte captura de tela:

4. Na maioria dos casos, a melhor opção é o plano de consumo para hospedar


o Azure Functions, a menos que você tenha um motivo forte para não fazê-lo
e preferir utilizar um dos seus serviços de aplicativo existentes. Para escolher
o plano de consumo, você precisa clicar no botão Novo que está disponível
para o plano de serviço de aplicativo, como mostrado na captura de tela anterior.
Selecione Consumo no menu suspenso Tamanho e clique no botão OK, como
mostrado na seguinte captura de tela:

[ 104 ]
Capítulo 4

5. Depois de revisar todas as informações, clique no botão Criar da janela Criar


Serviço de Aplicativo. Isso deve começar a implantar os serviços no Azure,
conforme mostrado nesta captura de tela:

6. Se tudo correr bem, você poderá exibir o aplicativo de função recém-criado


no Portal de gerenciamento do Azure, conforme mostrado na seguinte captura
de tela:

[ 105 ]
Noções básicas sobre a experiência integrada de desenvolvedor de Ferramentas do Visual Studio

7. Um momento! Nosso trabalho no Visual Studio ainda não foi concluído.


Acabamos de criar os serviços necessários no Azure diretamente do IDE do
Visual Studio. Nossa próxima tarefa é publicar o código da estação de trabalho
local na nuvem do Azure. Assim que a implementação for concluída, você
passará para a etapa de implantação da Web, conforme mostrado na captura
de tela. Clique no botão Publicar para iniciar o processo de publicação do código:

8. Após alguns segundos, você verá algo semelhante à seguinte captura de tela
na janela de Saída da sua instância do Visual Studio:

9. É isso. Concluímos a implantação do seu aplicativo de função e suas funções


para o Azure diretamente do seu IDE de desenvolvimento favorito, o Visual
Studio. Você pode revisar a implantação da função no Portal de gerenciamento
do Azure. Ambas os Azure Functions foram criados com êxito, conforme
mostrado na seguinte captura de tela:

[ 106 ]
Capítulo 4

E mais...
Os Azure Functions criados a partir do Visual Studio 2017 são pré-compilados. Isso
significa que você implanta os arquivos .dll do Visual Studio 2017 para o Azure.
Portanto, você não pode editar o código das funções no Azure depois de implantá-los.
No entanto, você pode fazer alterações nas configurações, tais como alterar a cadeia
de conexão do Armazenamento do Azure, o caminho do contêiner e assim por diante.
Veremos como fazer isso na próxima receita.

Depuração de um C# do Azure Functions


ao vivo, hospedada no ambiente de Nuvem
do Microsoft Azure, usando o Visual Studio
Em uma das receitas anteriores, Conectando-se à nuvem de armazenamento do Azure
a partir do ambiente local do Visual Studio, você aprendeu como conectar a conta de
armazenamento em nuvem do código local. Nesta receita, você aprenderá a depurar
o código ao vivo em execução no ambiente de nuvem do Azure. Executaremos
as seguintes etapas na função BlobTriggerCSharp do aplicativo de função
FunctionAppinVisualStudio:

• Alterar o caminho do contêiner no Portal de gerenciamento do Azure para


o novo contêiner
• Abrir o aplicativo de função no Visual Studio 2017
• Anexar o depurador do Visual Studio 2017 para o Azure Functions necessário
• Criar um blob no novo contêiner de armazenamento
• Depurar o aplicativo após atingir os pontos de interrupção

[ 107 ]
Noções básicas sobre a experiência integrada de desenvolvedor de Ferramentas do Visual Studio

Preparação
Crie um contêiner denominado cookbookfiles-live na conta de armazenamento.
Vamos carregar um blob neste contêiner.

Como fazer isso...


Execute as seguintes etapas:

1. Navegue até a função BlobTriggerCSharp no Portal de gerenciamento do


Azure e altere o caminho da variável path para apontar para o novo contêiner
cookbookfiles-live. Em seguida, publique-o novamente. Ele deve ser
parecido com o mostrado na seguinte captura de tela:

2. Abra o aplicativo de função no Visual Studio 2017. Abra


o Gerenciador de Servidores e navegue até o Azure Function;
Neste caso, o FunctionAppinVisualStudio2017, como mostrado
na seguinte captura de tela:

[ 108 ]
Capítulo 4

3. Clique com o botão direito do mouse em Anexar Depurador, como mostrado


na seguinte captura de tela:

[ 109 ]
Noções básicas sobre a experiência integrada de desenvolvedor de Ferramentas do Visual Studio

4. O Visual Studio levará algum tempo para habilitar a depuração remota,


conforme mostrado na seguinte captura de tela:

5. A URL do aplicativo de função será aberta no navegador, conforme mostrado


na seguinte captura de tela, indicando que nosso aplicativo de função está em
execução:

6. Navegue até Gerenciador de Armazenamento e carregue um novo arquivo


(neste caso, carreguei EmployeeInfo.json) no contêiner cookbookfiles-
live, conforme mostrado nesta captura de tela:

[ 110 ]
Capítulo 4

7. Após alguns instantes, o ponto de interrupção de depuração será atingido, mostrado


da seguinte maneira, em que você pode exibir o nome do arquivo que foi carregado:

Implantação do Azure Functions


em um contêiner
Imagino que você já tenha entendido o que leva ao uso do Azure Functions. Sim —
ao desenvolver um código e implantá-lo em um ambiente sem servidor, em que um
desenvolvedor ou administrador não precisa se preocupar com o provisionamento
e a escala de instâncias para hospedar seus aplicativos do servidor.

Tornar todos os recursos sem servidor só será possível quando


você criar seu Aplicativo de Função, escolhendo o plano de
consumo no menu suspenso Plano de Hospedagem.

[ 111 ]
Noções básicas sobre a experiência integrada de desenvolvedor de Ferramentas do Visual Studio

Ao observar o título desta receita, talvez você já esteja se perguntando por que e como
implantar um Azure Functions em um contêiner do Docker ajudaria. Sim, a combinação
do Azure Functions e do Contêiner do Docker talvez não faça sentido, pois você perderia
todos os benefícios da falta de servidor do Azure Functions ao implantar no Docker. No
entanto, pode haver alguns clientes cujos workloads existentes estejam na nuvem (pública
ou privada), mas agora eles desejam aproveitar alguns dos gatilhos do Azure Functions
e dos Serviços do Azure relacionados. Portanto, eles desejam implantar o Azure Functions
como uma imagem do Docker. Esta receita mostra como implementar isso.

Preparação
Estes estão os pré-requisitos para começar com esta receita:

• Instale a CLI do Azure a partir de https://docs.microsoft.com/cli/


azure/install-azure-cli?view=azure-cli-latest
• Você pode fazer download do Docker a partir de https://store.docker.
com/editions/community/docker-ce-desktop-windows. Instale a versão
do Docker que seja compatível com o sistema operacional do seu ambiente de
desenvolvimento.
• Também é necessário o conhecimento básico do Docker e seus comandos para
compilar e executar imagens do Docker. Examine a documentação oficial do
Docker para aprender isso caso você ainda não tenha esse conhecimento.
• Crie um Registro de Contêiner do Azure (ACR) com as etapas a seguir. Isso
pode ser usado como um repositório para todas as imagens do Docker.

[ 112 ]
Capítulo 4

Criando um ACR
Execute as seguintes etapas:

1. Crie um novo ACR fornecendo os seguintes detalhes, como mostrado nesta


captura de tela:

[ 113 ]
Noções básicas sobre a experiência integrada de desenvolvedor de Ferramentas do Visual Studio

2. Depois que o ACR for criado com êxito, navegue até a folha de Chaves de Acesso
e anote o Servidor de login, o Nome de usuário e a senha, que são destacados
na captura de tela a seguir. Você utilizará isso mais adiante nesta receita:

Como fazer isso...


Nos três primeiros capítulos, criamos o aplicativo de função e as funções diretamente
no portal. Até aqui, neste capítulo, criamos o aplicativo de função e as funções no próprio
Visual Studio.

Antes de começar, vamos fazer uma pequena alteração no HTTPTrigger para entender
que o código está sendo executado a partir do Docker, como destacado na imagem
a seguir. Para fazer isso, acabei de adicionar uma mensagem Do Docker para a saída,
da seguinte maneira:

[ 114 ]
Capítulo 4

Criação de uma imagem do Docker para


o aplicativo de função
Execute as seguintes etapas:

1. A primeira etapa na criação de uma imagem do Docker é criar um Dockerfile em


nosso projeto do Visual Studio. Crie um .Dockerfile com o seguinte conteúdo:
FROM microsoft/azure-functions-dotnet-core2.0:2.0 COPY ./bin/
Release/netstandard2.0 /home/site/wwwroot

2. Em seguida, navegue até o prompt de comando e execute o seguinte comando do


Docker, docker build -t functionsindocker, tomando cuidado para não
perder o ponto no final do comando, para criar uma imagem do Docker. Após
executar o comando docker build, você verá algo semelhante ao que aparece
nesta captura de tela:

3. Após a criação da imagem com êxito, a próxima etapa será executar a imagem
do Docker em uma porta específica. Execute o comando para executá-la. Você
deverá ver algo como a seguinte captura de tela:

[ 115 ]
Noções básicas sobre a experiência integrada de desenvolvedor de Ferramentas do Visual Studio

4. Verifique se tudo está funcionando bem no ambiente local navegando até o host
local com a porta direita, conforme mostrado na captura de tela a seguir.

Como mover a imagem do Docker para o ACR


Execute as seguintes etapas:

1. A primeira etapa é garantir que forneçamos uma marca válida para a imagem
usando o comando docker tag functionsindocker cookbookregistry.
azurecr.io/functionsindocker:v1. A execução deste comando não
fornecerá resultados. No entanto, para exibir nossas alterações, vamos executar
o comando docker images, conforme mostrado na seguinte captura de tela:

2. Para enviar a imagem ao ACR, você precisa autenticar-se no Azure. Para fazer
isso, você pode usar comandos da CLI do Azure. Vamos fazer logon no Azure
usando o comando az login. A execução deste comando abrirá um navegador e
autenticará suas credenciais, conforme mostrado nesta captura de tela:

[ 116 ]
Capítulo 4

3. A próxima etapa é autenticar-se no ACR usando o comando az acr login


--name cookbookregistry. Substitua o nome do ACR (no meu caso, ele
é cookbookregistry) por aquele criado por você:

4. Depois de autenticar-se, você pode enviar a imagem para o ACR,


executando o comando docker push cookbookregistry.azurecr.io/
functionsindocker:v1, conforme mostrado na seguinte captura de tela:

5. Vamos navegar para o ACR no portal do Azure e analisar se a nossa imagem foi
enviada para ela corretamente na folha Repositórios, como mostrado na seguinte
captura de tela:

Criamos com êxito uma imagem e a enviamos para o ACR. Agora, precisamos criar
o Azure Functions e referenciar a imagem do Docker que foi enviada para o ACR.

[ 117 ]
Noções básicas sobre a experiência integrada de desenvolvedor de Ferramentas do Visual Studio

Criação um novo aplicativo de função com


o Docker
Execute as seguintes etapas:

1. Navegue até a folha Novo | Aplicativo de Função e forneça as seguintes informações:

2. Agora, escolha Linux (Visualização) no campo OS e escolha Imagem do Docker


no campo Publicar Em seguida, clique em Plano de Serviço de Aplicativo/Local,
conforme mostrado na captura de tela anterior. Aqui, opte por criar um novo
plano de Serviço de Aplicativo Básico.
[ 118 ]
Capítulo 4

3. O passo seguinte e mais importante é indicar a imagem que enviamos ao ACR.


Para fazer isso, clique no botão Configurar contêiner e escolha Registro
de Contêiner do Azure. Depois, escolha a imagem correta, conforme
mostrado na seguinte captura de tela:

4. Depois de revisar todos os detalhes, clique no botão Criar para criar o aplicativo
de função.
5. É isso. Criamos um Aplicativo de Função que pode permitir implantar
as imagens do Docker, vinculando-as à imagem hospedada no Registro de
Contêiner do Azure. Vamos testar rapidamente o HttpTrigger navegando até
o ponto de extremidade HTTP no navegador. Veja a seguir o resultado do Azure
Functions.

Como funciona...
Nos três primeiros capítulos, criamos o aplicativo de função e as funções diretamente
no portal. Por outro lado, neste capítulo, criamos o aplicativo de função e as funções
no próprio Visual Studio.

[ 119 ]
Noções básicas sobre a experiência integrada de desenvolvedor de Ferramentas do Visual Studio

Nesta receita, fizemos o seguinte:

Os pontos numerados neste diagrama referem-se às seguintes etapas:

1. Crie uma imagem do Docker do aplicativo de função que criamos neste capítulo
usando o Visual Studio.
2. Envie a imagem do Docker para o ACR
3. No portal, crie um novo aplicativo de função, escolhendo publicar
o pacote executável como uma imagem do Docker
4. Anexe a imagem do Docker do ACR (da etapa 2 no guia anterior)
ao Azure Functions (da etapa 3 no guia anterior)

[ 120 ]
Exploração de ferramentas
de testes para a validação do
Azure Functions
Neste capítulo, vamos explorar diferentes maneiras de testar o Azure Functions mais
detalhadamente com as seguintes receitas:

• Testes do Azure Functions:


°° Testes de gatilhos HTTP usando o Postman
°° Testes do gatilho de blob usando o Gerenciador de Armazenamento
do Microsoft
°° Testes do gatilho de fila usando o Portal de gerenciamento do Azure

• Testes de um Azure Functions em um ambiente de teste utilizando slots


de implantação
• Testes de carga do Azure Functions usando o Azure DevOps
• Criação e testes locais do Azure Functions usando ferramentas da CLI do Azure
• Testes e validação da capacidade de resposta do Azure Functions usando
o Application Insights
• Desenvolvimento de testes de unidade para o Azure Functions com
gatilhos HTTP

Introdução
Nos capítulos anteriores, você aprendeu a desenvolver o Azure Functions, identificou
onde ele é útil e verificou a validação da funcionalidade dessas funções.

[ 121 ]
Exploração de ferramentas de testes para a validação do Azure Functions

Neste capítulo, vamos começar a verificar maneiras de testar diferentes Azure Functions.
Isso inclui, por exemplo, a execução de testes de funções de gatilho de HTTP usando
o Postman e o Gerenciador de Armazenamento do Microsoft para testar gatilhos de blob
do Azure, gatilhos de fila e outros gatilhos relacionados ao serviço de armazenamento.
Você também aprenderá como executar um teste de carga simples em um gatilho de
HTTP, para ajudá-lo a entender como a arquitetura sem servidor funciona, provisionando
as instâncias no back-end. Os desenvolvedores não precisarão se preocupar com as
configurações de escala em diferentes fatores. O tempo de execução do Azure Functions
cuidará automaticamente da escala das instâncias.

Você também aprenderá a configurar um teste que verifica a disponibilidade de nossas


funções ao continuamente executar ping dos pontos de extremidade do aplicativo
em uma frequência predefinida de vários locais.

Testes do Azure Functions


O tempo de execução do Azure Function nos permite criar e integrar muitos serviços do
Azure. No momento da gravação, você pode escolher entre 20 tipos do Azure Functions
para criar. Nesta receita, você aprenderá como testar os Azure Functions mais comuns,
listados da seguinte maneira:

• Testes de gatilhos HTTP usando o Postman


• Testes do gatilho de blob usando o Gerenciador de Armazenamento do Microsoft
• Testes do gatilho de fila usando o portal de gerenciamento do Azure

Preparação
Instale as seguintes ferramentas se ainda não tiver feito isso:

• Postman: Você pode fazer download disso em https://www.getpostman.com/


• Gerenciador de Armazenamento do Microsoft Azure: Você pode fazer
download disso em http://storageexplorer.com/

Você pode usar o Gerenciador de Armazenamento para conectar-se às suas contas


de armazenamento e exibir todos os dados disponíveis de diferentes serviços
de armazenamento, como blobs, filas, tabelas e arquivos. Você também pode criar,
atualizar e excluir dados direto do Gerenciador de Armazenamento.

[ 122 ]
Capítulo 5

Como fazer isso...


Nesta seção, criaremos três Azure Functions, utilizando os modelos predefinidos
disponíveis no portal de gerenciamento do Azure. Depois, iremos testá-los com
ferramentas diferentes.

Testes de gatilhos HTTP usando o Postman


Execute as seguintes etapas:

1. Crie uma função de gatilho de HTTP que aceite os parâmetros Firstname


e Lastname e envie-os na resposta. Após criá-la, verifique se você definiu
o Nível de Autorização como Anônimo.
2. Substitua o código padrão pelo código a seguir. Observe que, por questões
de simplicidade, removi as validações. Em aplicativos em tempo real, você
precisa validar cada parâmetro de entrada:
#r "Newtonsoft.Json"

using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;

public static async Task<IActionResult> Run(HttpRequest req,


ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a
request.");

string firstname=req.Query["firstname"];
string lastname=req.Query["lastname"];

string requestBody = await new StreamReader(req.Body).


ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
firstname = firstname ?? data?.firstname;
lastname = lastname ?? data?.lastname;

return (ActionResult)new OkObjectResult($"Hello,


{firstname + " " + lastname}");

[ 123 ]
Exploração de ferramentas de testes para a validação do Azure Functions

3. Abra a ferramenta Postman e conclua as seguintes etapas:


1. A
 primeira etapa é escolher o tipo de método de HTTP com o qual você
gostaria de fazer a solicitação de HTTP. Como a nossa função aceita
a maioria dos métodos por padrão, escolha o método GET, mostrado
a seguir:

2. A próxima etapa é fornecer a URL do gatilho de HTTP. Note que você


precisaria substituir <HttpTriggerTestUsingPostman> por seu nome
de função real HttpTrigger, mostrado a seguir:

3. Clique no botão Enviar para fazer a solicitação. Se você forneceu todos os


detalhes esperados pela API, verá um Status: 200 OK, junto com a resposta,
conforme mostrado aqui:

[ 124 ]
Capítulo 5

Testes de um gatilho de blob usando o Gerenciador


de Armazenamento do Microsoft
Execute as seguintes etapas:

1 Crie um novo gatilho de blob escolhendo o modelo de gatilho


de armazenamento de blob do Azure, como mostrado aqui:

2. Depois de clicar no modelo na captura de tela anterior, ele solicitará que você
forneça uma conta de armazenamento e um contêiner onde você armazenará
o blob, mostrado a seguir:

[ 125 ]
Exploração de ferramentas de testes para a validação do Azure Functions

3. Vamos nos conectar à conta de armazenamento que usaremos nesta receita.


Abra o Gerenciador de Armazenamento do Microsoft Azure e clique no
botão realçado na seguinte captura de tela para conectar-se ao Armazenamento
do Azure:

4. Você será solicitado a inserir vários detalhes, incluindo cadeia de conexão


de armazenamento , SAS (assinatura de acesso compartilhado) e sua chave
de conta. Para esta receita, vamos usar a cadeia de conexão de armazenamento.
Navegue até Conta de Armazenamento, copie a cadeia de conexão na folha
de Chaves de acesso e cole-a no popup Gerenciador de Armazenamento
do Microsoft Azure - Conectar, mostrado a seguir:

[ 126 ]
Capítulo 5

5. Se você clicar no botão Avançar na captura de tela anterior, acessará a janela


Resumo da Conexão, em que aparecerá o nome da conta e outros detalhes
relacionados para confirmação. Clique no botão Conectar para conectar-se
à conta escolhida de Armazenamento do Azure.
6. Conforme mostrado na seguinte captura de tela, você agora está conectado
à conta de Armazenamento do Azure, em que pode gerenciar todos os seus
serviços de Armazenamento do Azure:

7. Agora, vamos criar um contêiner de armazenamento denominado samples-


workitems. Clique com o botão direito do mouse na pasta Contêineres
de Blob e clique em Criar Contêiner de Blob para criar um novo contêiner
de blob denominado samples-workitems. Depois, clique no botão Carregar
arquivos, como mostrado na seguinte captura de tela:

8. Na janela Carregar arquivos, escolha um arquivo que gostaria de carregar


e clique no botão Carregar.

[ 127 ]
Exploração de ferramentas de testes para a validação do Azure Functions

9. Navegue imediatamente para o editor de código do Azure Function e verifique


a janela Logs, conforme mostrado na captura de tela a seguir. O log mostra
o Azure Functions acionado com êxito:

Testes do gatilho de fila usando o portal


de gerenciamento do Azure
Execute as seguintes etapas:

1. Crie um novo gatilho da fila do Armazenamento do Azure denominado


QueueTriggerTestusingPortal, conforme mostrado na captura de tela
a seguir. Anote o nome da fila, myqueue-items, pois precisamos criar um
serviço de fila com o mesmo nome, posteriormente usando o portal de
gerenciamento do Azure:

[ 128 ]
Capítulo 5

2. Navegue até a folha Visão geral da conta de armazenamento e clique em Filas,


conforme mostrado na seguinte captura de tela:

3. Na folha Serviço de fila, clique em Fila para adicionar uma nova fila:

4. Forneça myqueue-items como o Nome da fila no popup Adicionar fila, como


mostrado na captura de tela a seguir. Este foi o mesmo nome que usamos
ao criar o gatilho de fila. Clique em OK para criar o serviço de fila:

[ 129 ]
Exploração de ferramentas de testes para a validação do Azure Functions

5. Agora precisamos criar uma mensagem de fila. No portal de gerenciamento


do Azure, clique no serviço de fila myqueue-items para navegar até a folha
Mensagens. Clique no botão Adicionar mensagem, conforme mostrado na
captura de tela a seguir e forneça um texto da mensagem da fila. Por fim,
clique em OK para criar a mensagem da fila:

6. Navegue logo para o gatilho de fila QueueTriggerTestusingPortal e exiba


a folha Logs. Aqui, você pode descobrir como a função de fila foi acionada,
como mostrado na seguinte captura de tela:

[ 130 ]
Capítulo 5

E mais...
Para todos os seus gatilhos HTTP, se você desejar permitir que os consumidores de
API usem apenas o método POST, poderá restringi-lo como tal, escolhendo Métodos
selecionados e apenas POST em Métodos HTTP selecionados, conforme mostrado
nesta captura de tela:

Testes de um Azure Functions em


um ambiente de teste utilizando slots
de implantação
Em geral, cada aplicativo precisa de ambientes de pré-produção, como preparo,
beta e assim por diante, a fim de revisar as funcionalidades antes de publicá-las
para os usuários finais.

Embora os ambientes de pré-produção sejam ótimos e ajudem vários stakeholders


a validar a funcionalidade do aplicativo em relação aos requisitos de negócios,
há alguns problemas no gerenciamento e manutenção deles. Veja alguns deles:

• Precisaríamos criar e usar um ambiente separado para nossos ambientes


de pré-produção
• Após tudo ser revisado na pré-produção e a equipe de operações de TI obter
o sinal de avanço, haveria um pouco de tempo de inatividade no ambiente
de produção ao implantar a base de código de novas funcionalidades

[ 131 ]
Exploração de ferramentas de testes para a validação do Azure Functions

Todas as limitações anteriores podem ser abordadas no Azure Functions, usando


um recurso chamado slots (esses são chamados de slots de implantação em ambientes
de Serviço de Aplicativo). Usando slots, você pode configurar um ambiente de pré-
produção, em que pode rever todas as novas funcionalidades e promovê-las (por meio
de troca, que abordaremos mais adiante) para o ambiente de produção sem problemas
e sempre que necessário.

Como fazer isso...


Execute as seguintes etapas:

1. Criar um novo aplicativo de função denominado MyProductionApp.


2. Criar um novo gatilho de HTTP e chame-o de MyProd-HttpTrigger1. Substitua
a última linha pelo seguinte:
return name != null
? (ActionResult)new OkObjectResult("Welcome to MyProd-
HttpTrigger1 of Production App")
: new BadRequestObjectResult("Please pass a name on the
query string or in the request body");

3. Crie outro novo gatilho de HTTP e chame-o de MyProd-HttpTrigger2.


Use o mesmo código que você usou para MyProd-HttpTrigger1— basta
substituir a última linha pelo seguinte:
return name != null
? (ActionResult)new OkObjectResult("Welcome to MyProd-
HttpTrigger2 of Production App")
: new BadRequestObjectResult("Please pass a name on the
query string or in the request body");

4. Suponha que ambas as funções do aplicativo de função sejam ao vivo


no ambiente de produção com a URL https://<<functionappname.
azurewebsites.net>>.
5. Agora, o cliente solicitou que façamos algumas alterações em ambas as funções.
Em vez de fazer as alterações diretamente nas funções do seu aplicativo de
função de produção, talvez você precise criar um slot.
6. Um momento! Antes de criar um slot, primeiro você precisa ativar o recurso
navegando para as configurações do aplicativo de função sob Configurações
Gerais da guia Recursos da plataforma do aplicativo de função. Quando você
clicar nas configurações do aplicativo de função, uma nova guia será aberta
onde você poderá ativar Slots (visualização), como mostrado na seguinte
captura de tela:

[ 132 ]
Capítulo 5

O recurso de slots está atualmente em visualização. Quando


você ler isso, ele poderá estar Geralmente Disponível (GA).
Não é recomendável usar esse recurso em workloads de produção
até que ele esteja GA

7. Clique no botão Ativar na seção slots (visualização) realçada na captura


de tela anterior. Assim que você ativá-lo, a seção de slots ficará oculta, pois
ela é uma configuração única. Uma vez ativada, você não pode desativá-la.
8. Vamos criar um novo slot com todas as funções que temos em nosso aplicativo
de função, denominado MyProductionApp.
9. Clique no ícone +, disponível perto da seção Slots (visualização), conforme
mostrado na seguinte captura de tela:

10. Ele solicita que você digite um nome para o novo slot. Forneça um nome
significativo, algo como Preparação, como mostrado na seguinte captura
de tela:

[ 133 ]
Exploração de ferramentas de testes para a validação do Azure Functions

11. Após você clicar em Criar, um novo slot será criado, como mostrado na captura
de tela a seguir. No caso, se você ver as funções como somente leitura, poderá
torná-las leitura-gravação nas configurações do aplicativo de função.

A URL para o slot será https://<<functionappname>>-


<<Slotname>>.azurewebsites.net>>. Cada slot em um aplicativo
de função terá uma URL diferente.

12. Para tornar um ambiente de preparação completo, você precisa copiar


todos os Azure Functions do ambiente de produção (neste caso, o aplicativo
MyProductionApp) para o novo slot de preparação chamado Preparação. Crie
dois gatilhos HTTP e copie o código das duas funções (MyProd-HttpTrigger1
e MyProd-HttpTrigger2) de MyProductionApp para o novo slot Preparação.
Basicamente, você precisa copiar todas as funções para o novo slot manualmente.
13. Altere a cadeia de produção para preparação na última linha das duas funções
no slot de preparação. Isso é útil para testar o resultado da operação de troca:

[ 134 ]
Capítulo 5

Note que, em todos os slots criados como um aplicativo de pré-produção,


você precisa garantir que utilizou os mesmos nomes de função que tem
em seu ambiente de produção.

14. Clique no botão Trocar, disponível na folha Slots de implantação, conforme


mostrado nesta captura de tela:

15. Na folha Troca, você precisa escolher o seguinte:


°° Tipo de troca: escolha a opção Trocar.
°° Fonte: escolha o slot que você gostaria de mover para a produção.
Neste caso, estamos trocando a Preparação em geral, mas você
pode até mesmo trocar entre slots de não produção.

[ 135 ]
Exploração de ferramentas de testes para a validação do Azure Functions

°° Destino: escolha a opção de produção, conforme mostrado na seguinte


captura de tela:

16. Depois de revisar as configurações, clique no botão OK da etapa anterior. Levará


alguns instantes para trocar as funções. Uma barra de progresso aparecerá,
conforme mostrado nesta captura de tela:

[ 136 ]
Capítulo 5

17. Depois de um minuto ou dois, os slots de preparação e produção serão trocados.


Vamos revisar os arquivos de script run.csx da produção:

18. Se você não vir alterações, clique no botão Atualizar do aplicativo de função ,
conforme mostrado nesta captura de tela:

[ 137 ]
Exploração de ferramentas de testes para a validação do Azure Functions

19. Certifique-se de que as Configurações do Aplicativo e as Cadeias de Conexão


do Banco de Dados estejam marcadas como Configuração de Slot (específicas de
slot). Caso contrário, as Configurações do Aplicativo e as Cadeias de Conexão
do Banco de Dados também serão trocadas, o que poderá gerar comportamentos
inesperados. Você pode marcar qualquer uma dessas configurações dessa forma
em Recursos da plataforma, como mostrado na seguinte captura de tela:

20. Ao clicar em Configurações do aplicativo, você acessará a seguinte folha, em que


poderá marcar qualquer configuração como CONFIGURAÇÃO DE SLOT:

Todas as funções encontradas na receita são gatilhos HTTP; note que você
pode ter qualquer tipo de gatilho no aplicativo de função. Os slots de
implantação não se limitam aos gatilhos HTTP.
Você pode ter vários slots para cada um dos aplicativos de função. Estes
são alguns dos exemplos:
Alfa
Beta
Preparação

[ 138 ]
Capítulo 5

E mais...
Se você tentar criar um slot sem ativar o recurso de Slots de Implantação, você verá algo
semelhante ao que é mostrado na seguinte captura de tela:

Você precisa ter todos os Azure Functions em cada um dos slots que gostaria de trocar
com o seu aplicativo de função de produção:

• Slots são específicos do aplicativo de função, mas não da função individual.


• Após ativar os recursos de slots, todas as chaves serão regeneradas, incluindo
o mestre. Tenha cuidado se já tiver compartilhado as chaves das funções com
terceiros. Se você já tiver compartilhado-as e ativado os slots, todas as integrações
existentes com as chaves antigas não funcionarão.

Em geral, se você estiver usando Serviços de Aplicativos e desejar criar slots de


implantação, precisará ter seu plano de serviço de aplicativos no nível Standard
ou Premium. No entanto, você pode criar slots para o aplicativo de função, mesmo
que ele esteja com planos de Consumo (ou dinâmicos).

Testes de carga do Azure Functions


usando o Azure DevOps
Cada aplicativo precisa funcionar bem em termos de performance. É responsabilidade
de todos da equipe que o aplicativo funcione bem. Nesta receita, você aprenderá como
criar uma carga no Azure Functions usando a ferramenta Teste de Carga fornecida
pelo Azure DevOps (antes conhecido como VSTS). Esta receita também irá ajudá-lo
a entender como a escala automática de instâncias funciona no ambiente sem servidor,
sem que os desenvolvedores ou o arquiteto precisem se preocupar com as instâncias
responsáveis por atender às solicitações.

[ 139 ]
Exploração de ferramentas de testes para a validação do Azure Functions

Preparação
Crie uma conta do Azure DevOps em https://visualstudio.microsoft.com/.
Utilizaremos a ferramenta Teste de Carga do Azure DevOps para criar testes de carga
baseados em URL.

Como fazer isso...


Execute as seguintes etapas:

1. Crie um novo gatilho de HTTP, denominado LoadTestHttpTrigger,


com Nível de Autorização definido como Anônimo.
2. Substitua o código padrão em run.csx pelo seguinte:
using System.Net;
using Microsoft.AspNetCore.Mvc;
public static async Task<IActionResult> Run(HttpRequest req,
ILogger log)
{
System.Threading.Thread.Sleep(2000);
return (ActionResult)new OkObjectResult($"Hello");
}

3. O código precedente é auto-explicativo. Para tornar o teste de carga interessante,


simularemos uma carga de processamento, adicionando um tempo de espera
de dois segundos, usando System.Threading.Thread.Sleep(2000);.
4. Copie a URL de função clicando no link de </> Obter URL de função no lado
direito do editor de código run.csx.
5. Navegue até a guia Teste de carga da conta do Azure DevOps. Você pode
encontrá-lo no menu Teste após fazer logon no Azure DevOps:

[ 140 ]
Capítulo 5

6. Clique no link Novo e selecione Teste baseado em URL, como mostrado


na seguinte captura de tela:

7. Na guia Cenários da Web, forneça um nome significativo para o teste de carga,


conforme mostrado na seguinte captura de tela:

8. Cole a URL do gatilho de HTTP que você copiou na etapa 4 no campo de entrada
da URL, conforme mostrado nesta captura de tela:

9. Agora, clique no botão Salvar para salvar o teste de carga:

[ 141 ]
Exploração de ferramentas de testes para a validação do Azure Functions

10. A próxima etapa é fornecer detalhes sobre a carga que gostaríamos de criar
no Azure Functions. Como mostrado na captura de tela a seguir, clique em
Configurações e forneça os detalhes sobre o teste de carga que você gostaria,
de acordo com seus requisitos:

11. Após fornecer todos os seus detalhes para o teste de carga, clique em Salvar.
Após você salvar o teste, o botão Executar teste será ativado, conforme mostrado
na seguinte captura de tela:

12. Clique em Executar teste para iniciar o teste de carga. Como a duração de
execução do nosso teste de carga é de 20 minutos, levaria 20 minutos para
concluir o teste de carga. Quando a carga estiver concluída, o Azure DevOps
nos fornecerá os relatórios de performance, mostrados da seguinte maneira:

[ 142 ]
Capítulo 5

°° Relatório de resumo: ele nos fornece o tempo médio de resposta


do gatilho de HTTP para a carga de 1.000 usuários.

E mais...
Também podemos verificar como o Azure expande as instâncias automaticamente nos
bastidores na guia Live Metrics Stream do Application Insights. A captura de tela
a seguir mostra as IDs de instância e a integridade das máquinas virtuais alocadas
automaticamente, com base na carga na arquitetura sem servidor do Azure. Você
aprenderá a integrar o Application Insights com o Azure Functions no Capítulo 6,
Como monitorar e solucionar problemas de serviços sem servidor no Azure

[ 143 ]
Exploração de ferramentas de testes para a validação do Azure Functions

Consulte também
O Monitoramento do Azure Functions usando a receita do Application Insights
no Capítulo 6, Como monitorar e solucionar problemas de serviços sem servidor no Azure,
contém mais informações sobre este tópico.

Criação e testes locais do Azure


Functions usando ferramentas
da CLI do Azure
A maioria das receitas que você conheceu até agora foram criadas usando o navegador
ou o Ambiente de Desenvolvimento Integrado (IDE) do Visual Studio.

O Azure também nos fornece ferramentas para desenvolvedores que adoram trabalhar
com a linha de comando. Essas ferramentas nos permitem criar recursos do Azure com
comandos simples diretamente da linha de comando. Nesta receita, você aprenderá
a criar um novo aplicativo de função e também entenderá como criar uma função
e implantá-la na Nuvem do Azure diretamente da linha de comando.

Preparação
Execute as seguintes etapas:

• Faça download e instale o Node.js de https://nodejs.org/en/download/.


• Faça download de e instale as ferramentas da CLI do Azure de https://docs.
microsoft.com/cli/azure/install-azure-cli?view=azure-cli-
latest.

Como fazer isso...


Execute as seguintes etapas:

1. Quando o Azure Functions Core Tools estiver pronto, execute o seguinte


comando para criar um novo aplicativo de função:
func init

Você receberá a seguinte saída após executar o comando anterior:

[ 144 ]
Capítulo 5

Na captura de tela anterior, dotnet é selecionado por padrão. Se pressionar Enter,


você criará os arquivos necessários, como mostrado na seguinte captura de tela:

2. Execute o seguinte comando para criar uma nova função de gatilho HTTP
no novo aplicativo de função que criamos:
func new

Você receberá a seguinte saída após executar o comando anterior:

3. Como mostrado na captura de tela anterior, você será solicitado a escolher


o modelo de função. Para esta receita, escolhi HttpTrigger. Escolha
HttpTrigger usando a seta para baixo. Você pode escolher o tipo de Azure
Functions com base em seus requisitos. Você pode navegar entre as opções
usando as setas para cima/para baixo no teclado.

[ 145 ]
Exploração de ferramentas de testes para a validação do Azure Functions

4. A próxima etapa é fornecer um nome para o Azure Functions que você estiver
criando. Forneça um nome significativo e pressione Enter, como mostrado
na seguinte captura de tela:

5. Você pode usar seu IDE favorito para editar o código do Azure Functions.
Nesta receita, estou usando o código do Visual Studio para abrir a função
HttpTrigger, conforme mostrado na seguinte captura de tela:

6. Vamos testar o Azure Functions diretamente do seu computador local. Para isso,
precisamos iniciar o host do Azure Functions executando o seguinte comando:
func host start --build

[ 146 ]
Capítulo 5

7. Depois que o host for iniciado, você poderá copiar a URL e testá-la em
seu navegador, junto com um nome de parâmetro de cadeia de caracteres
de consulta, conforme mostrado na seguinte captura de tela:

Testes e validação da capacidade


de resposta do Azure Functions usando
o Application Insights
Qualquer aplicativo só será útil para negócios se estiver em operação. Os aplicativos
podem ficar inativos por vários motivos. Veja alguns deles:

• Qualquer falha de hardware, como falha do servidor, disco rígido incorreto


ou outro problema de hardware, até mesmo falha em um data center inteiro,
embora isso seja muito raro
• Pode haver erros de software devido a um código incorreto ou a um erro
de implantação
• O site pode receber tráfego inesperado e os servidores podem não ser capazes
de lidar com esse tráfego
• Em alguns casos, talvez seu aplicativo seja acessível em um país, mas não
em outros

Seria realmente útil receber uma notificação quando o nosso site não estivesse disponível
ou não respondesse a solicitações do usuário. O Azure fornece algumas ferramentas
para ajudar, alertando-nos se o site não está respondendo ou está inativo. Uma delas
é o Application Insights. Você aprenderá como configurar o Application Insights para
fazer ping em nosso aplicativo Azure Functions a cada minuto e configurá-lo para
alertar-nos se a função não estiver respondendo.

[ 147 ]
Exploração de ferramentas de testes para a validação do Azure Functions

Preparação
Execute as seguintes etapas:

1. Navegue até o portal de gerenciamento do Azure, procure o Application


Insights, depois clique no botão Criar e forneça todos os detalhes necessários,
conforme mostrado nesta captura de tela:

[ 148 ]
Capítulo 5

2. Navegue até a folha Visão geral do aplicativo de função e obtenha a URL


do aplicativo de função, conforme mostrado nesta captura de tela:

Como fazer isso...


Execute as seguintes etapas:

1. Navegue até a folha Disponibilidade e clique no botão de teste Adicionar,


como mostrado na seguinte captura de tela:

[ 149 ]
Exploração de ferramentas de testes para a validação do Azure Functions

2. Na folha Criar teste, insira um nome significativo para seu requisito e cole
a URL do aplicativo de função, que você anotou na etapa 2 da seção anterior,
Preparação, no campo URL da folha Criar teste. Na folha Alertas, forneça
um endereço de e-mail válido no campo Enviar e-mails de alerta para esses
endereços de e-mail:, para o qual um alerta deverá ser enviado se a função
não estiver disponível ou não estiver respondendo:

[ 150 ]
Capítulo 5

3. Clique em OK na folha Alertas e, em seguida, clique no botão Criar da folha


Criar teste para criar o teste, conforme mostrado na seguinte captura de tela,
na seção Todos os testes de disponibilidade:

4. Para testar a funcionalidade deste alerta, vamos parar o aplicativo de função,


clicando no botão Parar, encontrado na guia Visão geral do aplicativo de função.

[ 151 ]
Exploração de ferramentas de testes para a validação do Azure Functions

5. Quando o aplicativo de função for interrompido, o Application Insights tentará


acessar a URL de função usando o teste de ping. O código de resposta não
será 200, pois o aplicativo foi interrompido, o que significa que o teste falhou
e uma notificação deve ter sido enviada para o e-mail configurado, conforme
mostrado na seguinte captura de tela:

Como funciona...
Criamos um teste de disponibilidade, em que foi realizado ping em nosso aplicativo
de função uma vez a cada cinco minutos de um máximo de cinco locais diferentes
em todo o mundo. Você pode configurá-los na guia Local de teste da folha Criar teste
ao criar o teste. O critério padrão do ping é verificar se o código de resposta da URL
é 200. Se o código de resposta não for 200, então o teste falhou e um alerta será
enviado para o endereço de e-mail configurável.

E mais...
Você poderá usar um teste da Web de várias etapas (com a opção Tipo de Teste
na folha Criar teste) se desejar testar uma página ou funcionalidade que exija
a navegação para várias páginas.

Desenvolvimento de testes de unidade


para o Azure Functions com gatilhos HTTP
Até agora, criamos vários Azure Functions e validamos sua funcionalidade usando
diferentes ferramentas. As funcionalidades das funções que desenvolvemos até agora
são bem simples e diretas; no entanto, nos aplicativos reais, não será tão simples —
provavelmente haverá muitas alterações no código que criamos inicialmente. É uma
boa prática escrever testes de unidade automatizados que podem nos ajudar a testar
a funcionalidade de nossos Azure Functions. Toda vez que executamos esses testes
de unidade automatizados, podemos testar todos os diversos caminhos dentro do código.
[ 152 ]
Capítulo 5

Nesta receita, aprenderemos como usar o gatilho de HTTP básico e ver como é fácil
escrever casos de teste de unidade automatizados para isso usando o Visual Studio
Test Explorer e o Moq (uma estrutura open source disponível como um pacote NuGet).

Preparação
Utilizaremos a estrutura de simulação Moq para o teste da unidade de nosso Azure
Functions. Ter um conhecimento de trabalho básico de Moq é uma exigência para esta
receita. Se precisar, você poderá conhecer mais sobre Moq em https://github.com/
moq/moq4/wiki.

Para simplificar o Caso de Teste de Unidade, comentei as linhas de código que lê os


dados dos parâmetros Post para o método Run de HTTPTriggerCSharpFromVS
HTTPTrigger, como mostrado abaixo, em negrito.
[FunctionName("HTTPTriggerCSharpFromVS")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post",
Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a
request.");

string name = req.Query["name"];

//string requestBody = await new StreamReader(req.Body).


ReadToEndAsync();
//dynamic data = JsonConvert.
DeserializeObject(requestBody);
//name = name ?? data?.name;

return name != null


? (ActionResult)new OkObjectResult($"Hello, {name}")
: new BadRequestObjectResult("Please pass a name on
the query string or in the request body");
}

[ 153 ]
Exploração de ferramentas de testes para a validação do Azure Functions

Como fazer isso...


Execute as seguintes etapas:

1. Crie um novo projeto de teste de unidade clicando com o botão direito do


mouse na solução e, depois, em Adicionar Novo Projeto. Na janela Adicionar
Novo Projeto, escolha Testar na lista de Tipo de Projeto e escolha xUnit Test
Project(.NET Core) na lista de projetos, conforme mostrado aqui:

2. Verifique se você escolheu xUnit Test Project(.NET Core) no console


Gerenciador de Pacotes e execute os seguintes comandos:
°° Instale o pacote NuGet de Moq usando o comando Install-Package Moq
°° Instale o pacote ASP.NET Core usando o comando Install-Package
Microsoft.AspNetCore
3. No projeto de teste de unidade, também precisamos da referência
ao Azure Functions em que desejamos executar os testes de unidade.
Adicione uma referência ao aplicativo FunctionAppInVisualStudio
para que possamos chamar o método Run do gatilho de HTTP de nossos
testes de unidade.

[ 154 ]
Capítulo 5

4. Adicione todos os namespaces necessários para a classe Teste de Unidade,


da seguinte maneira: e substitua o código padrão pelo código a seguir. O código
a seguir simula as solicitações, cria uma coleção de cadeia de consulta com uma
chave denominada nome, atribui um valor de Praveen Sreeram, executa a
função, obtém a resposta e compara o valor de resposta com um valor esperado:
using FunctionAppInVisualStudio;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http.Internal;
using Microsoft.Extensions.Primitives;
using Moq;
using System;
using System.Collections.Generic;
using Xunit;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;

namespace AzureFunctions.Tests
{
public class ShouldExecuteAzureFunctions
{
[Fact]
public async Task WithAQueryString()
{
var httpRequestMock = new Mock<HttpRequest>();
var LogMock = new Mock<ILogger>();
var queryStringParams = new Dictionary<String,
StringValues>();
httpRequestMock.Setup(req => req.Query).Returns(new Qu
eryCollection(queryStringParams));
queryStringParams.Add("name", "Praveen Sreeram");

var result = await HTTPTriggerCSharpFromVS.


Run(httpRequestMock.Object,LogMock.Object);
var resultObject = (OkObjectResult)result;
Assert.Equal("Hello, Praveen Sreeram", resultObject.
Value);
}
}
}

[ 155 ]
Exploração de ferramentas de testes para a validação do Azure Functions

5. Agora, clique com o botão direito do mouse no teste de unidade e clique


em Executar teste(s), como mostrado na seguinte captura de tela:

Se tudo estiver configurado corretamente, os testes deverão passar, conforme mostrado


na seguinte captura de tela:

É isso. Aprendemos a escrever um caso de teste de unidade básico para um gatilho


de HTTP.

[ 156 ]
Como monitorar e solucionar
problemas de serviços sem
servidor no Azure
Neste capítulo, você aprenderá sobre o seguinte:

• Solução de problemas do Azure Functions


• Integração do Azure Functions com o Application Insights
• Monitoramento do Azure Functions
• Envio de detalhes de telemetria personalizados para o Application Insights
Analytics
• Envio de detalhes de telemetria do aplicativo via e-mail
• Integração de dados de monitoramento do Application Insights em tempo
real com Power BI usando o Azure Functions

Introdução
Não basta concluir o desenvolvimento de um projeto e ativar um aplicativo para finalizar
a implantação. Precisamos monitorar continuamente nossos aplicativos, analisar sua
performance e revisar seus logs para entender se os usuários finais enfrentam problemas.

O Azure fornece várias ferramentas para atender a todos os nossos requisitos


de monitoramento, desde os estágios de desenvolvimento e manutenção.

Neste capítulo, você aprenderá como utilizar essas ferramentas e adotar qualquer
ação necessária com base nas informações disponíveis.

[ 157 ]
Como monitorar e solucionar problemas de serviços sem servidor no Azure

Solução de problemas do Azure


Functions
Nesta receita, você aprenderá como exibir os logs de aplicativo de seus aplicativos
de função usando o recurso de streaming de log de funções.

Como fazer isso...


Após terminar o desenvolvimento e testar seus aplicativos em seu ambiente local,
convém implantá-los no Azure. Você poderá enfrentar problemas depois de implantar
um aplicativo no Azure, pois o ambiente é diferente. Por exemplo, um desenvolvedor
pode ter perdido a criação de Configurações do Aplicativo no aplicativo. Com uma
chave de configuração ausente, seu aplicativo pode não funcionar conforme o esperado
e não é fácil solucionar o erro. Felizmente, o ambiente do Azure facilita com o recurso
de Streaming de Log. Nesta receita, vamos aprender a exibir os logs em tempo real
e também compreender como usar o recurso Diagnosticar e solucionar problemas.

Visualização de logs de aplicativos em tempo real


Execute as seguintes etapas:

1. Navegue até Recursos da plataforma do aplicativo de função e clique no botão


Streaming de Log, em que você pode exibir os Logs do aplicativo, conforme
mostrado na seguinte captura de tela:

No momento da gravação, os logs do servidor Web não fornecem


informações relacionadas ao Azure Functions.

[ 158 ]
Capítulo 6

2. Vamos abrir qualquer Azure Functions adicionado anteriormente em uma nova


guia do navegador e adicionar uma linha de código que gere uma exceção.
Para simplificar (e apenas ilustrar como logs de aplicativo no streaming de logs
funcionam), adicionei a seguinte linha ao gatilho de HTTP simples que criei
anteriormente:

3. Posteriormente, clique no botão Salvar e no botão Executar. Como esperado,


você receberá uma exceção, junto com a mensagem na seção Logs do aplicativo,
conforme mostrado na seguinte captura de tela:

A janela de log mostra erros somente para essa função específica e não
para as outras funções associadas ao aplicativo de função. Nesse caso,
os logs do aplicativo de streaming de logs são úteis, pois podem ser
usados nas funções de qualquer aplicativo de função específico.

[ 159 ]
Como monitorar e solucionar problemas de serviços sem servidor no Azure

Diagnóstico do aplicativo de função inteiro


Na seção anterior, aprendemos a monitorar erros de aplicativos em tempo real, o que
será útil para identificar e corrigir rapidamente os erros encontrados. No entanto, nem
sempre é possível monitorar logs de aplicativo e entender os erros que os usuários
finais enfrentam. O Azure Functions fornece outra grande ferramenta, denominada
Diagnosticar e solucionar problemas:

1. Navegue até Recursos da plataforma e clique em Diagnosticar e resolver


problemas, como mostrado na seguinte captura de tela:

2. Logo depois, você passará para outra folha, em que poderá escolher a categoria
certa para os problemas que estiver solucionando no momento. Clique
em 5xx Erros para exibir detalhes sobre as exceções que os usuários finais
enfrentam, como mostrado na seguinte captura de tela:

[ 160 ]
Capítulo 6

3. Isso mostrará a você Disponibilidade e Performance da Função e Falhas


do Aplicativo. Clique na opção Disponibilidade e Performance da Função
para exibir os links reais, conforme mostrado na seguinte captura de tela:

4. Clique em Execuções e Erros da Função para exibir as exceções detalhadas,


conforme mostrado na seguinte captura de tela:

E mais...
Cada evento de função é registrado em um serviço de armazenamento de tabela do Azure.
Todos os meses, uma tabela é criada com o nome AzureWebJobsHostLogs<ano><mês>.

[ 161 ]
Como monitorar e solucionar problemas de serviços sem servidor no Azure

Como parte da solução de problemas, se você quiser obter mais detalhes sobre qualquer
erro, primeiro localize o campo ID na seção Detalhes da Invocação, conforme mostrado
na seguinte captura de tela:

Procure esses dados na coluna RowKey da tabela AzureWebJobsHostLogs<ano><mês>,


conforme mostrado na seguinte captura de tela:

Como mostrado na captura de tela anterior, você receberá a entrada de log armazenada
no armazenamento de tabela. Clicar na linha abrirá os detalhes completos do erro, como
mostrado na seguinte captura de tela:

[ 162 ]
Capítulo 6

Integração do Azure Functions com


o Application Insights
O Application Insights é um serviço de gerenciamento de performance do aplicativo.
Depois de integrar o Application Insights em seu aplicativo, ele começará a enviar dados
de telemetria para sua conta do Application insights, hospedada na nuvem. Nesta receita,
você aprenderá como é simples integrar o Azure Functions com o Application Insights.

Preparação
Criamos uma conta do Application Insights na receita Teste e validação da capacidade
de resposta do Azure Functions usando o Application insights do Capítulo 5, Exploração
de ferramentas de teste para a validação do Azure Functions. Crie uma conta, caso ainda não
tenha feito isso, seguindo as seguintes etapas:

1. Navegue até o portal de gerenciamento do Azure, clique em Criar um recurso


e selecione Ferramentas de gerenciamento.
2. Escolha Application Insights e forneça todos os detalhes necessários. Se você
já tiver criado uma conta do Application Insights na receita anterior, poderá
ignorar essa etapa.

[ 163 ]
Como monitorar e solucionar problemas de serviços sem servidor no Azure

Como fazer isso...


Execute as seguintes etapas:

1. Depois que a conta do Application Insights for criada, navegue até a guia
Visão geral e vá até Chave de Instrumentação, conforme mostrado na seguinte
captura de tela:

2. Navegue até Aplicativos de função, para os quais você gostaria de habilitar


o monitoramento e vá até Configurações do aplicativo.
3. Adicione uma nova chave com o nome APPINSIGHTS_INSTRUMENTATIONKEY
e forneça a chave de instrumentação que você copiou da conta do Application
Insights, mostrada da seguinte maneira e, depois, clique em Salvar para salvar
as alterações:

4. Pronto. Você pode começar a utilizar todos os recursos do Application Insights


para monitorar a performance do Azure Functions. Abra o Application
Insights e a função RegisterUser em duas guias diferentes para testar como
o Live Metrics Stream funciona:
°° Abra o Application Insights e clique em Live Metrics Stream
na primeira guia do seu navegador, conforme mostrado na seguinte
captura de tela:

[ 164 ]
Capítulo 6

°° Abra um dos Azure Functions (no meu caso, abri o gatilho de HTTP)
em outra guia e execute alguns testes para garantir que ele emita alguns
logs para o Application Insights.

5. Depois de concluir esses testes, vá para a guia que tem o Application Insights.
Você verá o tráfego ao vivo passando para o seu aplicativo de função, como
mostrado na seguinte captura de tela:

[ 165 ]
Como monitorar e solucionar problemas de serviços sem servidor no Azure

Como funciona...
Criamos uma conta do Application Insights. Após integrar a Chave de Instrumentação
do Application Insights com o Azure Functions, o tempo de execução cuidará de enviar
os dados de telemetria de forma assíncrona para sua conta do Application Insights.

E mais...
No Live Metrics Stream, você também pode exibir todas as instâncias, junto com alguns
outros dados, como o número de solicitações por segundo tratadas por suas instâncias.

Monitoramento do Azure Functions


Agora entendemos como integrar o Azure Functions com o Application Insights. Vejamos
agora como exibir os logs que são gravados no Application Insights pelo código do Azure
Functions para que, como desenvolvedor, você possa solucionar exceções que ocorram.

Vamos fazer uma pequena alteração na função do gatilho de HTTP e, depois, executá-lo
algumas vezes.

Como fazer isso...


Execute as seguintes etapas:

1. Navegue até o gatilho de HTTP que você criou e substitua o código a seguir.
Acabei de mover a linha de código que registra as informações para o console
Logs e adicionei o parâmetro name no final do método:
public static async Task<IActionResult> Run(HttpRequest req,
ILogger log)
{
string name = req.Query["name"];
string requestBody = await new
StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.
DeserializeObject(requestBody);
name = name ?? data?.name;
log.LogInformation($"C# HTTP trigger function processed
a request with the input value {name}");
return name != null
? (ActionResult)new OkObjectResult($"Hello, {name}")
: new BadRequestObjectResult("Please pass a name on
the query string or in the request body");
}

[ 166 ]
Capítulo 6

2. Agora, execute a função fornecendo o valor para o parâmetro name com valores
diferentes, como Azure Test Run 1, Azure Test Run 2 e Azure Test Run
3. Isto é apenas para fins de demonstração. Você pode usar a entrada da sua
preferência. O console Logs mostrará a seguinte saída:

3. Os logs no console Logs anterior só estarão disponíveis quando você estiver


conectado ao console Logs. Você não irá obtê-los quando estiver offline.
É nesse momento que o Application Insights é útil. Navegue até a instância
do Application Insights que você integrou com o aplicativo de função do Azure.
4. Clique no botão Análise que está disponível na guia Visão geral do Application
Insights, conforme mostrado nesta captura de tela:

[ 167 ]
Como monitorar e solucionar problemas de serviços sem servidor no Azure

5. Na janela consulta de análise, digite o comando traces | sort by timestamp


desc, que retorna todos os rastreamentos classificados por data decrescente,
conforme mostrado na seguinte captura de tela:

Como funciona...
No gatilho de HTTP, adicionamos uma instrução log que exibe o valor do parâmetro
name que o usuário fornece. Executamos o gatilho de HTTP algumas vezes. Após algum
tempo, clique no botão Análise no Application Insights, que abre a janela Análise, em
que você pode gravar consultas para exibir os dados de telemetria que estão sendo
emitidos pelo Azure Functions. Tudo isso pode ser obtido sem escrever códigos
personalizados.

Envio de detalhes de telemetria


personalizados para o Application
Insights Analytics
Nossos clientes solicitaram que você fornecesse relatórios analíticos para uma
métrica derivada no Application Insights. O que é uma métrica derivada? Por padrão,
o Application Insights fornece muitas informações sobre métricas, como solicitações,
erros, exceções e assim por diante.

Você pode executar consultas sobre as informações que o Application Insights fornece
usando sua linguagem de consulta de análise.

[ 168 ]
Capítulo 6

Nesse contexto, as solicitações por hora são uma métrica derivada. Se você quiser
criar um novo relatório no Application Insights, precisará alimentar o Application
Insights sobre a nova métrica derivada regularmente. Depois de alimentar os dados
necessários regularmente, o Application Insights fornecerá relatórios para sua análise.

Utilizaremos o Azure Functions que alimenta o Application Insights com uma métrica
derivada denominada solicitações por hora:

Para este exemplo, desenvolveremos uma consulta usando a linguagem de consulta


de análise para a métrica derivada solicitação por hora. Você pode fazer alterações
na consulta para gerar outras métricas derivadas para seus requisitos, digamos,
solicitações por hora para minha campanha ou algo semelhante.

Você pode saber mais sobre a linguagem de consulta de análise em


https://docs.microsoft.com/en-us/azure/application-
insights/app-insights-analytics-reference.

[ 169 ]
Como monitorar e solucionar problemas de serviços sem servidor no Azure

Preparação
Execute as seguintes etapas de pré-requisitos:

1. Crie uma nova conta do Application Insights, caso ainda não tenha uma.
2. Verifique se você tem um aplicativo em execução que se integre com
o Application Insights. Você pode aprender como integrar seu aplicativo com o
Application Insights em https://docs.microsoft.com/en-us/azure/
application-insights/app-insights-asp-net.

É recomendável criar esta receita e as duas seguintes em um


aplicativo de função do Azure separado que se baseia em tempo
de execução v1, pois esses modelos ainda não estão disponíveis
na v2. No momento, se não encontrar o modelo Análise
Agendada do Application Insights, altere a versão do tempo
de execução do Azure Functions para v1, definindo o valor
de FUNCTIONS_EXTENSIONS_VERSION como ~1, conforme
mostrado nesta captura de tela, nas configurações do aplicativo
do Azure Functions:

Como fazer isso...


Executaremos as seguintes etapas para enviar detalhes de telemetria personalizados para
o Application Insights Analytics.

[ 170 ]
Capítulo 6

Criação de uma função do Application Insights


Execute as seguintes etapas:

1. Crie um novo modelo de função escolhendo Monitoramento no menu suspenso


Cenário, conforme mostrado na captura de tela a seguir. Você também pode
procurar análises agendadas para encontrar facilmente o modelo:

2. Agora, clique em C# (mostrado na captura de tela anterior) e forneça o nome


junto com a frequência de agendamento na qual a função precisa ser executada:

3. Como mostrado na imagem anterior, clique no botão Criar para criar a função.

[ 171 ]
Como monitorar e solucionar problemas de serviços sem servidor no Azure

Configuração de chaves de acesso


Execute as seguintes etapas:

1. Navegue até a folha Visão geral do Application Insights, conforme mostrado.


Copie a Chave de Instrumentação. Utilizaremos a Chave de Instrumentação
para criar uma configuração de aplicativo denominada AI_IKEY no aplicativo
de função:

2. Navegue até a folha Acesso à API e copie a ID do aplicativo. Utilizaremos


esta ID do aplicativo para criar uma nova configuração de aplicativo
com o nome AI_APP_ID no aplicativo de função:

3. Também precisamos criar uma nova chave de API. Conforme mostrado na etapa
anterior, clique no botão Criar chave de API para gerar a nova chave de API,
conforme mostrado na captura de tela a seguir. Forneça um nome significativo,
verifique os dados de Telemetria de leitura e clique em Gerar chave:

[ 172 ]
Capítulo 6

4. Logo depois, você poderá ver e copiar a chave, como mostrado na captura de
tela a seguir. Utilizaremos isso para criar uma nova configuração de aplicativo
com o nome AI_APP_KEY no nosso aplicativo de função:

[ 173 ]
Como monitorar e solucionar problemas de serviços sem servidor no Azure

5. Crie todas as três chaves de configuração de aplicativo no aplicativo de função,


conforme mostrado na captura de tela a seguir. Essas três chaves serão usadas
em nosso Azure Functions denominado FeedAIwithCustomDerivedMetric.

Integração e teste de uma consulta do Application


Insights
Execute as seguintes etapas:

1. Agora, é hora de desenvolver uma consulta que nos forneça o valor de métrica
derivada de solicitações por hora. Navegue até a folha Visão geral do
Application Insights e clique no botão Análise.
2. Você passará para a folha Análise. Grave a seguinte consulta na guia de consulta.
Você pode gravar sua própria consulta conforme suas exigências. Certifique-se
de que a consulta retorne um valor escalar:
requests
| where timestamp > now(-1h)
| summarize count()

3. Ao concluir sua consulta, execute-a clicando no botão Executar para verificar


a contagem de registros, como mostrado na seguinte captura de tela:

[ 174 ]
Capítulo 6

4. Agora estamos prontos com a consulta necessária do Application Insights. Vamos


integrar a consulta com a nossa função FeedAIwithCustomDerivedMetrics.
Navegue até o editor de código do Azure Functions e faça as seguintes alterações:
1. Forneça um nome significativo para sua métrica derivada, neste caso,
Solicitações por hora.
2. Substitua a consulta padrão pela que desenvolvemos.
3. Salve as alterações, clicando no botão Salvar:

5. Vamos fazer um teste rápido para ver se você definiu as três configurações
do aplicativo e a consulta corretamente. Navegue até a guia Integrar e altere
a frequência de execução para um minuto, conforme mostrado nesta captura
de tela:

[ 175 ]
Como monitorar e solucionar problemas de serviços sem servidor no Azure

6. Agora, vamos navegar até a guia Monitorar e ver se tudo está funcionando bem.
Em caso de problemas, você verá uma marca X na coluna Status. Exiba o erro
na seção Logs da guia Monitorar clicando na entrada Log de invocação:

7. Após garantir que a função está funcionando sem problemas, reverta


a frequência da Agenda para uma hora.

Configuração do relatório métrico derivado


personalizado
Execute as seguintes etapas:

1. Navegue até a guia Visão geral do Application Insights e clique no menu


Métricas, conforme mostrado na seguinte captura de tela:

2. Metrics Explorer é onde você encontrará todas as suas análises relativas


a diferentes métricas. No Metrics Explorer, clique no botão Editar de qualquer
relatório para configurar sua métrica personalizada, conforme mostrado
na seguinte captura de tela (ou você pode clicar no botão Adicionar gráfico
no canto superior esquerdo da seguinte captura de tela):

[ 176 ]
Capítulo 6

3. Depois disso, você passará para a folha Detalhes do gráfico, onde você pode
configurar sua métrica personalizada e todos os outros detalhes relacionados
ao gráfico. No menu suspenso NAMESPACE MÉTRICO, escolha azure.
applicationinsghts, conforme mostrado na seguinte captura de tela e escolha
a métrica personalizada Solicitação por hora que você criou:

[ 177 ]
Como monitorar e solucionar problemas de serviços sem servidor no Azure

4. Posteriormente, seu gráfico será criado como mostrado na seguinte captura


de tela:

Como funciona...
É assim que todo o processo funciona:

• Criamos o Azure Functions por meio do modelo padrão de Análise Agendada


do Application Insights.
• Configuramos as seguintes chaves nas Configurações de aplicativo do aplicativo
de função do Azure:
°° Chave de Instrumentação do Application Insights
°° A ID do aplicativo
°° A chave de acesso da API

• O tempo de execução da função do Azure consumiu automaticamente a API


do Application Insights, executou a consulta personalizada para recuperar
as métricas necessárias e executou as operações necessárias para alimentar
os dados de telemetria derivados para o Application Insights.

[ 178 ]
Capítulo 6

• Após a configuração de tudo no Azure Functions, desenvolvemos uma consulta


simples que enviou a contagem de solicitações da última hora e a alimentou
no Application Insights como uma métrica derivada personalizada. Este processo
se repetiu a cada hora.
• Posteriormente, configuramos um novo relatório usando Métricas
do Application Insights com nossa métrica derivada personalizada.

Envio de detalhes de telemetria do


aplicativo via e-mail
Uma das atividades do seu aplicativo, quando estiver ao vivo, será receber um e-mail
de notificação com detalhes sobre saúde, erros, tempo de resposta e assim por diante,
pelo menos uma vez por dia.

O Azure Functions nos fornece a capacidade de obter todos os detalhes básicos usando
um modelo de função com código que é responsável por recuperar todos os valores
necessários do Application Insights e o código de canalização de estruturação do corpo
do e-mail e o envio do e-mail usando o SendGrid. Veremos como fazer isso nesta receita.

Preparação
Execute as seguintes etapas de pré-requisitos:

1. Crie uma nova conta SendGrid, se você ainda não tiver criado uma, e obtenha
a chave de API SendGrid
2. Crie uma nova conta do Application Insights, caso ainda não tenha uma
3. Verifique se você tem um aplicativo em execução que se integre com
o Application Insights

Você pode aprender como integrar seu aplicativo com o Application


Insights em https://docs.microsoft.com/en-us/azure/
application-insights/app-insights-asp-net.

[ 179 ]
Como monitorar e solucionar problemas de serviços sem servidor no Azure

Como fazer isso...


Execute as seguintes etapas:

1. Crie uma nova função escolhendo Monitoramento no menu suspenso Cenário


e selecione o modelo Resumo agendado do Application Insights — C #,
conforme mostrado nesta captura de tela:

2. Logo depois, você será solicitado a fornecer o nome da função, a frequência


agendada e a Chave de API SendGrid para a ligação de saída SendGrid,
conforme mostrado na seguinte captura de tela:

[ 180 ]
Capítulo 6

3. Em seguida, clique no botão Criar mostrado na etapa anterior para criar


o  novo Azure Functions. O modelo cria todo o código necessário para consultar
os dados do Application Insights e envia um e-mail para a pessoa mencionada
no Endereço do destinatário da captura de tela anterior.

Verifique se você seguiu as etapas na seção Configuração de chaves


de acesso da receita Envio de detalhes de telemetria personalizados
para o Application Insights Analytics para configurar essas chaves
de acesso: Application Insights Chave de Instrumentação, a ID
do aplicativo e a chave de acesso à API.

4. Navegue até a função run.csx e altere o nome do aplicativo para o nome


do seu aplicativo, como mostrado na seguinte captura de tela:

5. Se você definiu todas as configurações corretamente, começará a receber e-mails


com base nas configurações do temporizador.
6. Vamos fazer um teste rápido, clicando no botão Executar acima do editor
de código, como mostrado na seguinte captura de tela:

7. Esta é uma captura de tela do e-mail que recebi depois de clicar no botão
Executar na captura de tela anterior:

[ 181 ]
Como monitorar e solucionar problemas de serviços sem servidor no Azure

Como funciona...
O Azure Functions usa a API do Application Insights para executar todas as consultas
do Application Insights Analytics, recupera todos os resultados, estrutura o corpo
do e-mail com todos os detalhes e invoca a API SendGrid para enviar um e-mail
para a conta de e-mail configurada.

E mais...
Os modelos do Azure fornecem código padrão com algumas consultas que geralmente
são úteis para monitorar a integridade do aplicativo. Em caso de requisitos específicos
para receber alertas de notificação, vá em frente e adicione novas consultas ao método
GetQueryString. Para incorporar os novos valores, também será necessário alterar
a classe DigestResult e a função GetHtmlContentValue.

Consulte também
A receita Envio de uma notificação por e-mail ao administrador do site usando o serviço SendGrid
do Capítulo 2, Como trabalhar com notificações usando os serviços SendGrid e Twilio.

Integração de dados de monitoramento


do Application Insights em tempo real
com Power BI usando o Azure Functions
Às vezes, você precisará exibir dados em tempo real sobre a disponibilidade
ou as informações do seu aplicativo relacionadas à integridade do seu aplicativo
em um site personalizado. Recuperar informações para o Application Insights e exibi-
las em um relatório personalizado seria um trabalho tedioso, pois você precisaria
desenvolver um site separado e compilar, testar e hospedá-lo em algum lugar.

Nesta receita, você aprenderá como é fácil visualizar informações de integridade


em tempo real para o aplicativo integrando o Application Insights e o Power BI.
Aproveitaremos os recursos do Power BI para o streaming ao vivo de dados e as funções
de temporizador do Azure para alimentar continuamente as informações de integridade
para o Power BI. Este é um diagrama de alto nível do que vamos fazer no resto da receita:

[ 182 ]
Capítulo 6

Nesta receita, usaremos o modelo Power BI do Application Insights


de um aplicativo de função que é criado usando o tempo de execução
do Azure Functions v1. O tempo de execução do Azure Functions
v2 não esse modelo. Se você estiver usando o tempo de execução v2,
poderá simplesmente criar um gatilho de temporizador e seguir as
instruções desta receita.

Preparação
Execute as seguintes etapas de pré-requisitos:

1. Crie uma conta do Power BI em https://powerbi.microsoft.com/.


2. Crie uma nova conta do Application Insights, caso ainda não tenha uma.
3. Verifique se você tem um aplicativo em execução que se integre com o
Application Insights. Você pode aprender como integrar seu aplicativo com
o Application Insights em https://docs.microsoft.com/en-us/azure/
application-insights/app-insights-asp-net.

[ 183 ]
Como monitorar e solucionar problemas de serviços sem servidor no Azure

Você precisa usar sua conta de trabalho para criar uma conta do Power BI.
No momento da gravação, não é possível criar uma conta do Power BI usando
um endereço de e-mail pessoal, como Gmail, Yahoo e assim por diante.
Verifique se você seguiu as etapas na seção Configuração de chaves de
acesso da receita Envio de detalhes de telemetria personalizados para
o Application Insights Analytics para configurar essas chaves de acesso:
Application Insights Chave de Instrumentação, a ID do aplicativo e a
chave de acesso à API.

Como fazer isso...


Executaremos as etapas a seguir para integrar o Application Insights e o Power BI.

Configuração do Power BI com um painel,


um conjunto de dados e o URI de envio por push
Execute as seguintes etapas:

1. Se você estiver usando o portal do Power BI pela primeira vez, talvez precise
clicar em Ignorar na página de boas-vindas, conforme mostrado na seguinte
captura de tela:

[ 184 ]
Capítulo 6

2. A próxima etapa é criar um conjunto de dados de streaming clicando em


Criar e, depois, escolhendo Conjunto de dados de streaming, conforme
mostrado na seguinte captura de tela:

3. Na etapa Novo conjunto de dados de streaming, selecione API e clique no botão


Avançar, conforme mostrado na seguinte captura de tela:

[ 185 ]
Como monitorar e solucionar problemas de serviços sem servidor no Azure

4. Na próxima etapa, você precisa criar os campos para o conjunto de dados de


streaming. Forneça um nome significativo para o conjunto de dados e forneça
os valores que você gostaria de enviar por push para o Power BI. Para esta
receita, criei um conjunto de dados com apenas um campo, denominado
RequestsPerSecond, do tipo Number e cliquei em Criar, como mostrado
na seguinte captura de tela:

5. Após criar o conjunto de dados, você será solicitado com uma URL de Push,
conforme mostrado na captura de tela a seguir. Você usará essa URL de
Push no Azure Functions para enviar os dados RequestsPerSecond por
push a cada segundo (ou de acordo com seus requisitos) com o valor real
de solicitações por segundo. Clique em Concluído:

[ 186 ]
Capítulo 6

6. A próxima etapa é criar um painel com um bloco nele. Vamos criar um novo
painel clicando em Criar e escolhendo Painel, como mostrado na seguinte
captura de tela:

[ 187 ]
Como monitorar e solucionar problemas de serviços sem servidor no Azure

7. No popup Criar painel, forneça um nome significativo e clique em Criar,


conforme mostrado na seguinte captura de tela, para criar um painel vazio:

8. No painel vazio, clique no botão Adicionar bloco para criar um novo bloco.
Se você clicar em Adicionar bloco, abrirá um novo popup, em que poderá
selecionar a fonte de dados da qual o bloco deverá ser preenchido:

[ 188 ]
Capítulo 6

9. Selecione Dados de Streaming Personalizados e clique em Avançar, conforme


mostrado na captura de tela anterior. Na seguinte etapa, selecione o conjunto
de dados Solicitações e clique no botão Avançar:

10. A próxima etapa é escolher Tipo de Visualização (neste caso, ele é Cartão) e
selecionar os campos da fonte de dados, como mostrado na seguinte captura de tela:

11. A etapa final é fornecer um nome para seu bloco. Forneci RequestsPerSecond.
O nome pode não fazer sentido, neste caso. Mas você pode fornecer qualquer
nome, de acordo com suas exigências.

[ 189 ]
Como monitorar e solucionar problemas de serviços sem servidor no Azure

Criação de um Power BI em tempo real do Azure


Application Insights — função C#
Para criar um Power BI em tempo real do Azure Application Insights usando a função
C#, execute as seguintes etapas:

1. Navegue até o Azure Functions e crie uma nova função por meio do seguinte
modelo:

2. Clique em C# na captura de tela anterior, forneça o Nome e clique no botão


Criar, conforme mostrado na seguinte captura de tela:

[ 190 ]
Capítulo 6

3. Substitua o código padrão pelo código a seguir. Verifique se configurou o valor


certo para o qual a consulta de análise deve puxar os dados. No meu caso,
forneci cinco minutos (5m) no seguinte código:
#r "Newtonsoft.Json"
using System.Configuration;
using System.Text;
using Newtonsoft.Json.Linq;
private const string AppInsightsApi =
"https://api.applicationinsights.io/beta/apps";
private const string RealTimePushURL =
"PastethePushURLhere";
private static readonly string AiAppId =
ConfigurationManager.AppSettings["AI_APP_ID"];
private static readonly string AiAppKey =
ConfigurationManager.AppSettings["AI_APP_KEY"];

public static async Task Run(TimerInfo myTimer,


TraceWriter
log)
{
if (myTimer.IsPastDue)
{
log.Warning($"[Warning]: Timer is running late! Last
ran
at: {myTimer.ScheduleStatus.Last}");
}
await RealTimeFeedRun(
query: @"
requests
| where timestamp > ago(5m)
| summarize passed = countif(success == true),
total = count()
| project passed
",
log: log
);
log.Info($"Executing real-time Power BI run at:
{DateTime.Now}");
}

private static async Task RealTimeFeedRun( string query,


TraceWriter log)
{
log.Info($"Feeding Data to Power BI has started at:
{DateTime.Now}");
string requestId = Guid.NewGuid().ToString();
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Add("x-api-key",

[ 191 ]
Como monitorar e solucionar problemas de serviços sem servidor no Azure

AiAppKey);
httpClient.DefaultRequestHeaders.Add("x-ms-app",
"FunctionTemplate");
httpClient.DefaultRequestHeaders.Add("x-ms-client-
request-id", requestId);
string apiPath = $"{AppInsightsApi}/{AiAppId}/query?
clientId={requestId}&timespan=P1D&query={query}";
using (var httpResponse = await
httpClient.GetAsync(apiPath))
{
httpResponse.EnsureSuccessStatusCode();
var resultJson = await
httpResponse.Content.ReadAsAsync<JToken>();
double result;
if (!double.TryParse(resultJson.SelectToken
("Tables[0].Rows[0][0]")?.ToString(), out
result))
{
throw new FormatException("Query must result
in a
single metric number. Try it on Analytics
before
scheduling.");
}
string postData = $"[{{ "requests": "{result}"
}}]";
log.Verbose($"[Verbose]: Sending data:
{postData}");
using (var response = await
httpClient.PostAsync(RealTimePushURL, new
ByteArrayContent(Encoding.UTF8.
GetBytes(postData))))
{
log.Verbose($"[Verbose]: Data sent with
response:
{response.StatusCode}");
}
}
}
}

O código anterior executa uma consulta do Application Insights Analytics que


envia dados nos últimos cinco minutos (solicitações) e envia os dados para a
URL de push do Power BI. Este processo se repete continuamente com base na
frequência do temporizador que você configurou.

[ 192 ]
Capítulo 6

4. Esta é uma captura de tela que tem uma sequência de imagens mostrando
os dados em tempo real:

Como funciona...
Criamos o seguinte nesta ordem específica:

1. Um conjunto de dados de streaming no aplicativo do Power BI


2. Um painel e um novo bloco que podem exibir os valores disponíveis no conjunto
de dados de streaming
3. Um novo Azure Functions que executa uma consulta do Application Insights
Analytics e alimenta dados no Power BI usando a URL de push do conjunto
de dados
4. Após concluído todo o processo, poderemos ver os dados em tempo real no bloco
do Power BI do painel

E mais...
• O Power BI nos permite criar dados em tempo real em relatórios de várias
maneiras. Nesta receita, você aprendeu a criar relatórios em tempo real usando
o conjunto de dados de streaming. As outras maneiras são com o conjunto de
dados de envio por push e o conjunto de dados de streaming PubNub. Você pode
saber mais sobre as três abordagens em https://powerbi.microsoft.com/
documentation/powerbi-service-real-time-streaming/.
• Tenha cuidado ao obter dados de integridade do aplicativo em tempo real.
A API do Application Insights tem um limite de taxa. Verifique https://dev.
applicationinsights.io/documentation/Authorization/Rate-limits
para entender mais sobre os limites de API.

[ 193 ]
Desenvolver aplicativos
confiáveis sem servidor
usando o Durable Functions
Neste capítulo, você aprenderá a:

• Configurar o Durable Functions no Portal de Gerenciamento do Azure


• Criar um aplicativo Hello World do Durable Functions
• Testar e solucionar problemas do Durable Functions
• Implementar aplicativos confiáveis multi-threaded usando o Durable Functions

Introdução
Ao trabalhar no desenvolvimento de aplicativos modernos que precisam ser hospedados
na nuvem, você precisa garantir que eles não possuam estado. A ausência de estado
é um fator essencial para o desenvolvimento de aplicativos habilitados para a nuvem.
Por exemplo, você deve evitar persistir dados no recurso específico de instâncias
de máquina virtual (VM) provisionadas para Serviços do Azure (por exemplo, serviço
de aplicativo, a API etc.). Se você fizer isso, não poderá utilizar alguns dos serviços, como
a funcionalidade de dimensionamento automático, pois o provisionamento de instâncias
é dinâmico. Se você depender de quaisquer recursos específicos da VM, acabará
enfrentando problemas com comportamentos inesperados.

Dito isso, a desvantagem da abordagem mencionada anteriormente é que você acaba


trabalhando na identificação de formas de persistência de dados em diferentes mídias,
dependendo da arquitetura do aplicativo.

[ 195 ]
Desenvolver aplicativos confiáveis sem servidor usando o Durable Functions

Para obter mais informações sobre o Durable Functions, consulte a


documentação oficial disponível em https://docs.microsoft.com/
en-us/azure/azure-functions/durable-functions-overview.

Configurar o Durable Functions no Portal


de Gerenciamento do Azure
O Azure desenvolveu uma nova maneira de gerenciar a ausência de estado na
arquitetura sem servidor, junto com outros recursos como durabilidade e confiabilidade,
na forma do Durable Functions. Ela está disponível como uma extensão do Azure
Functions. Neste capítulo, começaremos conhecendo o Durable Functions.

Preparação
Crie um novo aplicativo de função, se ainda não tiver feito isso. Verifique se a versão
do tempo de execução é ~2 nas Configurações do aplicativo, como mostrado na captura
de tela a seguir:

[ 196 ]
Capítulo 7

Como fazer isso...


Execute estas etapas:

1. Clique no botão + para criar uma nova função:

2. Crie uma nova função do iniciador HTTP do Durable Functions escolhendo


Durable Functions no menu suspenso Cenário, como mostrado na captura
de tela a seguir:

3. Posteriormente, uma nova guia será aberta:

[ 197 ]
Desenvolver aplicativos confiáveis sem servidor usando o Durable Functions

4. Clique no botão Instalar, mostrado na etapa anterior, para começar a instalar as


extensões DurableTask. A instalação das dependências deve levar cerca de dois
minutos:

5. Quando o processo for concluído, você verá o seguinte:

E mais...
Atualmente, C# é a única linguagem compatível com o desenvolvimento do Durable
Functions. O suporte para outras linguagens está na fase de visualização.

[ 198 ]
Capítulo 7

Criar um aplicativo Hello World do


Durable Functions
Embora a intenção geral deste e-book seja que cada capítulo possa resolver pelo menos
um problema de negócios, este método não resolve problemas de domínio em tempo
real. Em vez disso, ele fornece algumas orientações de início rápido para ajudá-lo a
entender mais sobre o Durable Functions e seus componentes, junto com a abordagem
de desenvolvimento do Durable Functions. No próximo capítulo, veremos como é fácil
desenvolver um aplicativo baseado em fluxo de trabalho usando o Durable Functions.

Preparação
Antes de avançar, seguiremos as seguintes etapas:

1. Faça download e instale o Postman de https://www.getpostman.com/,


caso ainda não o tenha instalado
2. Leia mais sobre o Orchestrator e as associações de gatilho de atividade em
https://docs.microsoft.com/en-us/azure/azure-functions/durable-
functions-bindings

Como fazer isso...


Para desenvolver o Durable Functions, precisamos criar as três funções a seguir:

• Cliente Orchestrator: uma Função do Azure que pode gerenciar instâncias


do Orchestrator.
• Função Orchestrator: a função real do Orchestrator permite o desenvolvimento
de fluxos de trabalho com estado por meio de código. Essa função pode
chamar de maneira assíncrona outras funções do Azure (chamadas Funções
de atividade) e pode até mesmo salvar os valores de retorno dessas funções
em variáveis locais.
• Funções de atividade: são as funções que serão chamadas pelas funções
do Orchestrator.

[ 199 ]
Desenvolver aplicativos confiáveis sem servidor usando o Durable Functions

Criar uma função HttpStart no cliente Orchestrator


Execute as seguintes etapas:

1. Crie uma nova função do iniciador HTTP do Durable Functions escolhendo


Durable Functions no menu suspenso Cenário. Em seguida, clique no iniciador
HTTP do Durable Functions, que abrirá uma nova guia mostrada a seguir.
Vamos criar uma nova função HTTP chamada HttpStart:

2. Logo em seguida, você será direcionado ao editor de código. A função


a seguir é um gatilho HTTP que aceita o nome da função que precisa
ser executada junto com a entrada. Ela usa o método StartNewAsync
do objeto DurableOrchestrationClient para iniciar o Orchestration:
#r "Microsoft.Azure.WebJobs.Extensions.DurableTask"
#r "Newtonsoft.Json"

using System.Net;

public static async Task<HttpResponseMessage> Run(


HttpRequestMessage req,
DurableOrchestrationClient starter,
string functionName,
ILogger log)
{
// Function input comes from the request content.
dynamic eventData = await req.Content.
ReadAsAsync<object>();
string instanceId = await starter.
StartNewAsync(functionName,

[ 200 ]
Capítulo 7

eventData);

log.LogInformation($"Started orchestration with ID =


'{instanceId}'.");

return starter.CreateCheckStatusResponse(req,
instanceId);
}

3. Navegue até a guia Integrar e clique em Editor avançado, como mostrado


na captura de tela a seguir:

4. No Editor avançado, as associações devem ser semelhantes ao seguinte.


Caso contrário, substitua o código padrão pelo código a seguir:
{
"bindings":
[
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"route": "orchestrators/{functionName}",
"methods": [
"post",
"get"
]
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"name": "starter",

[ 201 ]
Desenvolver aplicativos confiáveis sem servidor usando o Durable Functions

"type": "orchestrationClient",
"direction": "in"
}
]
}

A função HttpStart funciona como um gateway para invocar todas


as funções no aplicativo de função. Todas as solicitações que você fizer
usando o formato de URL https://<durablefunctionname>.
azurewebsites.net/api/orchestrators/{functionName} serão
recebidas por esta função HttpStart. Esta função executará a função
do Orchestrator, com base no parâmetro disponível no parâmetro
Route {functionName}. Tudo isso é possível com o atributo route,
definido em function.json da função HttpStart.

Criar a função do Orchestrator


Execute as seguintes etapas:

1. Vamos criar uma função do Orchestrator clicando no modelo de Orchestrator


do Durable Functions, mostrado a seguir:

2. Depois de clicar no bloco do Orchestrator do Durable Functions, você


será direcionado à guia a seguir, onde fornecerá o nome da função. Depois
de fornecer o nome, clique no botão Criar para criar a função do Orchestrator:

[ 202 ]
Capítulo 7

3. No DurableFuncManager, substitua o código padrão pelo seguinte e clique


no botão Salvar para salvar as alterações: o Orchestrator a seguir chamará
as funções de atividade usando o método CallActivityAsync do objeto
DurableOrchestraionContext:
#r "Microsoft.Azure.WebJobs.Extensions.DurableTask"
public static async Task<List<string>>
Run(DurableOrchestrationContext context)
{
var outputs = new List<string>();
outputs.Add(await context.CallActivityAsync<string>
("ConveyGreeting", "Welcome Cookbook Readers"));
return outputs;
}

4. No Editor avançado da guia Integrar, substitua o código padrão pelo seguinte


código:
{
"bindings": [
{
"name": "context",
"type": "orchestrationTrigger",
"direction": "in"
}
]
}

[ 203 ]
Desenvolver aplicativos confiáveis sem servidor usando o Durable Functions

Criar uma função de atividade


Execute as seguintes etapas:

1. Crie uma nova função chamada ConveyGreeting usando o modelo atividade


do Durable Functions:

2. Substitua o código padrão pelo seguinte código que apenas exibe o nome que
é fornecido como entrada e, em seguida, clique no botão Salvar para salvar
as alterações:
#r "Microsoft.Azure.WebJobs.Extensions.DurableTask"
public static string Run(string name)
{
return $"Hello Welcome Cookbook Readers!";
}

3. No Editor avançado da guia Integrar, substitua o código padrão pelo seguinte


código:
{
"bindings": [
{
"name": "name",
"type": "activityTrigger",
"direction": "in"
}
]
}

Neste método, criamos um cliente Orchestration, uma função do Orchestrator e uma


função de atividade. Aprenderemos a testá-los a seguir.

[ 204 ]
Capítulo 7

Como funciona...
Vejamos o funcionamento do método:

• Primeiro desenvolvemos o cliente Orchestrator (no nosso caso, HttpStart),


que pode criar Orchestrators usando a função StartNewAsync da classe
DurableOrchestrationClient. Esse método cria uma nova instância
do Orchestrator.
• Em seguida, desenvolvemos a função do Orchestrator — a parte mais crucial
do Durable Functions. Veja a seguir alguns dos recursos principais mais
importantes do contexto do Orchestrator:
°° Ele pode invocar várias funções de atividade.
°° Ele pode salvar a saída retornada por uma função de atividade
e transmiti-la para outra função de atividade.
°° Essas funções do Orchestrator também podem criar pontos de
verificação que salvam pontos de execução. Assim, se houver
qualquer problema com as VMs, ele poderá substituir ou retomar
o serviço automaticamente.

• Por fim, desenvolvemos a função de atividade, onde escrevemos a maior


parte da lógica de negócios. No nosso caso, ele só está retornando uma
mensagem simples.

E mais...
O Durable Functions depende da estrutura de tarefas duráveis. Saiba mais sobre
a estrutura de tarefas duráveis em https://github.com/Azure/durabletask.

Testar e solucionar problemas do


Durable Functions
Nos capítulos anteriores, discutimos várias maneiras de testar as Funções do Azure.
Podemos testar o Durable Functions com o mesmo conjunto de ferramentas. No
entanto, a abordagem dos testes é totalmente diferente devido aos seus recursos
e à maneira como ele funciona.

Aqui, veremos alguns dos pontos essenciais que você precisa conhecer ao trabalhar
com o Durable Functions.

[ 205 ]
Desenvolver aplicativos confiáveis sem servidor usando o Durable Functions

Preparação
Faça download e instale os seguintes itens, caso ainda não tenha feito isso:

• A ferramenta Postman, disponível em https://www.getpostman.com.


• O Gerenciador de Armazenamento do Microsoft Azure, disponível em
http://storageexplorer.com.

Como fazer isso...


Execute as seguintes etapas:

1. Navegue até o editor de código da função HttpStart e capture o URL clicando


em </>Obter URL de função. Substitua o valor do modelo {functionName}
por DurableFuncManager.
2. Vamos fazer uma solicitação POST usando o Postman:

3. Depois de clicar no botão Enviar, você receberá uma resposta com o seguinte:
°° O ID da instância
°° O URL para recuperar o status da função
°° O URL para enviar um evento à função
°° O URL para encerrar a solicitação

4. Clique em statusQueryGetUri na etapa anterior para exibir o status da função.


Se você clicar no link na etapa anterior abrirá a consulta em uma nova guia
dentro da ferramenta Postman. Quando a nova guia for aberta, clique no botão
Enviar para obter a saída real:

[ 206 ]
Capítulo 7

5. Se tudo correr bem, poderemos ver o runtimeStatus como Concluído


no Postman, como mostrado na captura de tela anterior. Você também receberá
oito registros no armazenamento da tabela, onde o histórico de execução
é armazenado, como mostrado a seguir:

6. Se algo der errado, você poderá ver a mensagem de erro na coluna de resultados,
que informa em qual função ocorreu o erro. Em seguida, navegue até a guia
Monitor dessa função para ver uma explicação detalhada do erro.

[ 207 ]
Desenvolver aplicativos confiáveis sem servidor usando o Durable Functions

Implementar aplicativos confiáveis multi-


threaded usando o Durable Functions
Trabalhei em alguns dos aplicativos em que a execução paralela é necessária para
executar algumas tarefas de computação. A principal vantagem dessa abordagem
é que você obtém a saída desejada muito rapidamente, dependendo dos subthreads
que criar. Isso poderia ser feito de várias maneiras, usando diversas tecnologias.
No entanto, o desafio nessas abordagens é que, se algo der errado no meio de
qualquer um dos subthreads, não é fácil fazer a autocorreção e retomar a partir de
onde o processo parou. Tenho certeza de que muitos de vocês enfrentaram problemas
semelhantes em seu aplicativo, pois é um caso de negócios muito comum.

Aqui, implementaremos uma maneira simples de executar uma função em paralelo com
várias instâncias usando o Durable Functions para o cenário a seguir.

Imagine que temos cinco clientes (cujos IDs são 1, 2, 3, 4 e 5, respectivamente) que nos
procuraram para gerar um grande número de códigos de barras (cerca de 50.000). Seria
necessário muito tempo para gerar os códigos de barras, pois isso envolveria algumas
tarefas de processamento de imagens. Então, uma maneira simples de processar
rapidamente a solicitação é usar a programação assíncrona criando um thread para
cada um dos clientes e, em seguida, executar a lógica em paralelo para cada um deles.

Também simularemos um caso de uso simples para entender como o Durable Functions
faz a autocorreção quando a VM na qual ele está hospedado fica indisponível ou é
reiniciada.

Preparação
Instale os seguintes itens, caso ainda não tenha feito isso:

• A ferramenta Postman, disponível em https://www.getpostman.com/


• O Gerenciador de Armazenamento do Microsoft Azure, disponível em
http://storageexplorer.com/

[ 208 ]
Capítulo 7

Como fazer isso...


Aqui, criaremos os seguintes gatilhos do Azure Functions:

• Uma função do Orchestrator chamada GenerateBARCode


• Duas funções de gatilho de atividade:
°° GetAllCustomers: para simplificar, essa função apenas retorna
a matriz de IDs de cliente. Em seus aplicativos reais, haveria uma lógica
de negócios que decide quais clientes estão qualificados e, com base
nessa lógica, você retornaria os IDs dos clientes qualificados.
°° CreateBARCodeImagesPerCustomer: esta função não cria o código de
barras. Ela apenas registra uma mensagem para o console, pois nosso
objetivo é entender os recursos do Durable Functions. Para cada cliente,
geraremos aleatoriamente um número inferior a 50.000 e o repetiremos.

Criar a função do Orchestrator


Execute as seguintes etapas:

1. Crie uma nova função chamada GenerateBARCode usando o modelo


Orchestrator do Durable Functions. Substitua o código padrão pelo código
a seguir e clique no botão Salvar para salvar as alterações. O código a seguir
inicialmente classifica a função de atividade GetAllCustomers, armazena todos
os IDs de cliente em uma matriz e, para cada cliente, ele novamente chama outra
função de atividade que retorna o número de códigos de barras que são gerados.
Por fim, ele aguarda até que as funções de atividade de todos os clientes sejam
concluídas e retorna a soma de todos os códigos de barras gerados para todos
os clientes.
#r "Microsoft.Azure.WebJobs.Extensions.DurableTask"
public static async Task<int> Run(
DurableOrchestrationContext context)
{
int[] customers = await
context.CallActivityAsync<int[]>("GetAllCustomers",null);

var tasks = new Task<int>[customers.Length];


for (int nCustomerIndex = 0; nCustomerIndex < customers.
Length; nCustomerIndex++)
{
tasks[nCustomerIndex] = context.CallActivityAsync<int>
("CreateBARCodeImagesPerCustomer",
customers[nCustomerIndex]);

[ 209 ]
Desenvolver aplicativos confiáveis sem servidor usando o Durable Functions

await Task.WhenAll(tasks);
int nTotalItems = tasks.Sum(item => item.Result);

return nTotalItems;
}

2. No Editor avançado da guia Integrar, substitua o código padrão pelo seguinte


código:
{
"bindings": [
{
"name": "context",
"type": "orchestrationTrigger",
"direction": "in"
}
]
}

Criar uma função de atividade GetAllCustomers


Execute as seguintes etapas:

1. Crie uma nova função chamada GetAllCustomers usando o modelo Atividade


do Durable Functions, substitua o código padrão pelo código a seguir e clique
no botão Salvar para salvar as alterações:
#r "Microsoft.Azure.WebJobs.Extensions.DurableTask"
public static int[] Run(string name)
{
int[] customers = new int[]{1,2,3,4,5};
return customers;
}

2. No Editor avançado da guia Integrar, substitua o código padrão pelo seguinte


código:
{
"bindings": [
{
"name": "name",
"type": "activityTrigger",

[ 210 ]
Capítulo 7

"direction": "in"
}
]
}

Criar uma função de atividade


CreateBARCodeImagesPerCustomer
Execute as seguintes etapas:

1. Crie uma nova função chamada CreateBARCodeImagesPerCustomer usando


o modelo Atividade do Durable Functions. Substitua o código padrão
pelo código a seguir e clique no botão Salvar para salvar as alterações:
#r "Microsoft.Azure.WebJobs.Extensions.DurableTask"
#r "Microsoft.WindowsAzure.Storage"
using Microsoft.WindowsAzure.Storage.Blob;

public static async Task<int> Run(DurableActivityContext


customerContext,ILogger log)
{
int ncustomerId = Convert.ToInt32
(customerContext.GetInput<string>());
Random objRandom = new Random(Guid.NewGuid().
GetHashCode());
int nRandomValue = objRandom.Next(50000);
for(int nProcessIndex = 0;nProcessIndex<=nRandomValue;
nProcessIndex++)
{
log.LogInformation($" running for {nProcessIndex}");
}
return nRandomValue;
}

2. No Editor avançado da guia Integrar, substitua o código padrão pelo seguinte


código:
{
"bindings": [
{
"name": "customerContext",
"type": "activityTrigger",
"direction": "in"
}
]
}

[ 211 ]
Desenvolver aplicativos confiáveis sem servidor usando o Durable Functions

3. Vamos executar a função usando o Postman. Interromperemos o Serviço


de Aplicativo para simular a reinicialização da VM onde a função estaria em
execução e para ver como o Durable Function é retomado de onde foi pausado.
4. Faça uma solicitação POST usando o Postman, como mostrado a seguir:

5. Depois de clicar no botão Enviar, você receberá uma resposta com o URL
do status. Clique em statusQueryGetURi para exibir o status da função.
Se você clicar no link statusQueryGetURi, ele será aberto em uma nova guia
dentro da ferramenta Postman. Quando a nova guia for aberta, clique no botão
Enviar para ver o progresso da função.
6. Enquanto a função estiver em execução, navegaremos até a folha Visão geral
do aplicativo de função e interromperemos o serviço clicando no botão Parar:

7. A execução da função será interrompida no meio. Navegaremos até nossa conta


de armazenamento no Gerenciador de Armazenamento e abriremos a tabela
DurableFunctionsHubHistory para ver o progresso que foi feito:

8. Depois de algum tempo — no meu caso, depois de apenas cinco minutos


— volte para a folha Visão geral e inicie o serviço de aplicativo de função.
Você notará que o Durable Function será retomado a partir de onde havia
parado. Não escrevemos nenhum código para isso; é um recurso pronto
para uso. Veja a seguir a captura de tela da função concluída:

[ 212 ]
Capítulo 7

Como funciona...
O Durable Functions nos permite desenvolver a execução confiável das nossas funções,
o que significa que, mesmo que as VMs falhem ou sejam reiniciadas enquanto a função
estiver em execução, ela será retomada automaticamente no estado anterior. Ela faz isso
com a ajuda de algo chamado definição do ponto de verificação e reprodução, em que
o histórico da execução é armazenado na tabela de armazenamento.

Saiba mais sobre esse recurso em https://docs.microsoft.


com/en-us/azure/azure-functions/durable-functions-
checkpointing-and-replay.

E mais...
• Caso você receba uma resposta 404 Not Found ao executar o URL
statusQueryGetURi, não se preocupe. Levará algum tempo, mas acabará
funcionando quando você fizer uma solicitação posteriormente.
• Para exibir o histórico de execução do Durable Functions, navegue
até a tabela DurableFunctionsHubHistory, localizada na conta
de armazenamento que foi criada junto com o aplicativo de função:

Você poderá encontrar o nome da conta de armazenamento nas Configurações


do aplicativo, como mostrado na captura de tela anterior.

[ 213 ]
Importação em massa de
dados usando o Azure Durable
Functions e o Cosmos DB
Neste capítulo, vamos aprender as seguintes receitas:

• Carregar dados de funcionários no Armazenamento de Blobs


• Criar um gatilho de blob
• Criar o Orquestrador do Durable e acioná-lo para cada importação do Excel
• Ler dados do Excel usando funções de atividade
• Escalar automaticamente a taxa de transferência do Cosmos DB
• Inserir dados em massa no Cosmos DB

Introdução
Neste capítulo, desenvolveremos um miniprojeto considerando um caso de uso
muito comum que resolve o problema de negócios de compartilhamento de dados
em diferentes aplicativos que usam Excel. Usaremos a Durable Functions, que é uma
extensão para o Azure Functions que permite gravar fluxos de trabalho escrevendo
o número mínimo de linhas de código.

[ 215 ]
Importação em massa de dados usando o Azure Durable Functions e o Cosmos DB

Aqui estão os dois principais recursos da Durable Functions que usaremos nas receitas
deste capítulo:

• Orquestrador: uma função que é responsável pelo gerenciamento de todos


os gatilhos de atividade. Ele pode ser tratado como um gerenciador de fluxo
de trabalho que tem várias etapas. O Orquestrador é responsável por iniciar
o gatilho de atividade, transferir entradas para o gatilho de atividade, obter
a saída, manter o estado e, em seguida, transferir a saída de um gatilho
de atividade para outro, se necessário.
• Gatilho atividade: cada gatilho de atividade pode ser tratado como uma etapa
do fluxo de trabalho que executa uma função.

Para saber mais sobre o Durable Functions, acesse https://docs.


microsoft.com/en-us/azure/azure-functions/durable-
functions-overview.

Problema de negócios
Em geral, todas as organizações definitivamente estarão usando diversos aplicativos
hospedados em várias plataformas em diferentes data centers (na nuvem ou na
infraestrutura local). Muitas vezes, haverá requisitos em que os dados de um
aplicativo precisarão ser alimentados em outro sistema. Normalmente, planilhas do
Excel (ou, em alguns casos, arquivos JSON ou XML) são usadas para exportar dados
de um aplicativo e importá-los para outro.

Você pode pensar que exportar um arquivo do Excel de um aplicativo para outro
é um trabalho fácil, mas se houver muitos aplicativos que precisam alimentar dados
para outros aplicativos, em uma base semanal/mensal, isso se tornará muito tedioso
e dará muito espaço para erro manual. Então, obviamente, a solução é automatizar
o processo para a maior extensão possível.

Neste capítulo, aprenderemos como desenvolver uma solução durável com base
na arquitetura sem servidor usando o Durable Functions. Se você já leu o Capítulo 7,
Como desenvolver aplicativos confiáveis sem servidor usando Durable Functions, terá
algum conhecimento básico do que é o Durable Functions e como ele funciona. No
Capítulo 7, Como desenvolver aplicativos confiáveis sem servidor usando Durable Functions,
implementamos a solução do portal. No entanto, neste capítulo, implementaremos
um miniprojeto usando o Visual Studio 2017 (preferencialmente, 15.5 ou superior).

Antes de começarmos a desenvolver o projeto, vamos tentar entender a nova maneira


sem servidor de implementar a solução.

[ 216 ]
Capítulo 8

Maneira sem servidor do Durable de


implementar uma importação do Excel
Este diagrama mostra todas as etapas necessárias para compilar a solução usando a
arquitetura sem servidor:

1. Clientes externos ou aplicativos carregam um arquivo do Excel para


o Armazenamento de Blobs
2. O Gatilho de blob é acionado depois que o arquivo Excel é carregado com êxito
3. O Orquestrador do Durable é iniciado do Gatilho de blob
4. O Orquestrador invoca Ler Excel - Gatilho de atividades para ler o conteúdo
do Excel do Armazenamento de Blobs
5. O Orquestrador invoca Escalar RUs - Gatilho de atividades para aumentar
a taxa de produtividade da coleção do Cosmos DB, de forma que ela possa
acomodar a carga
6. O Orquestrador invoca Importar dados - Gatilho de atividades para preparar
a coleção para importar dados em massa
7. Por fim, Importar dados - Gatilho de atividades carrega os dados da coleção
para a coleção do Cosmos DB usando associações de saída do Cosmos DB

Carregar dados de funcionários no


Armazenamento de Blobs
Nesta receita, desenvolveremos um aplicativo de console que é responsável por carregar
a planilha do Excel para o Armazenamento de Blobs.

[ 217 ]
Importação em massa de dados usando o Azure Durable Functions e o Cosmos DB

Preparação
Execute os seguintes pré-requisitos:

1. Instale o Visual Studio 2017 versão 15.5 ou superior.


2. Crie uma conta de armazenamento e crie um contêiner de blob com o nome
Excelimports.
3. Crie um arquivo do Excel com alguns dados do funcionário, conforme mostrado
na captura de tela a seguir:

Como fazer isso...


Execute as seguintes etapas:

1. Crie um novo aplicativo de console denominado ExcelImport.Client usando


o Visual Studio, conforme mostrado na captura de tela a seguir:

[ 218 ]
Capítulo 8

2. Depois que o projeto for criado, execute os seguintes comandos no gerenciador


de pacotes NuGet:
Install-Package Microsoft.Azure.Storage.Blob

Install-Package Microsoft.Extensions.Configuration

Install-Package Microsoft.Extensions.Configuration.FileExtensions

Install-Package Microsoft.Extensions.Configuration.Json

3. Adicione os seguintes namespaces na parte superior do arquivo Program.cs:


using Microsoft.Extensions.Configuration;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using System;
using System.IO;
using System.Threading.Tasks;

4. A próxima etapa é desenvolver o código em uma função denominada


UploadBlob, que carrega o arquivo do Excel para o contêiner de blob que
criamos. Por uma questão de simplicidade, o código a seguir carrega o arquivo
do Excel de um local codificado. No entanto, em um aplicativo comum em tempo
real, esse arquivo é carregado pelo usuário final por meio de uma interface
Web. Copie o código a seguir e cole-o no arquivo Program.cs do aplicativo
ExcelImport.Client:

private static async Task UploadBlob()


{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile(“appsettings.json”, optional: true, reloadOnChange:
true);
IConfigurationRoot configuration = builder.Build();
CloudStorageAccount cloudStorageAccount = CloudStorageAccount.
Parse(configuration.GetConnectionString(“StorageConnection”));
CloudBlobClient cloudBlobClient = cloudStorageAccount.
CreateCloudBlobClient();
CloudBlobContainer ExcelBlobContainer = cloudBlobClient.GetContain
erReference(“Excelimports”);
await ExcelBlobContainer.CreateIfNotExistsAsync();
CloudBlockBlob cloudBlockBlob = ExcelBlobContainer.GetBlockBlobRef
erence(“EmployeeInformation” + Guid.NewGuid().ToString());
await cloudBlockBlob.UploadFromFileAsync(@”C:\Users\
vmadmin\source\repos\POC\ImportExcelPOC\ImportExcelPOC\
EmployeeInformation.xlsx”);
}

[ 219 ]
Importação em massa de dados usando o Azure Durable Functions e o Cosmos DB

5. Agora, copie o código a seguir para a função Main. Esta parte do código apenas
invoca a função UploadBlob, que internamente é responsável pelo carregamento
do blob:
{
UploadBlob().Wait();
}
catch (Exception ex)
{
Console.WriteLine(“An Error has occurred with the message” +
ex.Message);
}

6. A próxima etapa é criar um arquivo de configuração denominado appsettings.


json, que contém a cadeia de conexão da conta de armazenamento, conforme
mostrado na captura de tela a seguir:

7. Vá para as propriedades do arquivo appsettings.json e altere Copiar


para Diretório de Saída para a opção Copiar se for mais recente, a fim
de que as propriedades possam ser lidas pelo programa, conforme mostrado
na captura de tela a seguir:

[ 220 ]
Capítulo 8

8. Agora, compile o aplicativo e execute-o. Se você configurou tudo, deverá ver algo
como mostrado na seguinte captura de tela:

9. Vamos navegar para a conta de armazenamento e ir para o contêiner de blob


denominado Excelimports, onde você deve ver o arquivo do Excel que
carregamos, conforme mostrado na seguinte captura de tela:

É isso. Desenvolvemos um aplicativo que é responsável pelo carregamento do blob.

Como funciona...
Nesta receita, criamos um aplicativo de console que usa assemblies de armazenamento
para carregar um blob (em nosso caso, é apenas um arquivo do Excel) para o contêiner
de blob designado. Observe que toda vez que o aplicativo for executado, um novo
arquivo será criado no contêiner de blob. Para carregar os arquivos do Excel com
nomes exclusivos, estamos anexando um GUID.

[ 221 ]
Importação em massa de dados usando o Azure Durable Functions e o Cosmos DB

E mais...
Anote as convenções de nomenclatura que devem ser seguidas ao criar o contêiner
de blob:

No momento da escrita, esta é a mensagem de erro exibida pelo portal se


você não adere as regras de nomenclatura: Este nome pode conter apenas
letras minúsculas, números e hifens e deve começar com uma letra ou
um número. Cada hífen deve ser precedido e seguido por um caractere
que não seja hífen. O nome também deve ter entre 3 e 63 caracteres.

Criar um gatilho de blob


Nesta receita, criaremos um aplicativo de função com o tempo de execução do Azure
Functions V2 e aprenderemos como criar um gatilho de blob usando o Visual Studio.
Além disso, veremos como o gatilho de blob é acionado quando o arquivo do Excel
é carregado com êxito para o contêiner de blob.

Preparação
Execute os seguintes pré-requisitos:

1. Adicione um novo projeto denominado ExcelImport.DurableFunctions


à solução existente, escolhendo o modelo do Azure Functions, conforme
mostrado na seguinte captura de tela:

[ 222 ]
Capítulo 8

2. A próxima etapa é escolher o tempo de execução do Azure Functions, bem como


o gatilho. Escolha Azure Functions v2 (.NET Core), escolha Gatilho de blob
e forneça o seguinte:

°° Conta de Armazenamento (AzureWebJobsStorage): nome da conta


de armazenamento em que nosso contêiner de blob reside

°° Configuração da cadeia de conexão: o nome da chave da cadeia


de conexão que se refere à conta de armazenamento
°° Caminho: o nome do contêiner de blob em que os arquivos do Excel
estão sendo carregados

[ 223 ]
Importação em massa de dados usando o Azure Durable Functions e o Cosmos DB

3. Quando você cria o projeto, a estrutura deve ser algo parecido com a seguinte
captura de tela:

4. Vamos adicionar uma cadeia de conexão com o nome StorageConnection


(lembre-se, usamos isso no arquivo de configuração da cadeia de conexão em
uma das etapas anteriores) a local.settings.json, conforme mostrado na
seguinte captura de tela:

5. Agora, abra o arquivo Function1.cs e renomeie-o para


ExcelImportBlobTrigger, e também substitua Function1 (o nome da função) por
ExcelImportBlobTrigger (linha 10), como mostrado na seguinte captura de tela:

[ 224 ]
Capítulo 8

6. Configure ExcelImport.DurableFunctions como o projeto padrão, conforme


mostrado na captura de tela a seguir:

7. Crie um ponto de interrupção em ExcelImportBlobTrigger e execute


o aplicativo pressionando a tecla F5. Se tudo estiver configurado corretamente,
você deve ver o console da seguinte maneira:

[ 225 ]
Importação em massa de dados usando o Azure Durable Functions e o Cosmos DB

8. Vamos agora carregar um novo arquivo executando o aplicativo ExcelImport.


Client. Logo após o carregamento do arquivo, o gatilho de blob será acionado,
conforme mostrado na captura de tela a seguir. Seus pontos de interrupção
também devem ser atingidos junto com isto:

Terminamos de criar o gatilho de blob que é acionado sempre que um novo blob
é adicionado ao contêiner de blob.

Como fazer isso...


Nesta receita, criamos um novo aplicativo de função com base no tempo de execução
do Azure Functions V2, que é baseado na estrutura do .NET Core e pode ser executado
em todas as plataformas compatíveis com .NET Core (como Windows e Linux OSes).
Também criamos um gatilho de blob e o configuramos para ser executado quando um
novo Blob é adicionado definindo a configuração da cadeia de conexão. Também criamos
um arquivo de configuração local.setting.json para armazenar os valores de
configuração usados no desenvolvimento local. Depois que criamos o gatilho de blob,
executamos o aplicativo ExcelImport.Client para carregar um arquivo para validar
se o gatilho de blob está sendo executado.

E mais...
Todas as configurações serão obtidas do arquivo local.settings.json enquanto
você está executando as funções em seu ambiente local. No entanto, quando você
implanta as funções no Azure, todos os itens de configurações (como cadeia de conexão
e configurações do aplicativo) serão mencionados nas Configurações do Aplicativo
de seu aplicativo de função. Verifique se você criou todos os itens de configuração
no aplicativo de função depois de implantar as funções.

[ 226 ]
Capítulo 8

Criar o Orquestrador do Durable


e acioná-lo para cada importação do Excel
Esta receita é uma das mais importantes e interessantes. Aprenderemos como criar
o Orquestrador do Durable responsável por gerenciar todas as funções de atividade
que criamos para as diferentes tarefas individuais necessárias para concluir o projeto
ExcelImport.

Como fazer isso...


Execute as seguintes etapas:

1. Crie uma nova função clicando com o botão direito do mouse em ExcelImport.
DurableFunctions, clique em Adicionar e escolha Nova Função do Azure,
como mostrado na captura de tela a seguir:

2. Na janela pop-up Adicionar Novo Item, escolha Função do Azure, forneça


o nome ExcelImport_Orchestrator e clique em Adicionar, conforme mostrado
na seguinte captura de tela:

[ 227 ]
Importação em massa de dados usando o Azure Durable Functions e o Cosmos DB

3. Na janela pop-up Nova Função do Azure, selecione o modelo Orquestração


do Durable Function e clique no botão OK, que cria o seguinte:

°° HttpStart: esta é a função do iniciador do Durable Function


(um gatilho de HTTP), que funciona como um cliente que pode invocar
o Orquestrador do Durable. No entanto, em nosso projeto, não usaremos
esse Gatilho HTTP; usaremos a lógica dentro dele em nosso gatilho
de blob ExcelImportBlobTrigger para invocar o Orquestrador
do Durable.
°° RunOrchestrator: o Orquestrador real do Durable capaz de invocar
e gerenciar as funções de atividade.
°° SayHello: uma função de atividade simples. Criaremos algumas
funções de atividade. Vamos continuar e remover este método:

[ 228 ]
Capítulo 8

4. No gatilho de blob ExcelImportBlobTrigger, vamos fazer as seguintes


alterações de código para invocar o Orquestrador:

°° Decore a função para ser assíncrona


°° Adicione as associações de saída do cliente de Orquestração
°° Chame StartNewAsync usando o DurableOrchestrationClient

5. O código na função ExcelImportBlobTrigger deve ser semelhante ao seguinte


após fazer estas alterações:
using System.IO;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;
namespace ExcelImport.DurableFunctions
{
public static class ExcelImportBlobTrigger
{
[FunctionName(“ExcelImportBlobTrigger”)]
public static async void Run(
[BlobTrigger(“Excelimports/{name}”, Connection =
“StorageConnection”)]Stream myBlob,
string name,
[OrchestrationClient]DurableOrchestrationClient starter,
ILogger log)
{
string instanceId = await starter.StartNewAsync(“ExcelImport_
Orchestrator”, name);
log.LogInformation($”C# Blob trigger function Processed blob\n
Name:{name} \n Size: {myBlob.Length} Bytes”);
}
}
}

6. Crie um ponto de interrupção na função do Orquestrador ExcelImport_


Orchestrator e execute o aplicativo pressionando F5.

[ 229 ]
Importação em massa de dados usando o Azure Durable Functions e o Cosmos DB

7. Agora vamos carregar um novo arquivo (enquanto ExcelImport.


DurableFunctions está em execução) executando a função ExcelImport.
Client. (Você também pode carregar diretamente o arquivo do Excel do portal
do Azure.) Depois que o arquivo é carregado, em apenas alguns instantes
o ponto de interrupção na função ExcelImport_Orchestrator deve ser
atingido, conforme mostrado na seguinte captura de tela:

Nós aprendemos como invocar a função Orchestration do Durable do gatilho de blob.

Como funciona...
Iniciamos a receita criando a função Orchestration e, em seguida, fizemos alterações
no gatilho de blob ExcelImportBlobTrigger adicionando as associações de saída
OrchestratonClient para invocar a função do Orquestrador do Durable.

Quando você cria uma nova função Orchestration, ela cria algumas funções de atividade.
Nas próximas receitas, vamos removê-las e criar novas funções de atividade de acordo
com nossas necessidades.

E mais...
Nesta receita, usamos DurableOrchestrationClient, que compreende como iniciar
e terminar Orquestrações do Durable.

[ 230 ]
Capítulo 8

Aqui estão algumas das operações importantes que são compatíveis:

• Inicie uma instância usando o método StartNewAsync


• Termine uma instância usando o método TerminateAsync
• Consulte o status da instância atualmente em execução usando o método
GetStatusAsync
• Ele também pode acionar um evento para a instância para atualizar sobre
qualquer evento externo usando o método RaiseEventAsync

Saiba mais sobre isso em https://docs.microsoft.com/


en-us/azure/azure-functions/durable-functions-
instance-management#sending-events-to-instances.

Ler dados do Excel usando funções


de atividade
Nesta receita, recuperaremos todos os dados de planilhas específicas do Excel escrevendo
uma função de atividade.

Vamos agora fazer algumas alterações de código na função Orchestration escrevendo


uma nova função de atividade que pode ler dados de uma planilha do Excel que
é carregada para o contêiner de blob.

Preparação
Nesta receita, criaremos o gatilho de atividade denominado função ReadExcel_AT, que
lê os dados do blob armazenado na conta de armazenamento. Esse gatilho de atividade
executa os seguintes trabalhos:

Conecta-se ao blob usando uma função, ReadBlob, de uma classe denominada


StorageManager.

1. Lê os dados do Excel usando um componente denominado EPPlus. Leia mais


sobre isso em https://github.com/JanKallman/EPPlus.
2. Retorna os dados do arquivo do Excel como uma coleção de objetos
de funcionário.

Em seguida, instale os seguintes pacotes NuGet no projeto ExcelImport.


DurableFunctions:

Install-Package WindowsAzure.Storage
Install-Package EPPlus

[ 231 ]
Importação em massa de dados usando o Azure Durable Functions e o Cosmos DB

Como fazer isso...


Se você pensar no Durable Functions como um fluxo de trabalho, a função de gatilho
de atividade poderá ser tratada como uma etapa de fluxo de trabalho que usa algum
tipo de entrada opcional, executa alguma funcionalidade e retorna uma saída opcional.
É um dos principais conceitos do Azure Durable Functions.

Saiba mais sobre o Gatilho de Atividade em https://docs.


microsoft.com/en-us/azure/azure-functions/durable-
functions-types-features-overview.

Antes de começarmos a criar a função de gatilho de atividade, vamos primeiro compilar


as funções de dependência.

Ler dados do Armazenamento de Blob


Execute as seguintes etapas:

1. Crie uma classe denominada StorageManager e cole no código a seguir.


Esse código conecta à conta de armazenamento especificada, lê os dados
dos blobs e retorna um objeto Stream para a função de chamador:
class StorageManager
{
public async Task<Stream> ReadBlob(string BlobName)
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile(“local.settings.json”, optional: true,
reloadOnChange: true);
IConfigurationRoot configuration = builder.Build();
CloudStorageAccount cloudStorageAccount = CloudStorageAccount.
Parse(configuration.GetConnectionString(“StorageConnection”));
CloudBlobClient cloudBlobClient = cloudStorageAccount.
CreateCloudBlobClient();
CloudBlobContainer ExcelBlobContainer = cloudBlobClient.
GetContainerReference(“Excel”);
CloudBlockBlob cloudBlockBlob = ExcelBlobContainer.GetBlockBlobRe
ference(BlobName);
return await cloudBlockBlob.OpenReadAsync();
}
}

[ 232 ]
Capítulo 8

2. Cole as seguintes referências de namespace na classe StorageManager:


using Microsoft.Extensions.Configuration;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using System.IO;
using System.Threading.Tasks;

3. Por último, adicione uma cadeia de conexão (se ainda não tiver feito isso)
da conta de armazenamento ao arquivo local.settings.json, como
mostrado aqui:

Ler dados do Excel do fluxo


Execute as seguintes etapas:

1. Crie uma classe denominada EPPLusExcelManager e cole o código a seguir. Essa


classe tem um método denominado ReadExcelData, que usa uma biblioteca
denominada EPPlus para ler os dados do arquivo do Excel (extensão .xlsx).
Ele lê cada linha, cria um objeto Employee para cada linha e, em seguida, retorna
uma coleção de funcionários. Nós criaremos a classe Employee em instantes:
class EPPLusExcelManager
{
public List<Employee> ReadExcelData(Stream stream)
{
List<Employee> employees = new List<Employee>();
//FileInfo existingFile = new FileInfo(“EmployeeInformation.
xlsx”);
using (ExcelPackage package = new ExcelPackage(stream))
{
ExcelWorksheet ExcelWorksheet = package.Workbook.Worksheets[0];
for (int EmployeeIndex = 2; EmployeeIndex < ExcelWorksheet.
Dimension.Rows + 1; EmployeeIndex++)
{
[ 233 ]
Importação em massa de dados usando o Azure Durable Functions e o Cosmos DB

employees.Add(new Employee()
{
EmpId = Convert.ToString(ExcelWorksheet.Cells[EmployeeIndex,
1].Value),
Name = Convert.ToString(ExcelWorksheet.Cells[EmployeeIndex,
2].Value),
Email = Convert.ToString(ExcelWorksheet.Cells[EmployeeIndex,
3].Value),
PhoneNumber = Convert.ToString(ExcelWorksheet.
Cells[EmployeeIndex, 4].Value)
});
}
}
return employees;
}
}

2. Agora, vamos criar outra classe denominada Employee e copiar o seguinte


código:
public class Employee
{
public string EmpId { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string PhoneNumber { get; set; }
}

Se compilar o aplicativo agora, você não deve ver erros. Nós concluímos o
desenvolvimento das dependências para nossa primeira função de gatilho de atividade.
Agora, vamos começar a compilar o gatilho de atividade real.

Criar a função de atividade


Execute as seguintes etapas:

1. Crie uma nova função de atividade denominada ReadExcel_AT que conecta ao


blob usando a classe StorageManager que desenvolvemos na seção anterior e,
em seguida, lê os dados usando a classe EPPLusExcelManager. Copie o seguinte
código para a classe ExcelImport_Orchestrator:
[FunctionName(“ReadExcel_AT”)]
public static async Task<List<Employee>> ReadExcel_AT(
[ActivityTrigger] string name,
ILogger log)
{

[ 234 ]
Capítulo 8

log.LogInformation(“Orchestration started”);
StorageManager storageManager = new StorageManager();
Stream stream = null; ;
log.LogInformation(“Reading the Blob Started”);
stream = await storageManager.ReadBlob(name);
log.LogInformation(“Reading the Blob has Completed”);
EPPLusExcelManager ePPLusExcelManager = new EPPLusExcelManager();
log.LogInformation(“Reading the Excel Data Started”);
List<Employee> employees = ePPLusExcelManager.
ReadExcelData(stream);
log.LogInformation(“Reading the Blob has Completed”);
return employees;
}

2. Adicione System.IO à lista de namespaces, se ainda não estiver incluído,


e compile o aplicativo.
3. Vamos agora invocar esta função de atividade do Orquestrador. Vá para a função
do Orquestrador ExcelImport_Orchestrator e substitua-a pelo código a seguir.
A função Orchestration invoca a função de atividade passando o nome do Excel que
é carregado para que a função de atividade leia os dados do arquivo do Excel:
[FunctionName(“ExcelImport_Orchestrator”)]
public static async Task<List<string>> RunOrchestrator(
[OrchestrationTrigger] DurableOrchestrationContext context)
{
var outputs = new List<string>();
string ExcelFileName = context.GetInput<string>();
List<Employee> employees = await context.CallActivityAsync<List<E
mployee>>(“ReadExcel_AT”, ExcelFileName);
return outputs;
}

[ 235 ]
Importação em massa de dados usando o Azure Durable Functions e o Cosmos DB

4. Vamos executar o aplicativo e, em seguida, carregar um arquivo do Excel.


Se tudo estiver configurado corretamente, você deve ver algo como mostrado
a seguir na função de gatilho de atividade ReadExcel_AT, em que é possível
o número de registros de funcionários que estão sendo lidos da planilha de Excel:

E mais...
A função do Orquestrador recebe a entrada usando o método GetInput() da classe
DurableOrchestratorContext. Essa entrada é passada pelo gatilho de blob usando
o método StartNewAsync da função da classe DurableOrchestrationClient.

[ 236 ]
Capítulo 8

Escalar automaticamente a taxa de


transferência do Cosmos DB
Na receita anterior, lemos os dados do Excel e os colocamos em uma coleção de
funcionários. A próxima etapa é inserir a coleção em uma coleção do Cosmos DB.
No entanto, antes de inserir os dados na coleção do Cosmos DB, precisamos entender
que, em cenários do mundo real, o número de registros que precisamos importar
será enorme e, portanto, você pode ter problemas de performance se a capacidade
da coleção do Cosmos DB não for suficiente.

A produtividade da coleção do Cosmos DB é medida pelo número de


Unidades de Solicitação (RU) alocadas para a coleção. Leia mais sobre
isso em https://docs.microsoft.com/en-us/azure/cosmos-
db/request-units.

Além disso, para reduzir custos, para cada serviço, é recomendável ter a capacidade
em um nível inferior e aumentá-la sempre que necessário. A API do Cosmos DB
nos permite controlar o número de RUs com base em nossas necessidades. Quando
precisarmos fazer uma importação em massa, aumentaremos as RUs antes de começar
a importar os dados. Depois que o processo de importação estiver concluído, poderemos
diminuir as RUs para o nível mínimo.

Preparação
Execute os seguintes pré-requisitos:

1. Crie uma conta do Cosmos DB seguindo as instruções mencionadas no artigo


em https://docs.microsoft.com/en-us/azure/cosmos-db/create-sql-
api-dotnet.

[ 237 ]
Importação em massa de dados usando o Azure Durable Functions e o Cosmos DB

2. Crie um banco de dados do Cosmos e uma coleção com armazenamento fixo


e defina as unidades de solicitação como 400 por segundo, conforme mostrado
na captura de tela a seguir:

Por uma questão de simplicidade, usei Fixa (10 GB) como a Capacidade
de armazenamento. No entanto, em cargas de produção, dependendo de seus
modelos de dados, você pode ter uma capacidade de armazenamento Ilimitada.
3. Execute o seguinte comando no gerenciador de pacotes NuGet para instalar
as dependências do Cosmos DB:
Install-Package Microsoft.Azure.WebJobs.Extensions.CosmosDB

[ 238 ]
Capítulo 8

Como fazer isso...


Execute as seguintes etapas:

1. Crie um novo gatilho de atividade denominado ScaleRU_AT no arquivo


ExcelImport_Orchestrator.cs. A função deve ser ficar mais ou menos assim
e aceitar o número de RUs a serem aumentadas, juntamente com a associação do
Cosmos DB que está sendo usada e em que substituímos a taxa de transferência:
[FunctionName(“ScaleRU_AT”)]
public static async Task<string> ScaleRU_AT(
[ActivityTrigger] int RequestUnits,
[CosmosDB(ConnectionStringSetting = “CosmosDBConnectionString”)]
DocumentClient client
)
{
DocumentCollection EmployeeCollection = await client.ReadDocumen
tCollectionAsync(UriFactory.CreateDocumentCollectionUri(“cookbook
db”, “EmployeeCollection”));
Offer offer = client.CreateOfferQuery().Where(o => o.ResourceLink
== EmployeeCollection.SelfLink).AsEnumerable().Single();
Offer replaced = await client.ReplaceOfferAsync(new
OfferV2(offer, RequestUnits));
return $”The RUs are scaled to 500 RUs!”;
}

2. Adicione os seguintes namespaces ao arquivo ExcelImport_Orchestrator.


cs:

using System.Linq;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;

[ 239 ]
Importação em massa de dados usando o Azure Durable Functions e o Cosmos DB

3. Crie uma nova cadeia de conexão para o Cosmos DB, conforme mostrado
na captura de tela a seguir. Você pode copiar a conexão da folha de Chaves
da conta do Cosmos DB:

4. Agora, na função ExcelImport_Orchestrator, adicione a seguinte linha para


invocar ScaleRU_AT. Neste exemplo, estou passando 500 como o valor de RU.
Dependendo das suas necessidades, você pode escolher um valor diferente:
await context.CallActivityAsync<string>(“ScaleRU_AT”, 500);

5. Agora, carregue um arquivo do Excel para acionar a Orchestration, que invoca


internamente o novo gatilho de atividade ScaleRU_AT e, se tudo correu bem,
a nova capacidade da coleção do Cosmos DB deve ser 500. Vamos navegar
para a guia Data Explorer do Cosmos DB e para a seção Escala e Configurações,
em que você pode ver 500 como a nova taxa de transferência da coleção, como
mostrado aqui:

[ 240 ]
Capítulo 8

E mais...
A capacidade da coleção do Cosmos DB é representada como um recurso denominado
oferta. Nesta receita, recuperamos a oferta existente e a substituímos por uma nova
oferta. Saiba mais sobre isso em https://docs.microsoft.com/en-us/rest/api/
cosmos-db/offers.

Inserir dados em massa no Cosmos DB


Agora que aumentados a coleção, é hora de inserir os dados na coleção do Cosmos DB.
Nesta receita, aprenderemos sobre uma das maneiras mais simples de inserir dados
no Cosmos DB, para tornar a receita simples e direta.

Como fazer isso...


Execute as seguintes etapas:

1. Crie um novo gatilho de atividade denominado ImportData_AT, que usa


a coleção de funcionários como entrada e salva os dados na coleção. Cole
o código a seguir no novo gatilho de atividade:
[FunctionName(“ImportData_AT”)]
public static async Task<string> ImportData_AT(
[ActivityTrigger] List<Employee> employees,
[CosmosDB(ConnectionStringSetting = “CosmosDBConnectionString”)]
DocumentClient client,
ILogger log)
{
foreach (Employee employee in employees)
{
await client.CreateDocumentAsync(UriFactory.CreateDocumentCollect
ionUri(“cookbookdb”, “EmployeeCollection”), employee);
log.LogInformation($”Successfully inserted {employee.Name}.”);
}
return $”Data has been imported to Cosmos DB Collection
Successfully!”;
}

2. Vamos adicionar a linha a seguir à função Orchestration que invoca o gatilho


de atividade ImportData_AT:
await context.CallActivityAsync<string>(“ImportData_AT”,
employees);

[ 241 ]
Importação em massa de dados usando o Azure Durable Functions e o Cosmos DB

Vamos executar o aplicativo e carregar um arquivo do Excel para testar


a funcionalidade. Se tudo correu bem, você deve ver todos os registros
criados na coleção do Cosmos DB, como mostrado aqui:

E mais...
A equipe do Cosmos DB lançou uma biblioteca chamada executor em massa do Cosmos
DB. Saiba mais sobre isso em https://docs.microsoft.com/en-us/azure/cosmos-
db/bulk-executor-overview.

Nesta receita, codifiquei o nome da coleção e o banco de dados para torná-lo simples.
Você terá que configurá-los no arquivo de configurações do aplicativo.

[ 242 ]
Implementação de práticas
recomendadas para o Azure
Functions
Neste capítulo, você aprenderá algumas das práticas recomendadas que podem ser
seguidas ao trabalhar com o Azure Functions, como as seguintes:

• Adição de várias mensagens a uma fila usando a função IAsyncCollector


• Implementação de aplicativos de defesa usando o Azure Functions e gatilhos
de fila
• Manipulação de ingresso massivo usando Hubs de Eventos para IoT e outros
cenários semelhantes
• Como evitar partidas a frio ao aquecer o aplicativo em intervalos regulares
• Como habilitar a autorização para aplicativos de função
• Controle de acesso ao Azure Functions usando teclas de função
• Como proteger o Azure Functions usando o Azure Active Directory
• Configuração da limitação do Azure Functions usando o Gerenciamento de API
• Como acessar com segurança o Banco de Dados SQL do Azure Functions usando
Identidade de Serviço Gerenciada
• Código compartilhado no Azure Functions usando bibliotecas de classe
• Uso de classes fortemente tipadas no Azure Functions

[ 243 ]
Implementação de práticas recomendadas para o Azure Functions

Adição de várias mensagens a uma fila


usando a função IAsyncCollector
No primeiro capítulo, você aprendeu a criar uma mensagem de fila para cada solicitação
proveniente da solicitação HTTP. Agora, vamos supor que cada usuário esteja registrando
seus dispositivos usando aplicativos cliente (como aplicativos da área de trabalho,
aplicativos móveis ou qualquer site de cliente) que possam enviar vários registros
em uma única solicitação. Nesses casos, o aplicativo de back-end deve ser inteligente
o suficiente para lidar com a carga que recebe; deve haver um mecanismo para criar
várias mensagens de fila de uma vez e de forma assíncrona. Você aprenderá a criar
várias mensagens de fila usando a interface IAsyncCollector.

Aqui está um diagrama que descreve o fluxo de dados de diferentes aplicativos cliente
para a API Web de back-end:

Nesta receita, simularemos as solicitações usando o Postman, que enviará a solicitação


para a API Web de back-end (HTTPTrigger), que pode criar todas as mensagens
de fila de uma única vez.

Preparação
Estas são as etapas necessárias:

1. Criar uma conta de armazenamento usando o portal do Azure se você ainda não
tiver criado uma
2. Instalar o Gerenciador de Armazenamento da Microsoft de http://
storageexplorer.com/ se ainda não o tiver instalado

[ 244 ]
Capítulo 9

Como fazer isso...


Execute as seguintes etapas:

1. Criar um novo gatilho HTTP denominado BulkDeviceRegistrations


configurando o nível de autorização como Anônimo.
2. Substituir o código padrão pelo código a seguir e clicar no botão Salvar para
salvar as alterações. O código a seguir espera uma matriz JSON como um
parâmetro de entrada com um atributo chamado devices. Se encontrado, ele irá
iterar pelos itens da matriz e, em seguida, exibi-los nos logs. Posteriormente,
modificaremos o programa para inserir em massa os elementos da matriz
na mensagem da fila:
#r "Newtonsoft.Json"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
public static async Task<IActionResult> Run(HttpRequest req,
ILogger log )
{
log.LogInformation("C# HTTP trigger function processed a
request.");
string requestBody = await new StreamReader(req.Body).
ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
string Device = string.Empty;
for(int nIndex=0;nIndex<data.devices.Count;nIndex++)
{
Device = Convert.ToString(data.devices[nIndex]);
log.LogInformation("devices data" + Device);
}
return (ActionResult)new OkObjectResult("Program has been executed
Successfully.");
}

3. A próxima etapa é criar uma associação de saída de Armazenamento de Filas


do Azure. Clique no botão salvar, navegue até a guia Integrar e adicione uma
nova associação de saída do Armazenamento de Filas do Azure. Em seguida,
clique no botão Selecionar e forneça o nome da fila e outros parâmetros.

[ 245 ]
Implementação de práticas recomendadas para o Azure Functions

4. Clique no botão Salvar e navegue até o editor de código da Azure Function.


Adicione o outro código necessário para a associação da saída com a fila para
salvar as mensagens, conforme mostrado no código a seguir. Faça as alterações
realçadas no editor de código e clique no botão Salvar para salvar as alterações:
public static async Task<IActionResult> Run(HttpRequest req,
ILogger log,
IAsyncCollector<string> DeviceQueue )
{
....
....
for(int nIndex=0;nIndex<data.devices.Count;nIndex++)
{
Device = Convert.ToString(data.devices[nIndex]);
DeviceQueue.AddAsync(Device); }
....
....

5. Vamos executar a função na guia Teste do portal com o seguinte JSON de


solicitação de entrada:
{
"devices":
[
{
"type": "laptop",
"brand":"lenovo",
"model":"T440"
},
{
"type": "mobile",
"brand":"Mi",
"model":"Red Mi 4"
}
]
}

6. Clique no botão Executar para testar a funcionalidade. Agora abra o Gerenciador


de Armazenamento do Azure e navegue até a fila denominada devicequeue.
Como mostrado na captura de tela a seguir, você deve ver dois registros:

[ 246 ]
Capítulo 9

Como funciona...
Criamos uma nova função HTTP com um parâmetro do tipo iIAsyncCollector<cadeia
de caracteres>, que pode ser usado para armazenar várias mensagens em um serviço
de fila de uma vez e de forma assíncrona. Essa abordagem de armazenamento de vários itens
de forma assíncrona reduzirá a carga nas instâncias.

Por fim, testamos a invocação do gatilho HTTP do portal do Azure e também vimos
que as mensagens de fila são adicionadas usando o Gerenciador de Armazenamento
do Azure.

E mais...
Você também poderá usar a interface ICollector no lugar de IAsyncCollector
se quiser armazenar várias mensagens de forma síncrona.

Observe que talvez seja necessário instalar Extensões de


Armazenamento do Azure para a adição de associações de
saída caso isso ainda não tenha sido feito. No Azure Functions
Runtime V2, a adição de extensões a cada um dos serviços
(armazenamento, neste caso) é obrigatória.

Implementação de aplicativos de defesa


usando o Azure Functions e gatilhos
de fila
Para muitos aplicativos, mesmo depois da execução de vários testes de diferentes
ambientes, ainda poderá haver motivos imprevistos para falhas de aplicativo.
Os desenvolvedores e arquitetos não podem prever todas as entradas inesperadas
durante toda a vida útil de um aplicativo que esteja sendo usado por usuários
corporativos ou usuários finais gerais. Portanto, é uma boa prática certificar-se de
que seu aplicativo alerte se houver erros ou problemas inesperados com os aplicativos.

[ 247 ]
Implementação de práticas recomendadas para o Azure Functions

Nesta receita, você aprenderá como o Azure Functions nos ajuda a lidar com esses tipos
de problemas com o mínimo de código.

Preparação
Estas são as etapas necessárias:

1. Criar uma conta de armazenamento usando o portal do Azure se você ainda não
tiver criado uma
2. Instalar o Gerenciador de Armazenamento do Azure de http://
storageexplorer.com/ se ainda não o tiver instalado

Como fazer isso...


Nesta receita, nós faremos o seguinte:

• Desenvolveremos um aplicativo de console usando C# que se conecte à conta de


armazenamento e crie mensagens de fila na fila denominada myqueuemessages
• Criaremos um gatilho de fila do Azure Function chamado ProcessData,
acionado sempre que uma nova mensagem é adicionada à fila denominada
myqueuemessages

CreateQueueMessage – aplicativo de console C#


Execute as seguintes etapas:

1. Criaremos um novo aplicativo de console usando a linguagem C# do


.NET Core e criaremos uma chave de configuração de aplicativo chamada
StorageConnectionString com sua cadeia de conexão de conta
de armazenamento. Você pode obter a cadeia de conexão da folha Chaves
de Acesso da conta de armazenamento, conforme mostrado:

2. Instale os pacotes NuGet de configuração e armazenamento de fila usando os


seguintes comandos:
Install-Package Microsoft.Azure.Storage.Queue
Install-Package System.Configuration.ConfigurationManager

3. Adicione os seguintes namespaces:


using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Queue;
using System.Configuration;
[ 248 ]
Capítulo 9

4. Adicione a função a seguir ao seu aplicativo de console e chame-a do método


Main. A função CreateQueueMessages cria 100 mensagens com o índice como
conteúdo de cada uma delas:
static void CreateQueueMessages()
{
CloudStorageAccount storageAccount =
CloudStorageAccount.Parse(ConfigurationManager.
AppSettings
["StorageConnectionString"]);
CloudQueueClient queueclient =
storageAccount.CreateCloudQueueClient();

CloudQueue queue = queueclient.GetQueueReference


("myqueuemessages");
queue.CreateIfNotExists();

CloudQueueMessage message = null;


for(int nQueueMessageIndex = 0; nQueueMessageIndex <=
100;
nQueueMessageIndex++)
{
message = new CloudQueueMessage(Convert.ToString
(nQueueMessageIndex));
queue.AddMessage(message);
Console.WriteLine(nQueueMessageIndex);
}
}

Desenvolvimento do Azure Function – gatilho de fila


Execute as seguintes etapas:

1. Crie um novo Azure Function chamado ProcessData usando o gatilho de fila


e configure a fila myqueuemessages. A guia de integração deve ficar assim
após a criação da função:

[ 249 ]
Implementação de práticas recomendadas para o Azure Functions

2. Substitua o código padrão pelo código a seguir:


using System;
public static void Run(string myQueueItem,
ILogger log)
{
if(Convert.ToInt32(myQueueItem)>50)
{
throw new Exception(myQueueItem);
}
else
{
log.LogInformation($"C# Queue trigger function
processed: {myQueueItem}");
}
}

O gatilho da fila anterior registra em log uma mensagem com o conteúdo da fila
(é apenas um índice numérico) para as primeiras 50 mensagens e, em seguida, lança
uma exceção para todas as mensagens com conteúdo superior a 50.

Execução de testes usando o aplicativo de console


Execute as seguintes etapas:

1. Vamos executar o aplicativo de console pressionando Ctrl + F5, navegar até


o Gerenciador de Armazenamento do Azure e exibir o conteúdo da fila.
2. Em apenas alguns instantes, você deve começar a exibir mensagens na
fila myqueuemessages. Atualmente, o portal do Azure e o Gerenciador
de Armazenamento exibem as 32 primeiras mensagens. Você precisa usar
o SDK  de Armazenamento do C# para exibir todas as mensagens na fila.

Não se surpreenda se você notar que suas mensagens em


myqueuemessage estão desaparecendo. É esperado que,
assim que for lida com êxito, a mensagem será excluída da fila.

3. Como mostrado aqui, você também deve ver uma nova fila denominada
myqueuemessages-poison (<NomeDaFilaOriginal>-Poison) com as outras
50 mensagens de fila nela. O Azure Function Runtime cuidará automaticamente
da criação de uma nova fila e da adição das mensagens que não são lidas
corretamente pelo Azure Functions:

[ 250 ]
Capítulo 9

Como funciona...
Criamos um aplicativo de console que cria mensagens no armazenamento de Filas
do Azure e também desenvolvemos um gatilho de fila capaz de ler as mensagens
na fila. Como parte da simulação de um erro inesperado, lançaremos um erro
se o valor no conteúdo da mensagem de fila for maior do que 50.

O Azure Functions cuidará da criação de uma nova fila com o nome


<NomeDaFilaOriginal>-Poison e incluirá todas as mensagens não processadas na nova
fila. Usando essa nova fila de mensagens suspeitas, os desenvolvedores podem revisar o
conteúdo das mensagens e tomar as ações necessárias para corrigir erros nos aplicativos.

O Azure Function Runtime cuidará da exclusão da mensagem da fila após a conclusão da


execução do Azure Function. Se houver algum problema na execução do Azure Function,
ele criará automaticamente uma nova fila de mensagens suspeitas e adicionará as
mensagens processadas à nova fila.

E mais...
Antes de enviar por push uma mensagem de fila para a fila de mensagens suspeitas,
o Azure Function Runtime faz cinco tentativas de escolher e processar a mensagem.
Você pode saber mais sobre o funcionamento desse processo ao adicionar um novo
parâmetro dequecount do tipo int ao método Run e registrar em log seu valor.

[ 251 ]
Implementação de práticas recomendadas para o Azure Functions

Manipulação de ingresso massivo


usando Hubs de Eventos para IoT
e outros cenários semelhantes
Em muitos cenários, você pode ter que lidar com enormes quantidades de dados
de entrada; os dados de entrada podem ser provenientes de sensores e de telemetria, e
podem ser tão simples quanto os dados enviados de dispositivos Fitbit. Nesses cenários,
precisamos ter uma solução confiável que seja capaz de lidar com grandes quantidades
de dados. Os Hubs de Evento do Azure são um desses tipos de solução que o Azure
oferece. Nesta receita, você aprenderá a integrar os Hubs de Eventos e o Azure Functions.

Preparação
Execute as seguintes etapas:

1. Crie um namespace de Hubs de Eventos navegando até a Internet das Coisas


e escolhendo Hubs de Eventos
2. Depois que o namespace de Hubs de Eventos for criado, navegue até a guia
Visão geral e clique no ícone Hub de Eventos para criar um novo Hub de Eventos
3. Por padrão, um Grupo de Consumidores chamado $Default é criado e nós
o usaremos nesta receita

Como fazer isso...


Nós faremos o seguinte nesta receita:

• Como criar um gatilho de hub de eventos do Azure Function


• Desenvolvimento de um aplicativo de console que simula dados da
Internet das Coisas (IoT)

Como criar um gatilho de hub de eventos do Azure


Function
Execute as seguintes etapas:

1. Crie um novo Azure Function escolhendo o Gatilho de Hub de Eventos na lista


de modelos.
2. Depois de selecionar o modelo, talvez seja necessário instalar as extensões. Em
seguida, será necessário fornecer o nome do hub de eventos, capturemessage. Se
ainda não tiver uma conexão configurada, você precisará clicar no botão Novo.
3. Clicar no botão Novo abrirá um pop-up Conexão, onde será possível escolher
seu Hub de Eventos e outros detalhes. Escolha os detalhes necessários e clique
no botão Selecionar, como mostrado na seguinte captura de tela:
[ 252 ]
Capítulo 9

4. A etapa anterior preencherá a lista suspensa Conexão do Hub de Eventos. Por


fim, clique em Criar para criar a função.

Desenvolvimento de um aplicativo de console


que simula dados da IoT
Execute as seguintes etapas:

1. Crie um novo aplicativo de console que enviará eventos para o Hub de Eventos.
Eu o chamei de EventHubApp.

2. Execute os seguintes comandos no gerenciador de pacotes do NuGet para instalar


as bibliotecas necessárias e interagir com os Hubs de Eventos do Azure:
Install-Package Microsoft.Azure.EventHubs
Install-Package Newtonsoft.Json

3. Adicione os namespaces a seguir e uma referência para System.


Configuration.dll:
using Microsoft.Azure.EventHubs;
using System.Configuration;

4. Adicione a cadeia de conexão a App.config, que é usado para conectar o hub de


eventos. Este é o código para App.config. Você pode obter a cadeia de conexão
clicando no link ConnectionStrings na guia Visão geral do namespace do hub
de eventos:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0"
sku=".NETFramework,Version=v4.6.1" />
</startup>
<appSettings>
<add key="EventHubConnection"

[ 253 ]
Implementação de práticas recomendadas para o Azure Functions

value="Endpoint=sb://<event hub namespace


here>.servicebus.windows.net/;Entitypath=<Event
Hubname>;
SharedAccessKeyName= RootManageSharedAccessKey;
SharedAccessKey=<Key here>"/>
</appSettings>
</configuration>

5. Crie um novo arquivo de classe C# e coloque o código a seguir no novo arquivo


de classe:
using System;
using System.Text;
using Microsoft.Azure.EventHubs;
using System.Configuration;
using System.Threading.Tasks;

namespace EventHubApp
{
class EventHubHelper
{
static EventHubClient eventHubClient = null;
public static async Task GenerateEventHubMessages()
{

EventHubsConnectionStringBuilder conBuilder = new


EventHubsConnectionStringBuilder
(ConfigurationManager.AppSettings
["EventHubConnection"].ToString());

eventHubClient =
EventHubClient.CreateFromConnectionString
(conBuilder.ToString());
string strMessage = string.Empty;
for (int nEventIndex = 0; nEventIndex <= 100;
nEventIndex++)
{
strMessage = Convert.ToString(nEventIndex);
await eventHubClient.SendAsync(new EventData
(Encoding.UTF8.GetBytes(strMessage)));
Console.WriteLine(strMessage);
}
await eventHubClient.CloseAsync();
}
}
}

6. Em sua função main, coloque o código a seguir, que invoca o método para enviar
a mensagem:
namespace EventHubApp

[ 254 ]
Capítulo 9

{
class Program
{
static void Main(string[] args)
{
EventHubHelper.GenerateEventHubMessages().Wait();
}
}
}

7. Agora execute o aplicativo pressionando Ctrl + F5. Você deve ver algo
semelhante ao que é mostrado aqui:

8. Quando o console estiver imprimindo os números, você poderá navegar até


o Azure Function para ver se o hub de eventos é acionado automaticamente
e se registra em log os números enviados para o Hub de Eventos.

[ 255 ]
Implementação de práticas recomendadas para o Azure Functions

Como evitar partidas a frio ao aquecer


o aplicativo em intervalos regulares
Agora, é possível estar ciente de que você pode criar funções do Azure nos dois planos
de hospedagem a seguir:

• Plano de Serviço de Aplicativo


• Plano de consumo

Você só receberá todos os benefícios da arquitetura sem servidor quando criar


o aplicativo de função usando o plano de consumo. No entanto, uma das preocupações
que os desenvolvedores relatam sobre o uso do plano de consumo é algo chamado
de partida a frio, que se refere à criação de uma função do Azure para atender às
solicitações após algum tempo sem solicitações. Você pode saber mais sobre este
tópico em https://blogs.msdn.microsoft.com/appserviceteam/2018/02/07/
understanding-serverless-cold-start/.

Nesta receita, aprenderemos uma técnica que pode ser usada para manter a instância
sempre viva e quente para que todas as solicitações sejam atendidas corretamente.

O plano de Serviço de Aplicativo é um plano de hospedagem


dedicado onde suas instâncias são reservadas para você
e sempre podem estar quentes, mesmo se não houver
solicitações por um curto período.

Preparação
A fim de completar esta receita, precisamos ter um aplicativo de função com o seguinte:

• Um gatilho HTTP denominado HttpALive


• Um gatilho de timer denominado KeepFunctionAppWarm que é executado
a cada 5 minutos e cria uma solicitação HTTP para o gatilho HTTP HttpALive

Se você entendeu claramente o que é uma inicialização a frio, então ficará claro que não
é necessário se preocupar se o seu aplicativo tem tráfego regular durante o dia. Portanto,
se pudermos garantir que o aplicativo tenha tráfego durante todo o dia, a instância
do Azure Function não será desprovisionada e, portanto, não haveria nenhuma
preocupação sobre o plano de consumo.

[ 256 ]
Capítulo 9

Como fazer isso...


Nesta receita, criaremos um gatilho de timer que simula o tráfego para o gatilho HTTP,
fazendo com que o aplicativo de função esteja ativo o tempo todo e as instâncias sem
servidor estejam sempre no estado provisionado.

Como criar um gatilho HTTP


Crie um novo gatilho HTTP e substitua o código a seguir que apenas imprime uma
mensagem quando é executado:
using System.Net;
using Microsoft.AspNetCore.Mvc;
public static async Task<IActionResult> Run(HttpRequest req, ILogger
log)
{
return (ActionResult)new OkObjectResult($"Hello User! Thanks for
keeping me Warm");
}

Como criar um gatilho de timer


Execute as seguintes etapas:

1. Clique no ícone +, procure pelo timer e clique no botão Gatilho de timer.


2. No pop-up Nova Função, forneça os detalhes. A Agenda aqui é uma expressão
CRON que assegura que o gatilho de timer seja acionado automaticamente
a cada 5 minutos:

[ 257 ]
Implementação de práticas recomendadas para o Azure Functions

3. Cole o código a seguir no editor de código e salve as alterações. O código a


seguir simula o tráfego fazendo solicitações HTTP programaticamente. Substitua
<<NomeDoAplicativoDeFunção>> pelo nome real do seu aplicativo de função:
using System;
public async static void Run(TimerInfo myTimer, ILogger log)
{
using (var httpClient = new HttpClient())
{
var response = await httpClient.GetAsync("https://<FunctionAppNa
me>>.azurewebsites.net/api/HttpALive");
}
}

E mais...
Se já conhece o Azure Functions, você poderá notar que as durações de inicialização
a frio para Azure Functions que têm C# como linguagem são de apenas alguns segundos.
No entanto, se você estiver trabalhando com Azure Functions que tenham o JavaScript
(como o Node.js) como linguagem, então a duração da inicialização a frio seria maior,
já que o tempo de execução precisaria fazer download de todos os pacotes npm que são
dependências para seu aplicativo. Nesses cenários, um recurso chamado Run-from-
Package vem a ser muito útil. Aprenderemos a implementar isso no próximo capítulo.

Consulte também
Consulte a receita Implantação do Azure Functions usando Executar de Pacote do Capítulo 10,
Configuração de aplicativos sem servidor no ambiente de produção.

Como habilitar a autorização para


aplicativos de função
Se sua API Web (gatilho HTTP) estiver sendo usada por vários aplicativos cliente e você
quiser fornecer acesso somente aos aplicativos pretendidos e autorizados, será necessário
implementar a autorização para restringir o acesso ao Azure Function.

Preparação
Presumo que você já saiba como criar uma função de gatilho HTTP. Faça download
da ferramenta Postman de https://www.getpostman.com/. A ferramenta Postman
é usada para enviar solicitações HTTP. Você também pode usar qualquer ferramenta
ou aplicativo que possa enviar solicitações e cabeçalhos HTTP.

[ 258 ]
Capítulo 9

Como fazer isso...


Execute as seguintes etapas:

1. Crie uma nova função de gatilho HTTP (ou abra uma função HTTP existente).
Ao criar a função, selecione Função como a opção na lista suspensa do nível
Autorização.

Se você quiser usar uma função de gatilho HTTP existente que


criamos em uma de nossas receitas anteriores, clique na guia
Integrar, altere o nível de Autorização para Função e clique no
botão Salvar para salvar as alterações.

2. Na guia Editor de Código, escolha a URL da função clicando no link Obter URL
da Função disponível no canto direito do editor de código no arquivo run.csx.
3. Navegue até o Postman e cole a URL da função:

4. Observe que a URL tem as seguintes cadeias de consulta:


°° code: é a cadeia de consulta padrão esperada pelo tempo de execução
da função e que valida os direitos de acesso da função. A funcionalidade
de validação é habilitada automaticamente sem que o desenvolvedor
precise escrever o código. Tudo isso é feito por meio da configuração
do nível de Autorização como Função.
°° name: é uma cadeia de consulta exigida pela função de gatilho HTTP.

5. Vamos remover a cadeia de consulta de código da URL no Postman e tentar fazer


uma solicitação. Você obterá um erro 401 Não Autorizado.

[ 259 ]
Implementação de práticas recomendadas para o Azure Functions

Como funciona...
Quando você faz uma solicitação via Postman ou qualquer outra ferramenta ou
aplicativo que possa enviar solicitações HTTP, a solicitação será recebida pelo aplicativo
Web do Serviço de Aplicativo do Azure subjacente (observe que o Azure Functions é
criado com base nos Serviços de Aplicativo) que primeiro verifica a presença do código
do nome do cabeçalho na coleção de cadeias de consulta ou no corpo da Solicitação.
Se encontrar, então ele validará o valor da cadeia de consulta de código com as teclas
de função. Se for válido, então ele autorizará a solicitação e permitirá que o tempo de
execução processe a solicitação. Caso contrário, ele gerará um erro com uma mensagem
401 Não Autorizado.

E mais...
Observe que a chave de segurança (na forma do parâmetro de cadeia de consulta
denominado code) no exemplo anterior é usada apenas para fins de demonstração.
Em cenários de produção, em vez de passar a chave como um parâmetro de cadeia
de consulta (o parâmetro code), você precisará adicionar a x-functions-key como
um cabeçalho HTTP, conforme mostrado na seguinte captura de tela:

Controle de acesso ao Azure Functions


usando teclas de função
Agora você aprendeu a habilitar a autorização de um gatilho HTTP individual definindo
o campo Nível Anônimo com a função value na guia Integrar da função de gatilho
HTTP. Ele funcionará bem se houver apenas um Azure Function como uma API Web
de back-end para um dos aplicativos e você não quiser restringir o acesso ao público.

[ 260 ]
Capítulo 9

No entanto, em aplicativos de nível corporativo, você acabará desenvolvendo vários


Azure Functions entre vários aplicativos de função. Nesses casos, você precisará ter
acesso granular refinado ao seu Azure Function para seus próprios aplicativos ou
para alguns outros aplicativos de terceiros que integrem suas APIs em seus aplicativos.

Nesta receita, você aprenderá a trabalhar com teclas de função no Azure Functions.

Como fazer isso...


O Azure dá suporte às chaves a seguir, que podem ser usadas para controlar o acesso
às funções do Azure:

• Teclas de função: podem ser usadas para conceder permissões de autorização


para uma determinada função. Essas chaves são específicas da função com
a qual eles estão associados.
• Teclas host: nós podemos usá-los para controlar a autorização de todas
as funções em um aplicativo de função do Azure.

Como configurar a tecla de função para cada


aplicativo
Se você estiver desenvolvendo uma API com o Azure Functions que poderá ser usada
por vários aplicativos, então será uma boa prática ter uma tecla de função diferente para
cada aplicativo cliente que usará suas funções.

Navegue até a guia Gerenciar do Azure Functions para exibir e gerenciar todas as chaves
relacionadas à função.

Por padrão, uma chave com o nome padrão é gerada para nós. Se você quiser gerar
uma nova chave, então clique no botão Adicionar nova tecla de função.

De acordo com a instrução anterior, eu criei as chaves para os seguintes aplicativos:

• WebApplication: o nome da chave WebApplication é configurado para


ser usado no site que utiliza o Azure Function
• MobileApplication: o nome da chave MobileApplication é configurado
para ser usado no aplicativo móvel que utiliza o Azure Function

De uma maneira semelhante, você pode criar chaves diferentes para qualquer outro
aplicativo (como um aplicativo de IoT), dependendo de seus requisitos.

[ 261 ]
Implementação de práticas recomendadas para o Azure Functions

A ideia por trás de ter chaves diferentes para a mesma função é ter o controle sobre
as permissões de acesso para o uso das funções por aplicativos diferentes. Por exemplo,
se quiser revogar as permissões apenas para um aplicativo, mas não para todos
os aplicativos, você simplesmente excluirá (ou revogará) essa chave. Dessa forma,
você não afeta outros aplicativos que estejam usando a mesma função.

Aqui está a desvantagem das teclas de função; se você estiver desenvolvendo


um aplicativo em que é necessário ter várias funções e cada função está sendo usada
por vários aplicativos, então você acabará tendo muitas chaves. O gerenciamento dessas
chaves e a documentação delas seria um pesadelo. Nesse caso, você pode usar as teclas
host, que serão discutidas a seguir.

Configuração de uma tecla host para todas


as funções em um único aplicativo de função
Ter chaves diferentes para funções diferentes é uma boa prática quando você tem
um punhado de funções usadas por alguns aplicativos. No entanto, as coisas poderão
piorar se você tiver muitas funções e muitos aplicativos cliente usando suas APIs.
O gerenciamento das teclas de função nesses grandes aplicativos corporativos com
bases de clientes imensas seria doloroso. Para simplificar, você pode segregar todas
as funções relacionadas em um único aplicativo de função e configurar a autorização
para cada aplicativo de função em vez de para cada função individual. Você pode
configurar a autorização para um aplicativo de função usando teclas host.

Aqui estão os dois tipos diferentes de teclas host disponíveis:

• Teclas host regulares


• Chave mestra

Crie dois aplicativos de gatilho HTTP, conforme mostrado na seguinte captura de tela:

[ 262 ]
Capítulo 9

Navegue até a guia Gerenciar de ambos os aplicativos, conforme mostrado nas capturas
de tela a seguir. Você observará que a chave mestra e as teclas host são as mesmas
em ambos os aplicativos:

• Esta é a guia de gerenciamento de MyApp1:

• Esta é a guia de gerenciamento de MyApp2:

Assim como no caso das teclas de função, você também pode criar
várias teclas host se seus aplicativos de função estiverem sendo usados
por vários aplicativos. Você pode controlar o acesso de cada um dos
aplicativos de função por aplicativos diferentes usando teclas diferentes.
Você pode criar várias teclas host seguindo as mesmas etapas que
seguiu ao criar as teclas de função regulares.

[ 263 ]
Implementação de práticas recomendadas para o Azure Functions

E mais...
Se achar que a tecla foi comprometida, então você pode regenerá-la a qualquer
momento clicando no botão Renovar. Observe que, quando você renovar uma tecla,
todos os aplicativos que acessam a função não funcionarão mais e isso geraria um erro
de código de status 401 Não Autorizado.

Você pode excluir ou revogar a tecla se ela não for mais usada em qualquer um dos
aplicativos.

Aqui está uma tabela com mais algumas diretrizes sobre as teclas:

Tipo de Quando devo É revogável Renovável? Comentários


tecla usá-la? (pode ser
excluída)?
Chave Quando Não Sim Você pode usar uma
mestra o nível de chave mestra para
Autorização qualquer função dentro
for Admin do aplicativo de função,
independentemente
do nível de autorização
configurado.
Tecla Quando Sim Sim Você pode usar a tecla
host o nível de host para todas as
Autorização funções dentro do
for Função aplicativo de função.
Tecla de Quando Sim Sim Você pode usar a tecla
função o nível de de função somente
Autorização para uma determinada
for Função função.

A Microsoft não recomenda o compartilhamento da chave mestra,


pois ela também é usada por APIs de tempo de execução. Seja
ainda mais cauteloso com as chaves mestras.

Como proteger o Azure Functions


usando o Azure Active Directory
Na receita anterior, nós aprendemos a habilitar a segurança com base em aplicativos
cliente que acessam o Azure Functions. No entanto, se o seu requisito for autenticar os
usuários finais que acessam as funções no Azure Active Directory (AD), então o Azure
Functions oferece uma maneira fácil de configurar isso, a EasyAuth.

[ 264 ]
Capítulo 9

Graças ao Serviço de Aplicativo do Azure, do qual o recurso EasyAuth é herdado,


podemos fazer o que precisamos fazer sem escrever uma única linha de código.

Preparação
Nesta receita, para simplificarmos, usaremos o AD padrão criado quando você cria
uma conta do Azure. No entanto, em seus cenários de produção em tempo real, você
já teria um AD existente que precisa ser integrado. Eu recomendaria a leitura deste
artigo: https://docs.microsoft.com/azure/active-directory-b2c/active-
directory-b2c-tutorials-web-app.

Como fazer isso...


Esta receita envolverá o seguinte:

• Configuração do Azure AD para o aplicativo de função


• Como registrar o aplicativo cliente no Azure AD
• Como conceder ao aplicativo cliente acesso ao aplicativo de back-end
• Como testar a funcionalidade de autenticação usando um token JWT

Configuração do Azure AD para o aplicativo


de função
Execute as seguintes etapas:

1. Navegue até a seção Recursos da plataforma do Azure Functions.


2. Na folha Autenticação/Autorização, execute as etapas a seguir para habilitar
a autenticação do AD:
1. Clique no botão Ativar para habilitar a autenticação.
2. Escolha o Logon usando a opção de menu do Azure Active Directory.
3. Clique no botão Não Configurado para iniciar a configuração das
opções.

3. A próxima etapa é escolher um registro existente ou criar um novo registro


para o aplicativo cliente ao qual queremos fornecer acesso. Isso pode ser feito
pressionando o botão Expresso no campo Modo de Gerenciamento. Além disso,
optei por criar um novo e forneci AzureFunctionCookbookV2 como o nome
para o meu registro de aplicativo. Clique em OK para salvar as configurações,
o que o levará para a tela a seguir.

[ 265 ]
Implementação de práticas recomendadas para o Azure Functions

4. Obtenha a ID do Aplicativo como mostrado. Nós a usaremos durante os testes


em alguns momentos:

É isso. Sem escrever uma única linha de código, terminamos a configuração de uma
instância do Azure AD que se baseia em uma camada de segurança e permite o acesso
somente a usuários autenticados. Em outras palavras, nós habilitamos o OAuth para
nosso aplicativo de função de back-end usando o Azure AD. Vamos testá-lo rapidamente
acessando qualquer um dos gatilhos HTTP que você tem no aplicativo de função. Eu usei
o Postman para fazer isso. Como esperado, você obterá um erro solicitando que efetue
logon.

Com as configurações atuais, nenhum dos aplicativos cliente externos poderá acessar
nossa API de back-end. A fim de fornecer acesso, precisamos executar as seguintes
etapas:

Registre todos os aplicativos cliente no Azure AD (para nosso exemplo, faremos


um registro para o aplicativo Postman).

Conceda acesso ao aplicativo de back-end.

Como registrar o aplicativo cliente no Azure AD


Execute as seguintes etapas:

1. Navegue até o Azure AD clicando no botão do Azure Active Directory, conforme


mostrado. Se ele não estiver exibido na lista de favoritos, busque-o na folha
Todos os Serviços, que também está realçada na seguinte captura de tela:

[ 266 ]
Capítulo 9

2. No menu AD, clique em Registros de Aplicativo e clique no botão de registro


Novo aplicativo.
3. Preencha os campos como a seguir e clique no botão Criar para completar
o registro para o nosso aplicativo Postman. Como nosso aplicativo cliente
é o Postman, a URL de Logon não tem qualquer importância, então apenas
http://localhost deve servir para o nosso exemplo:

[ 267 ]
Implementação de práticas recomendadas para o Azure Functions

4. Em apenas um momento, o aplicativo será criado e você será levado para a


tela a seguir. Obtenha a ID do Aplicativo e salve-o no seu bloco de notas. Nós
a usaremos nas próximas etapas. Clique no botão Configurações:

5. Na folha Configurações, clique no item de menu Chave para gerar uma chave
que será passada do Postman. A fim de gerar a chave, primeiro precisamos
fornecer uma Descrição e a Duração após a qual a chave deverá expirar.
Forneça os detalhes conforme mostrado na captura de tela a seguir e clique
no botão Salvar. A chave real é exibida para nós no campo de valor apenas
uma vez imediatamente depois de você clicar no botão Salvar, então copie-a
e a armazene em um lugar seguro. Nós a usaremos em alguns momentos:

[ 268 ]
Capítulo 9

Como conceder ao aplicativo cliente acesso


ao aplicativo de back-end
Depois que o aplicativo cliente for registrado, precisaremos fornecer a ele acesso ao nosso
aplicativo de back-end. Nesta seção, aprenderemos a configurá-lo:

1. Clique na guia Permissões Necessárias e clique no botão Adicionar, que mostra


a folha Adicionar Acesso à API, onde você escolhe a API necessária (no nosso
caso, é nossa API do Azure Functions de back-end).
2. Na folha Adicionar Acesso à API, clique no botão Selecionar uma API;
inicialmente, as APIs padrão serão exibidas. Você precisa procurar seu
aplicativo de back-end com o nome que você forneceu (no meu caso, foi
AzureFunctionCookBookV2). Selecione o aplicativo de back-end e clique
no botão Selecionar.
3. A próxima etapa é fornecer as permissões reais. Clique na guia Permissões
e marque Acessar <nome do Aplicativo de Back-end>, então clique em
Selecionar e depois no botão Concluído.
4. Acesse a tela a seguir. Você também pode clicar no botão Conceder Permissão
para aplicar as alterações:

Como testar a funcionalidade de autenticação


usando um token JWT
Você deve ter o seguinte pronto para testar a funcionalidade usando o Postman:

1. Ponto de extremidade do token OAuth 2.0, você pode obtê-lo na guia


Pontos de Extremidade do Azure AD e obtenha a URL:
°° Tipo de concessão: um valor client_credentials codificado.
°° ID do Cliente do aplicativo cliente: você a anotou na quarta etapa
da seção Registro do aplicativo cliente no Azure AD.

[ 269 ]
Implementação de práticas recomendadas para o Azure Functions

°° Chave que você gerou para seu aplicativo cliente: você a anotou
na quarta etapa da seção Registro do aplicativo cliente no Azure AD.
°° Recurso: recurso ao qual precisamos de acesso. É a ID do cliente
do aplicativo de back-end; você a anotou na quarta etapa da seção
Configuração do Azure AD para o aplicativo de função.

2. Depois de ter todas essas informações, você precisará passar todos os parâmetros
e fazer uma chamada para um locatário do Azure AD, que retorna o token
de portador da seguinte maneira:

3. A etapa seguinte e final é fazer uma chamada para o back-end real (o gatilho
HTTP do Azure Function) passando o token JWT de portador (access_token)
que copiamos da tela anterior:

[ 270 ]
Capítulo 9

4. Como mostrado nesta captura de tela, adicione um cabeçalho Autorização e cole


o token JWT. Não se esqueça de fornecer a palavra de portador de texto.

Configuração da limitação do Azure


Functions usando o Gerenciamento de API
Já aprendemos em capítulos anteriores que podemos usar os gatilhos HTTP do Azure
Functions como API Web de back-end. Se quiser restringir o número de solicitações feitas
por seus aplicativos cliente a, digamos, 10 solicitações por segundo, então você poderá
ter que desenvolver uma grande quantidade de lógica. Graças ao Gerenciamento de API
do Azure, você não precisa escrever nenhuma lógica personalizada se integrar o Azure
Functions com o Gerenciamento de API.

Nesta receita, aprenderemos a restringir os clientes ao acesso à API apenas uma vez
por minuto para um determinado endereço IP. A seguir, as etapas de alto nível que
acompanharemos:

1. Como criar um serviço de Gerenciamento de API do Azure


2. Como integrar Azure Functions ao Gerenciamento de API
3. Configuração da limitação de solicitações usando políticas de entrada
4. Como testar a configuração de política de entrada de limite de taxa

[ 271 ]
Implementação de práticas recomendadas para o Azure Functions

Preparação
Para começar, precisamos criar um serviço de Gerenciamento de API do Azure
executando as seguintes etapas:

1. Procure o Gerenciamento de API e forneça todos os detalhes a seguir.


No exemplo a seguir, escolhi o tipo de preço Desenvolvedor. Mas para seus
aplicativos de produção, você precisa escolher camadas não desenvolvedor
(Basic/Standard/Premium) como a camada Desenvolvedor (Sem SLA)
não fornece nenhum SLA. Depois de ter analisado todos os detalhes, clique
no botão Criar:

[ 272 ]
Capítulo 9

2. No momento, a criação de uma instância de Gerenciamento de API demora cerca


de 30 minutos. Depois que ela tiver sido criada, você poderá exibi-lo na folha
de serviços Gerenciamento de API:

Como fazer isso...


Para aproveitar os recursos do Gerenciamento de API, precisamos integrar os pontos
de extremidade do serviço (em nosso caso, os gatilhos HTTP que criamos) com o serviço
Gerenciamento de API. Esta seção fala sobre as etapas necessárias para a integração.
Vamos começar a integrar ambos.

Como integrar Azure Functions ao Gerenciamento


de API
Execute as seguintes etapas:

1. Navegue até a folha APIs da Instância de Gerenciamento de API que você criou
e clique no bloco Aplicativo de Função.
2. Você verá um pop-up Criar de Aplicativo de Função, onde poderá clicar
no botão Procurar, o que abrirá a barra lateral com o título Importar Azure
Functions, onde você pode configurar os aplicativos de função. Clique
no botão Definir Configuração Necessária para ver todos os aplicativos
de função que tenham gatilhos HTTP neles. Depois de selecionar o aplicativo
de função, clique no botão Selecionar.

[ 273 ]
Implementação de práticas recomendadas para o Azure Functions

3. A próxima etapa é escolher o gatilho HTTP que você gostaria de integrar com
o Gerenciamento de API do Azure. Depois de clicar no botão Selecionar, como
mencionado na etapa anterior, todos os gatilhos HTTP associados ao aplicativo
de função aparecerão, como mostrado na captura de tela a seguir. Eu escolhi
apenas um gatilho HTTP para simplificar:

[ 274 ]
Capítulo 9

4. Depois de executar todas as etapas anteriores, o pop-up Criar do Aplicativo


de Função aparecerá, procurando algo parecido com o seguinte. Depois
de ter analisado todos os detalhes, clique no botão Criar:

5. Se tudo correr bem, você deverá obter uma captura de tela como a seguir. Agora,
terminamos a integração do Azure Functions com o Gerenciamento de API:

[ 275 ]
Implementação de práticas recomendadas para o Azure Functions

Configuração da limitação de solicitações usando


políticas de entrada
Execute as seguintes etapas:

1. Como mostrado na captura de tela anterior, escolha a operação necessária (GET)


e clique no link do editor de políticas de entrada (rotulado como 3), que abrirá
o editor de políticas.

O Gerenciamento de API nos permite controlar o comportamento


das APIs de back-end (em nosso caso, gatilhos HTTP) usando políticas
de Gerenciamento de API. Você pode controlar as respostas da
solicitação de entrada e saída. Leia mais sobre isso em https://docs.
microsoft.com/azure/api-management/api-management-
howto-policies.

2. Como precisamos restringir a taxa de solicitação no Gerenciamento de


API antes de enviar a solicitação para o aplicativo de função de back-end,
precisamos configurar o limite de taxa na política de entrada. Crie uma nova
política como mostrado com um valor 1 para o atributo de chamadas e um
valor 60 (em segundos) para o atributo de período de renovação e, por fim,
defina a contra-chave para o endereço IP do aplicativo cliente:

[ 276 ]
Capítulo 9

Com esta política de entrada, estamos instruindo o


Gerenciamento de API para restringir uma solicitação por
minuto para um determinado endereço IP.

3. Uma etapa final antes de testarmos a limitação é publicar a API navegando


até a guia Configurações na etapa anterior e associando a API a um produto
publicado (no meu caso, tenho um produto inicial padrão que já foi publicado).
Como mostrado na captura de tela a seguir, escolha o produto necessário
e clique no botão Salvar:

Os produtos no Gerenciamento de API são um grupo de APIs as quais


os desenvolvedores de diferentes aplicativos clientes podem assinar.
Para obter mais informações sobre produtos de Gerenciamento de API,
consulte https://docs.microsoft.com/azure/api-management/api-
management-howto-add-products.

[ 277 ]
Implementação de práticas recomendadas para o Azure Functions

Como testar a configuração de política de entrada


de limite de taxa
Execute as seguintes etapas:

1. Navegue até a guia Testar e adicione quaisquer parâmetros ou cabeçalhos


necessários que sejam esperados pelo gatilho HTTP. No meu caso, meu gatilho
HTTP requer um parâmetro denominado name.
2. Agora, clique no botão Enviar que aparece quando você conclui a etapa anterior
para fazer sua primeira solicitação. Você deve ver algo parecido com o seguinte
depois de obter uma resposta do back-end:

3. Agora clique imediatamente no botão Enviar outra vez. Como mostrado aqui,
você deve ver um erro, como nossa regra de política de entrada é permitir apenas
uma solicitação por minuto para um determinado endereço IP:

[ 278 ]
Capítulo 9

Como funciona...
Nesta receita, criamos uma instância de Gerenciamento de API do Azure e integramos
um Aplicativo de Função do Azure para aproveitar os recursos de Gerenciamento de
API. Uma vez integrados, nós criamos uma política de entrada que restringe os clientes
a apenas uma chamada por minuto de um determinado endereço IP. Aqui está um
diagrama de alto nível que retrata todo o processo:

[ 279 ]
Implementação de práticas recomendadas para o Azure Functions

Como acessar com segurança o Banco


de Dados SQL do Azure Functions
usando Identidade de Serviço
Gerenciada
Em uma de nossas receitas, Interações do Banco de Dados SQL do Azure usando Azure
Functions, do Capítulo 3, Integração perfeita de Azure Functions com Serviços do Azure,
aprendemos a acessar um Banco de Dados SQL e seus objetos desde o Azure Functions
fornecendo a cadeia de conexão (nome de usuário e senha).

Digamos que, por algum motivo, você altere a senha de uma conta, o que significa
que todos os aplicativos que usam essa conta não poderão obter acesso. Como um
desenvolvedor, não seria bom se houvesse uma instalação onde você não precisa se
preocupar com as credenciais e, em vez disso, a estrutura tomasse conta da autenticação?
Nesta receita, aprenderemos a acessar um Banco de Dados SQL de um Azure Function
sem fornecer uma ID do usuário ou senha usando um recurso chamado Identidade de
Serviço Gerenciada.

No momento da criação desta receita, o código relacionado à recuperação


do token de acesso estava disponível apenas com o Azure Functions V1
(.NET Framework), mas não com o V2 (.NET Core). Quando você estiver
lendo este livro, talvez ele esteja disponível na versão mais recente do
.NET Core Framework e, portanto, essa receita deve funcionar com o
tempo de execução do Azure Functions V2 também.

Preparação
Esta receita requer que criemos o Azure Functions (com o tempo de execução V1)
e o Banco de Dados SQL no mesmo grupo de recursos. Se você não os tiver criado,
faça isso e volte a esta receita para continuar. Aqui estão as etapas que executaremos
nesta receita:

1. Criação de um aplicativo de função usando o Visual Studio 2017 com o tempo


de execução V1
2. Como criar um SQL Server lógico e um banco de dados SQL
3. Como habilitar a Identidade de Serviço Gerenciada do portal
4. Como recuperar informações de Identidade de Serviço Gerenciada usando a CLI
do Azure
5. Como permitir o acesso do SQL Server à nova Identidade de Serviço Gerenciada
6. Execução do gatilho e de testes HTTP

[ 280 ]
Capítulo 9

Como fazer isso...


Executaremos esta receita usando as seguintes etapas:

1. Criar um aplicativo de função usando o Visual Studio 2017 com o tempo


de execução V1
2. Criar um SQL Server lógico e um Banco de Dados SQL
3. Como habilitar a Identidade de Serviço Gerenciada

Criação de um aplicativo de função usando o Visual


Studio 2017 com o tempo de execução V1
Execute as seguintes etapas:

1. Crie um novo aplicativo de função escolhendo o Azure Functions v1 Runtime.


2. Depois que o gatilho HTTP for criado, substitua a função pelo código a seguir:
public static class HttpTriggerWithMSI
{
[FunctionName("HttpTriggerWithMSI")]
public static async Task<HttpResponseMessage> Run([HttpTr
igger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]
HttpRequestMessage req, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a
request.");

string firstname = string.Empty, lastname = string.


Empty, email = string.Empty, devicelist = string.Empty;

dynamic data = await req.Content.


ReadAsAsync<object>();
firstname = data?.firstname;
lastname = data?.lastname;
email = data?.email;
devicelist = data?.devicelist;

SqlConnection con = null;


try
{
string query = "INSERT INTO EmployeeInfo
(firstname,lastname, email, devicelist) " + "VALUES (@firstname,@
lastname, @email, @devicelist) ";

con = new
SqlConnection("Server=tcp:dbserver.database.
windows.net,1433;Initial Catalog=database;Persist Security Info=Fa

[ 281 ]
Implementação de práticas recomendadas para o Azure Functions

lse;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertifi
cate=False;Connection Timeout=30;");
SqlCommand cmd = new SqlCommand(query, con);

con.AccessToken = (new
AzureServiceTokenProvider()).GetAccessTokenAsync("https://
database.windows.net/").Result;

cmd.Parameters.Add("@firstname", SqlDbType.
VarChar,
50).Value = firstname;
cmd.Parameters.Add("@lastname", SqlDbType.VarChar,
50)
.Value = lastname;
cmd.Parameters.Add("@email", SqlDbType.VarChar,
50)
.Value = email;
cmd.Parameters.Add("@devicelist", SqlDbType.
VarChar)
.Value = devicelist;
con.Open();
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (con != null)
{
con.Close();
}
}
return req.CreateResponse(HttpStatusCode.OK, "Hello,
Successfully inserted the data");
}

O código anterior é o código que copiei do Capítulo 3, Integração perfeita do Azure


Functions com Serviços do Azure, com as alterações a seguir, mas a cadeia de conexão
não tem detalhes da ID do usuário e senha.

1. Adicione uma nova linha de código para recuperar o token de acesso:


con.AccessToken = (new AzureServiceTokenProvider()).
GetAccessTokenAsync("https://database.windows.net/").Result;

2. Adicione os seguintes pacotes NuGet ao aplicativo de função:


Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory
Install-Package Microsoft.Azure.Services.AppAuthentication

[ 282 ]
Capítulo 9

3. Depois de garantir que não haja erros de build, publique o aplicativo de função
no Azure. Esta etapa garante a criação do aplicativo de função com o tempo
de execução V1. Clique no botão Publicar, que abre o pop-up como mostrado:

4. Em seguida, forneça o Grupo de Recursos e outros detalhes, como mostrado


na captura de tela a seguir e clique no botão Criar:

[ 283 ]
Implementação de práticas recomendadas para o Azure Functions

Como criar um SQL Server lógico e um Banco


de Dados SQL
Crie um SQL Server e um banco de dados SQL no mesmo grupo de recursos em que você
criou o aplicativo de função do Azure. No meu caso, meu nome do grupo de recursos
é AzureServerlessCookbookv1.

Como habilitar a identidade de serviço gerenciada


Execute as seguintes etapas:

1. Navegue até os recursos da Plataforma do aplicativo de função e clique


em Identidade de serviço gerenciada
2. Na guia Identidade de serviço gerenciada, clique em Ativar e Salvar, conforme
mostrado:

Como recuperar informações de Identidade de Serviço


Gerenciada
Execute as seguintes etapas:

1. Autentique a identidade da Conta do Azure usando a CLI do Azure executando


o comando az login Prompt de Comando, conforme mostrado na seguinte
captura de tela:

2. Você será solicitado a fornecer suas credenciais de conta do Azure para fazer
logon no portal do Azure. Depois de ter fornecido suas credenciais, ele mostrará
as assinaturas disponíveis no console de comando.

[ 284 ]
Capítulo 9

3. Agora precisamos recuperar os detalhes do princípio de serviço executando


o seguinte comando:
az resource show --name <<Function App Name>> --resource-group
<<Resource Group>> --resource-type Microsoft.Web/sites --query
identity

4. Se tiver configurado a identidade gerenciada corretamente, você verá algo


semelhante ao seguinte como a saída do comando anterior:

5. Anote a principalId, recuperada na etapa anterior. Nós a usaremos na próxima


seção.

Como permitir o acesso do SQL Server ao novo Serviço


de Identidade Gerenciada
Nesta seção, criaremos um usuário administrador que tenha acesso ao SQL Server que
criamos anteriormente:

1. Execute o seguinte comando no Prompt de Comando passando a principalId


que você anotou na seção anterior:
az sql server ad-admin create --resource-group
AzureServerlessCookbookv1 --server-name azuresqlmsidbserver
--display-name sqladminuser --object-id <Principe Id>

2. A execução do comando anterior cria um novo usuário administrador no banco


de dados mestre do SQL Server.

3. Crie uma tabela denominada EmployeeInfo utilizando o seguinte script:


CREATE TABLE [dbo].[EmployeeInfo]( [PKEmployeeId] [bigint]
IDENTITY(1,1) NOT NULL, [firstname] [varchar](50) NOT NULL,
[lastname] [varchar](50) NULL, [email] [varchar](50) NOT NULL,
[devicelist] [varchar](max) NULL, CONSTRAINT [PK_EmployeeInfo]
PRIMARY KEY CLUSTERED ( [PKEmployeeId] ASC ) )

[ 285 ]
Implementação de práticas recomendadas para o Azure Functions

Execução do gatilho e de testes HTTP


Execute as seguintes etapas:

1. Abra o Postman e envie uma solicitação conforme mostrado:

2. Vamos analisar o Banco de Dados SQL para ver se o registro foi inserido:

[ 286 ]
Capítulo 9

E mais...
Certifique-se de que você tenha todos os namespaces a seguir na classe:
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;
using System.Data.SqlClient;
using System.Data;
using System;
using Microsoft.Azure.Services.AppAuthentication;

Consulte também
Consulte as interações do Banco de Dados SQL do Azure usando a receita do Azure Functions
do Capítulo 3, Integração perfeita do Azure Functions com Serviços do Azure.

Código compartilhado no Azure


Functions usando bibliotecas de classe
Você aprendeu a reutilizar um método Auxiliar em um aplicativo de função do Azure. No
entanto, você não pode reutilizá-lo em outros aplicativos de função ou em qualquer outro
tipo de aplicativo, como um aplicativo da Web ou WPF. Nesta receita, desenvolveremos
e criaremos um novo arquivo .dll e você aprenderá a usar as classes e seus métodos no
Azure Functions.

[ 287 ]
Implementação de práticas recomendadas para o Azure Functions

Como fazer isso...


Execute as seguintes etapas:

1. Crie um novo aplicativo Biblioteca de Classe usando o Visual Studio. Eu usei


o Visual Studio 2017:

2. Crie uma nova classe denominada Helper e cole o código a seguir no novo
arquivo de classe:
namespace Utilities
{
public class Helper
{
public static string GetReusableFunctionOutput()
{
return "This is an output from a Resuable Library
across functions";
}
}
}

3. Altere a configuração de build para a versão e compile o aplicativo para criar


o arquivo .dll, que será usado em nosso Azure Functions.
4. Navegue até o Editor de Serviço de Aplicativo do aplicativo de função
clicando no botão Editor de Serviço de Aplicativo, que está disponível em
Recursos da Plataforma.

[ 288 ]
Capítulo 9

5. Agora crie uma nova pasta bin clicando com o botão direito do mouse na área
vazia abaixo dos arquivos localizados em WWWROOT.
6. Depois de clicar no item Nova Pasta na tela obtida, uma nova caixa de texto será
exibida, onde você precisará fornecer o nome como bin.
7. Em seguida, clique com o botão direito do mouse na pasta bin e selecione a opção
Carregar Arquivos para carregar o arquivo .dll criado no Visual Studio
8. Esta é a sua aparência após o upload do arquivo .dll para a pasta bin:

9. Navegue até o Azure Function onde você gostaria de usar o método


compartilhado. Para demonstrar, criei dois Azure Functions (um gatilho
HTTP e um gatilho de timer):

[ 289 ]
Implementação de práticas recomendadas para o Azure Functions

10. Vamos navegar até a função ReusableMethodCaller1 e faça as seguintes


alterações:
°° Adicione uma nova diretiva #r, da seguinte forma, ao método run.
csx do Azure Function ReusableMethodCaller1. Observe que .dll
é necessário neste caso:
#r "../bin/Utilities.dll"

°° Adicione um novo namespace, da seguinte maneira:


using Utilities;

11. Agora estamos prontos para usar o método compartilhado


GetReusableFunctionOutput em nosso Azure Function. Agora substitua
o código do gatilho HTTP pelo seguinte:
log.LogInformation(Helper.GetReusableFunctionOutput());

12. Quando executar o aplicativo, você deverá ver a seguinte mensagem nos logs:

13. Repita as mesmas etapas de adição da referência e o namespace da biblioteca


de utilitários até mesmo no segundo Azure Function, ReusableMethodCaller2.
Se você tiver feito alterações com êxito, você deverá ver algo parecido com
o seguinte:

Como funciona...
Criamos um arquivo .dll que contém o código reutilizável que pode ser usado
em qualquer um dos Azure Functions que exigem a funcionalidade disponibilizada pelo
arquivo .dll.

Quando o arquivo .dll estiver pronto, criaremos uma pasta bin no aplicativo de função
e adicionamos o arquivo .dll à pasta bin.

[ 290 ]
Capítulo 9

Observe que adicionamos a pasta bin ao WWWROOT para que


ela esteja disponível para todos os Azure Functions disponíveis no
aplicativo de função.

E mais...
Se quiser usar o código compartilhado apenas em uma função, você precisará adicionar
a pasta bin junto com o arquivo .dll na pasta necessária do Azure Function.

Outra grande vantagem do uso de bibliotecas de classe é que isso melhora


o desempenho, uma vez que elas já estão compiladas e prontas para execução.

Uso de classes fortemente tipadas no


Azure Functions
Em nossos capítulos iniciais, desenvolvemos um gatilho HTTP chamado RegisterUser,
que atua como uma API Web e pode ser consumido por qualquer aplicativo capaz de
fazer solicitações HTTP. No entanto, pode haver alguns outros requisitos, onde você pode
ter aplicativos diferentes que criam mensagens em uma fila com os detalhes necessários
para a criação de um usuário. Por razões de simplicidade, usaremos Gerenciador
de Armazenamento do Azure para criar uma mensagem da fila.

Nesta receita, veremos como obter os detalhes do usuário da fila usando objetos
fortemente tipados.

Preparação
Antes de avançarmos, executaremos as seguintes etapas:

1. Criar uma conta de armazenamento (eu criei azurefunctionscookbook)


em sua assinatura do Azure
2. Instalar o Gerenciador de Armazenamento do Microsoft Azure se ainda não
o tiver instalado
3. Após a criação do Gerenciador de Armazenamento, conecte-se à sua conta
de armazenamento do Azure

[ 291 ]
Implementação de práticas recomendadas para o Azure Functions

Como fazer isso...


Execute as seguintes etapas:

1. Usando o Gerenciador de Armazenamento do Azure, crie uma fila


chamada registeruserqueue na conta de armazenamento chamada
azurefunctionscookbook. Partimos do princípio de que todos os outros
aplicativos estariam criando mensagens na fila registeruserqueue.
2. Navegue até o Azure Functions e crie um novo Azure Function usando o gatilho
do Gerenciador de Armazenamento do Azure, então escolha a fila que criamos.
3. Você pode ser solicitado a instalar extensões de armazenamento se ainda não
tiver instalado. Depois de instalar as extensões, forneça os detalhes da fila
e clique no botão Criar, conforme mostrado na captura de tela a seguir:

4. Após a criação da função, substitua o código padrão com o código a seguir:


Sempre que uma mensagem de fila é criada, a mensagem JSON será
desserializada automaticamente e preenchida em um objeto denominado
myQueueItem. No código a seguir, estamos apenas imprimindo os valores dos
objetos na janela Logs:
using System;
public static void Run(User myQueueItem, ILogger log)
{

[ 292 ]
Capítulo 9

log.LogInformation($"A Message has been created for a new


User");
log.LogInformation($"First name: {myQueueItem.firstname}" );
log.LogInformation($"Last name: {myQueueItem.lastname}" );
log.LogInformation($"email: {myQueueItem.email}" );
log.LogInformation($"Profile Url: {myQueueItem.ProfilePicUrl}"
);
}
public class User
{
public string firstname { get;set;}
public string lastname { get;set;}
public string email { get;set;}
public string ProfilePicUrl { get;set;}
}

5. Navegue até o Gerenciador de Armazenamento do Azure e crie uma nova


mensagem na registeruserqueue, conforme mostrado na seguinte captura
de tela:

[ 293 ]
Implementação de práticas recomendadas para o Azure Functions

6. Clique em OK para criar a mensagem de fila e navegue de volta até o Azure


Function e examine os logs conforme mostrado na seguinte captura de tela:

Como funciona...
Desenvolvemos uma nova função de fila que é acionada quando uma nova mensagem
é adicionada à fila. Nós criamos uma nova mensagem de fila com todos os detalhes
necessários para criar o usuário. Você pode reutilizar ainda mais o código do Azure
Function para passar o objeto de usuário (neste caso, myQueueItem) para a classe
de camada de banco de dados, que é capaz de inserir os dados em um banco de dados
ou em qualquer outro meio persistente.

E mais...
Nesta receita, o tipo do parâmetro de mensagem de fila que foi aceito pelo método Run
era User. O Azure Functions Runtime cuidará da desserialização da mensagem JSON
disponível na fila para o tipo personalizado; usuário, no nosso caso.

[ 294 ]
Configuração de aplicativos
sem servidor no ambiente
de produção
Neste capítulo, vamos aprender as seguintes receitas:

• Implantar Azure Functions usando Run From Package


• Implantar o Azure Functions usando modelos ARM
• Configurar o domínio personalizado para o Azure Functions
• Técnicas para acessar Configurações do Aplicativo
• Criar e gerar especificações de API abertas usando o Swagger
• Quebrar APIs grandes em pequenos subconjuntos de APIs usando proxies
• Mover itens de configuração de um ambiente para outro usando recursos

Introdução
Temos falado sobre todos os diferentes recursos do Azure Functions que ajudam
os desenvolvedores a criar rapidamente aplicativos de back-end. O foco deste
capítulo está nas configurações que o desenvolver precisa criar em um ambiente
de não desenvolvimento (como Preparo, UAT e produção).

[ 295 ]
Configuração de aplicativos sem servidor no ambiente de produção

Implantar o Azure Functions usando


Run From Package
Temos aprendido sobre as diferentes técnicas para desenvolvimento do Azure Functions
e sua implantação na nuvem.

Como você já deve estar ciente, cada aplicativo de função pode ter várias funções
hospedadas nele. Todos os códigos relacionados a essas funções serão localizados
na pasta D:\home\site\wwwroot:

D:\home\site\wwwroot é o local onde o tempo de execução procurará os binários


e todos os arquivos de configuração necessários para executar o aplicativo.

Nesta receita, aprenderemos outra técnica nova, chamada Run From Package
(anteriormente chamada Run From Zip) para implantar o Azure Function como um pacote.

[ 296 ]
Capítulo 10

Usando Run From Package, podemos alterar o local padrão para uma conta
de armazenamento externo.

Preparação
Precisamos do seguinte para completar esta receita:

1. Visual Studio 2017 instalado no computador local do desenvolvedor; crie uma


ou mais Azure Functions usando o Visual Studio. Para este exemplo, criei um
gatilho de HTTP e um gatilho de timer:

2. Crie um aplicativo de função vazio usando o portal de Gerenciamento do Azure:

3. Uma conta de armazenamento: carregaremos o arquivo de pacote para a conta


de armazenamento.

[ 297 ]
Configuração de aplicativos sem servidor no ambiente de produção

Como fazer isso...


Execute as seguintes etapas:

1. Crie um arquivo de pacote para o aplicativo. Estou usando o mesmo aplicativo


que criamos no Capítulo 4, Noções básicas sobre a experiência integrada de
desenvolvedor de Ferramentas do Visual Studio.
2. Navegue até o local onde você vê a pasta bin juntamente com outros
arquivos relacionados às suas funções. Crie um arquivo .zip fora dos arquivos,
que é realçado na seguinte captura de tela:

3. Crie um contentor de Blob (com acesso privado) e carregue o arquivo de pacote


do portal ou por meio do Gerenciador de Armazenamento do Azure.
4. A próxima etapa é gerar um token de assinatura de acesso compartilhado
(SAS) para o Contêiner de Blob, de forma que o tempo de execução do Azure
Function tenha as permissões necessárias para acessar os arquivos localizados no
contêiner. Saiba mais sobre SAS em https://docs.microsoft.com/azure/
storage/common/storage-dotnet-shared-access-signature-part-1:

5. Navegue para as Configurações de aplicativo do aplicativo de função que


criamos e crie uma nova configuração de aplicativo com a chave WEBSITE_RUN_
FROM_PACKAGE e o valor a ser a URL de SAS do Blob que você criou na etapa
anterior, como mostrado aqui. Clique em Salvar para salvar as alterações.

[ 298 ]
Capítulo 10

6. É isso. Depois de definir a configuração anterior, você pode testar a função:

Como funciona...
Quando o tempo de execução do Azure Function localiza uma configuração de aplicativo
com o nome WEBSITE_RUN_FROM_PACKAGE, ele entende que deve procurar os pacotes
na conta de armazenamento. Portanto, em tempo real, o tempo de execução faz
download dos arquivos e usa-os para iniciar o aplicativo.

E mais...
Saiba mais sobre esta técnica e suas vantagens em https://github.com/Azure/app-
service-announcements/issues/84.

Implantar o Azure Functions usando


modelos ARM
Até agora, temos provisionado manualmente o Azure Functions usando o portal
de Gerenciamento do Azure.

Nesta receita, aprenderemos como automatizar o processo de provisionamento


do Azure Function usando modelos do Azure Resource Manager (ARM).

Preparação
Antes de começar a criar os modelos do ARM, precisamos entender os outros serviços
do Azure dos quais o Azure Function depende. Os seguintes serviços são criados
automaticamente quando você cria um aplicativo de função:

[ 299 ]
Configuração de aplicativos sem servidor no ambiente de produção

Como mostrado na captura de tela anterior, o aplicativo de função (neste caso,


azurefunctioncookbook-gateway) depende de um Plano do Serviço de Aplicativo
e de uma Conta de Armazenamento:

• Plano do Serviço de Aplicativo: pode ser um Plano do Serviço de Aplicativo


regular e um Plano de consumo.
• Conta de armazenamento: o tempo de execução do Azure Function usa a Conta
de armazenamento para registrar informações de diagnóstico que podemos usar
para solução de problemas.
• Application Insights: uma conta opcional do Application Insights. Se não
estivermos usando o Application Insights, precisamos criar uma configuração
de aplicativo com o nome AzureWebJobsDashboard nas configurações do
aplicativo da função que usa o Serviço de Tabela de Armazenamento do Azure
para registrar informações de diagnóstico.
Junto com esses serviços, obviamente precisamos ter um grupo de recursos. Nesta receita,
presumiremos que o grupo de recursos já existe.

Como fazer isso...


Agora, você já sabe que, ao criar Azure Functions, precisamos garantir que também
acomodamos um plano do Serviço de Aplicativo e uma conta de armazenamento.
Vamos começar a criar o modelo do ARM usando o Visual Studio:
1. Crie um novo projeto escolhendo Visual C# | Cloud e, em seguida, escolha
Grupo de Recursos do Azure:

[ 300 ]
Capítulo 10

2. Clicar no botão OK na etapa anterior abrirá a janela Selecionar Modelo


do Azure, em que você escolhe os modelos de Início Rápido do Azure (github.
com/Azure/azure-quickstart-templates):

3. Procure a palavra função e clique no modelo 101-function-app-create-dynamic


para criar o aplicativo de função do Azure com o Plano de consumo:

[ 301 ]
Configuração de aplicativos sem servidor no ambiente de produção

4. O modelo JSON necessário será criado no Visual Studio. Saiba mais sobre
o conteúdo JSON em https://docs.microsoft.com/azure/azure-
functions/functions-infrastructure-as-code.
5. Implante o ARM para provisionar o aplicativo de função e seus recursos
dependentes. Você pode implantá-lo clicando com o botão direito do mouse no
nome do projeto (em meu caso ARMTemplateforFunctionApp), em Implantar
e no botão Novo:

6. Escolha a Assinatura, Grupo de recursos e outros parâmetros para provisionar


o aplicativo de função. Escolha todos os campos obrigatórios e clique no
botão Implantar:

[ 302 ]
Capítulo 10

7. É isso. Em alguns minutos, a implantação será iniciada e cada um dos recursos


mencionados nos modelos ARM JSON será provisionado:

E mais...
Aqui estão algumas das vantagens de provisionar Recursos do Azure usando modelos ARM:

• Ao ter as configurações nos arquivos JSON, é útil para os desenvolvedores enviar


os arquivos para algum tipo de sistema de controle de versão, como Git ou TFS,
para que possamos manter as versões dos arquivos a fim de acompanhar todas
as alterações.
• Também é possível criar rapidamente os serviços em ambientes diferentes.
• Com os modelos ARM, também podemos enviá-los em pipelines de CI/CD
para automatizar o provisionamento para ambientes adicionais.

Configurar o domínio personalizado para


o Azure Functions
Agora, analisando a URL padrão no formato functionappname.azurewebsites.net
do aplicativo de função do Azure, você pode estar se perguntando se é possível ter um
domínio separado em vez do domínio padrão, pois seus clientes podem ter seus próprios
domínios. Sim, é possível configurar um domínio personalizado para os aplicativos
de função. Nesta receita, aprenderemos como configurá-lo.

[ 303 ]
Configuração de aplicativos sem servidor no ambiente de produção

Preparação
Crie um domínio com qualquer um dos registradores de domínio. Você também
pode adquirir um domínio diretamente do portal usando o botão Comprar domínio,
que está disponível na folha Domínios Personalizados:

Depois que o domínio estiver pronto, crie os seguintes registros DNS usando
o registrador de domínio:

• Registro A
• Registro CName

Como fazer isso...


Execute as seguintes etapas:

1. Navegue para a folha Domínios personalizados do aplicativo de função


do Azure para o qual você gostaria de configurar um domínio:

[ 304 ]
Capítulo 10

2. Se você tiver criado um domínio personalizado do portal do Azure, será


solicitado que escolha os nomes de host, conforme mostrado na folha
Domínio do Serviço de Aplicativo:

[ 305 ]
Configuração de aplicativos sem servidor no ambiente de produção

3. Se você escolheu os dois, então pronto. Todo o trabalho na integração


do aplicativo de função e do domínio personalizado é praticamente feito
para você pelo portal de Gerenciamento do Azure. Você pode ver a integração
dos nomes de host aqui:

Configuração do aplicativo de função com


um domínio existente
Se você já tiver um domínio personalizado e quiser integrá-lo ao aplicativo de função,
será necessário criar os dois registros a seguir no DNS:

1. Crie um registro A e um CNAME no registrador de domínio. Você pode obter


o endereço IP da folha Domínios Personalizados:

[ 306 ]
Capítulo 10

2. Navegue para a folha Domínios Personalizados do aplicativo de função e crie


os seguintes nomes de host:

É isso. Você integrou um domínio personalizado com o aplicativo de função do Azure.


Agora, você pode procurar seu aplicativo de função usando o novo domínio, em vez
daquele padrão que o Azure fornece:

[ 307 ]
Configuração de aplicativos sem servidor no ambiente de produção

Técnicas para acessar Configurações


do Aplicativo
Em cada aplicativo, você terá pelo menos alguns itens de configuração que talvez não
queira codificar. Em vez disso, você pode desejar alterá-los no futuro, depois que o
aplicativo for lançado, sem tocar no código.

Em geral, eu classificaria os itens de configuração em duas categorias:

• Alguns dos itens de configuração podem ser diferentes entre os ambientes,


por exemplo, as cadeias de conexão do banco de dados e do servidor SMTP
• Alguns deles podem ser iguais entre os ambientes, como alguns números
constantes que são usados em alguns cálculos no código

Não importa qualquer seja o uso do valor de configuração, você precisa ter um lugar
para armazená-los que seja acessível a seu aplicativo.

Nesta receita, aprenderemos como e onde armazenar esses itens de configuração


e as diferentes técnicas para acessá-los a partir do código do aplicativo.

Preparação
Crie um Azure Function com o tempo de execução da Função V2, se ainda não tiver
sido criado. Eu usarei o aplicativo de função que criamos no Capítulo 4, Noções básicas
sobre a experiência integrada de desenvolvedor de Ferramentas do Visual Studio.

Como fazer isso...


Nesta receita, vamos analisar algumas maneiras de acessar os valores de configuração.

Acesso a Configurações do Aplicativo e cadeias


de conexão no código do Azure Function
Execute as seguintes etapas:

1. Crie um item de configuração com a chave MyAppSetting e um


ConnectionStrings com a chave sqldb_connection no arquivo local.
settings.json. local.settings.json deve ser parecido com a seguinte
captura de tela:

[ 308 ]
Capítulo 10

2. Substitua o código existente pelo código a seguir. Adicionamos algumas linhas


que leem os valores de configuração e as cadeias de conexão:
public class HttpTriggerCSharpFromVS
{
[FunctionName("HttpTriggerCSharpFromVS")]
public static IActionResult Run([HttpTrigger(AuthorizationLevel.
Anonymous, "get", "post", Route = null)]HttpRequest req,ILogger
logger)
{
var configuration = new ConfigurationBuilder()
.AddEnvironmentVariables()
.AddJsonFile("appsettings.json", true)
.Build();
var ValueFromGetConnectionStringOrSetting = configuration.GetConne
ctionStringOrSetting("MyAppSetting");
logger.LogInformation("GetConnectionStringOrSetting" +
ValueFromGetConnectionStringOrSetting);
var ValueFromConfigurationIndex= configuration["MyAppSetting"];
logger.LogInformation("ValueFromConfigurationIndex" +
ValueFromConfigurationIndex);
var ValueFromConnectionString = configuration.GetConnectionStringO
rSetting("ConnectionStrings:sqldb_connection");
logger.LogInformation("ConnectionStrings:sqldb_connection" +
ValueFromConnectionString);
string name = req.Query["name"];
return name != null ? (ActionResult)new OkObjectResult($"Hello,
{name}")
: new BadRequestObjectResult("Please pass a name on the query
string or in the request body");
}
}

[ 309 ]
Configuração de aplicativos sem servidor no ambiente de produção

3. Publique o projeto no Azure clicando nele com o botão direito do mouse e,


em seguida, clicando em Publicar no menu.
4. Adicione a chave de configuração e a cadeia de conexão na folha Configurações
de Aplicativo:

5. Execute a função clicando no botão Executar, que registra a saída na janela Saída:

[ 310 ]
Capítulo 10

Configuração do aplicativo – expressões


de associação
Na seção anterior, aprendemos como acessar as definições de configuração a partir
do código. Às vezes, convém configurar alguns dos itens declarativos também. Você
pode conseguir isso usando a expressão de associação. Em breve, você entenderá o que
eu quero dizer quando analisamos o código:

1. Abra o Visual Studio e faça alterações no método Run para adicionar um novo
parâmetro para configuração do QueueTrigger:

2. O parâmetro hardcodedqueuename é o nome da fila para a qual as


mensagens serão criadas. É óbvio que codificar o nome da fila não é uma
prática recomendada. Para torná-lo configurável, você precisa usar a expressão
de associação da configuração do aplicativo:

3. A chave de configuração do aplicativo deve ser incluída entre %...% e uma


chave com o nome queuename deve ser criada nas Configurações de Aplicativo.

Criar e gerar especificações de API


abertas usando o Swagger
Para um desenvolvedor de API Web de back-end, uma de suas responsabilidades é
fornecer uma documentação adequada para os desenvolvedores de aplicativo de front-
end, para que eles possam consumir as APIs sem problemas. Para consumir qualquer
API, a seguir estão os dois pontos mínimos que um desenvolvedor precisa entender:

• Os parâmetros de entrada e seus tipos de dados


• Os parâmetros de saída e seus tipos de dados

[ 311 ]
Configuração de aplicativos sem servidor no ambiente de produção

Portanto, é responsabilidade dos desenvolvedores de back-end fornecer a documentação


adequada para as APIs e não é fácil fornecer a documentação adequada, pois há muitas
ferramentas e padrões/especificações disponíveis para fornecer a documentação
adequada para as APIs REST. Um padrão desse tipo é conhecido como a especificação
de API aberta (é popularmente conhecido como Swagger).

O Azure Functions nos fornece o suporte de ferramentas necessário para gerar as


definições de API abertas para nossos gatilhos HTTP. Nesta receita, aprenderemos
como gerá-las.

Preparação
Crie uma função e um ou mais gatilhos HTTP. Para simplificar, criei um aplicativo
de função e um gatilho de HTTP, que aceita apenas os métodos Get.

Observe que, no momento da gravação, o recurso de definição


de API é permitido apenas pelo tempo de execução do Azure
Function V1.0 e ainda está em visualização. Ele não funciona
com a V2.0 ainda.

Verifique se o aplicativo de função do Azure está configurado para apontar para a versão
1 do tempo de execução, como mostrado nas Configurações de Aplicativo:

Como fazer isso...


Execute as seguintes etapas:

1. Navegue para os Recursos da plataforma e clique na guia Definição de API:

[ 312 ]
Capítulo 10

2. Na guia Definição de API, clique na opção Função (versão prévia) para permitir
a fonte da definição de API:

3. Assim que você clicar no botão Função (versão prévia), o recurso será habilitado.
No entanto, você pode ver um erro na nova guia que é aberta. Não se preocupe,
como o recurso ainda está em visualização, a Microsoft pode corrigi-lo antes que
ele esteja disponível de forma geral (GA). Em seguida, clique em Gerar modelo
de definição de API:

[ 313 ]
Configuração de aplicativos sem servidor no ambiente de produção

4. Isso apenas criará um modelo da definição de API aberta. É responsabilidade


do desenvolvedor de nuvem preencher o modelo, com base nas APIs que eles
desenvolveram. Ela deve ter esta aparência. Nós alteraremos o modelo em breve:

5. Na captura de tela anterior, a guia de código contém todos os modelos padrão


necessários para gerar a definição do Swagger com base na especificação
de API aberta. A seção à direita mostra como a UI do Swagger é exibida.
A UI do Swagger é algo que será compartilhado com as outras equipes de
desenvolvimento de aplicativo cliente que consomem as APIs de back-end.
6. Vamos substituir o modelo padrão adicionando os parâmetros necessários
das operações da API, e clique no botão Salvar para salvar as alterações.
Para simplificar, acabei de fazer algumas alterações que descrevem
a API e suas operações. Deve ser simples de entender.
7. A UI do Swagger terá a seguinte aparência com mensagens adequadas,
juntamente com os formatos de solicitação e resposta:

[ 314 ]
Capítulo 10

8. Ela também nos permite executar alguns testes. Clique no botão Tentar esta
operação que é mostrado na captura de tela anterior. Ele abre uma janela onde
você pode fornecer entrada:

[ 315 ]
Configuração de aplicativos sem servidor no ambiente de produção

9. Eu forneci Praveen Kumar como o valor para o nome, cliquei no botão


Enviar Solicitação e obtive a seguinte saída:

Quebrar APIs grandes em pequenos


subconjuntos de APIs usando proxies
Nos últimos tempos, um dos jargões na indústria é microsserviços, em que você
desenvolve seus componentes da Web como microsserviços que podem ser gerenciados
(escalonamento, implantação, e assim por diante) individualmente sem afetar os
outros componentes relacionados. Embora o assunto de microsserviços seja bastante
amplo, tentaremos conseguir criar alguns microsserviços que poderão ser gerenciados
individualmente como aplicativos de função independentes. Mas, vamos expô-los ao
mundo externo como uma única API com operações diferentes com a ajuda de Proxies
do Azure Function.

Preparação
Nesta receita, estaremos implementando a seguinte arquitetura:

[ 316 ]
Capítulo 10

Vamos supor que estamos trabalhando para um portal de comércio eletrônico onde
temos apenas três módulos (homens, mulheres e crianças) e nosso objetivo é criar as
APIs de back-end em uma arquitetura de microsserviço, em que cada microsserviço
é independente dos outros.

Nesta receita, conseguiremos isso criando os seguintes aplicativos de função:

• Um componente de gateway (aplicativo de função) que é responsável por


controlar o tráfego para o microsserviço certo com base na rota (/men, /women
e /kids). Neste aplicativo de função, criaremos Proxies do Azure Function
que redirecionarão o tráfego usando configurações de rota.
• Três novos aplicativos de função em que cada um deles é tratado como
um microsserviço separado.

Como fazer isso...


Nesta receita, executaremos as seguintes etapas:

1. Crie todos os três microsserviços com um gatilho de HTTP em cada um deles


2. Crie, use proxy e configure o respectivo microsserviço
3. Teste a URL do proxy

[ 317 ]
Configuração de aplicativos sem servidor no ambiente de produção

Criação de microsserviços
Execute as seguintes etapas:

1. Crie três aplicativos de função para cada um dos microsserviços que planejamos:

2. Crie os seguintes gatilhos HTTP anônimos em cada um dos aplicativos de função


que exibem uma mensagem como mostrada a seguir:

Nome do gatilho de Http Mensagem de saída


Olá, <<Nome>> - Bem-vindo ao
Men-HttpTrigger
microsserviço Men
Olá, <<Nome>> - Bem-vindo ao
Women-HttpTrigger
microsserviço Women
Olá, <<Nome>> - Bem-vindo ao
Kids-HttpTrigger
microsserviço Kids

Criação dos proxies de gateway


Execute as seguintes etapas:

1. Navegue até o aplicativo de função de gateway e crie um novo proxy:

[ 318 ]
Capítulo 10

2. Você passará para a folha de detalhes:

[ 319 ]
Configuração de aplicativos sem servidor no ambiente de produção

3. Crie os proxies para women e kids. Aqui estão os detalhes de todos os três
proxies. Observe que as URLs de back-end (dos aplicativos de função) podem
ser diferentes no seu caso:

Nome do Modelo URL de back-end (as URLs dos gatilhos HTTP criadas na
proxy de rota etapa anterior)
Homens /Men https://azurefunctioncookbook-men.
azurewebsites.net/api/Men-HttpTrigger
Mulheres /Women https://azurefunctioncookbook-women.
azurewebsites.netapi/Women-HttpTrigger
Crianças /Kids https://azurefunctioncookbook-kids.
azurewebsites.netapi/Kids-HttpTrigger

4. Depois de criar os três proxies, a lista deverá ficar mais ou menos assim:

5. Na captura de tela anterior, você pode exibir três domínios diferentes. No


entanto, se você desejar compartilhar os proxies com os aplicativos cliente,
não será necessário compartilhar essas URLs. Tudo o que você precisa fazer
é compartilhar a URL dos proxies que você pode exibir na guia proxy. Aqui
estão as URLs de proxy dos três proxies que criamos:

• https://azurefunctioncookbook-gateway.azurewebsites.net/Men
• https://azurefunctioncookbook-gateway.azurewebsites.net/Women
• https://azurefunctioncookbook-gateway.azurewebsites.net/Kids

[ 320 ]
Capítulo 10

Teste das URLs de proxy


Como você já sabe, nossos gatilhos HTTP aceitam um parâmetro name obrigatório,
então precisamos passar a cadeia de consulta name para a URL do proxy. Vamos acessar
as seguintes URLs no navegador:

• Homens:

• Mulheres:

• Crianças:

Observe as URLs das três capturas de tela. Você observará que parece que elas são
fornecidas de um único aplicativo com rotas diferentes. No entanto, elas são três
microsserviços diferentes que podem ser gerenciados individualmente.

E mais...
Todos os microsserviços que criamos nesta receita são anônimos, o que significa que eles
são acessíveis publicamente a todos. Para torná-los seguros, você precisa seguir qualquer
uma das abordagens recomendadas no Capítulo 9, Implementação de práticas recomendadas
para o Azure Functions.

[ 321 ]
Configuração de aplicativos sem servidor no ambiente de produção

Os proxies do Azure Function também permitem que você intercepte a solicitação


original e, se necessário, você pode adicionar novos parâmetros e passá-los para a
API de back-end. Da mesma forma, você pode adicionar outros parâmetros e enviar
a resposta de volta para o aplicativo cliente. Saiba mais sobre os proxies do Azure
Function na documentação oficial em https://docs.microsoft.com/azure/azure-
functions/functions-proxies.

Consulte também
• A receita Controle de acesso ao Azure Functions usando teclas de função do Capítulo 9,
Implementação de práticas recomendadas para o Azure Functions
• A receita Proteção do Azure Functions usando o Azure AD do Capítulo 9,
Implementação de práticas recomendadas para o Azure Functions
• A receita Configuração da limitação do Azure Functions usando o Gerenciamento de
API no Capítulo 9, Implementação de práticas recomendadas para o Azure Functions

Mover itens de configuração de um


ambiente para outro usando recursos
Cada aplicativo que você desenvolver terá muitos itens de configuração (como
configurações do aplicativo como cadeias de conexão) que serão armazenados em
arquivos Web.Config para todos os seus aplicativos Web baseados em .NET.

No mundo tradicional da infraestrutura local, o arquivo Web.Config ficaria localizado


no servidor e seria acessível a todas as pessoas que têm acesso ao servidor. Embora
fosse possível criptografar todos os itens de configuração do arquivo Web.Config, ele
tinha suas limitações e não é fácil descriptografá-los toda vez que você deseja exibi-los
ou atualizá-los.

No mundo de PaaS do Azure, com Serviços de Aplicativos do Azure, você ainda pode
ter os arquivos Web.Config e eles funcionam como costumavam no mundo tradicional
da infraestrutura local. No entanto, o Serviço de Aplicativo do Azure oferece um
recurso adicional no que diz respeito às configurações de aplicativo, no qual você pode
definir essas configurações (manualmente ou por meio de modelos ARM) e elas são
armazenadas em um formato criptografado. Porém, você poderá exibi-las como texto
normal no portal se tiver acesso.

[ 322 ]
Capítulo 10

Dependendo do tipo de aplicativo, o número de configurações correspondentes


pode aumentar bastante e, se você quiser criar novos ambientes, a criação dessas
configurações de aplicativo poderá levar bastante tempo. Nesta receita, aprenderemos
uma dica de como exportar e importar essas configurações de aplicativo de um ambiente
mais baixo (por exemplo, Dev) para um ambiente mais alto (por exemplo, Prod).

Preparação
Execute as seguintes etapas:

1. Crie um aplicativo de função (por exemplo, MyApp-Devdev), caso ainda não


tenha feito isso
2. Crie algumas configurações do aplicativo:

3. Crie outro aplicativo de função (por exemplo, MyApp-Prod)

Nesta receita, aprenderemos como é fácil copiar as configurações do aplicativo


de uma função para outra. Esta técnica será útil quando houver muitas configurações
de aplicativo.

[ 323 ]
Configuração de aplicativos sem servidor no ambiente de produção

Como fazer isso...


Execute as seguintes etapas:

1. Navegue para a guia Recursos da plataforma do aplicativo de função MyApp-


Dev e clique no Gerenciador de Recursos:

2. O Gerenciador de Recursos será aberto e nele você poderá percorrer


todos os elementos internos de determinado serviço:

[ 324 ]
Capítulo 10

3. Clique no elemento config, como mostrado na captura de tela anterior, que abre
todos os itens relacionados às configurações:

4. O Gerenciador de Recursos exibirá todas as configurações do aplicativo


na janela do lado direito. Agora, você pode editá-las clicando no botão Editar,
que é realçado na captura de tela anterior, ou pode copiar todas as configurações
do aplicativo de AppSetting0 para AppSetting 9.

[ 325 ]
Configuração de aplicativos sem servidor no ambiente de produção

5. Navegue para o aplicativo de função MyApp-Prod (que não tem as configurações


do aplicativo destacadas na captura de tela anterior), clique no Gerenciador
de Recursos e clique nos elementos config | appsettings elementos para abrir
as configurações do aplicativo existentes. Ela deve ter esta aparência:

6. Clique no botão Editar e cole o conteúdo que você copiou anteriormente.


Depois de revisar as configurações, clique em PUT, que é mostrado na captura
de tela anterior.

[ 326 ]
Capítulo 10

7. Navegue para a folha de configuração do aplicativo de função MyApp-Prod:

Você deve ver todas as configurações do aplicativo que criamos no Gerenciador


de Recursos em uma só captura.

[ 327 ]
Como implementar e implantar
a integração contínua usando
o Azure DevOps
Neste capítulo, você aprenderá a:

• Integração contínua – criar uma definição de build


• Integração contínua – enfileirar um build e acioná-lo manualmente
• Configurar e acionar um build automatizado
• Integração contínua – executar casos de teste de unidade no pipeline
• Criar uma definição da versão
• Acionar a versão automaticamente

Introdução
Como um profissional de software, você já deve estar ciente das diferentes metodologias
de desenvolvimento de software que as pessoas praticam. Independentemente da
metodologia que está sendo seguida, existem vários ambientes, como desenvolvimento,
preparo e produção, onde o ciclo de vida do aplicativo precisa ser seguido com estes
estágios críticos relacionados ao desenvolvimento:

1. Desenvolver com base nos requisitos


2. Compilar o aplicativo e corrigir os erros
3. Implantar/liberar o pacote para um ambiente (desenvolvimento/preparo/
produção)

[ 329 ]
Como implementar e implantar a integração contínua usando o Azure DevOps

4. Testar com relação aos requisitos


5. Promover a liberação para o próximo ambiente (do desenvolvimento para
o preparo e do preparo para a produção)

Observe que, por uma questão de simplicidade, os estágios iniciais, como


coleta de requisitos, planejamento, projeto e arquitetura, são excluídos
apenas para enfatizar os estágios relevantes para este capítulo.

Para cada alteração que você faz no software, precisamos compilar e implantar o
aplicativo em vários ambientes e, neste caso, diferentes equipes podem ser responsáveis
para liberar os builds para ambientes distintos. Como diferentes ambientes e equipes
estão envolvidos, considerando a quantidade de tempo gasto na execução dos builds,
implantá-los em diferentes ambientes dependerá mais dos processos que as diferentes
equipes seguem.

A fim de agilizar e automatizar algumas das etapas mencionadas anteriormente, neste


capítulo, abordaremos algumas das técnicas comuns que a indústria segue para fornecer
software rapidamente, com uma infraestrutura mínima.

Nos capítulos anteriores, a maioria das receitas nos forneceu uma


solução para um problema de negócios individual. No entanto, todo
este capítulo como uma única entidade tentará fornecer uma solução
para a Integração Contínua e a Entrega Contínua do seu aplicativo
comercialmente crítico.

A equipe do Azure DevOps adiciona continuamente novos recursos ao Azure


DevOps em https://dev.azure.com (anteriormente conhecido como VSTS
em https://www.visualstudio.com) e também atualiza a interface do usuário.
Não se  surpreenda se as capturas de tela fornecidas neste capítulo não forem
correspondentes com aquelas exibidas de suas telas em https://dev.azure.com
enquanto você estiver lendo este capítulo.

Pré-requisitos
Crie o seguinte, se você ainda não fez isso:

1. Crie uma organização do Azure DevOps de sua escolha em https://dev.


azure.com e crie um novo projeto nessa conta. Ao criar o projeto, você pode
escolher Git ou Controle de Versão do Team Foundation como seu repositório
de controle de versão. Eu usei o Controle de Versão do Team Foundation
para meu projeto:

[ 330 ]
Capítulo 11

2. Configure o projeto do Visual Studio que você desenvolveu no Capítulo 4, Noções


básicas sobre a experiência integrada de desenvolvedor de Ferramentas do Visual Studio,
para o Azure DevOps. Você pode acessar o link https://www.visualstudio.com/
en-us/docs/setup-admin/team-services/set-up-vs para seguir o processo passo
a passo de criar uma nova conta e projeto usando o Azure DevOps.

Eu estarei fazendo algumas pequenas alterações nas mensagens de


resposta incorporadas no código para mostrar diferentes saídas.
Certifique-se de modificar os testes de unidade de forma adequada.
Caso contrário, o build falhará.

Integração contínua – criar uma definição


de build
Uma definição de build é um conjunto de tarefas que são necessárias para configurar
um build automatizado do software. Nesta receita, vamos fazer o seguinte:

• Criar o modelo de definição de build


• Fornecer todas as entradas necessárias para cada uma das etapas para criar
a definição de build

[ 331 ]
Como implementar e implantar a integração contínua usando o Azure DevOps

Preparação
Execute os seguintes pré-requisitos:

1. Crie uma conta do Azure DevOps.


2. Crie um projeto escolhendo Controle de Versão do Team Foundation, conforme
mostrado na seguinte captura de tela:

[ 332 ]
Capítulo 11

Como fazer isso...


Execute as seguintes etapas:

1. Navegue para a guia Pipelines em sua conta do Azure DevOps, clique em


Builds e escolha Novo pipeline para iniciar o processo de criação de uma nova
definição de build, conforme mostrado na captura de tela a seguir:

2. Na próxima etapa, clique no link Usar um designer visual, conforme mostrado


na seguinte captura de tela:

[ 333 ]
Como implementar e implantar a integração contínua usando o Azure DevOps

3. Você será levado para a tela Selecione seu repositório, em que você pode
escolher seu repositório. Para este exemplo, o meu se originou no TFVC. Como
mostrado a seguir, selecione TFVC e clique em Continuar. Verifique se você
escolheu seu projeto, que no meu caso é AzureServerlessCookBook:

4. Você será levado para a etapa Selecione um modelo, em que pode escolher o
modelo requerido para o seu aplicativo. Para esta receita, escolheremos Função
C#, como mostrado na captura de tela a seguir, clicando no botão Aplicar:

[ 334 ]
Capítulo 11

5. A etapa de criação de build é um conjunto de etapas usadas para definir o


modelo de build, em que cada etapa tem determinados atributos que precisamos
revisar e fornecer entradas para cada um desses campos com base em nossos
requisitos. Vamos começar fornecendo um nome significativo na etapa de
pipeline e também garantir que você escolha VS2017 Hospedado no menu
suspenso Pool de Agente, conforme mostrado na seguinte captura de tela:

Um agente é um software hospedado na nuvem que é


capaz de executar um build. Como nosso projeto é baseado
em VS2017, escolhemos VS2017 Hospedado.

[ 335 ]
Como implementar e implantar a integração contínua usando o Azure DevOps

6. Na etapa Obter fontes, verifique se as seguintes opções estão selecionadas:


1. Selecione o sistema de controle de versão que você gostaria de ter.
2. Escolha o repositório que você deseja compilar. No meu exemplo, escolhi
AzureServerlessCookBook:

7. Deixe as opções padrão para todas as etapas a seguir:


°° Usar NuGet e restauração do NuGet: esta etapa é necessária para fazer
download e instalar todos os pacotes necessários para o aplicativo.
°° Compilar solução: esta etapa usa o build da MS e tem todos os
comandos predefinidos para criar o build.
°° Assemblies de teste: seria útil se tivéssemos algum teste automatizado.
Faremos algumas alterações nesta etapa na receita Integração contínua –
executar casos de teste de unidade no pipeline mais adiante neste capítulo.
°° Arquivamento: esta etapa permite arquivar as pastas no formato
requerido.
°° Publicar caminho de símbolos: esses símbolos são úteis se você deseja
depurar seu aplicativo hospedado na VM do Agente.
°° Publicar artefato: a etapa tem a configuração relacionada aos artefatos
e o caminho para armazenar o artefato (pacote de build).

8. Depois de revisar todos os valores em todos os campos, clique em Salvar,


conforme mostrado na captura de tela a seguir, e clique em Salvar novamente
na janela pop-up Salvar definição de build:

[ 336 ]
Capítulo 11

Como funciona...
Uma definição de build é apenas um plano gráfico das tarefas que são necessárias
para a compilação de um aplicativo de software. Nesta receita, usamos um modelo
padrão para criar a definição de build. Podemos escolher um modelo em branco e criar
a definição escolhendo as tarefas disponíveis no Azure DevOps também.

Quando você executa a definição de build (manual ou automaticamente, que será


discutido nas próximas receitas), cada uma das tarefas será executada na ordem
em que foram configuradas. Você também pode reorganizar as etapas arrastando-as
e soltando-as na seção de pipeline.

O processo de compilação começa com a obtenção do código-fonte do repositório escolhido


e o download dos pacotes NuGet necessários e, em seguida, inicia o processo de compilação
do pacote. Quando esse processo é concluído, ele cria um pacote e o armazena em uma
pasta configurada para o diretório build.artifactstagingdirectory (consulte o campo
Caminho para publicar da tarefa Publicar artefato).

Você pode aprender sobre todos os diferentes tipos de variáveis na guia Variáveis
mostrada aqui:

[ 337 ]
Como implementar e implantar a integração contínua usando o Azure DevOps

E mais...
• O Azure DevOps fornece muitas tarefas. Você pode escolher uma nova tarefa
para o modelo clicando no botão Adicionar tarefa (+), conforme mostrado
na captura de tela a seguir:

• Se não encontrar uma tarefa que atenda às suas necessidades, você poderá
procurar uma adequada no Marketplace, clicando no botão Marketplace
mostrado na captura de tela anterior.
• A função C# tem o conjunto correto de tarefas necessárias para configurar
a definição de build para o Azure Functions também.

Integração contínua – enfileirar um build


e acioná-lo manualmente
Na receita anterior, você aprendeu como criar e configurar a definição de build. Nesta
receita, você aprenderá como acionar o build manualmente e entender o processo
de compilação do aplicativo.

Preparação
Antes de começar, verifique o seguinte:

• Você configurou a definição de build como mencionado na receita anterior


• Todo o código-fonte foi verificado no projeto de equipe do Azure DevOps

[ 338 ]
Capítulo 11

Como fazer isso...


Execute as seguintes etapas:

1. Navegue para a definição de build denominada


AzureServerlessCookBook-C# Function-CI e clique no botão Fila
disponível no lado direito, conforme mostrado na captura de tela a seguir:

2. Na janela pop-up Fila de compilação para AzureServerlessCookBook-C#


Function-CI, verifique se a opção VS2017 Hospedado está selecionada no menu
suspenso Pool de Agente, se você estiver usando o Visual Studio 2017, e clique
no botão Fila, como mostrado na seguinte captura de tela:

[ 339 ]
Como implementar e implantar a integração contínua usando o Azure DevOps

3. Em apenas alguns instantes, o build será colocado na fila e a mensagem será


exibida, conforme mostrado na seguinte captura de tela:

4. Clicar na ID do build (em nosso caso, 20181025.1) iniciará o processo e ele


aguardará alguns segundos até um agente disponível iniciá-lo.
5. Depois de alguns instantes, o processo de compilação será iniciado e, em apenas
alguns minutos, a compilação será concluída e você poderá revisar as etapas
da compilação nos logs, como mostrado aqui. Por enquanto, ignore o aviso que
é mostrado para Assemblies de teste. Corrigiremos isso na receita Integração
contínua – executar casos de teste de unidade no pipeline mais adiante neste capítulo:

[ 340 ]
Capítulo 11

6. Se você quiser ver a saída do build, clique no botão Artefatos realçado na captura
de tela a seguir. Você pode fazer download dos arquivos clicando no botão
Download como mostrado aqui:

Configurar e acionar um build


automatizado
Para a maioria dos aplicativos, talvez não faça sentido executar compilações manuais
no Azure DevOps. Isso faz sentido se podemos configurar a Integração Contínua (CI)
automatizando o processo de acionamento da compilação para cada check-in/commit
concluído pelos desenvolvedores.

Nesta receita, você aprenderá como configurar a integração contínua no Azure DevOps
para seu projeto de equipe, bem como acionar a compilação automatizada fazendo uma
alteração no código do gatilho de HTTP Azure Function que criamos no Capítulo 4,
Noções básicas sobre a experiência integrada de desenvolvedor de Ferramentas do Visual Studio.

[ 341 ]
Como implementar e implantar a integração contínua usando o Azure DevOps

Como fazer isso...


Execute as seguintes etapas:

1. Navegue para a definição de build AzureServerlessCookBook-C# Function-


CI clicando no botão Editar, conforme mostrado na captura de tela a seguir:

2. Depois que estiver na definição de build, clique no botão Gatilhos, mostrado


da seguinte maneira:

3. Agora, clique na caixa de seleção Habilitar integração contínua para habilitar


o gatilho de compilação automatizada.
4. Salve as alterações clicando na marca de seta disponível ao lado do botão
Salvar e enfileirar, e clique no botão Salvar disponível no menu suspenso,
que é mostrado na seguinte captura de tela:

[ 342 ]
Capítulo 11

5. Vamos navegar para o projeto do Azure Function no Visual Studio. Faça uma
pequena alteração na última linha do código-fonte da função Run que é mostrado
a seguir. Eu apenas substitui a palavra hello por Automated Build Trigger
test by:
return name != null ? (ActionResult)new OkObjectResult($"Automated
Build Trigger test by, { name}")
: new BadRequestObjectResult("Please pass a name on the
query string or in the request body");

6. Vamos verificar o código e confirmar as alterações feitas no controle de origem.


Como mostrado aqui, você receberá uma nova ID de conjunto de alterações
gerada. Neste caso, é Changeset 32:

7. Agora, navegue imediatamente de volta para a definição de build do Azure


DevOps para ver que um novo build foi acionado automaticamente e está
em andamento, conforme mostrado na seguinte captura de tela:

[ 343 ]
Como implementar e implantar a integração contínua usando o Azure DevOps

Como funciona...
Estas são as etapas seguidas nesta receita:

1. Habilitamos o gatilho de build automático para a definição de build


2. Fizemos uma alteração na base de código e a verificamos no TFVC
3. Automaticamente, uma nova compilação foi acionada no Azure DevOps;
compilações imediatamente após o código são confirmadas para o TFVC

E mais...
Se você quiser restringir para que os desenvolvedores verifiquem o código somente após
uma compilação bem-sucedida, será necessário habilitar gated-check-in. Para habilitar
isso, edite a definição de build e navegue para a guia Gatilhos e Habilitar check-in
restrito, conforme mostrado na seguinte captura de tela:

Agora, volte para o Visual Studio e faça algumas alterações no código. Se você tentar
fazer check-in do código sem compilar o aplicativo no Visual Studio, receberá um alerta,
conforme mostrado aqui:

[ 344 ]
Capítulo 11

Clique em Alterações da Compilação na etapa anterior para iniciar a compilação


no Visual Studio. Assim que a compilação no Visual Studio estiver concluída, o código
será verificado no Azure DevOps e, em seguida, uma nova compilação será acionada
automaticamente, conforme mostrado aqui:

Integração contínua – executar casos


de teste de unidade no pipeline
Uma das etapas mais importantes em qualquer metodologia de desenvolvimento de
software é gravar testes de unidade automatizados que validem a exatidão do nosso
código. Também é importante que executemos esses testes de unidade sempre que
o desenvolvedor libera um novo código para fornecer cobertura de código de teste.

Nesta receita, aprenderemos a incorporar o processo de compilação dos testes de unidade


que desenvolvemos na receita Desenvolvimento de testes de unidade para o Azure Functions
com gatilhos HTTP do Capítulo 5, Exploração de ferramentas de teste para a validação do Azure
Functions.

[ 345 ]
Como implementar e implantar a integração contínua usando o Azure DevOps

Como fazer isso…


Execute as seguintes etapas:

1. Na receita Integração contínua – criar uma definição de build deste capítulo,


utilizamos um modelo de compilação que tinha as etapas Compilar solução
e compilar Assemblies de Teste, conforme mostrado na seguinte captura de tela:

2. Clique em Assemblies de Teste, como mostrado na captura de tela anterior.


Substitua a configuração padrão por aquela fornecida aqui, no campo
Arquivos de teste:
**\$(BuildConfiguration)\**\*test*.dll
!**\obj\**
!**\*TestAdapter.dll

3. As definições de configuração anteriores permitem que o executor de teste


faça o seguinte:
°° Procure qualquer arquivo .dll que contenha a palavra Teste em seu
nome que esteja localizado na pasta release em qualquer lugar nos
artefatos. Você pode estar se perguntando onde release aparece na
imagem. É o valor da variável $(BuildConfiguration) na seção
Variáveis mostrada na seguinte captura de tela:

[ 346 ]
Capítulo 11

°° Ignore todos os arquivos .dll na pasta obj, pois nosso objetivo


é trabalhar apenas nos arquivos .dll localizados dentro da pasta
release.

4. É isso. Vamos agora colocar o build em fila clicando no botão Enfileirar depois
de salvar as alterações. Depois de alguns minutos, o pipeline de build é aprovado
sem nenhum aviso, conforme mostrado na seguinte captura de tela:

[ 347 ]
Como implementar e implantar a integração contínua usando o Azure DevOps

5. Aqui está o resumo dos casos de teste. Você pode ver o gráfico que mostra
a porcentagem dos casos de teste que foram aprovados e reprovados:

E mais...
Se você seguiu todas as convenções de nomenclatura de acordo com as instruções,
não enfrentará problemas com esta receita. No entanto, se você tiver usado um nome
diferente para o projeto de unidade e se não tiver usado a palavra test em nenhum
lugar no nome do projeto (que é o mesmo nome do arquivo .dll gerado), sinta-se
à vontade para alterar o formato na seguinte configuração:
**\$(BuildConfiguration)\**\*whateverwordyouhaveinthenameofthedllfi
le*.dll

Na receita, você usou *, ** e !, que são chamados de padrões de correspondência


de arquivos. Saiba mais sobre os padrões de correspondência de arquivos em https://
docs.microsoft.com/en-us/azure/devops/pipelines/tasks/file-matching-
patterns?view=vsts.

Criar uma definição da versão


Agora que sabemos como criar uma definição de build e acionar uma compilação
automatizada no Azure DevOps: pipelines, nossa próxima etapa é liberar ou implantar
o pacote em um ambiente em que os stakeholders do projeto podem revisá-lo e fornecer
comentários. Para fazer isso, primeiro precisamos criar uma definição da versão
da mesma forma que criamos as definições de build.

[ 348 ]
Capítulo 11

Preparação
Usei o novo editor de definição da versão para visualizar os pipelines de implantação.
O editor de definição da versão ainda está em visualização. No momento em que você
ler isso, se ele ainda estiver em visualização, você poderá habilitá-lo clicando na imagem
do perfil e, em seguida, clicando no link Recursos de visualização, como mostrado
na seguinte captura de tela:

Em seguida, você pode habilitar o novo editor de definição da versão, conforme


mostrado na seguinte captura de tela:

Vamos começar criando uma nova definição da versão.

[ 349 ]
Como implementar e implantar a integração contínua usando o Azure DevOps

Como fazer isso...


Execute as seguintes etapas:

1. Navegue para a guia Versões, conforme mostrado na captura de tela a seguir,


e clique Novo Pipeline:

2. A próxima etapa é escolher um modelo de Definição da versão. Na janela pop-


up Selecione um modelo, selecione Implantação do Serviço de Aplicativo do
Azure e clique no botão Aplicar, conforme mostrado na captura de tela a seguir.
Logo depois de clicar no botão Aplicar, uma nova janela pop-up do ambiente
(estágio) será exibida. Por enquanto, apenas feche a janela pop-up Ambiente:

[ 350 ]
Capítulo 11

3. Clique no botão Adicionar disponível na caixa Artefatos para adicionar


um novo artefato, conforme mostrado na captura de tela a seguir:

[ 351 ]
Como implementar e implantar a integração contínua usando o Azure DevOps

4. Na janela pop-up Adicionar um artefato, verifique se você escolheu o seguinte:


1. Tipo de origem: Build
2. Projeto: o projeto de equipe ao qual seu código-fonte está vinculado
3. Origem (definição de build): o nome da definição de build em que
seus builds são criados
4. Versão padrão: Mais recente

5. Depois de revisar todos os valores na página, clique no botão Adicionar para


adicionar o artefato.
6. Depois que o artefato é adicionado, a próxima etapa é configurar os estágios,
onde o pacote precisa ser publicado. Clique no link 1 fase, 1 tarefa, mostrado
na captura de tela a seguir. Além disso, altere o nome da definição da versão
para release-def-stg:

[ 352 ]
Capítulo 11

7. Você será levado para a guia Tarefas, mostrada a seguir. Forneça um nome
significativo para o campo Nome do estágio. Eu forneci o nome Ambiente
de Preparo para este exemplo. Em seguida, escolha a assinatura do Azure
na qual você gostaria de implantar o Azure Function. Será necessário clicar
no botão Autorizar para fornecer as permissões, como mostrado aqui:

[ 353 ]
Como implementar e implantar a integração contínua usando o Azure DevOps

8. Depois de autorizar a assinatura, você precisa garantir que escolheu o Tipo


de aplicativo para ser Aplicativo de Função e, em seguida, escolha o nome
do aplicativo de função no Nome do Serviço de Aplicativo para o qual você
deseja implantar o pacote, como mostrado aqui:

Se você não vir sua assinatura ou serviço de aplicativo,


atualize o item clicando no ícone que está disponível
após o botão Autorizar da captura de tela acima.

9. Clique no botão Salvar para salvar as alterações. Agora, vamos usar esta
definição da versão e tentar criar uma nova versão clicando em Criar versão,
como mostrado na seguinte captura de tela:

[ 354 ]
Capítulo 11

10. Em seguida, você será levado para a janela pop-up Criar uma nova versão, em
que poderá configurar a definição de build que precisa ser usada. Como temos
apenas uma, podemos ver apenas uma definição de build. Você também precisa
escolher a versão certa do build, como mostrado aqui. Depois de revisá-la, clique
no botão Criar para colocar a versão na fila:

[ 355 ]
Como implementar e implantar a integração contínua usando o Azure DevOps

11. Clicar no botão Criar na etapa anterior levará você para a etapa a seguir. Clique
no botão Implantar preparo como mostrado aqui para iniciar o processo
de implantação da versão:

12. Agora, será solicitado que você revise os artefatos associados. Depois de revisá-
los, clique no botão Implantar, como mostrado aqui:

[ 356 ]
Capítulo 11

13. Imediatamente, o processo começará e mostrará Em andamento para indicar


o progresso da versão, como mostrado aqui:

[ 357 ]
Como implementar e implantar a integração contínua usando o Azure DevOps

14. Clique nos links Em andamento mostrados na captura de tela anterior para
revisar o andamento. Como mostrado a seguir, o processo de versão foi
bem-sucedido:

Como funciona...
Na guia Pipeline, criamos artefatos e um ambiente denominado preparo e os vinculamos
juntos.

Também configuramos o ambiente para ter o Serviço de Aplicativo do Azure relacionado


ao Azure Functions que criamos no Capítulo 4, Noções básicas sobre a experiência integrada
de desenvolvedor de Ferramentas do Visual Studio.

E mais...
Se você estiver configurando a implantação contínua pela primeira vez, poderá ver um
botão com o Autorizar na etapa de Implantação do Serviço de Aplicativo do Azure.
Clicar no botão Autorizar abrirá uma janela pop-up em que será solicitado que você
forneça suas credenciais do portal de Gerenciamento do Azure.

Você pode renomear o pipeline de versão clicando no nome na parte superior, como
mostrado aqui:

[ 358 ]
Capítulo 11

Atualmente, há um modelo específico para o Azure Functions, mostrado a seguir. No


entanto, parece que não está funcionando. Quando ler este livro, você provavelmente
deverá testar:

Consulte também
A receita Implantação do aplicativo Azure Functions para a Nuvem do Azure usando o Visual
Studio do Capítulo 4, Noções básicas sobre a experiência integrada de desenvolvedor de
Ferramentas do Visual Studio.

[ 359 ]
Como implementar e implantar a integração contínua usando o Azure DevOps

Acionar a versão automaticamente


Nesta receita, você aprenderá como configurar a implantação contínua para um
ambiente. Em seu projeto, você pode configurar o desenvolvimento/preparo ou qualquer
outro ambiente de pré-produção, bem como configurar a implantação contínua para
simplificar o processo de implantação.

Em geral, não é recomendável configurar a implantação contínua para um ambiente


de produção. No entanto, isso pode depender de vários fatores e requisitos. Tenha
cuidado e pense em vários cenários antes de configurar a implantação contínua para
seu ambiente de produção.

Preparação
Faça download e instale a ferramenta Postman, se ainda não tiver instalado.

Como fazer isso...


Execute as seguintes etapas:

1. Por padrão, as versões são configuradas para serem enviadas manualmente.


Vamos configurar a Implantação Contínua navegando de volta para a guia
Pipeline e clicando no Gatilho de implantação contínua, como mostrado
na captura de tela a seguir:

[ 360 ]
Capítulo 11

2. Como mostrado na captura de tela a seguir, habilite o Gatilho de implantação


contínua e clique em Salvar para salvar as alterações:

3. Navegue para o Visual Studio e faça algumas alterações de código, como


realçado aqui:
return name != null ? (ActionResult)new OkObjectResult($"Automated
Build Trigger and Release test by, { name}")
: new BadRequestObjectResult("Please pass a name on the
query string or in the request body");

4. Agora, faça check-in do código com um comentário, Implantação Contínua, para


confirmar as alterações no Azure DevOps. Assim que fizer o check-in do código,
navegue para a guia Builds para ver se um novo build foi acionado, como
mostrado na seguinte captura de tela:

[ 361 ]
Como implementar e implantar a integração contínua usando o Azure DevOps

5. Navegue para a guia Versões depois que a compilação for concluída para
ver se uma nova versão foi acionada automaticamente, conforme mostrado
na captura de tela a seguir:

6. Depois que o processo de versão for concluído, você poderá revisar a alteração
fazendo uma solicitação ao Gatilho HTTP usando a ferramenta Postman:

Como funciona...
Na guia Pipeline, habilitamos o Gatilho de implantação contínua.

Sempre que um build associado a AzureServerlessCookBook-C# Function-CI


é  acionado, a versão Livro de receitas da computação sem servidor do Azure
será acionada automaticamente para implantar o build mais recente para o ambiente
designado. Nós também vimos a versão automática em ação ao fazer uma alteração
de código no Visual Studio.

E mais...
Você também pode criar vários ambientes e configurar as definições para liberar os builds
requeridos para esses ambientes.

[ 362 ]
Outros livros que você pode gostar
Se você gostou deste livro, você pode se interessar por estes outros livros da Packt:

Architecting Microsoft Azure Solutions – Exam Guide 70-535 (Arquitetar soluções


do Microsoft Azure – Guia de exame 70-535)
Sjoukje Zaal
ISBN: 978-1-78899-173-5
ff Usar Máquinas Virtuais do Azure para projetar implantações de VM eficazes
ff Implementar estilos de arquitetura, como computação sem servidor
e microsserviços
ff Proteger dados usando diferentes recursos de segurança e desenvolver
estratégias de segurança eficazes
ff Desenvolver soluções de armazenamento do Azure usando vários recursos
de armazenamento
ff Criar soluções de gerenciamento de identidade para aplicativos e recursos
ff Arquitetar soluções de última geração usando Inteligência Artificial,
IoT e Serviços de Mídia do Azure
ff Usar diferentes soluções de automação que sejam incorporadas na plataforma do Azure

[ 363 ]
Outros livros que você pode gostar

Hands-On Linux Administration on Azure (Administração prática do Linux no Azure)

Frederik Vos

ISBN: 978-1-78913-096-6

ff Entender por que o Azure é a solução ideal para seus workloads de open source
ff Dominar habilidades essenciais do Linux e aprender a descobrir o seu caminho
no ambiente Linux
ff Implantar o Linux em um ambiente do Azure
ff Usar o gerenciamento de configuração para gerenciar o Linux no Azure
ff Gerenciar contêineres em um ambiente do Azure
ff Melhorar a segurança do Linux e usar os sistemas de gerenciamento
de identidade do Azure
ff Automatizar a implantação com o Azure Resource Manager (ARM)
e o PowerShell
ff Usar o Ansible para gerenciar instâncias do Linux em um ambiente de nuvem
do Azure

[ 364 ]
Outros livros que você pode gostar

Deixe um comentário - deixe outros


leitores saberem o que você pensa
Compartilhe suas opiniões sobre este livro com outras pessoas deixando um comentário
no site que você comprou. Se você comprou o livro na Amazon, deixe um comentário
honesto na página da Amazon sobre este livro. Isso é essencial para que outros possíveis
leitores possam ler e usar sua opinião imparcial para tomar decisões de compra, para
que possamos entender o que nossos clientes pensam sobre nossos produtos e para que
nossos autores possam ver seus comentários sobre o livro no qual eles têm trabalhado
junto com a Packt. Levará apenas alguns minutos do seu tempo, mas será valioso para
outros possíveis clientes, para nossos autores e para a Packt. Obrigado!

[ 365 ]

Você também pode gostar