Cloud Computing com o Windows Azure - Revista Infra Magazine 2

Neste artigo veremos as principais características do padrão computacional conhecido como cloud computing. Em seguida, será apresentada a iniciativa disponibilizada pela Microsoft dentro deste segmento: a plataforma Windows Azure.

De que se trata o artigo: Neste artigo veremos as principais características do padrão computacional conhecido como cloud computing. Em seguida, será apresentada a iniciativa disponibilizada pela Microsoft dentro deste segmento: a plataforma Windows Azure.

Para que serve: Soluções de cloud computing possibilitam, através da Internet, o compartilhamento de recursos computacionais como infraestrutura de servidores ou armazenamento de dados, por exemplo. Tais serviços são cobrados por parte das empresas provedoras com base nos níveis de utilização dos mesmos. A plataforma Windows Azure da Microsoft se encaixa neste perfil.

Em que situação o tema será útil: A adoção de uma solução de cloud computing pode ser de grande valia para as organizações. Dentre os motivos que podem levar ao emprego deste tipo de arquitetura, pode ser citada a busca por uma maior flexibilidade para as operações de TI, assim como a redução de custos com pessoal especializado, hardware e software.

É inegável a importância atual da Tecnologia da Informação para o mundo dos negócios. O ambiente empresarial exige que novas soluções de software sejam desenvolvidas frequentemente, assim como aplicações já existentes se adaptem a mudanças. Tudo isto busca garantir a continuidade de uma organização ou, ainda, possibilitar meios para o aproveitamento de oportunidades ainda inexploradas.

Uma gama de sistemas exige, contudo, vultosos e constantes investimentos em infraestrutura de hardware e suporte. Além disso, diversos requisitos como disponibilidade, segurança e escalabilidade, devem ser levados em consideração.

Atentos a isto, grandes fornecedores de soluções de tecnologia desenvolveram serviços computacionais que podem ser utilizados por outras companhias, mediante prévio acordo entre as partes. Este modelo de serviço recebe o nome de cloud computing ou “computação nas nuvens”.

A plataforma Azure, objeto de estudo deste artigo, representa a solução da Microsoft para este segmento e procura, através de uma série de serviços, oferecer uma solução flexível e que seja, ao mesmo tempo, de fácil implementação.

Cloud computing: uma visão geral

O termo cloud computing ou “computação nas nuvens” é definido, em termos gerais, como um modelo em que recursos computacionais são compartilhados através da Internet por provedores de serviços especializados.

Tais recursos, por sua vez, são oferecidos por meio de uma abordagem em que se cobra pelo nível de uso dos mesmos, mediante acordo prévio estabelecido entre fornecedor e a empresa contratante.

Os diversos tipos de serviços existentes podem ser classificados nas seguintes categorias:

Soluções On-premise x Off-premise

Serviços computacionais e aplicações corporativas, levando-se em conta o paradigma de “computação nas nuvens”, podem ser classificados em:

Vantagens e pontos de atenção

Dentre os benefícios normalmente almejados e que podem levar, por sua vez, uma empresa a investir em soluções de cloud computing, convém destacar:

Sendo assim, ao contratar uma solução de cloud computing, uma organização deverá levar em conta aspectos como:

Plataforma Windows Azure

A plataforma Windows Azure é uma solução de cloud computing lançada oficialmente pela Microsoft em Outubro de 2008. O objetivo da mesma é prover uma estrutura escalável e baseada na Internet, facilitando para tanto o processo de criação e implantação de aplicações e serviços na “nuvem”.

O ambiente de desenvolvimento Microsoft Visual Studio .Net possui amplo suporte para a concepção e disponibilização de aplicativos na “nuvem”, com uma abordagem que em nada difere daquela utilizada com softwares on-premise. Tudo isto possibilita um maior foco na criação de soluções, diminuindo assim a preocupação com detalhes de infraestrutura.

Esta plataforma é composta por três serviços principais:

Estes três serviços podem tanto ser empregados separadamente no desenvolvimento de novas soluções, quanto combinados, conferindo assim flexibilidade na sua utilização. O acesso aos mesmos ocorre através da criação de uma conta no Windows Live Id, além da vinculação desta última a cada um dos serviços desejados, mediante acesso ao site dos mesmos.

É importante ressaltar ainda, a possibilidade de se escolher em qual data center aplicações ou dados serão hospedados, técnica esta conhecida como geolocalização. Tal necessidade pode surgir em virtude de razões legais que obriguem o armazenamento de dados numa determinada localidade, fatores políticos ou mesmo questões de performance (uma aplicação executando numa maior proximidade geográfica de dados dos quais depende, por exemplo).

Como é de praxe entre os fornecedores de soluções de cloud computing, o custo de utilização da plataforma Azure dependerá dos serviços que foram contratados por um cliente, assim como do nível de utilização dos mesmos. O portal do Windows Azure na Internet possui mais detalhes a respeito disso.

Sistema Operacional Windows Azure

O sistema operacional Windows Azure pode ser considerado como um ambiente virtual, funcionando como uma “camada na nuvem”. O mesmo é executado em múltiplas máquinas configuradas com o Windows Server 2008 R2. Tais equipamentos contam, por sua vez, com a tecnologia Hyper-V de suporte à virtualização, situados em data centers da Microsoft.

É importante mencionar que o Windows Azure funciona como uma abstração do hardware envolvido no processo, ocultando detalhes físicos das aplicações e serviços hospedados na “nuvem”. Além disso, encontra-se dividido em três componentes principais:

A Figura 1 representa a arquitetura do sistema operacional Windows Azure, incluindo os diversos serviços que o constituem.

Figura 1. Arquitetura do Sistema Operacional Windows Azure.

Componente Compute

O componente Compute permite a hospedagem e a execução de aplicações na “nuvem”, utilizando-se da plataforma de 64 bits com a tecnologia Hyper-V, oferecida pelo Windows Server 2008.

