WSO2 – Open Source SOA Suite

WSO2 – Open Source SOA Suite

E você vai passando pelas empresas, vai ganhando experiência, acaba vendo problemas recorrentes e em algum momento pode passar o seguinte pensamento: Putz, esse problema aqui se resolveria de forma super simples com um API Manager, ou um ESB, e quem sabe essa infinidade de API’s de consulta poderiam ser criadas com uma ferramenta. Hoje vou falar um pouco de alguns produtos da WSO2.

Bom esses e muitos outros problemas endereçados no SOA são geralmente atendidos com soluções caras como Data Power, Integration Bus (ambos da IBM) e diversas outras soluções extremamente difundidas, mas caras! Seja IBM, Oracle, Microsoft, CA, inevitavelmente você irá esbarrar em custo, principalmente se você não tiver um bom orçamento para se jogar fora.

(mais…)

MonolithFirst @ Fowler, artigo comentado

MonolithFirst @ Fowler, artigo comentado

Olá pessoal, hoje vou falar um pouco sobre um padrão detalhado pelo Fowler meses depois da minha saída do iMusica. Por sinal, há algo de interessante com esse padrão, pois era algo que alguns membros do meu time reclamavam e consideravam um anti-pattern. Vou aproveitar esse post vou tentar usar uma linguagem ainda mais informal que a de praxe.

O nascimento dos padrões

Na real, uma máxima você não pode ter fora da sua cabeça:

Padrões são escritos por pessoas que interpretam situações, problemas e soluções recorrentes e resolvem escrever sobre o tema.

Um padrão nasce da observação de um grupo de pessoas ou projetos que fazem algo de uma determinada forma (parecida ou idêntica) e que chamam a atenção do observador. O observador identifica o “jeitão”, técnica ou solução para escrever sobre aquilo. Assim nasce um padrão.

Se você não entendeu as implicações disso, pense: (mais…)

Integrações, XML`s e NoSQL

Integrações, XML`s e NoSQL

Olá, tudo bom?

Nesse post gostaria de abordar uma solução que usei no iMusica e que pode também te ajudar com integrações baseadas em XML ou qualquer formato unquerable(neologismo). Antes de falar da solução, vou falar do problema. Nossas integrações no iMusica geralmente se dão por meio de troca de arquivos, contendo pacotes com mídia e metadados. Os metadados são armazenados em arquivos XML complexos. Independente do schema do XML usado, uns mais completos, outros mais enxutos, a quantidade de informação é colossal. O metadado do mercado fonográfico é muito extenso.

A dificuldade de manipulação desse conteúdo era gigantesco, pelos seguintes motivos:

  • Segmentação do storage
  • Necessidade de queries em arquivos
  • Acesso a grandes volumes de informação para obter dados pontuais

Toda essa complexidade fazia parte do dia-a-dia do meu time. Não que hoje ainda não faça, mas estamos trabalhando para minimizar isso. O metadado tem um destino, sempre, a manutenção de tabelas em um SGDB. Começamos a reestruturação dos serviços redesenhando os modelos de integração em uma base intermediária no SGDB, mas ao chegarmos próximos a 100 tabelas (e não havíamos mapeado sequer a metade do schema xsd) optei por abortar a ideia. Outro maluco já havia tentado fazer isso antes, e no final das contas, essa foi a terceira iniciativa, que assim como as outras, morreu! Pensei em bases XML, mas armazenar XML é extremamente insano, principalmente se comparado a formatos mais enxutos, como json. Busquei algumas bases XML, achei o Sedna e o eXist-db mas usar XQuery não foi algo motivador. Já que estava estudando sobre NoSQL tive a ideia de pesquisar sobre outras alternativas NoSQL e o resultado foi excelente.

Talvez você esteja perguntando sobre as vantagens de usar o MongoDB:

  • Queries complexas
  • Armazenamento (quase que infinito)
  • Schemaless (poupa muito trabalho)

Agora um desafio, salvar o XML, que diga-se de passagem, já vi chegar a 3mb no MongoDB.

