Slides pro primeiro Workshop de SOA realizado na SEA. A essência deste material é apenas mostrar uma visão new-school do hype-corporativo tão martelado pelos grandes fabricantes.
41. Interview
John Crupi on Enterprise SOA
So service oriented architecture, hype or reality?
A little of both there's a lot of hype behind it. (...) it's
architectural driven and if
you don't have the architecture
in place there's no product that
out of the box will give you
SOA today.
Friday, February 13, 2009
43. #1
SOA
tem a ver
com filosofia
e não
com tecnologia
Friday, February 13, 2009
44. #2
SOA
tem a ver
com R.O.I.
Friday, February 13, 2009
45. #3
SOA
tem a ver com
governança de ativos
Friday, February 13, 2009
46. Article
Quest for True SOA
Posted by Alex Maclinovsky on Sep 10, 2008
According to these definitions, SOA
Governance is what turns Enterprise Services
from digital artifacts into true business
assets by allowing responsible reuse
across the domains of control of SOA
participants
Friday, February 13, 2009
49. Lato Sensu em Sistemas Orientados a Objetos
Laboratório de Tópicos Avançados - 2°/2008
Antes de trocar,
você reforma
Friday, February 13, 2009
50. Lato Sensu em Sistemas Orientados a Objetos
Laboratório de Tópicos Avançados - 2°/2008
...até a última ponta gota
Friday, February 13, 2009
51. Article
SOA Governance: An Enterprise View
Posted by Michael Poulin on Aug 20, 2008 03:54 AM
Friday, February 13, 2009
52. Article
SOA Governance: An Enterprise View
Posted by Michael Poulin on Aug 20, 2008 03:54 AM
(...)organisations were assured that SOA was new
IT technology for integration and reuse of
existing assets.
Friday, February 13, 2009
53. Article
SOA Governance: An Enterprise View
Posted by Michael Poulin on Aug 20, 2008 03:54 AM
Very few succeeded and went forward
Friday, February 13, 2009
54. Article
SOA Governance: An Enterprise View
Posted by Michael Poulin on Aug 20, 2008 03:54 AM
Other organisations failed in gaining
promised ROI and time to market
Friday, February 13, 2009
55. Interview
Jim Webber on quot;Guerilla SOAquot;
A lot of SOA projects I have seen, have been
somewhat akin to mobilizing an army.
We want to address specific discrete business
problems, organized by
priorities according
to the business stakeholder
and get those processes
implemented rapidly in an
incremental way with
feedback.
lots of
Friday, February 13, 2009
56. Major changes in
technology have
not been driven by
the technologies
themselves but by
the change in
thinking that
they enabled.
Friday, February 13, 2009
57. “Enterprises around the world are increasingly pursuing the
core business benefits of Service-Oriented Architecture
(SOA)—business agility, reduction in integration expense,
greater asset reuse, and improved business visibility. And
yet, many large organizations are running into roadblocks
with their heavyweight, enterprise-wide SOA initiatives. As
an alternative, many organizations are finding a “right
weight,” step-by-step approach to SOA is more
effective and lowers risk as well.”
SIMPLIFYING SOA
LOW RISK, HIGH VALUE, “RIGHT WEIGHT” SOA
December 2007
Analyst: Jason Bloomberg
Friday, February 13, 2009
58. Economically,
quot;right-sourcingquot;
is far more eficient
than quot;outsourcingquot;
and SaaS.
Friday, February 13, 2009
59. Interview
Stefan Tilkov on SOA
Why SOA? Why now? What's
actually new?
(...) What I think is exciting is
the fact that it creates, or at
least that it is perceived to
create the opportunity to
align business and
technology.
Friday, February 13, 2009
84. Lato Sensu em Sistemas Orientados a Objetos
Laboratório de Tópicos Avançados - 2°/2008
Na vida real, as coisas não são tão simples assim
Friday, February 13, 2009
85. Lato Sensu em Sistemas Orientados a Objetos
Laboratório de Tópicos Avançados - 2°/2008
Nem sempre as peças se encaixam
Friday, February 13, 2009
86. Nem sempre os serviços falam a mesma língua
Friday, February 13, 2009
91. Lato Sensu em Sistemas Orientados a Objetos
Laboratório de Tópicos Avançados - 2°/2008
Nem sempre o destino da mensagem é conhecido
Friday, February 13, 2009
99. ?
Como tomar esta decisão?
Friday, February 13, 2009
100. package poker; import java.util.ArrayList; import java.util.Arrays; import
java.util.Collection; import java.util.Collections; import java.util.Comparator; import
?xml version = quot;1.0quot; encoding = quot;UTF-8quot;? jbossesb xmlns=quot;http://
java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map;
anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/
import java.util.Set; import java.util.Map.Entry; public class PokerHand { public static
final int HIGH_CARD = 0; public static final int ONE_PAIR = 1; public static final int jbossesb-1.0.1.xsdquot; parameterReloadSecs=quot;5quot;providers jms-provider
TWO_PAIRS = 2; public static final int THREE_OF_A_KIND = 3; public static final int name=quot;JBossMQquot; connection-factory=quot;ConnectionFactoryquot; jms-bus
STRAIGHT = 4; public static final int FLUSH = 5; public static final int FULL_HAND = 6;
busid=quot;quickstartGwChannelquot; jms-message-filter dest-type=quot;QUEUEquot; dest-
public static final int FOUR_OF_A_KIND = 7; public static final int STRAIGHT_FLUSH = 8;
name=quot;queue/quickstart_simple_cbr_Requestquot; / /jms-bus jms-bus
private Card[] cards = new Card[5]; public PokerHand(Card c1, Card c2, Card c3, Card c4,
busid=quot;quickstartEsbChannelquot; jms-message-filter dest-type=quot;QUEUEquot; dest-
Card c5) throws InvalidHandException { cards[0] = c1; cards[1] = c2; cards[2] = c3;
name=quot;queue/Bquot; / /jms-bus jms-bus busid=quot;CBRNormalShippingquot; jms-message-
cards[3] = c4; cards[4] = c5; if (!isValid()) throw new InvalidHandException(cards); }
private boolean isValid() { SetCard set = new HashSetCard(); for (Card c : cards) filter dest-type=quot;QUEUEquot; dest-name=quot;queue/CBRNormalShippingquot; / /jms-bus
set.add(c); if (set.size() != cards.length) return false; return true; } public int jms-bus busid=quot;CBRExpressFreeShippingquot; jms-message-filter dest-type=quot;QUEUEquot;
getGame() { MapInteger, Integer cardsCount = countCards(); CollectionInteger
dest-name=quot;queue/CBRExpressFreeShippingquot; / /jms-bus/jms-provider /
combinations = cardsCount.values(); if (combinations.contains(3)) { if
providersservices!-- ESB CBR Service -- service
(combinations.contains(2)) { return FULL_HAND; } return THREE_OF_A_KIND; } if
category=quot;MyFirstCBRServicesESBquot; name=quot;FirstCBRServiceESBquot; description=quot;ESB
(combinations.remove(2)) { if (combinations.contains(2)) { return TWO_PAIRS; } else
?
{ return ONE_PAIR; } } if(combinations.contains(4)){ return FOUR_OF_A_KIND; } Listenerquot; listeners !-- Gateway -- jms-listener name=quot;the-gatewayquot;
MapInteger, Integer suitCounter = countSuits(); if (isStraight()){ if busidref=quot;quickstartGwChannelquot; is-gateway=quot;truequot; / jms-listener
(suitCounter.values().contains(5)){ return STRAIGHT_FLUSH; } else { return STRAIGHT; } }
name=quot;XPathContentBasedRouterquot; busidref=quot;quickstartEsbChannelquot; /jms-listener
if (suitCounter.values().contains(5)){ return FLUSH; } return HIGH_CARD; } private
/listeners actions mep=quot;OneWayquot; action
MapInteger, Integer countSuits() { MapInteger, Integer suitCounter = new
class=quot;org.jboss.soa.esb.actions.ContentBasedRouterquot; name=quot;ContentBasedRouterquot;
HashMapInteger, Integer(); for (Card card : cards) { if
property name=quot;ruleSetquot; value=quot;SimpleCBRRules-XPath.drlquot;/ property
(suitCounter.get(card.getSuit()) == null) { suitCounter.put(card.getSuit(), 1); } else
programaticamente declarativamente
{ suitCounter.put(card.getSuit(), suitCounter.get(card.getSuit()) + 1); } } return name=quot;ruleLanguagequot; value=quot;XPathLanguage.dslquot;/ property name=quot;ruleReloadquot;
suitCounter; } /** * [ [k, 2], * [q, 2], * [T, 1]] * @return */ private MapInteger, value=quot;truequot;/ property name=quot;destinationsquot; route-to destination-
Integer countCards() { MapInteger, Integer counter = new HashMapInteger, Integer();
name=quot;expressquot; service-category=quot;ExpressShippingquot; service-
for (Card card : cards) { if (counter.get(card.getNumber()) == null)
name=quot;ExpressShippingServicequot;/ route-to destination-name=quot;normalquot; service-
{ counter.put(card.getNumber(), 1); } else { counter.put(card.getNumber(),
category=quot;NormalShippingquot; service-name=quot;NormalShippingServicequot;/ /property
counter.get(card.getNumber()) + 1); }} return counter; }private boolean isStraight()
{ Arrays.sort(cards); int i = 1; int limit; //Verifica sequencia onde o straight termina /action /actions /service!-- Normal Shipping -- service
com ace if(cards[4].getNumber() == Card.ACE cards[0].getNumber() == Card.TWO){ limit = category=quot;NormalShippingquot; name=quot;NormalShippingServicequot; description=quot;Normal
4; } else { limit = 5; } for (i=1 ; i limit; i++) { if (cards[i - 1].getNumber() + 1 !=
Shipping Servicequot; listeners jms-listener name=quot;CBRNormalShippingquot;
cards[i].getNumber()) return false; } return true; } @Override public String toString()
busidref=quot;CBRNormalShippingquot;/ /listeners actions mep=quot;OneWayquot; action
{ return quot; quot; + cards[0].getNumber() + quot; quot;+ cards[0].getSuit() + quot; - quot; +
name=quot;testStorequot; class=quot;org.jboss.soa.esb.actions.TestMessageStorequot;/ action
cards[1].getNumber() + quot; quot;+ cards[1].getSuit() + quot; - quot; + cards[2].getNumber() + quot; quot;+
name=quot;displayMessageActionquot;
cards[2].getSuit() + quot; - quot; + cards[3].getNumber() + quot; quot;+ cards[3].getSuit() + quot; - quot; +
cards[4].getNumber() + quot; quot;+ cards[4].getSuit(); } public Card[] getCards(){ return class=quot;org.jboss.soa.esb.samples.quickstart.simplecbr.MyJMSListenerActionquot;
cards; } public int compareTo(PokerHand hand2) { int comparison = this.getGame()- process=quot;displayMessagequot; / !-- This can be replaced with notification --
hand2.getGame(); //desempate. if(comparison==0){ Integer[] criteriosHand2 =
action name=quot;routequot;
hand2.getCriteriosDesempate(); Integer[] criteriosThis = this.getCriteriosDesempate();
class=quot;org.jboss.soa.esb.samples.quickstart.simplecbr.RouteNormalShippingquot;
for(int i=0;icriteriosThis.length;i++){ comparison = criteriosThis[i]-criteriosHand2[i];
process=quot;sendResponsequot; / /actions /service!-- Express Shipping --
if(comparison!=0){ break; } } } return comparison; } /** * Retorna um array com as cartas
na ordem em que so consideradas para o * desempate de duas mos que tem o mesmo jogo. * service category=quot;ExpressShippingquot; name=quot;ExpressShippingServicequot;
* ex: KKKQQ retorna [K,Q] * ex: QQQKK retorna [Q,K] * ex: A2345 retorna [5, 4, 3, 2, A] * description=quot;Express Shipping Servicequot; listeners jms-listener
ex: TT245 retorna [T,5,4,2] * ex: T2245 retorna [2,T,5,4] * ex: flush 2379T retorna [T,
name=quot;CBRExpressFreeShippingquot; busidref=quot;CBRExpressFreeShippingquot;/ /listeners
9,7,3,2] * * @return */ public Integer[] getCriteriosDesempate() { MapInteger, Integer
actions mep=quot;OneWayquot; action name=quot;testStorequot;
mapa = this.countCards(); ListEntry criterios = new ArrayListEntry();
class=quot;org.jboss.soa.esb.actions.TestMessageStorequot;/ action
criterios.addAll(mapa.entrySet()); Collections.sort(criterios, new ComparatorEntry(){ /
name=quot;displayMessageActionquot;
** * Ordena primeiro pelo valor e depois pela chave * * @param o1 * @param o2 * @return
*/ public int compare(Entry o1, Entry o2) { int comparacao = ((Integer)o2.getValue()) - class=quot;org.jboss.soa.esb.samples.quickstart.simplecbr.MyJMSListenerActionquot;
((Integer)o1.getValue()); if (comparacao == 0) { comparacao = ((Integer)o2.getKey()) - process=quot;displayMessagequot; / !-- This can be replaced with notification --
((Integer)o1.getKey()); } return comparacao; } }); // extrai os keys dos entrysets
action name=quot;routequot;
ordenados Integer[] retorno = new Integer[criterios.size()]; for (int i=0 ;
class=quot;org.jboss.soa.esb.samples.quickstart.simplecbr.RouteExpressShippingquot;
icriterios.size() ; i++) { retorno[i] = (Integer) criterios.get(i).getKey(); } //
process=quot;sendResponsequot; / /actions /service /services/jbossesb
straight comeando com ace if (isStraight() retorno[4] == Card.TWO retorno[0] ==
Card.ACE) { return new Integer[]{Card.FIVE, Card.FOUR, Card.THREE, Card.TWO, Card.ACE}; }
return retorno; } }
Friday, February 13, 2009
101. package poker; import java.util.ArrayList; import java.util.Arrays; import
java.util.Collection; import java.util.Collections; import java.util.Comparator; import
?xml version = quot;1.0quot; encoding = quot;UTF-8quot;? jbossesb xmlns=quot;http://
java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map;
anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/
import java.util.Set; import java.util.Map.Entry; public class PokerHand { public static
final int HIGH_CARD = 0; public static final int ONE_PAIR = 1; public static final int jbossesb-1.0.1.xsdquot; parameterReloadSecs=quot;5quot;providers jms-provider
TWO_PAIRS = 2; public static final int THREE_OF_A_KIND = 3; public static final int name=quot;JBossMQquot; connection-factory=quot;ConnectionFactoryquot; jms-bus
STRAIGHT = 4; public static final int FLUSH = 5; public static final int FULL_HAND = 6;
busid=quot;quickstartGwChannelquot; jms-message-filter dest-type=quot;QUEUEquot; dest-
public static final int FOUR_OF_A_KIND = 7; public static final int STRAIGHT_FLUSH = 8;
name=quot;queue/quickstart_simple_cbr_Requestquot; / /jms-bus jms-bus
private Card[] cards = new Card[5]; public PokerHand(Card c1, Card c2, Card c3, Card c4,
busid=quot;quickstartEsbChannelquot; jms-message-filter dest-type=quot;QUEUEquot; dest-
Card c5) throws InvalidHandException { cards[0] = c1; cards[1] = c2; cards[2] = c3;
name=quot;queue/Bquot; / /jms-bus jms-bus busid=quot;CBRNormalShippingquot; jms-message-
cards[3] = c4; cards[4] = c5; if (!isValid()) throw new InvalidHandException(cards); }
private boolean isValid() { SetCard set = new HashSetCard(); for (Card c : cards) filter dest-type=quot;QUEUEquot; dest-name=quot;queue/CBRNormalShippingquot; / /jms-bus
set.add(c); if (set.size() != cards.length) return false; return true; } public int jms-bus busid=quot;CBRExpressFreeShippingquot; jms-message-filter dest-type=quot;QUEUEquot;
getGame() { MapInteger, Integer cardsCount = countCards(); CollectionInteger
dest-name=quot;queue/CBRExpressFreeShippingquot; / /jms-bus/jms-provider /
combinations = cardsCount.values(); if (combinations.contains(3)) { if
providersservices!-- ESB CBR Service -- service
(combinations.contains(2)) { return FULL_HAND; } return THREE_OF_A_KIND; } if
category=quot;MyFirstCBRServicesESBquot; name=quot;FirstCBRServiceESBquot; description=quot;ESB
(combinations.remove(2)) { if (combinations.contains(2)) { return TWO_PAIRS; } else
{ return ONE_PAIR; } } if(combinations.contains(4)){ return FOUR_OF_A_KIND; } Listenerquot; listeners !-- Gateway -- jms-listener name=quot;the-gatewayquot;
MapInteger, Integer suitCounter = countSuits(); if (isStraight()){ if busidref=quot;quickstartGwChannelquot; is-gateway=quot;truequot; / jms-listener
(suitCounter.values().contains(5)){ return STRAIGHT_FLUSH; } else { return STRAIGHT; } }
name=quot;XPathContentBasedRouterquot; busidref=quot;quickstartEsbChannelquot; /jms-listener
if (suitCounter.values().contains(5)){ return FLUSH; } return HIGH_CARD; } private
/listeners actions mep=quot;OneWayquot; action
MapInteger, Integer countSuits() { MapInteger, Integer suitCounter = new
class=quot;org.jboss.soa.esb.actions.ContentBasedRouterquot; name=quot;ContentBasedRouterquot;
HashMapInteger, Integer(); for (Card card : cards) { if
property name=quot;ruleSetquot; value=quot;SimpleCBRRules-XPath.drlquot;/ property
(suitCounter.get(card.getSuit()) == null) { suitCounter.put(card.getSuit(), 1); } else
declarativamente
programaticamente
{ suitCounter.put(card.getSuit(), suitCounter.get(card.getSuit()) + 1); } } return name=quot;ruleLanguagequot; value=quot;XPathLanguage.dslquot;/ property name=quot;ruleReloadquot;
suitCounter; } /** * [ [k, 2], * [q, 2], * [T, 1]] * @return */ private MapInteger, value=quot;truequot;/ property name=quot;destinationsquot; route-to destination-
Integer countCards() { MapInteger, Integer counter = new HashMapInteger, Integer();
name=quot;expressquot; service-category=quot;ExpressShippingquot; service-
for (Card card : cards) { if (counter.get(card.getNumber()) == null)
name=quot;ExpressShippingServicequot;/ route-to destination-name=quot;normalquot; service-
{ counter.put(card.getNumber(), 1); } else { counter.put(card.getNumber(),
category=quot;NormalShippingquot; service-name=quot;NormalShippingServicequot;/ /property
counter.get(card.getNumber()) + 1); }} return counter; }private boolean isStraight()
{ Arrays.sort(cards); int i = 1; int limit; //Verifica sequencia onde o straight termina /action /actions /service!-- Normal Shipping -- service
com ace if(cards[4].getNumber() == Card.ACE cards[0].getNumber() == Card.TWO){ limit = category=quot;NormalShippingquot; name=quot;NormalShippingServicequot; description=quot;Normal
4; } else { limit = 5; } for (i=1 ; i limit; i++) { if (cards[i - 1].getNumber() + 1 !=
Shipping Servicequot; listeners jms-listener name=quot;CBRNormalShippingquot;
cards[i].getNumber()) return false; } return true; } @Override public String toString()
busidref=quot;CBRNormalShippingquot;/ /listeners actions mep=quot;OneWayquot; action
{ return quot; quot; + cards[0].getNumber() + quot; quot;+ cards[0].getSuit() + quot; - quot; +
name=quot;testStorequot; class=quot;org.jboss.soa.esb.actions.TestMessageStorequot;/ action
cards[1].getNumber() + quot; quot;+ cards[1].getSuit() + quot; - quot; + cards[2].getNumber() + quot; quot;+
name=quot;displayMessageActionquot;
cards[2].getSuit() + quot; - quot; + cards[3].getNumber() + quot; quot;+ cards[3].getSuit() + quot; - quot; +
cards[4].getNumber() + quot; quot;+ cards[4].getSuit(); } public Card[] getCards(){ return class=quot;org.jboss.soa.esb.samples.quickstart.simplecbr.MyJMSListenerActionquot;
cards; } public int compareTo(PokerHand hand2) { int comparison = this.getGame()- process=quot;displayMessagequot; / !-- This can be replaced with notification --
hand2.getGame(); //desempate. if(comparison==0){ Integer[] criteriosHand2 =
action name=quot;routequot;
hand2.getCriteriosDesempate(); Integer[] criteriosThis = this.getCriteriosDesempate();
class=quot;org.jboss.soa.esb.samples.quickstart.simplecbr.RouteNormalShippingquot;
for(int i=0;icriteriosThis.length;i++){ comparison = criteriosThis[i]-criteriosHand2[i];
process=quot;sendResponsequot; / /actions /service!-- Express Shipping --
if(comparison!=0){ break; } } } return comparison; } /** * Retorna um array com as cartas
na ordem em que so consideradas para o * desempate de duas mos que tem o mesmo jogo. * service category=quot;ExpressShippingquot; name=quot;ExpressShippingServicequot;
* ex: KKKQQ retorna [K,Q] * ex: QQQKK retorna [Q,K] * ex: A2345 retorna [5, 4, 3, 2, A] * description=quot;Express Shipping Servicequot; listeners jms-listener
ex: TT245 retorna [T,5,4,2] * ex: T2245 retorna [2,T,5,4] * ex: flush 2379T retorna [T,
name=quot;CBRExpressFreeShippingquot; busidref=quot;CBRExpressFreeShippingquot;/ /listeners
9,7,3,2] * * @return */ public Integer[] getCriteriosDesempate() { MapInteger, Integer
actions mep=quot;OneWayquot; action name=quot;testStorequot;
mapa = this.countCards(); ListEntry criterios = new ArrayListEntry();
class=quot;org.jboss.soa.esb.actions.TestMessageStorequot;/ action
criterios.addAll(mapa.entrySet()); Collections.sort(criterios, new ComparatorEntry(){ /
name=quot;displayMessageActionquot;
** * Ordena primeiro pelo valor e depois pela chave * * @param o1 * @param o2 * @return
*/ public int compare(Entry o1, Entry o2) { int comparacao = ((Integer)o2.getValue()) - class=quot;org.jboss.soa.esb.samples.quickstart.simplecbr.MyJMSListenerActionquot;
((Integer)o1.getValue()); if (comparacao == 0) { comparacao = ((Integer)o2.getKey()) - process=quot;displayMessagequot; / !-- This can be replaced with notification --
((Integer)o1.getKey()); } return comparacao; } }); // extrai os keys dos entrysets
action name=quot;routequot;
ordenados Integer[] retorno = new Integer[criterios.size()]; for (int i=0 ;
class=quot;org.jboss.soa.esb.samples.quickstart.simplecbr.RouteExpressShippingquot;
icriterios.size() ; i++) { retorno[i] = (Integer) criterios.get(i).getKey(); } //
process=quot;sendResponsequot; / /actions /service /services/jbossesb
straight comeando com ace if (isStraight() retorno[4] == Card.TWO retorno[0] ==
Card.ACE) { return new Integer[]{Card.FIVE, Card.FOUR, Card.THREE, Card.TWO, Card.ACE}; }
return retorno; } }
Friday, February 13, 2009
102. Lato Sensu em Sistemas Orientados a Objetos
Laboratório de Tópicos Avançados - 2°/2008
Configuração declarativa de regras
Friday, February 13, 2009
103. Pra isso, usa-se um
Engine de Regras
para
declaração execução
Friday, February 13, 2009
104. Pra isso, usa-se um
Engine de Regras
para
declaração execução
Friday, February 13, 2009
105. regras
fatos engine de regras decisão
Friday, February 13, 2009
106. regras
+ + =
engine de regras decisão
fatos
Friday, February 13, 2009
108. Lato Sensu em Sistemas Orientados a Objetos
Laboratório de Tópicos Avançados - 2°/2008
Às vezes o processamento de uma mensagem
envolve vários serviços, que precisam ser
coordenados entre si.
Friday, February 13, 2009
124. PR
alexandre.gomes@seatecnologia.com.br
blog.seatecnologia.com.br
Friday, February 13, 2009
Notes de l'éditeur
O pilar fundamental chama-se serviço.
Tem gente que diz que SOA é arquitetura, uma infra-estrutura, um padrão, um método
Independente do que seja, o que todos querem é a interoperabilidade de serviços que, através do intercâmbio de mensagens são capazes de integrarem entre si de forma altamente desacoplada, coordenada e orquestrada, para a composição de processos de negócio, tudo isso pra viabilizar o reuso
Tudo começa quando um elemento X deseja comunicar-se com um elemento Y, numa estratégia chamada de RPC, de onde derivaram tecnologias como CORBA, RMI e WebServices
No mundo real, essa comunicação se dá com vários elementos X, Y e Z
Com a tendência utópica de se chegar no ponto de criarmos aplicações como se fossem Legos.
UTOPIA que existiu no CORBA, no EJB e nos WebServices
E aí os grandes fabricantes trouxeram para o mercado soluções complexíssimas, cheias de tecnologias e prome$$a$
E, para a implantação de SOA, usam a estratégia stop-the-world. 1 ano para a implantação completa.
Sem, contudo, avisar de que se trata de uma longa e solitária viagem.
E aí, a história colou?
Em 2005 fizemos o Café Brasil....
Alguns projetos até que vingaram de lá pra cá, mas quase sempre no melhor estilo Torre de Babel (querer alcancar os céus)
Ou seria um castelo de cartas?
Só que o modelo não tava escalando (fazer mais com o mesmo ou o mesmo com menos)
- E aí você pode perguntar: SOA é hype ou realidade?
- CTO for Sun's Enterprise Web Service Practice: “SOA não está num produto”
E é daí que começa a idéia do SOA de Guerrilha
SOA é a disciplina de aproveitar ao máximo o que já existe...
...pra evitar que o mesmo investimento seja refeito várias vezes
Afinal, software é um ativo tão valioso quanto móveis e máquinas.
Geralmente, nunca descartamos algo antes de tentar recuperar sua utilidade.
E, se em tudo na vida, sempre queremos aproveitar até a última gota, por que não com software?
- Entretanto, o caminho seguido não tem sido dos melhores
- Muitos estão fazendo exageradamente o que se diz certo
- Poucos têm obtido êxito
- Vários têm falhado
- Por falta de governança!
- Jim Webber, da ThoughtWorks. Empresa do Martin Fowler.
- Artigo que resume bem tudo o que tá acontecendo por aí.
- SOA: Implantação incremental, por prioridades e guiado por muito feedback.
Este livro diz tudo.
As grandes mudanças não estão na tecnologia, mas na forma de se pensar software.
Ao invés de abordagems pesadas e trabalhosas, prefira as adoções passo-a-passo, colhendo os benefícios o mais rápido possível
innoQ SOA consultant and InfoQ SOA Community editor
- Então, nesta visão moderna (ou pós-moderna), SOA, em primeiro lugar, é um ESTILO de arquitetura que busca primordialmente maiores LUCROS através da preocupação constante com o ROI.
- Para isso, o REAPROVEITAMENTO dos ATIVOS existentes deve ser sempre realizado o quão antes possível, com AGILIDADE, não necessariamente visando a rapidez, mas a EFETIVIDADE dos resultados.
Temos então o seguinte cenário.
Você já possui alguns legados existentes que precisam ser integrados.
Só que novos legados podem sempre aparecer, de fornecedores, clientes, etc, que também precisam ser incorporados ao ecosistema existente.
Como integrá-los?
Existem alguns modelos....
Todo mundo fala com todo mundo.
Comunicação centralizada.
Mais simples.
Lógica de integração separada da lógica de negócio (clichê)
Em ambos os casos, busca-se a mesma coisa: reaproveitamento
Tecnologias de comunicação ponto-a-ponto
A tecnologia da moda para este tipo de integração se chama “Barramento de integração de serviços”
E são nos ESBs que nos concentraremos.
- A idéia é que todos os seviços estejam ligados ao barramento.
- Um serviço cria uma mensagem
- Posta a mensagem no barramento
- O barramento entrega a mensagem
- A mensagem é lida pelo serviço de destino
Mas, na vida real, as coisas não são tão simples assim.
Ou seja, nem sempre a mensagem produzida por um serviço é compreendida por outro, sendo necessária sua transformação no meio do caminho.
Não necessariamente um serviço entende o formato da mensagem de outro serviço.
Ou seja, o destino da mensagem pode ser calculado dinamicamente, durante o seu envio.
E não necessariamente o destinatário da mensagem é estaticamente definido. Daí, fica no barramento a responsabilidade de decidir (rotear) o rumo das mensagens.
Sempre há duas formas.
- Uma com código Java e outra com código XML
- Em Java há a cultura da programação declarativa: segurança, transação, persistência...
Ou seja, ao invés de programar a regra, você a declara em alto nível
-Então, o que um engine de regras faz é analisar os FATOS sob a luz das REGRAS existentes para proferir sua DECISÃO
- Ou seja, REGRAS + FATOS + ENGINE = DECISAO
Quem faz isso no mercado?
Uma mensagem pode ser processada por vários serviços.
Mais ainda. Uma mensagem pode ser consumida por um serviço, que gera outra mensagem, que é consumida por outro serviço...
E se um dos serviços for, na verdade, uma tarefa manual que deve ser executada por um ser humano?
A medida que a quantidade de serviços aumenta, sua composição e coordenação torna-se mais complexa.
- E aí que se torna necessária a utilização de um engine de processos.
- Ferramenta para automação do processo de controle de processos
O funcionamento é o seguinte:
- Você define o processo
- Submete-o ao engine
- Deixa que o engine o execute quantas vezes forem necessárias
No mercado, um exemplo de aplicação dessa natureza é o JBoss jBPM