Um dos objetivos principais da plataforma Azure é permitir um grande número de usuários simultâneos. Isso é possível através da criação de diversas instâncias para uma mesma aplicação, com cada uma destas executando sua própria VM (virtual machine). Cada VM, por sua vez, conta com um componente chamado Agent, que trabalha em estreita ligação com o Fabric Controller (este último é responsável pelo controle da infraestrutura e do ciclo de vida das instâncias criadas).

Este serviço permite a execução de dois tipos de aplicações (roles):

Web Roles, portanto, devem ser desenvolvidas como stateless, ou seja, sem manter informações de estado de um cliente. Tais informações, quando necessárias, serão persistidas no serviço de Storage da plataforma Azure ou, ainda, devolvidas instantaneamente a cada requisição. Isto se deve ao fato de ser impossível associar diversas requisições de um usuário a uma mesma instância de uma aplicação, já que o mecanismo de balanceamento de carga, empregado no tratamento das solicitações, não suporta este comportamento.

Desenvolvedores podem criar soluções que utilizem cada um dos tipos de roles definidos ou que combinem a utilização de ambos.

Componente Storage

O componente Storage da plataforma Azure possibilita o armazenamento de dados na “nuvem”, bem como o acesso posterior aos mesmos, estando dividido em três serviços: Blob, Queue e Table.

Para se utilizar cada um dos tipos de Storage, deve-se fornecer uma conta de acesso e gerar requisições que atendam ao padrão REST por meio de uma API específica para cada serviço.

Em REST dados são representados por endereços únicos, através do uso de URLs. Um endereço único, por sua vez, é constituído por informações de identificação do dado no serviço de Storage, pela operação que se deseja efetuar sobre o mesmo e, ainda, pelo código da conta de acesso ao serviço.

O serviço Blob representa a forma mais simples de armazenamento, envolvendo a manipulação de dados binários (imagens, áudio, vídeos, etc.) sob a forma de arquivos. Blobs são agrupados logicamente em containers, podendo estes serem públicos (acessíveis para qualquer usuário) ou privados (visíveis somente ao proprietário da conta de acesso).

Existem dois tipos de Blobs:

A principal função do serviço Queue é fornecer meios para a comunicação assíncrona entre aplicações, através da troca de mensagens entre as mesmas. Embora o uso de queues (filas) sugira um comportamento restrito seguindo o padrão FIFO (First In First Out), não existe nenhuma garantia quanto à ordem de recebimento das mensagens dentro do sistema operacional Windows Azure. Além disso, uma mensagem não pode exceder o tamanho de 8 KB.

Queues representam um destino lógico para o envio de mensagens, ao passo que estas últimas, por sua vez, podem conter instruções e outras informações em formato texto ou mesmo binário.

Um uso possível para queues seria na comunicação entre instâncias Web Role e Worker Role de uma aplicação:

O serviço Table possibilita o armazenamento de dados na “nuvem” sob a forma de tabelas. No entanto, o formato deste tipo de estrutura no Windows Azure difere bastante daquele existente em bancos de dados relacionais.

Uma tabela criada no ambiente de Storage é formada por um conjunto de entidades, com cada uma destas possuindo várias propriedades. Tais propriedades, por sua vez, podem ser do tipo String, DateTime, Binary, Bool, GUID, Int ou Int64.

Toda entidade conta, obrigatoriamente, com três propriedades:

O conteúdo das propriedades PartitionKey e RowKey pode ser definido livremente pelos desenvolvedores de uma aplicação.

A forma como uma tabela encontra-se estruturada no Azure permite à mesma armazenar terabytes de dados sob a forma de entidades. Já estas últimas, de acordo com o valor da PartitionKey, podem estar particionadas em diversos servidores, como uma maneira de aumentar a performance no acesso a dados. Para acessar uma tabela as aplicações farão de forma transparente, sem a necessidade de conhecer em quais partições estão as entidades a serem manipuladas.

O acesso às tabelas de Storage do Azure não é realizada de maneira convencional (usando um driver/framework de acesso, além de instruções SQL), mas através de frameworks como ADO.NET Data Services ou LINQ (Language Integrated Query), os quais são capazes de se comunicar com o serviço Table via padrão REST.

Componente Management

O componente Management controla toda a infraestrutura básica, bem como oferece recursos de monitoramento das aplicações que se encontram na “nuvem”. O hardware envolvido para a execução de uma aplicação ou serviço abrange servidores, switches, roteadores, equipamentos de balanceamento de carga, dentre outras estruturas. O controle de tais dispositivos ocorre através de um software denominado Fabric Controller.

É responsabilidade também deste componente o gerenciamento de todo o ciclo de vida de uma solução na “nuvem”, permitindo aos serviços Compute e Storage atuar sem preocupações diretas com aspectos físicos.

Ademais, arquivos de configuração, específicos para cada aplicação implantada na rede, contêm parâmetros que orientam as ações do Fabric Controller (quantas instâncias de uma role deverão ser criadas e mantidas, por exemplo).

Constituem atribuições do Fabric Controller atividades como:

É possível ainda, dentro do serviço Management, a utilização de técnicas customizadas de log, tracing e monitoramento de nível do uso de aplicações.

AppFabric

O Windows Azure Platform AppFabric tem por função principal conectar aplicações e serviços, independentemente dos mesmos estarem na “nuvem” ou serem soluções on-premise. Todavia, não deve ser confundido com o componente Fabric do sistema operacional Windows Azure.

Diante destas características, é possível integrar aplicações nas mais diferentes plataformas, a exemplo do Windows Azure, Windows Server, Java, Ruby, PHP.

O componente AppFabric é constituído por dois serviços principais: Access Control e Service Bus.

Serviço Access Control

O serviço Access Control oferece mecanismos para o controle de acesso (autorização) em aplicações distribuídas, podendo estas últimas tanto representarem serviços na “nuvem”, quanto soluções on-premise. Possibilita ainda a utilização de protocolos como REST, certificados X.509, recursos de Active Directory, dentre outros.

Existem dois métodos possíveis para se gerenciar o acesso:

A Figura 2 apresenta um exemplo de integração entre aplicações, utilizando o serviço Access Control, com um token sendo gerado para a aplicação cliente consumir o serviço de que necessita; esta última, por sua vez, compartilha com o Access Control uma chave com prazo de validade, que serve de base à validação do token.

Figura 2. Serviço Access Control.

Service Bus

O componente Service Bus representa, dentro da solução de cloud computing da Microsoft, a implementação do padrão de arquitetura conhecido como ESB (Enterprise Service Bus). Tem, por objetivo principal, possibilitar meios para uma conexão segura e de baixo acoplamento entre sistemas de software, permitindo aos mesmos superar barreiras que seriam impostas por firewalls ou outros dispositivos de hardware / software.

Permite ainda o uso de variados protocolos de comunicação no processo de integração entre aplicações, possibilitando a troca de informações entre softwares desenvolvidos nas mais variadas plataformas (Java, .Net, mainframe, etc.). HTTP, HTTPS, TCP, SOAP, MSMQ (Microsoft Message Queuing) e REST são alguns dos padrões disponíveis para utilização.

Serviços on-premise ou situados na “nuvem”, podem ser registrados sob a forma de “endpoints” (endereços de acesso) no Service Bus. Uma aplicação que deseja consumir as funcionalidades oferecidas por um endpoint envia requisições ao mesmo, enquanto o Service Bus redireciona as chamadas aos endereços reais, devolvendo posteriormente os resultados a quem o invocou.

A compatibilidade entre o fornecedor e o consumidor de um conjunto de funcionalidades é assegurada, basicamente, através do uso de contratos (interfaces) detalhando as operações disponíveis; “schemas” descrevem a estrutura dos dados envolvidos na troca de mensagens entre aplicação-cliente e serviço.

A referida técnica oferece maior segurança, visto que o endereço real de um serviço registrado no Service Bus estará, forçosamente, oculto àqueles que venham a utilizar as operações do mesmo. O uso em conjunto com o componente Access Control do AppFabric tornará este processo ainda mais seguro.

Outro benefício desta metodologia consiste na facilidade em se descobrir serviços e capacidades destes, em virtude dos mesmos terem sido disponibilizados anteriormente através de endpoints.

A Figura 3 apresenta, de maneira simplificada, o funcionamento do Service Bus dentro da plataforma Azure.

Figura 3. Service Bus.

SQL Azure

O SQL Azure é um conjunto de serviços da plataforma de cloud computing da Microsoft, que procura, essencialmente, fornecer as capacidades de um sistema de gerenciamento de banco de dados relacional. Para tanto, o mesmo foi construído tomando por base o produto Microsoft SQL Server.

Dentre os principais benefícios deste componente da plataforma Azure, vale a pena destacar:

O principal serviço dentro do SQL Azure chama-se SQL Azure Database (SAD). O SAD representa o meio através do qual ocorre a persistência de dados seguindo o modelo relacional.

No momento, os principais recursos de T-SQL como tabelas, índices, views, stored procedures, triggers e constraints podem ser utilizados sem restrições.

O diagrama representado na Figura 4 apresenta dois cenários de utilização do SQL Azure: aplicações na nuvem (Web e Worker roles) acessando o banco de dados, assim como uma aplicação on-premise externa.

Figura 4. Aplicações acessando o SQL Azure.

Outras soluções de cloud computing

Além do Windows Azure, merecem destaque como soluções de cloud computing as seguintes plataformas:

No Brasil, a LocaWeb, companhia de destaque no segmento de hospedagem de aplicações, também disponibiliza uma solução de cloud computing. Além dela, a operadora Telefônica, em parceria com a empresa de tecnologia NEC, anunciou desde o início de 2010, planos em que este tipo de serviço seria oferecido futuramente.

Análise de casos

Diversas empresas, nos mais variados segmentos de atuação, já fazem uso de soluções de cloud computing na plataforma Azure, a exemplo de 3M, Siemens e Kia Motors, grandes companhias de atuação global, que alcançaram sucesso.

Caso 1: 3M

Um dos projetos da 3M, denominado Visual Attention Service (VAS), consistia em uma aplicação Web que tornava possível a designers estimar, através de uma série de algoritmos de previsão, como suas criações poderiam ser vistas pelo tipo de audiência a que se destinavam.

Tais criações envolveriam desde a concepção de um logotipo, a um Web site ou, ainda, o local em que um painel eletrônico seria posicionado no lobby de um hotel. A partir de imagens, o serviço VAS pode sugerir (por meio de marcações) quais áreas do objeto em análise podem ser mais facilmente visualizadas e lembradas por um grupo de espectadores.

Buscando alta performance e disponibilidade, além de evitar vultosos investimentos em servidores e armazenamento, a 3M optou pela utilização da plataforma Azure. A aplicação resultante utiliza o .Net Framework, juntamente com os componentes, da plataforma Azure, a saber, o sistema operacional Windows Azure, Service Bus, Access Control Service e SQL Azure.

Caso 2: Siemens

Conhecido como cRSP (common Remote Service Platform), é um dos serviços desenvolvidos pela divisão de Tecnologia da Informação da Siemens. Trata-se de um sistema de serviços remotos, cujo gerenciamento utiliza uma grande infraestrutura disponibilizada por três data centers ao redor do globo.

A plataforma cRSP, utilizada pela Siemens, fornece suporte a mais de 80 mil dispositivos espalhados pelo mundo, permitindo que qualquer um destes equipamentos receba remotamente, via conexões VPN Virtual Private Network), atualizações ou mesmo novas distribuições de software.

Em busca de mais agilidade, segurança, alta disponibilidade, redução de custos e complexidade, bem como de escalabilidade na utilização dos recursos, a companhia optou por utilizar a solução de cloud computing oferecida pela plataforma Azure. A nova solução de distribuição de software foi implementada empregando-se o .Net Framework 3.5, em conjunto com as tecnologias SQL Server, SQL Azure e Windows Azure. O armazenamento de pacotes de software a serem distribuídos ocorre por meio do uso conjunto do serviço Blob com o SQL Azure.

