Aplicações Financeiras Flexíveis através de DSLs na Plataforma Java

1,321 views
1,200 views

Published on

Nesta palestra, será apresentado um case de uma grande aplicação financeira, em que um conjunto de tecnologias Java foram utilizadas para inovar no desenvolvimento e na arquitetura – de Drools, a DSLs na JVM, a APIs Java do Google e WebSockets.

O case inicia-se com a geração de movimentos contábeis e gerenciais através de Decision Tables no framework Drools. Por se tratar de um projeto numa nova área de negócios, o cliente não possuía definição de todas as regras contábeis do sistema, implicando em alterações constantes na especificação. Além disso, os movimentos gerenciais eram variáveis, pois a estrutura da empresa estava em expansão. O uso de uma DSL (Domain Specific Language), trouxe flexibilidade e robustez ao sistema, tornando a manutenção e evolução simples e efetiva, além de aproximar o departamento contábil do desenvolvimento da aplicação.

Um segundo desafio foi o desenvolvimento de um painel gerencial da instituição. Os requisitos não eram claros e cada stakeholder possuía ideia divergente sobre a composição dessas informações. A solução encontrada novamente fez uso de uma DSL como plano de fundo, sendo desenvolvida através de APIs Java do Google Docs. Cada stakeholder ganhou sua própria versão do painel e a personalizou, através da manipulação dos dados na sua planilha GDocs.

Numa terceira parte do case mostramos como WebSockets e Drools podem ser utilizados para prover em tempo real o monitoramento de riscos de uma instituição financeira. O Drools permite ao cliente atualizar as regras de risco “a quente” e a tecnologia de WebSockets proporciona a atualização em tempo real de painéis de monitoração de riscos.

Published in: Technology