A solução: Schemas e Geração de Código

  1. Usamos Xsd2Code para gerar as classes, em C# para mapeamento de todos as entidades e propriedades definidas no XSD. Gerou mais de 200 classes.
  2. Fazemos a leitura do XML com base em deserialização, e persistimos os mesmos objetos (classes geradas com Xsd2Code) no MongoDB.

Você poderia usar CouchBase, CouchDB, entre outras soluções, eu usei MongoDB.

Enfim, essa foi uma solução simples, e eficiente para o meu problema de integrações. Após a persistência no MongoDB, toda a minha infra que depende dos documentos, usa o MongoDB e nunca mais o XML original. Para integrações em formatos diferentes, fazemos parsers em XSLT para transformar do formato original para o formato utilizado na plataforma e assim a base de código para tratar esses documentos continua sendo a mesma.

Esses pensamentos ajudam muito a evitar segmentação em aplicações corporativas. O custo de manutenção é bem menor do que construir bases de código diferentes para realizar as mesmas coisas.

Esta não é a única solução nem cogito ser a melhor, mas foi a que me atendeu graciosamente! Espero que compartilhando contigo possa pelo menos abrir suas cabeça para ideias do tipo.

Um grande abraço e até mais!

[deprecated]Oragon Architecture – Por que? Pra que?

[deprecated]Oragon Architecture – Por que? Pra que?

[deprecated]

Olá, tudo bom?

Vou falar um pouco do meu projeto pessoal o Oragon Architecture. Se você me acompanha, sabe que falo bastante dele, e vou aproveitar para responder algumas perguntas que já me fizeram nos últimos dias.

 

Já fui questionado algumas vezes porque criar um framework de aplicação, uma arquitetura relativamente gorda, baseada em geração de código com base em banco e muita configuração com Spring.Net.

Bom, primeiro, o Oragon Architecture me viabilizou criar projetos que jamais seriam possíveis sem ele, no prazo que foram realizados. Esse é o principal motivador! Com ele alguns projetos de anos, conseguem ser realizados em meses, pelo simples fato de eliminar necessidade de codificação repetitiva. Quando você se preocupa apenas com o negócio deixando de lado aspectos não funcionais, tudo fica mais fluente no dia-a-dia de desenvolvimento. Gestão de Exceptions, Tratamento de erro, gestão de conexões, leak de conexões, sessões não finalizadas, tudo isso deixa de fazer parte do seu código na medida que você passa a usar os aspectos de AOP do Oragon Architecture.

O acesso a dados é bem facilitado, usando NHibernate e FluentNHibernate. Há quem questione o modelo. Bom, tive poucas chances na vida de trabalhar com bases de dados criadas do Zero, ou chances de realizar code-first. Muitas das vezes as empresas possuem equipes de DBA`s ou AD`s que são responsáveis pela modelagem do banco. Essa foi a melhor forma de me adaptar a estes cenários. Do ponto de vista do código gerado, há uma boa riqueza de detalhes na geração de código, como a criação de padrões que podem gerar facilmente nomes fluentes para bancos cheios de regras. Como uma coluna USUA_CD_USUARIO, virar CodigoUsuario, ou apenas Codigo, da mesma forma que USUA_DT_CRIACAO pode virar DataCriacao, com o case correto também. Pluralização em PT-BR e EN-US também são features interessantes da geração de código. Isso permite gerar código de uma forma bem inteligente, muito próximo do que nós mesmo modelaríamos manualmente, contemplando relações 1xN, Nx1, NxN e 1×1.

Quanto ao Spring.Net, bom, o primeiro fator que motiva na utilização dele é o fato de injetarmos modelos de dependências completas e a riqueza de features, como AOP e seus diversos helpers para outros muitos frameworks, como Quartz, RabbitMQ. Uso o Spring.Net desde 2006, uma pesquisa no google pode mostrar isso, nesse período ainda não existia WCF, e o Spring.Net já fazia abstração completa de protocolo para WebServices, Enterprise Services (COM+), Remoting e InProcess.