Caso 3: Kia Motors

Com o objetivo de promover o novo automóvel da companhia (o utilitário esportivo Kia Sorento 2011), a subsidiária norte-americana da Kia Motors decidiu pela veiculação de um comercial televisivo durante a final do campeonato de futebol americano (Super Bowl), em 7 de Fevereiro de 2010. No anúncio, possíveis consumidores eram estimulados a realizar um test-drive no veículo, devendo para isto efetuar a inscrição em um site promocional.

A campanha em questão tinha duração prevista para três meses. A organização pretendia evitar investimentos estimados em 100 mil dólares apenas com hardware, infraestrutura esta que entraria em desuso dado o caráter temporário da promoção.

Optou-se, assim, pelo desenvolvimento de uma solução utilizando o .Net Framework 3.5, com as tecnologias ASP.Net, SQL Azure e Windows Azure (sistema operacional). Inicialmente, o Web site criado contaria com 100 instâncias Web Role, com a possibilidade de se aumentar este número à medida que o número de acessos fosse aumentando. A referida estratégia permitiu que se atingisse o objetivo inicial: um recurso facilmente escalável e de baixo custo.

Desenvolvimento de aplicações com o Azure

O desenvolvimento de aplicações voltadas à plataforma Azure requer a instalação dos seguintes componentes:

O Windows Azure SDK encontra-se atualmente (Abril/2011) na versão 1.4, possuindo dois componentes para simulação de um ambiente de cloud computing em desenvolvimento:

Exemplo de utilização do Windows Azure

O desenvolvimento das aplicações apresentadas neste artigo foi realizado através da utilização do Microsoft Visual Studio 2010 Ultimate Edition, além da versão 1.2 dos pacotes Windows Azure SDK e Windows Azure Tools for Visual Studio.

O exemplo a seguir tem por objetivo demonstrar:

Utilizando o Development Storage

O serviço de armazenamento local pode ser executado a partir do menu Iniciar do Windows, acessando-se para isto o submenu Windows Azure SDK e, em seguida, a opção Development Storage.

A Figura 5 apresenta este serviço já em execução (nota-se que ao lado do status de cada serviço há o endereço/endpoint para o envio de requisições ao mesmo).

Figura 5. Development Storage.

Para testar o serviço Table do Development Storage, se faz necessário criar uma solução no Visual Studio chamada GeracaoDadosAzure. O objetivo da mesma é a gravação de dados fictícios sobre ações negociadas em Bolsas de Valores. Esta solução será composta, por sua vez, pelos seguintes projetos:

Na Figura 6 é apresentada a estrutura da solução GeracaoDadosAzure dentro do Visual Studio, assim que o desenvolvimento da mesma tenha sido concluído.

Figura 6. Estrututura da solução GeracaoDadosAzure.

O projeto StorageClient foi baixado através do site da Microsoft, tendo sido adicionada uma referência ao mesmo na solução aqui apresentada.

Exemplo.Cloud.Entities é um projeto do tipo Class Library. No mesmo foi criada a classe AcaoEntity a qual define, por sua vez, a estrutura da entidade ação utilizada neste exemplo.

AcaoEntity (que está detalhada na Listagem 1) implementa a classe abstrata TableStorageEntity, sendo esta última a representação de uma entidade (linha) numa tabela. TableStorageEntity está definida dentro do projeto StorageClient, contando com as propriedades PartitionKey, RowKey e Timestamp. Convém ressaltar que estas três propriedades são obrigatórias para toda estrutura criada no serviço Table.

Listagem 1. Código da classe AcaoEntity.


  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using Microsoft.Samples.ServiceHosting.StorageClient;
   
  namespace Exemplo.Cloud.Entities
  {
      public class AcaoEntity : TableStorageEntity
      {
          public AcaoEntity()
              : base()
          {
              this.Timestamp = DateTime.Now;
          }
   
          public DateTime DataCotacao { get; set; }
          public String NomeEmpresa { get; set; }
          public String Moeda { get; set; }
          public Double ValorAtualAcao { get; set; }
          public Double ValorAnterior { get; set; }
          public Double PercentualVariacao { get; set; }
      }
  }

O projeto Exemplo.Cloud.DataAccess, também uma Class Library, contém a classe AcaoDataServiceContext. A mesma é responsável por fornecer os métodos que possibilitam a manipulação de entidades correspondentes a ações.

TableStorageDataService é uma classe abstrata implementada por AcaoDataServiceContext, estando definida no projeto StorageClient. Esta classe disponibiliza, por meio de uma série de operações, mecanismos de acesso aos dados contidos no serviço Table do componente de Storage.

AcaoDataServiceContext, definida na Listagem 2, faz uso do tipo AcaoEntity, que está contido no projeto Exemplo.Cloud.Entities. Utiliza ainda as seguintes classes definidas em StorageClient:

Listagem 2. Código da classe AcaoDataServiceContext.


  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Data.Services.Client;
  using Microsoft.Samples.ServiceHosting.StorageClient;
  using Exemplo.Cloud.Entities;
   
  namespace Exemplo.Cloud.DataAccess
  {
      public class AcaoDataServiceContext : 
          TableStorageDataServiceContext
      {
          private const string TableName = "AcaoTable";
          private StorageAccountInfo accountInfo;
   
          public AcaoDataServiceContext(
              StorageAccountInfo accountInfo)
              : base(accountInfo)
          {
              this.accountInfo = accountInfo;
          }
   
          public void CriarTabela()
          {
              TableStorage ts = 
                  TableStorage.Create(this.accountInfo);
              if (!ts.DoesTableExist(
                   AcaoDataServiceContext.TableName))                      
                  ts.CreateTable(
                      AcaoDataServiceContext.TableName);
              else
                  throw new Exception(
                      "Tabela de ações já criada");
          }
   
          public void IncluirAcao(AcaoEntity acao)
          {
              this.AddObject(
                  AcaoDataServiceContext.TableName, acao);
              this.SaveChanges();
          }
   
          public List<AcaoEntity> ListarAcoesPorBolsa(
              string codigoBolsaValores)
          {
              var resultado =
                  from acao in 
                  this.CreateQuery<AcaoEntity>(TableName)
                  where acao.PartitionKey == 
                        codigoBolsaValores
                  select acao;
              return resultado.ToList();
          }
          
          public List<AcaoEntity> ListarTodasAcoes()
          {
              var resultado =
                  from acao in 
                  this.CreateQuery<AcaoEntity>(TableName)
                  select acao;
              return resultado.ToList();
          }
      }
  } 

