Neste post gostaríamos de aprofundar o relato sobre nossa parceria com um de nossos clientes.
Como já dissemos trata-se de nossa experiência na entrega de um projeto que visou a re-construção de um produto existente.
Dentre as motivações por trás do projeto existia o desejo de reduzir os custos com a operação do produto.
Para outras informações sobre o cenário deste relato leia este post.

O modelo SaaS esteve em nosso horizonte desde o início dos trabalhos do projeto.
É interessante o fato de que as promessas deste modelo não anulavam em nosso cliente o interesse em adotar também a abordagem on-premises. Pois é, sabemos que o mercado nunca é muito óbvio.

Nós, time de desenvolvimento, fizemos o seguinte: não engessamos nenhum destes modelos na arquitetura do novo aplicativo. E não lembro disto ter custado qualquer coisa para nós. Após mais de 20 sprints de projeto o PO colocou no topo do backlog requisitos relacionados à distribuição do aplicativo, e só então chegou o momento de priorizarmos um dos modelos. O Molesim, então nosso Scrum Master, facilitou uma reunião onde os stakeholders do projeto apresentaram seus interesses e o time apresentou diferentes opções de arquitetura. Optou-se pelo modelo SaaS e por uma arquitetura que oferece um ótimo equilíbrio entre compartilhamento de recursos e isolamento de dados.

Estranhou o fato de que tratamos um assunto tão importante depois da vigésima sprint?
O fato é que cultivamos uma arquitetura emergente durante todo o projeto. Também prezamos pela simplicidade e pelo bom design de código, mas neste quesito é importante evitar pecar por excesso. Uma boa cobertura de testes é o último elemento desta fórmula. O resultado é a coragem necessária para conciliar a ansiedade de resolver um problema complexo com as prioridades do negócio. Se a solução para o problema fosse desconhecida, teríamos planejado uma prova de conceito com o PO, e assim fizemos antes de solucionar alguns outros requisitos do projeto.

Quais resultados foram conseguidos?

Atualmente a projeção de custos com operação e infra-estrutura está compatível com a realidade desejada pela Lumera.
Esta projeção está aderente à expectativa de que os custos não aumentem exponencialmente em função do número de cartórios atendidos pelo produto (lembrando que o cartório é o cliente final).

Mais detalhes sobre a solução

Daqui em diante vamos aprofundar os aspectos técnicos existentes e como implementamos a arquitetura escolhida. Um bom momento para enchermos nossa xícara de café.

As diferentes opções de arquitetura identificadas resumem-se a três abordagens macro:

  1. On-premises
    Instalação dos componentes do aplicativo em servidores que integram a infra-estrutura do cliente final.
  2. SaaS não compartilhado
    Distribuição do software a partir da nuvem. Cada cliente possui servidores exclusivos.
  3. SaaS compartilhado
    Distribuição do software a partir da nuvem. Os mesmos servidores são compartilhados por diferentes clientes. Existem diferentes maneiras de implementar este compartilhamento.

A abordagem escolhida foi aquela que oferece o menor custo operacional e de infra-estrutura: SaaS compartilhado. Existem diferentes opções para implementar este modelo no que diz respeito à arquitetura dos dados:

A opção escolhida foi aquela que oferece equilíbrio entre os benefícios gerados por isolamento de dados e os riscos inerentes a compartilhamento de dados: Separated Schema.

Essa arquitetura parece mesmo bonitinha, mas como tiramos a idéia do papel?
Os principais componentes envolvidos no momento eram:

  1. A interface do aplicativo, uma grande aplicação JavaScript que implementa o conceito de Single-page application
  2. A api REST do aplicativo, escrita em Java
  3. O banco de dados PostgreSQL
  4. Uma api REST de busca fonética, também escrita em Java e que expõe os serviços de um índice Lucene

A implementação inicial da arquitetura SaaS foi feita durante uma sprint de uma semana. A grosso modo os trabalhos consistiram em:

  • Criar um subdomínio por cliente e identificar  qual cliente está por trás de cada requisição  http
  • Reservar um Schema por cliente
  • Garantir que uma vez identificado o cliente, qualquer comunicação com o banco de dados envolvida na requisição seja dirigida ao Schema do cliente em questão

O PostgreSQL foi uma grata surpresa. Em um primeiro momento foi frustrante saber que não é possível escolher o schema na string de conexão do banco. Depois disso entendemos que o mecanismo de Search Path era a melhor resposta para nossas necessidades.

O Hibernate, outra peça-chave neste quebra-cabeças, se mostrou bastante amigável. Não tivemos a mesma sorte com o Hibernate Search que até então parece não oferecer suporte a multitenancy. Por isso os trabalhos com a api de busca fonética ficaram para a sprint seguinte.

Outra informação relevante é que hoje a infra-estrutura gira em torno dos serviços da Cloudbees, um fornecedor de PaaS especialista na plataforma Java.
Até então as partes envolvidas estão satisfeitas com a dependência sobre estes serviços.

Sinta-se convidado a tirar dúvidas e trocar experiência com a gente, os comentários estão aí para isto!
Este foi mais um post relatando a experiência de nossa parceria com a Lumera. Ainda existe bastante conteúdo por vir!