Aliás, essas abstrações de protocolo`me ajudaram a ver um mundo diferente, e desde então tudo que faço abstrai sempre o protocolo de comunicação. No Oragon Architecture, temos um conjunto de abstrações para plugar serviços em filas RabbitMQ, seguindo os mesmos princípios. Você implementa suas regras de negócio, o resto fica com a arquitetura. Como será a hospedagem, envelope de mensagem In/Out, tratamento de exceções, timeout, isso tudo fica a cargo da arquitetura.

O modelo desconectado do protocolo, permite que possamos desenvolver soluções com múltiplas distribuições, e permite mudar a estratégia de deploy em minutos, saindo de WCF, para WebServices, embedded, ou usando filas RabbitMQ. São muitas possibilidades com um código apenas. Nenhuma dessas mudanças exigem mudanças nos códigos e essa é a mágica dessa arquitetura: Abdicar das decisões mais complexas pelo tempo necessário para que elas obtenham o maior grau de maturidade possível. O pipeline em cima do RabbitMQ também é excelente, permite que um fluxo completo seja dividido em steps com filas de erro e filas de processamento, viabilizando uma grande escalabilidade horizontal.

Mas não são só flores, foram muitos anos construindo o projeto, evoluindo a cada parceiro e empresa que eu passava.

Muito mudou ao longo dos anos, os aspectos de AOP não trabalhavam em conjunto, agora cooperam entre si. A cada demanda nova, novas features nascem, novos conceitos são aplicados. Me orgulho de ter feito, para a BRQ um modelo de MVC, bem próximo do que há no Web API. Quando comecei a estudar Web API, joguei muito código fora, assim como quando encontrei o TopShelf. Me orgulho muito disso pois sempre que eu puder usar algo pronto, para me fornecer uma infraestrutura robusta, vou fazê-lo.

O papel do Oragon Architecture não é recriar a roda, mas coordenar as engrenagens para que se construa software mais fácil.

Muitas vezes sou questionado sobre a performance e escalabilidade da arquitetura:

A arquitetura provê uma infraestrutura robusta para o desenvolvimento corporativo, conta com soluções mais e menos performáticas/escaláveis, mas se usarmos as soluções corretas, como cache, por exemplo, podemos escalar bem mais que soluções que usam ADO.NET para acesso a dados e código 100% inline. Ganhando infinitamente no tempo de desenvolvimento. Não há mistério, cada escolha implica necessariamente em uma renúncia, mas para cada dificuldade, há um facilitador ao lado, e com um pouco de conhecimento de arquitetura, é possível chegar ao infinito!!

 

Grande abraço,

espero que gostem!

Roadmap de Arquitetura – Um exemplo real

Roadmap de Arquitetura – Um exemplo real

As vezes sou questionado sobre meus desenhos de arquitetura e porque criar tantas abstrações, tanta configuração e tantas dependências e frameworks de terceiros, alguns que só eu e um tibetano conhecemos. No post Como definir Arquitetura de Software, cito quais são os pensamentos primários necessários para se desenhar um arquitetura, mas vamos aplicar isso a um contexto real para exemplificar.

Tudo começa com minha chegada na atual empresa, onde encontrei um cenário extremamente complexo e difícil de se trabalhar.

  • Umas 8 bases de dados, entre SQL Server e MySQL, cada uma seguindo dois ou mais padrões antagônicos (sim, na mesma base), diversos padrões nomenclatura. As bases não possuíam um responsável. Eram “da empresa”, não havia um dono.  O acoplamento do modelo de dados era entre database/tecnologia. Isso quer dizer que um dado em uma base SQL Server só deixa de ser dado vira informação em conjunto com dados que estavam em outras bases MySQL, por exemplo.
  • Alto acoplamento entre as diversas aplicações e suas bases de dados.
  • Um parque de aplicações baseadas em .net framework 2.0, usando ADO.NET puro para escrever o acesso a dados: Manualmente. Uma quantidade infinita de código de acesso a dados realizando N+1 Anti-Pattern por causa da forma como o acesso a dados era escrito.
  • Dezenas de micro aplicações, forks de uma aplicação inicial que realizava um processo batch de importação de conteúdo, extremamente importantes para o business. Muitas delas exigiam rodavam na IDE, em modo debug pois um dev trocava algumas strings e executava em modo supervisionado. Isso não era ao acaso, era a forma como processávamos dados de produção no dia-a-dia.
  • Gerência de configuração inexistente, havia um SVN, mas mal era usado para versionador de código.
  • Nenhuma gestão de releases.
  • Centenas de micro-aplicações responsáveis por micro-tarefas, sem documentação, sem identificação e algumas sem sequer os fontes. Sem falar que muitos dos fontes sequer eram versionados ou estavam defasados no repositório de código.
  • Todo o conhecimento tecnológico dependia exclusivamente da memória do time ou daqueles que passaram pela equipe e ainda estavam na empresa.

Dá para ver que há muito a se trabalhar nesse lugar. Né?! Ok, assim começamos.

Primeiro passo foi definir um fluxo geral de gerência de configuração: A partir de então 100% do que fazíamos era versionado. 100% do que conhecemos também precisa ser. Agora com algum alívio, por não ter mais medo de que HD’s queimados me tirassem o sono, poderíamos partir para a identificação e melhoria da vida das pessoas.

  1. Identificação do cenário atual

Um dos processos, que considero dos mais importantes da empresa é a ingestão de conteúdo, por ele recebíamos milhares de XML’s e mídias(WAV, AVI) todos os dias, são diversos formatos e padrões de integração, o que nos demandava uma quantidade razoável de storage, alguns petabytes. Esse processo era composto por diversas micro-aplicações, onde cada uma era um fork de um projeto base, e nela tínhamos um desenvolvedor gerindo esse código, uma loucura para uma pessoa só. Óbvio que daria merda em algum momento. Fiz o trabalho de entender o cenário de negócio e compreender quais são os gaps do processo atual. Entre eles estão:

  • Alta segmentação das versões da base de código, cada uma com ligeiras mudanças para atender ligeiras diferenças entre parceiros.
  • Alta complexidade em cada uma das aplicações que possuíam formatos de XML diferentes.
  • Baixa completude no processamento do conteúdo recebido (boa parte das aplicações, ou precisava de tapas na hora de processar, ou só processava parte do XML que recebíamos)
  • Alta complexidade na gestão do processo
  • Falta de visibilidade do estágio do processo
  • Nenhuma escalabilidade
  • Paralelismo Moleculá (o moleco lá tentava paralelizar com braço esquerdo e direito)
  • Equipe tecnicamente desatualizada, que vivia uma era inteira apagando incêndios
  • Equipe reduzidíssima

Como resolver essa questão:

1) Durante as discussões sobre os formatos de XML, vimos que muitos parceiros, e o mercado em si, estavam convergindo para um padrão chamado DDEX. Esse standard serve para qualquer integração imaginável (programas, músicas, vídeos, ringtones, wallpapers etc). Apostar nesse formato foi uma escolha ousada, mas trouxe muito resultado. Como o padrão é extremamente amplo e aberto para diversas finalidades, há campos demais para dados de menos. O resultado é a possibilidade de interpretação particular de cada parceiro sobre cada uma das áreas do XML. São 8 formas diferentes de se tirar um conteúdo do ar, de forma implícita ou explícita entre outras variações bem peculiares. Mesmo com essa complexidade, unificar o modelo de entrega nesse formato nos trouxe a segurança para criar uma única aplicação só para processar esse conteúdo, então conseguimos ter uma visão unificada do processo, e ainda escalável.

2) Viabilizar a análise eficiente dos XML`s