A interface gráfica para a carga dos dados está contida no projeto GeracaoDadosAzure. Este último foi criado a partir do template “Web Application”, dentro do Visual Studio, e faz referência a outros projetos já mencionados anteriormente, a saber, StorageClient, Exemplo.Cloud.Entities e Exemplo.Cloud.DataAccess.

O acesso ao Development Storage deve ser configurado no Web.config da aplicação GeracaoDadosAzure, que é automaticamente gerado ao se criar uma nova “Web Application”. Os parâmetros necessários para a utilização do Windows Azure estão demonstrados na Listagem 3 (outras configurações geradas de maneira automática foram omitidas, para efeitos de simplificação).

Listagem 3. Web.config – Configurações de acesso ao Azure.


  <configuration>
   
    ...
   
    <appSettings>
   
      ...
   
      <add key="AccountName" 
           value="devstoreaccount1"/>
      <add key="AccountSharedKey" 
           value="Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ
           6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="/>
      <add key="BlobStorageEndpoint" 
           value="http://127.0.0.1:10000"/>
      <add key="QueueStorageEndpoint" 
           value="http://127.0.0.1:10001"/>
      <add key="TableStorageEndpoint" 
           value="http://127.0.0.1:10002"/>
      <add key="ContainerName"
           value="devstoreaccount1"/>
   
      ...
   
    </appSettings>
   
    ...
   
  </configuration> 

Os valores dos itens especificados na Listagem 3, referem-se aos endereços e demais configurações para simulação através do Development Storage. Caso esta aplicação acessasse diretamente os serviços do Azure, seriam configurados na mesma os endereços disponibilizados pela Microsoft, bem como a conta do Windows Live Id para uso do ambiente de cloud computing.

Tem-se na Listagem 4 o código da página Default.aspx, no qual foram definidas as funcionalidades para criação de uma tabela no Windows Azure, carga inicial e visualização dos dados carregados.

Listagem 4. Implementação da página Default.aspx.


  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Web;
  using System.Web.UI;
  using System.Web.UI.WebControls;
  using System.Drawing;
  using Microsoft.Samples.ServiceHosting.StorageClient;
  using Exemplo.Cloud.DataAccess;
  using Exemplo.Cloud.Entities;
   
  namespace GeracaoDadosAzure
  {
      public partial class Default : System.Web.UI.Page
      {
          protected void btnCriarTabela_Click(
              object sender, EventArgs e)
          {
              try
              {
                  CriarTabelaAcoes();
                  ConfigurarMensagem(
                      "Tabela de ações criada com sucesso", 
                      false);
              }
              catch (Exception ex)
              {
                  ConfigurarMensagem(
                      "Erro durante a criação da " + 
                      "tabela de ações: " +
                       ex.Message, true);
              }
          }
   
          protected void btnPreencherTabela_Click(
              object sender, EventArgs e)
          {
              try
              {
                  PreencherTabelaAcoes();
                  ConfigurarMensagem(
                      "Tabela de ações preenchida " +
                      "com sucesso", false);
              }
              catch (Exception ex)
              {
                  ConfigurarMensagem(
                      "Erro durante o preenchimento da " + 
                      "tabela de ações: " +
                      ex.Message, true);
              }
          }
   
          protected void btnConsultarDados_Click(
              object sender, EventArgs e)
          {
              try
              {
                  ConsultarTabelaAcoes();
                  ConfigurarMensagem(
                      "Consulta à tabela de ações " +
                      "efetuada com sucesso", false);
              }
              catch (Exception ex)
              {
                  ConfigurarMensagem(
                      "Erro durante a consulta à tabela " +
                      "de ações: " + ex.Message, true);
              }
          }
   
          private AcaoDataServiceContext CreateContext()
          {
            StorageAccountInfo accountInfo =
             StorageAccountInfo.
             GetDefaultTableStorageAccountFromConfiguration();
   
            return new AcaoDataServiceContext(accountInfo);
          }
   
          private void CriarTabelaAcoes()
          {
              AcaoDataServiceContext contextAcoes = 
                 this.CreateContext();
              contextAcoes.CriarTabela();
          }
   
          private void PreencherTabelaAcoes()
          {
              AcaoDataServiceContext contextAcoes = 
                  this.CreateContext();
              DateTime dataCotacao = new DateTime(
                  2010, 8, 10);
              AcaoEntity acao;
   
              // Criação de dados para a Bolsa de Londres
              acao = new AcaoEntity()
              {
                  PartitionKey = "LOND",
                  RowKey = "STEE0",
                  DataCotacao = dataCotacao,
                  NomeEmpresa = "Steel Factories Inc.",
                  Moeda = "Euro",
                  ValorAtualAcao = 44.05,
                  ValorAnterior = 43.8,
                  PercentualVariacao = 0.57
              };
              contextAcoes.IncluirAcao(acao);
   
              acao = new AcaoEntity()
              {
                  PartitionKey = "LOND",
                  RowKey = "WEBL1",
                  DataCotacao = dataCotacao,
                  NomeEmpresa = "Web Learning Corporation",
                  Moeda = "Euro",
                  ValorAtualAcao = 44.55,
                  ValorAnterior = 42.44,
                  PercentualVariacao = 4.97
              };
              contextAcoes.IncluirAcao(acao);
   
   
              // Criação de dados para a Bolsa de Nova York
              acao = new AcaoEntity()
              {
                  PartitionKey = "NY",
                  RowKey = "BLUS1",
                  DataCotacao = dataCotacao,
                  NomeEmpresa = "Blue Sky Corporation",
                  Moeda = "US$",
                  ValorAtualAcao = 62.4,
                  ValorAnterior = 60.47,
                  PercentualVariacao = 3.19
              };
              contextAcoes.IncluirAcao(acao);
   
              acao = new AcaoEntity()
              {
                  PartitionKey = "NY",
                  RowKey = "FAST2",
                  DataCotacao = dataCotacao,
                  NomeEmpresa = "Fast Aerolines Corporation",
                  Moeda = "US$",
                  ValorAtualAcao = 52.11,
                  ValorAnterior = 52.97,
                  PercentualVariacao = -1.62
              };
              contextAcoes.IncluirAcao(acao);
   
              acao = new AcaoEntity()
              {
                  PartitionKey = "NY",
                  RowKey = "SPEE0",
                  DataCotacao = dataCotacao,
                  NomeEmpresa = "Speed Stores Inc.",
                  Moeda = "US$",
                  ValorAtualAcao = 56.03,
                  ValorAnterior = 55.89,
                  PercentualVariacao = 0.25
              };
              contextAcoes.IncluirAcao(acao);
   
   
              // Criação de dados para a Bolsa de São Paulo
              acao = new AcaoEntity()
              {
                  PartitionKey = "SP",
                  RowKey = "ACME1",
                  DataCotacao = dataCotacao,
                  NomeEmpresa = "Empresas Acme S. A.",
                  Moeda = "R$",
                  ValorAtualAcao = 33.87,
                  ValorAnterior = 32.78,
                  PercentualVariacao = 3.33
              };
              contextAcoes.IncluirAcao(acao);
   
              acao = new AcaoEntity()
              {
                  PartitionKey = "SP",
                  RowKey = "AUTO1",
                  DataCotacao = dataCotacao,
                  NomeEmpresa = 
                     "Empresa Brasileira de Automóveis S. A.",
                  Moeda = "R$",
                  ValorAtualAcao = 25.83,
                  ValorAnterior = 25.21,
                  PercentualVariacao = -2.4
              };
              contextAcoes.IncluirAcao(acao);
   
              acao = new AcaoEntity()
              {
                  PartitionKey = "SP",
                  RowKey = "BORR1",
                  DataCotacao = dataCotacao,
                  NomeEmpresa = 
                      "Empresa Brasileira de Borrachas S. A.",
                  Moeda = "R$",
                  ValorAtualAcao = 20.71,
                  ValorAnterior = 21.28,
                  PercentualVariacao = 2.75
              };
              contextAcoes.IncluirAcao(acao);
          }
   
          private void ConsultarTabelaAcoes()
          {
              AcaoDataServiceContext contextAcoes = 
                  this.CreateContext();
              gridAcoes.DataSource = 
                  contextAcoes.ListarTodasAcoes();
              gridAcoes.DataBind();
          }
   
          private void ConfigurarMensagem(
              string mensagem, bool erro)
          {
              lblMensagem.Visible = true;
              lblMensagem.Text = mensagem;
              if (!erro)
                  lblMensagem.ForeColor = Color.Black;
              else
                  lblMensagem.ForeColor = Color.Red;
          }
      }
  } 