Aplicações Financeiras Flexíveis através de DSLs na Plataforma Java

  1. 1. Aplicações Financeiras Flexíveis através de DSLs na Plataforma Java Eder Ignatowicz Dextra quinta-feira, 5 de setembro de 2013
  2. 2. Software Craftsman @ Dextra Professor na Faccamp e Unisal Doutorando Unicamp Editor líder no InfoQ Brasil @ederign quinta-feira, 5 de setembro de 2013
  3. 3. Domain-Specific Language quinta-feira, 5 de setembro de 2013
  4. 4. Inovação quinta-feira, 5 de setembro de 2013
  5. 5. Java <3 quinta-feira, 5 de setembro de 2013
  6. 6. Projeto Maior Banco de Câmbio do Brasil 100 “Sprints” 1 release por semana 1.2k Testes de Aceitação MUITOS testes unitários 360k Operações/mês 450k Requests/dia 1k usuários regulares/dia 21 nós cluster Apache + JBoss quinta-feira, 5 de setembro de 2013
  7. 7. Operações/dia 5k 10k 20k 2011 2012 2013 quinta-feira, 5 de setembro de 2013
  8. 8. Desafios... quinta-feira, 5 de setembro de 2013
  9. 9. Desafios...(como eu me ferrei) quinta-feira, 5 de setembro de 2013
  10. 10. Desafio I quinta-feira, 5 de setembro de 2013
  11. 11. Geração de Movimentos Contábeis e Gerenciais quinta-feira, 5 de setembro de 2013
  12. 12. Sem perder “time to market” aka Lean quinta-feira, 5 de setembro de 2013
  13. 13. Contabilidade bancária é difícil? quinta-feira, 5 de setembro de 2013
  14. 14. E se os movimentos são variáveis pois a instituição está em expansão? quinta-feira, 5 de setembro de 2013
  15. 15. E de um banco de câmbio multi moeda? quinta-feira, 5 de setembro de 2013
  16. 16. E se este banco de câmbio é o primeiro do Brasil? quinta-feira, 5 de setembro de 2013
  17. 17. quinta-feira, 5 de setembro de 2013
  18. 18. EquipeRocket<3 quinta-feira, 5 de setembro de 2013
  19. 19. KISSdo the simplest thing that could possibly work (We'll need to refactor this later) quinta-feira, 5 de setembro de 2013
  20. 20. liquidar(){ //(regra de negócio aqui) proposta.gerarMovimentoAnaliticoX(); } quinta-feira, 5 de setembro de 2013
  21. 21. liquidar(){ //(regra de negócio aqui) proposta.gerarMovimentoAnaliticoX(); proposta.gerarMovimentoAnaliticoY(); } quinta-feira, 5 de setembro de 2013
  22. 22. liquidar(){ //(regra de negócio aqui) proposta.gerarMovimentoAnaliticoX(); proposta.gerarMovimentoAnaliticoY(); proposta.gerarMovimentoAnaliticoZ(); } quinta-feira, 5 de setembro de 2013
  23. 23. liquidar(){ //(regra de negócio aqui) proposta.gerarMovimentoAnaliticoX(); if(condicaoParaGerarY()){ proposta.gerarMovimentoAnaliticoY(); } proposta.gerarMovimentoAnaliticoZ(); } quinta-feira, 5 de setembro de 2013
  24. 24. liquidar(){ //(regra de negócio aqui) proposta.gerarMovimentoAnaliticoX(); if(condicaoParaGerarY1()){ proposta.gerarMovimentoAnaliticoY1(); } else if(condicaoParaGerarY2()){ proposta.gerarMovimentoAnaliticoY2(); } proposta.gerarMovimentoAnaliticoZ(); } quinta-feira, 5 de setembro de 2013
  25. 25. liquidar(){ //(regra de negócio aqui) proposta.gerarMovimentoAnaliticoX(); if(condicaoParaGerarY1()){ proposta.gerarMovimentoAnaliticoY1(); } else if(condicaoParaGerarY2()){ if(proposta instanceof XYZ ){ proposta.gerarMovimentoAnaliticoY2X(); } else proposta.gerarMovimentoAnaliticoY2(); } else if(condicaoParaGerarY3()){ proposta.gerarMovimentoAnaliticoY3(); } proposta.gerarMovimentoAnaliticoZ(); }quinta-feira, 5 de setembro de 2013
  26. 26. Quais são os movimentos gerados por esta operação? quinta-feira, 5 de setembro de 2013
  27. 27. Vamos corrigir a geração do movimento da operação XYZ? quinta-feira, 5 de setembro de 2013
  28. 28. liquidar(){ //(regra de negócio aqui) proposta.gerarMovimentoAnaliticoX(); if(condicaoParaGerarY1()){ proposta.gerarMovimentoAnaliticoY1(); } else if(condicaoParaGerarY2()){ if(proposta instanceof XYZ ){ proposta.gerarMovimentoAnaliticoY2X(); } else proposta.gerarMovimentoAnaliticoY2(); } else if(condicaoParaGerarY3()){ proposta.gerarMovimentoAnaliticoY3(); } proposta.gerarMovimentoAnaliticoZ(); }quinta-feira, 5 de setembro de 2013
  29. 29. quinta-feira, 5 de setembro de 2013
  30. 30. Redesign/Refactoring Machine!!!! MicroTesting Design Patterns quinta-feira, 5 de setembro de 2013
  31. 31. liquidar(){ //(regra de negócio aqui) //strategy proposta.processarMovimentos(); } quinta-feira, 5 de setembro de 2013
  32. 32. quinta-feira, 5 de setembro de 2013
  33. 33. E o tempo passa... (explosão de crescimento de produtos do banco) quinta-feira, 5 de setembro de 2013
  34. 34. E o tempo passa... Explosão combinatória (strategy) MUITAS classes gerando alta complexidade N tipo de movimentos com N combinações Movimentos cada vez mais complexos quinta-feira, 5 de setembro de 2013
  35. 35. Ficou difícil escrever e entender os movimentos quinta-feira, 5 de setembro de 2013
  36. 36. Código difícil de manter e evoluir quinta-feira, 5 de setembro de 2013
  37. 37. Especificação em expansão quinta-feira, 5 de setembro de 2013
  38. 38. Difícil de validar os movimentos com o negócio quinta-feira, 5 de setembro de 2013
  39. 39. E agora? quinta-feira, 5 de setembro de 2013
  40. 40. Domain-Specific Language quinta-feira, 5 de setembro de 2013
  41. 41. DSL Negócio pode ler (e entender) o código e ajudar a refinar requisitos Devs escrevem o código e mostram pros experts do negócio União de dois mundos diferentes (jargões e mindset) quinta-feira, 5 de setembro de 2013
  42. 42. Business Readable DSLs quinta-feira, 5 de setembro de 2013
  43. 43. Como? quinta-feira, 5 de setembro de 2013
  44. 44. quinta-feira, 5 de setembro de 2013
  45. 45. Separação de Lógica e Dados Escalabilidade e Desempenho Regras Compreensíveis Centralização do conhecimento Framework de Regras Pattern matching quinta-feira, 5 de setembro de 2013
  46. 46. Regras? quinta-feira, 5 de setembro de 2013
  47. 47. rule <rule_name> <atributte><value> when <conditions> then <actions> end quinta-feira, 5 de setembro de 2013
  48. 48. rule “Adulto” when $p : Pessoa( idade >=18) then System.out.println(“Adulto”) end quinta-feira, 5 de setembro de 2013
  49. 49. pattern matching Pessoa ( idade >= 18) Atributo Restrição ConstraintTipo Objeto Pattern quinta-feira, 5 de setembro de 2013
  50. 50. Production Memory (rules) Inference Engine (ReteOO) Working Memory (facts)Pattern Matcher quinta-feira, 5 de setembro de 2013
  51. 51. DSL? quinta-feira, 5 de setembro de 2013
  52. 52. Decision Tables Regras no “formato excel” Excelente para escrever comportamentos complexos Cada linha da tabela é uma regra Linguagem natural do negócio quinta-feira, 5 de setembro de 2013
  53. 53. Decision Tables https://github.com/paulovmr/engine-drools quinta-feira, 5 de setembro de 2013
  54. 54. public List<MovimentoAnalitico> processarMovimentoAnaliticoPara( Object objeto, MovimentoAnaliticoConfiguration configuration) { KnowledgeBase base = KnowledgeBaseUtil.getKnowledgeBase (configuration.getSpreadsheetsFileSystemPath()); StatefulKnowledgeSession ksession = base.newStatefulKnowledgeSession(); MovimentosAnaliticos movimentos = new MovimentosAnaliticos (configuration); ksession.insert(movimentos); ksession.insert(objeto); ksession.fireAllRules(); ksession.dispose(); validarMovimentosAnaliticos(movimentos.getMovimentosGerados()); return movimentos.movimentosGerados(); } quinta-feira, 5 de setembro de 2013
  55. 55. quinta-feira, 5 de setembro de 2013
  56. 56. quinta-feira, 5 de setembro de 2013
  57. 57. Decision Tables ~1500 Regras ~5 condições e 25 ações/regra 23+ milhões de movimentos gerados quinta-feira, 5 de setembro de 2013
  58. 58. Decision Tables - pros Simplicidade na geração dos movimentos Business Readable Aproximação do departamento contábil e desenvolvimento Alta performance (algoritmo RETE) quinta-feira, 5 de setembro de 2013
  59. 59. Decision Tables - cons Risco de modelo anêmico Risco na escrita das regras Dificulta o processo de teste Versionamento das planilhas quinta-feira, 5 de setembro de 2013
  60. 60. Desafio II quinta-feira, 5 de setembro de 2013
  61. 61. Construir um Painel Gerencial quinta-feira, 5 de setembro de 2013
  62. 62. 1.0 quinta-feira, 5 de setembro de 2013
  63. 63. Rocket Team quinta-feira, 5 de setembro de 2013
  64. 64. E o tempo passa... quinta-feira, 5 de setembro de 2013
  65. 65. 2.0 Dificuldade de extração de requisitos Cada stakeholder quer uma versão do painel quinta-feira, 5 de setembro de 2013
  66. 66. quinta-feira, 5 de setembro de 2013
  67. 67. Análise dos “requisitos” quinta-feira, 5 de setembro de 2013
  68. 68. JavaAPI Spreedshet quinta-feira, 5 de setembro de 2013
  69. 69. Painel Gerencial Cron Job Gerar Extração Backoffice Processar Extração Upload Extração quinta-feira, 5 de setembro de 2013
  70. 70. @POST @Path("/cotacao") public Response atualizarCotacoesPainel() { PaineisGoogleDocs.todos().atualizaExtracao (new ExtracaoCotacoes()); return Response.status(Status.OK).entity (SUCCESS).build(); } quinta-feira, 5 de setembro de 2013
  71. 71. protected void atualizaExtracao(Extracao extracao, PainelGoogleDocs... paineis) { List<String[]> resultadoExtracao = extracao.executar(); String guia = extracao.getGuia(); for (PainelGoogleDocs painel : paineis) { painel.atualizaExtracao(resultadoExtracao, guia); } } quinta-feira, 5 de setembro de 2013
  72. 72. public class ExtracaoCotacoes implements Extracao { @Override public List<String[]> executar() { List<CotacaoMercadoFechamento> cotacoes =lookupCotacaoRepository() .buscarUltimaCotacaoFechamento(DateUtils.hojeSemHora()); List<String[]> valoresParaSpreadsheet = ExtracaoUtils.montarExtracao("Moeda", "Tipo", "Data", "Paridade Compra", "Paridade Venda","Valor Compra", "Valor Venda"); String[] linha; for (CotacaoMercadoFechamento cotacao : cotacoes) { linha = ExtracaoUtils.montarLinha (valoresParaSpreadsheet,cotacao); valoresParaSpreadsheet.add(linha); } return valoresParaSpreadsheet; } quinta-feira, 5 de setembro de 2013
  73. 73. protected void atualizaExtracao(Extracao extracao, PainelGoogleDocs... paineis) { List<String[]> resultadoExtracao = extracao.executar(); String guia = extracao.getGuia(); for (PainelGoogleDocs painel : paineis) { painel.atualizaExtracao(resultadoExtracao, guia); } } quinta-feira, 5 de setembro de 2013
  74. 74. public void atualizaExtracao(List<String[]> dados, String guia) { this.mudarConteudoLinhas(guia, 1, 1, dados); } private void mudarConteudoLinhas(String nomeGuia, int linhaInicial, int colunaInicial, List<String[]> valores) { try { IntegracaoSpreadsheetUtils .mudarConteudoLinhas(servico, url, nomePlanilha, nomeGuia, linhaInicial, colunaInicial, valores); }catch (ServiceException e) { throw new RuntimeException("Erro ao mudar conteudo da linha " + nomePlanilha); } } quinta-feira, 5 de setembro de 2013
  75. 75. Painel Gerencial quinta-feira, 5 de setembro de 2013
  76. 76. Painel Gerencial quinta-feira, 5 de setembro de 2013
  77. 77. Painel Gerencial quinta-feira, 5 de setembro de 2013
  78. 78. Business Writable DSLs quinta-feira, 5 de setembro de 2013
  79. 79. DSL Cada stakeholder escreveu sua própria visão do Painel Só necessitamos escrever as extrações quinta-feira, 5 de setembro de 2013
  80. 80. Painel Gerencial - pros Alto valor agregado ao Banco Business Writable DSL Personalização da Solução pra cada StakeHolder Mobile grátis quinta-feira, 5 de setembro de 2013
  81. 81. Painel Gerencial - cons Risco do tráfego de informação sensível Dados armazenados na “Cloud” quinta-feira, 5 de setembro de 2013
  82. 82. Novos Desafios quinta-feira, 5 de setembro de 2013
  83. 83. Pull Based Pooling Client Server Qual a cotação do $? 2,45 Qual a cotação do $? a mesma Qual a cotação do $? 2,46 quinta-feira, 5 de setembro de 2013
  84. 84. API Real Time quinta-feira, 5 de setembro de 2013
  85. 85. Web Sockets quinta-feira, 5 de setembro de 2013
  86. 86. Web Sockets Stream de Mensagens Bi-Direcional (Client <-> Server) Ajax Reverso, Comet, Long Pooling “TCP Socket” (Canal de Comunicação Full Duplex) Baixa latência (sem overhead de pooling) Suporte Nativo Browsers quinta-feira, 5 de setembro de 2013
  87. 87. Web SocketsBETA quinta-feira, 5 de setembro de 2013
  88. 88. Web Socket (Push) Client Server HandShake Request HandShake Response Me atualize a cotação 2,45 2,45 2,48 ... quinta-feira, 5 de setembro de 2013
  89. 89. Web Socket (Push) Client Server Drools Rules Exposição Cambial Cotação WebSocket Atualização Informação Atualização Informação ... quinta-feira, 5 de setembro de 2013
  90. 90. Domain-Specific Language quinta-feira, 5 de setembro de 2013
  91. 91. Business Readable DSLs com Drools quinta-feira, 5 de setembro de 2013
  92. 92. Business Writable DSLs com GDocs Java API quinta-feira, 5 de setembro de 2013
  93. 93. Inovações Drools + Web Sockets quinta-feira, 5 de setembro de 2013
  94. 94. Seja Criativo!!!! quinta-feira, 5 de setembro de 2013
  95. 95. Ecossistema Java <3 quinta-feira, 5 de setembro de 2013
  96. 96. Obrigado! @ederign quinta-feira, 5 de setembro de 2013

×