Primeiro pensei em um database SQL para armazenar o conteúdo do XML, mas quando estávamos próximos de modelar 100 tabelas, e não estávamos sequer na metade do mapeamento, pedi que parassem a atividade para que pudesse repensar. Já haviam empenhado algum esforço nessa mesma iniciativa no passado, mas ignorei. Acreditei que com alguma supervisão mais técnica seria possível: Não. não era! Subestimei o padrão “dos infernos”. Era surreal, se modelássemos, seriam pelo menos 300 tabelas para gerir. Era necessário encontrar uma alternativa.

Após a desistência de bases SQL, pensei em usar uma base XML, mas nada me agradou: nem bancos, nem tecnologias, nada. Então pensando muito na possibilidade, optei por usar o MongoDB para realizar essa tarefa. Como MongoDB não trabalha com XML, geramos conjunto de classes com base no XSD, fazendo o parser direto de XML para .Net, que em seguida é persistido diretamente os objetos no MongoDB. O resultado foi um sucesso, extremamente eficiente, agora permitindo consultas nos dados que eram do XML, e agora são BSON direto no MongoDB. Foi uma excelente decisão, poupando muito tempo e facilitando muito o trabalho. Pelo fato das classes terem sido geradas com base no XSD, as garantias de formato estão todas presentes, então tenho o melhor dos mundos!