Conforme apresentado na Listagem 4, a propriedade PartitionKey de cada entidade, que representa uma ação, foi preenchida com o código da Bolsa de Valores (LOND – Londres, NY – Nova York, SP – São Paulo) à qual a mesma se refere. Já no caso da propriedade RowKey, utilizou-se como conteúdo o código da ação.

Conforme a informação dada anteriormente, a performance no acesso a entidades pode ser aumentada através do uso de diferentes PartitionKeys.

Na Figura 7 é apresentada a aplicação GeracaoDadosAzure já em execução, através do acesso à sua interface gráfica via browser. No caso, as opções Criar Tabela e Preencher Tabela foram previamente executadas. Após isto, clicou-se no botão Consultar Dados, tendo esta ação retornado todos os registros que constam na tabela AcaoTable, gerada no serviço de Storage local.

Figura 7. Dados já carregados através da aplicação GeracaoDadosAzure.

O ambiente de desenvolvimento Microsoft Visual Studio .Net possui amplo suporte para a concepção e disponibilização de aplicativos na “nuvem”, com uma abordagem que em nada difere daquela utilizada com softwares on-premise. Possibilitando, portanto, um maior foco na criação de novas soluções, diminuindo assim a preocupação com detalhes de infraestrutura.

Criação de uma Web Role

Para criar e testar uma Web Role, utilizando o Development Fabric, deve-se, primeiramente, executar o Visual Studio com privilégios de Administrador. Isto pode ser feito no Windows 7, clicando-se com o botão direito do mouse sobre o ícone do Visual Studio, no menu Iniciar; em seguida, seleciona-se a opção Executar como administrador.

A solução a ser criada chama-se ServicoAzure e fará uso do template “Cloud” (instalado através do pacote Windows Azure Tools for Visual Studio), conforme indicado na Figura 8.

Figura 8. Criação da solução ServicoAzure.

Como próximo passo, é necessário selecionar o template de projeto a ser empregado para o desenvolvimento da Web Role. No caso, será criado um serviço chamado WCFServiceAcoes, tendo sido escolhida a opção WCF Service Web Role (Figura 9).

Figura 9. Criação do projeto WCFServiceAcoes.

WCFServiceAcoes é um Web Service que faz uso da tecnologia WCF (Windows Communication Foundation), sendo esta última uma solução da Microsoft para a criação de aplicações distribuídas. O referido serviço visa, basicamente, simular uma aplicação com três instâncias em execução, responsável por retornar cotações de ações comercializadas em uma Bolsa de Valores.

Na Figura 10 é apresentada a estrutura da solução ServicoAzure dentro do Visual Studio, tão logo o desenvolvimento da mesma tenha sido finalizado.

Figura 10. Estrutura da solução ServicoAzure.

O projeto ServicoAzure é gerado durante a criação da solução, possuindo uma referência para a role que faz parte da mesma (no caso, WCFServiceAcoes). Além disso, contém os seguintes arquivos de configuração:

Listagem 5. Arquivo ServiceDefinition.csdef.


  <?xml version="1.0" encoding="utf-8"?>
  <ServiceDefinition name="ServicoAzure" xmlns="http://schemas.microsoft.com/ServiceHosting/
         2008/10/ServiceDefinition">
    <WebRole name="WCFServiceAcoes">
      <InputEndpoints>
        <InputEndpoint name="HttpIn" protocol="http"
             port="80" />
      </InputEndpoints>
      <ConfigurationSettings>
        <Setting name="DiagnosticsConnectionString" />
        <Setting name="AccountName"/>
        <Setting name="AccountSharedKey"/>
        <Setting name="BlobStorageEndpoint"/>
        <Setting name="QueueStorageEndpoint"/>
        <Setting name="TableStorageEndpoint"/>
        <Setting name="ContainerName"/>
      </ConfigurationSettings>
    </WebRole>
  </ServiceDefinition> 

Listagem 6. Arquivo ServiceConfiguration.csdef.


  <?xml version="1.0"?>
  <ServiceConfiguration serviceName="ServicoAzure" 
  xmlns="http://schemas.microsoft.com/ServiceHosting/
         2008/10/ServiceConfiguration">
    <Role name="WCFServiceAcoes">
      <Instances count="3" />
      <ConfigurationSettings>
        <Setting name="DiagnosticsConnectionString" 
             value="UseDevelopmentStorage=true" />
        <Setting name="AccountName"
             value="devstoreaccount1" />
        <Setting name="AccountSharedKey" 
             value="Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1
                    OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZ
                    FPTOtr/KBHBeksoGMGw==" />
        <Setting name="BlobStorageEndpoint" 
             value="http://127.0.0.1:10000" />
        <Setting name="QueueStorageEndpoint" 
             value="http://127.0.0.1:10001" />
        <Setting name="TableStorageEndpoint" 
             value="http://127.0.0.1:10002/" />
        <Setting name="ContainerName" 
             value="devstoreaccount1" />
      </ConfigurationSettings>
    </Role>
  </ServiceConfiguration> 

Configurar o número de instâncias da Web Role WCFServiceAcoes a serem executadas, é um procedimento muito simples, conforme indicado na Figura 11, podendo ser feito por meio de um duplo clique, sobre a referência para a mesma no projeto ServicoAzure.

Figura 11. Configurando o número de instâncias da role WCFServiceAcoes.

Deste modo, definiu-se (Figura 11) que serão criadas três instâncias do serviço WCFServiceAcoes quando da execução do mesmo, via Development Fabric.

O projeto WCFServiceAcoes representa a implementação em WCF da Web Role a ser hospedada na “nuvem”. Constituído por uma interface chamada IServicoAcoes, bem como pelas classes Acao e ServicoAcoes, faz uso das bibliotecas StorageClient, Exemplo.Cloud.Entities e Exemplo.Cloud.DataAcess.

A classe Acao, apresentada na Listagem 7, é um tipo de dado complexo, conhecido em WCF como “Data Contract”, representando uma cotação negociada em Bolsa de Valores.

Listagem 7. Código da classe Acao.


  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Web;
  using System.Runtime.Serialization;
   
  namespace WCFServiceAcoes
  {
      [DataContract]
      public class Acao
      {
          [DataMember]
          public String CodigoBolsaValores { get; set; }
   
          [DataMember]
          public String CodigoAcao { get; set; }
   
          [DataMember]
          public DateTime DataCotacao { get; set; }
   
          [DataMember]
          public String NomeEmpresa { get; set; }
   
          [DataMember]
          public String Moeda { get; set; }
   
          [DataMember]
          public Double ValorAtualAcao { get; set; }
   
          [DataMember]
          public Double ValorAnterior { get; set; }
   
          [DataMember]
          public Double PercentualVariacao { get; set; }
      }
  } 

IServicoAcoes (Listagem 8), representa um tipo de interface conhecido em WCF como “Service Contract”. O referido tipo serve de base, dentro desta tecnologia, à geração do arquivo WSDL contendo as especificações de um serviço.

Listagem 8. Código da interface IServicoAcoes.


  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Runtime.Serialization;
  using System.ServiceModel;
  using System.Text;
   
  namespace WCFServiceAcoes
  {
      [ServiceContract]
      public interface IServicoAcoes
      {
          [OperationContract]
          List<Acao> ListarAcoesPorBolsa(
              string codigoBolsaValores);
      }
  } 

A classe ServicoAcoes, implementação da interface IServicoAcoes e apresentada na Listagem 9, servirá de base para a geração das diversas instâncias da Web Role WCFServiceAcoes. Será responsável, ainda, pelo processamento de requisições enviadas por consumidores do serviço.

Listagem 9. Código da classe ServicoAcoes.


  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Runtime.Serialization;
  using System.ServiceModel;
  using System.Text;
  using Microsoft.Samples.ServiceHosting.StorageClient;
  using Exemplo.Cloud.DataAccess;
  using Exemplo.Cloud.Entities;
   
  namespace WCFServiceAcoes
  {
      public class ServicoAcoes : IServicoAcoes
      {
         public List<Acao> ListarAcoesPorBolsa(
             string codigoBolsaValores)
         {
           List<Acao> listResultado = new List<Acao>();
           Acao acao;
   
           StorageAccountInfo accountInfo =
             StorageAccountInfo.
             GetDefaultTableStorageAccountFromConfiguration();
           AcaoDataServiceContext context =
               new AcaoDataServiceContext(accountInfo);
           List<AcaoEntity> listCloudAcoes = 
               context.ListarAcoesPorBolsa(
                   codigoBolsaValores);
   
           foreach (AcaoEntity entidadeCloud
                    in listCloudAcoes)
           {
               acao = new Acao();
               acao.CodigoBolsaValores = 
                   entidadeCloud.PartitionKey;
               acao.CodigoAcao =
                   entidadeCloud.RowKey;
               acao.DataCotacao = 
                   entidadeCloud.DataCotacao;
               acao.NomeEmpresa = 
                   entidadeCloud.NomeEmpresa;
               acao.Moeda =
                   entidadeCloud.Moeda;
               acao.ValorAtualAcao = 
                   entidadeCloud.ValorAtualAcao;
               acao.ValorAnterior = 
                   entidadeCloud.ValorAnterior;
               acao.PercentualVariacao = 
                   entidadeCloud.PercentualVariacao;
               listResultado.Add(acao);
           }
   
           return listResultado;
         }
      }
  } 