3) A falta de visibilidade dos pacotes (pacotes são entregas de 1 XML de metadados com suas N mídias) e a pulverização do FileSystem era problema do passado e do presente, agravante e complicómetro para o processo. Analisar diretórios de servidores de produção era tarefa diária. Entenda, eram pelo menos 16 storages, onde cada pacote poderia estar em qualquer um deles. O processo de gestão de espaço em disco era apontar o FTP para O MESMO path relativo EM OUTRO DISCO. Todos os 16 storages possuíam as mesmas estruturas base, e o endpoint do FTP hora apontava para qualquer um desses 16 storages, de acordo com a disponibilidade de discos.

Gerir esse caos, era complicado, pois o acesso a disco é muito custoso. Nesses storages onde petabytes eram armazenados em poucas pastas, era surreal fazer qualquer busca ou leitura. Não havia eficiência na leitura desses discos, portanto, eu precisava de alguma representação desse file system, mais rápida e eficiente. Algo como um file system virtual que representasse o file system físico. Pois diversas análises precisam ser feitas com base na estrutura, nos nomes do arquivos, para que pudesse tomar uma decisão sistêmica. Na prática eu precisava consolidar os pacotes fragmentados, para que no final do processo, fosse eliminada a fragmentação.

Criei uma base SQL para gerir o processo com uma visão semelhante à do FileSystem (Diretórios, arquivos, tamanho), tudo exceto o conteúdo do arquivo em si, permitindo com queries determinar exatamente o que cada disco possui. Agora não precisamos estar em contato direto com o File System, queries em um banco SQL mostravam todo a estrutura do File System. Um processo simples fazia a sincronização periodicamente. Uma característica legal é que por mais que o pessoal de infraestrutura cuidasse do FTP da mesma forma como sempre fizeram, meu trabalho poderia ser feito de forma coesa, reduzindo os impactos dessas decisões. Por outro lado, para o processamento das tarefas, havia uma escolha de prioridade entre os discos, isso permitia que eu mesmo não sofresse com as necessidades específicas de gerir storages tão grandes.

4) Criação de uma infraestrutura de arquitetura robusta que facilitasse e promovesse o refactoring contínuo.

Geração de Código

O Oragon Architecture foi fundamental para a criação desse modelo. Com ele geramos código de acesso a dados, para todas as bases necessárias, gerando código e configuração para NHibernate e FluentNHibernate. Trabalhando com MySQL e SQL Server side-by-side, com múltiplos databases, hora em contexto transacional, hora somente read-only. Agora, a ausência de um owner de cada database, não representa mais um problema. O banco muda, mas periodicamente geramos código a partir do banco, e é comum ver coisas mudando. O que nos afetar, diretamente e for incompatível, gera uma quebra no build: automaticamente, aumentando a segurança e resiliência na solução. Da mesma forma que geramos código com uma grande riqueza de detalhes, estamos aptos a regerar os bancos a qualquer momento, e identificar o que mudou estruturalmente no banco, bastando analisar nosso mapping com a ajuda de históricos do scm.

AOP

Sob o framework de AOP do Spring.Net, o Oragon Architecture implementa uma série de aspectos que torna viável trabalhar com Redis, MongoDB, MySQL, DB2 e SQL Server de forma transparente e simples. Um único template é necessário para todos os bancos SQL citados. Para o NoSQL, como é schemaless (não é mais), não havia como gerar código, mas os aspectos são úteis por definir a conectividade da mesma forma para todas as soluções. Do ponto de vista do código, nenhum OpenSession ou Connect é visível, apenas precisa-se marcar os métodos com os atributos corretos para que a infraestrutura cuide de todo o resto. Outro ganho direto é a resolução de connection leaks.

Ainda falando do Spring.Net, jobs agendados foram criados com Quartz.Net para iniciar operações de negócio agendadas, como emissão de relatórios que anteriormente eram criados manualmente periodicamente entre outras operações recorrentes agendadas. A sincronização do File System com o banco SQL que citei acima, também era agendada aqui.

Mensageria e Exception Handling

Para escalar a solução, um pipeline foi criado em cima do RabbitMQ para processar todo o fluxo de trabalho das importações, desde a gestão (monitoramento) do file system, até a ingestão propriamente dita. Nesse modelo o Oragon fornece as abstrações para que você só implemente as operações necessárias em cada passo do pipeline, sem que seu código saiba sequer que faz parte de um. Assim basta programar uma operação de negócio e plugar no pipeline, caso haja erro no processamento, lance suas exceptions e o próprio orquestrador (Oragon) se encarregará de colocar a mensagem na fila de erro, para que a mensagem não seja reprocessada infinitamente, com o mesmo status de erro. Geralmente os erros são de duas naturezas, ou o cliente errou no contrato ou o código encontrou uma situação não prevista, há um terceiro cenário, pouco comum que é uma falha em validação de negócio. Para essa temos um fluxo de tratamento diferenciado.

Em todos os casos, as exceptions são logadas, automaticamente, pelos aspectos Oragon Architecture, em filas RabbitMQ, isso com ajuda do pacote Spring.NET AMQP, posteriormente são armazenadas no Sentry sem causar gargalos na aplicação. Mais tarde, após inúmeros problemas, substituímos o Sentry por ElasticSearch.

Worker Process

Agora, estamos aptos a iniciar diversos hosts de processos, para consumir uma infinidade de filas, segmentando cada operação por parceiro se assim nos interessar. Conseguimos trabalhar com diversos processos em diversas máquinas, escalando até quanto o hardware e os databases suportarem.

A arquitetura, cheia de abstrações viabilizou tomar as decisões que envolviam estratégia de deploy o mais tarde possível. Esse é o ganho trazido por uma aplicação extremamente configurável. Mas não há almoço grátis. As configurações são tão relevantes quanto o código e são extensas. No código, não precisamos ver sequer um try-catch, e não há nada de errado nisso. Os Aspectos são responsáveis por pela gestão e tratamento das mensagens. As operações transacionais, são geridas pelos aspectos e eles são responsáveis pelo rollback em caso de erro. As configurações são muito mutáveis e maleáveis, mas são de extrema importância para o fluxo. Enfim, toda escolha, uma renúncia.

Continous Integration e Continuous Deploy

Para o processo de build e deploy, havíamos configurado o Jenkins, mas agora estou apanhando um bocado do TeamCity. mas em breve teremos novamente um processo de build e deploy automatizado nele.

Esse foi o roadmap de um ano de trabalho. É realmente muito excitante trabalhar com essas tecnologias, mas também bem relevante conseguir atender e endereçar todas essas demandas.

Hoje a maior dificuldade está no Business. Compreender e estabilizar as expectativas quanto ao business, que no caso de um processo de importação de metadados, é preencher as devidas tabelas, garantindo retro-compatibilidade com um parque de aplicações complexo e infinito.

Resumo

Bom, novamente, os frameworks utilizados foram utilizados para sanar necessidades reais.

Spring.Net para IoC, DI e AOP

Oragon Architecture para AOP (implementação)

Quartz.Net para Agendamentos

TopShelf para Serviços Windows (joguei um monte de código fonte fora, depois que achei esse framework)

T4 para os templates de geração de código

Spring AMQP para abstrações com RabbitMQ

Lembre-se das premissas:

Equipe:

Equipe reduzida.

Contexto:

GAP técnico, falta de Gerência de Configuração, e segmentação do código. Falta de padronização de recebimento de conteúdo e dificuldade de gestão de código, plataforma e manutenção.

Enfim, Arquitetura

A correlação entre as diversas peças que irão compor a solução, cada uma oferecendo uma feature de negócio.

Espero que tenha gostado!

 

[03/04/2018] – Revisão do Texto para melhorar a explicação sobre algumas necessidades.