Com todas as configurações, classes e interfaces já definidas, chega o momento de se executar o Web Service para consulta de ações. O mesmo deve ser ativado, para efeitos de simulação, através do Visual Studio. Para isto deve-se acessar a opção Start Debugging do menu Debug.

A Figura 12 apresenta o serviço Development Fabric com a Web Role WCFServiceAcoes já em execução. Nota-se que foram criadas três instâncias do Web Service, numeradas de 0 a 2.

Figura 12. Role WCFServiceAcoes em execução no Development Fabric.

O endereço http://127.0.0.1:81/ServicoAcoes.svc será disponibilizado pelo Development Fabric automaticamente, a fim de possibilitar testes com o serviço WCFServiceAcoes. Acessando este Web Service, através do Internet Explorer, será exibida uma página com instruções para o consumo do mesmo (Figura 13).

Figura 13. Acesso ao Web Service através do browser.

Consumindo um serviço na “nuvem”

Com a Web Role WCFServiceAcoes em execução, será necessária a abertura de uma nova instância do Visual Studio, a fim de se consumir a mesma em uma aplicação de teste chamada ConsumidorServicoAzure.

ConsumidorServicoAzure será uma solução formada por um site on-premise, tendo sido criada com o objetivo de demonstrar a facilidade em se consumir um Web Service hospedado na “nuvem” (neste caso, através do ambiente de simulação oferecido pelo Development Fabric). A Figura 14 apresenta a estrutura da mesma.

Figura 14. Estrutura da solução ConsumidorServicoAzure.

É imprescindível adicionar uma referência à Web Role WCFServiceAcoes, com o intuito de permitir que o serviço disponibilizado por ela seja consumido pela aplicação ConsumidorServicoAzure. Isto pode ser feito dentro do Visual Studio, clicando-se com o botão direito do mouse sobre o projeto e selecionando a opção Add Service Reference (Figura 15).

Figura 15. Adicionando uma referência ao Web Service na “nuvem”.

A adição da referência à Web Role WCFServiceAcoes atualizará automaticamente o arquivo Web.config, da aplicação ConsumidorServicoAzure, gerando um item de configuração que aponta ao endereço de testes do Web Service, conforme indicado na Listagem 10 (alguns itens de configuração foram omitidos, para efeitos de simplificação).

Listagem 10. Arquivo Web.config da aplicação ConsumidorServicoAzure.


  <?xml version="1.0"?>
  <configuration>
      ...
      <system.serviceModel>
          <bindings>
              <basicHttpBinding>
                  <binding
                       name="BasicHttpBinding_IServicoAcoes" 
                  ... />
                      ...
                  </binding>
              </basicHttpBinding>
          </bindings>
          <client>
              <endpoint 
                address="http://127.0.0.1:81/ServicoAcoes.svc" 
                binding="basicHttpBinding"
                bindingConfiguration=
                    "BasicHttpBinding_IServicoAcoes" 
                contract="WSAcoes.IServicoAcoes"
                name="BasicHttpBinding_IServicoAcoes" />
          </client>
      </system.serviceModel>
  </configuration> 

A página Default.aspx (Listagem 11), por meio de sua funcionalidade de consulta às ações de uma determinada Bolsa de Valores, acessa o Web Service definido anteriormente neste artigo (e que está hospedado no Development Fabric).

Listagem 11. Implementação da página Default.aspx.


  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Web;
  using System.Web.UI;
  using System.Web.UI.WebControls;
   
  namespace ConsumidorServicoAzure
  {
      public partial class Default : System.Web.UI.Page
      {
          protected void btnPesquisarAcoes_Click(
              object sender, EventArgs e)
          {
              using (WSAcoes.ServicoAcoesClient servicoAcoes = 
                  new WSAcoes.ServicoAcoesClient())
              {
                  grdDadosBolsaValores.DataSource = 
                      servicoAcoes.ListarAcoesPorBolsa(
                          ddlBolsaValores.SelectedValue);
                  grdDadosBolsaValores.DataBind();
              }
          }
      }
  } 

Com a aplicação ConsumidorServicoAzure em execução, torna-se possível consumir o serviço WCFServiceAcoes, obtendo-se assim cotações para uma determinada Bolsa de Valores (Figura 16).

Figura 16. Site consumindo o Web Service de ações.

Conclusão

O Azure, solução de cloud computing da Microsoft, oferece um conjunto variado de recursos, conforme apresentado neste artigo, buscando com isto ser a resposta a uma série de necessidades do ambiente empresarial.

A questão financeira pode representar um item importante a possíveis interessados nos componentes oferecidos pelo Azure, já que a cobrança se faz mediante o grau de utilização dos serviços. O que, por outro lado, vem de encontro à necessidade que muitas empresas possuem em reduzir investimentos, gastos com recursos em hardware, dando maior ênfase ao desenvolvimento de soluções específicas de software, essencial para o sucesso dos negócios.

Sua arquitetura, assim como a de outras plataformas do mesmo tipo, prima pelo fornecimento de serviços com alta disponibilidade, tolerância a falhas, escalabilidade e segurança.

Levando-se em conta todos estes fatores, bem como à sua estrutura, ao suporte dado a desenvolvedores pela Microsoft e à utilização de padrões de comunicação de grande aceitação como REST, a plataforma Azure possibilita o desenvolvimento de aplicações robustas e dotadas de grande flexibilidade. Tais aspectos são, portanto, muito apreciados em um cenário corporativo de contínuas e aceleradas transformações.


Artigos relacionados