Esfinge SystemGlue - Framework para Integração de Aplicações
Visão geral
Ele permite que sejam criados contextos na aplicação de forma que o framework possa:
- Executar um método de integração, de forma síncrona ou assíncrona, com a possibilidade de utilizar seus próprios objetos como parâmetros a serem passados ou sinalizados como destino de retorno da chamada. Esta execução pode ser configurada para disparar antes ou após a invocação de um método da aplicação principal;
- Executar um conjunto de métodos em uma ou mais classes, da mesma forma que o item anterior;
- Agendar a execução de métodos;
- Enviar ou consumir mensagens de um servidor JMS;
Configuração de metadados
@Executions ({ @Execute(clazz=InteligenceIntegration.class, method="getTargetInfo", when=ExecutionMoment.BEFORE, rule="order.targets.size==0") , @Execute(clazz= UnitsIntegration.class, method="sendOrder", when = ExecutionMoment.AFTER,async = true) }) public void saveOrder(@Param("order") Order order){ //core functionality implementation }
Utilizando Arquivos XML
<systemglue> <class name="expl.OrderService"> <method name="saveOrder" params="expl.Order"> <execute class="expl.InteligenceIntegration" method="getTargetInfo" when="BEFORE" rule="order.targets.size == 0"/> <execute class="expl.UnitsIntegration" when="AFTER" method="sendOrder" async="true"/> </method> </class> </systemglue>
Anotações de Domínio
//anotação de domínio @Executions({ @Execute(clazz = InteligenceIntegration.class, when=ExecutionMoment.AFTER, method="getTargetInfo", rule="order.targets.size==0"), @Execute (clazz= UnitsIntegration.class, when = ExecutionMoment.AFTER, method="sendOrder", async = true) }) public @interface OrderModification{} //definição do método @OrderModification public void saveOrder(@Param("order") Order o){}
<systemglue> <annotation name="expl.OrderModification"> <execute class="expl.InteligenceIntegration" method="getTargetInfo" when="BEFORE" rule="order.targets.size == 0"/> <execute class="expl.UnitsIntegration" when="AFTER" method="sendOrder" async="true"/> </annotation> <systemglue>
Anotações do SystemGlue
Segue uma lista que dá uma visão geral as anotações do SystemGlue que configuram execuções nos métodos:
- @Execute (Métodos e outras anotações): Configura a classe e o método a ser executado em outra aplicação.
- @Executions (Métodos e outras Anotações): Aceita um array de @Execute. Portanto, permite a execução de vários métodos em um só evento.
- @ScheduleAt (Métodos e outras Anotações): Agenda a execução de um método para data e hora definidas. Pode definir ainda um intervalo e uma data / hora final para um ciclo de execuções.
- @ScheduleFor (Métodos e outras Anotações): Agenda a execução de um método dentro de um intervalo definido. Exemplo: em 5 minutos. Permite ainda configurar ciclos de execução.
- @MessageRetriever (Métodos): Configura um método para receber uma mensagem de um servidor JMS.
- @MessageSender (Métodos): Configura um método para enviar um objeto a um servidor JMS.
Seguem as anotações utilizadas para o mapeamento de parâmetros e retorno:
- @ReturnName (Métodos): Define um rótulo para o objeto de retorno da execução do método principal, para que o framework possa reutilizá-lo posteriormente.
- @Param (Parâmetros): Utilizado em parâmetros para sinalizá-lo com um rótulo específico e poder mapeá-lo para reutilização durante a execução do método.
A seguir estão detalhadas as anotações com seus respectivos atributos:
@Execute
- clazz: Class – classe que contém o método a ser executado.
- method: String – nome do método a ser executado.
- finder: Class – classe que estende de ObjectFinder e é responsável por instanciar “clazz”. Uma classe padrão é fornecida.
- rule: String – expressão que define uma regra condicional para a execução do método. Como padrão ele sempre será executado.
- async: Boolean – indicador de execução assíncrona do método. O padrão é “false”.
- when: ExecutionMoment – sinaliza o momento de execução do método na outra aplicação, em relação à que dispara a integração: antes (BEFORE) ou depois (AFTER – sendo este o valor padrão).
@Executions
- value: Execute[ ] – array de Anotações @Execute.
@ScheduleAt
- clazz: Class – classe que contém o método a ser executado.
- method: String – nome do método a ser executado.
- startExecution: String – Data e hora para o início da execução, no formato “dd,MM,yyyy,hh24,mi,ss”. Para indicar o dia corrente, é possível utilizar apenas a notação “*,*,*,hh24,mi,ss” onde cada um dos três asteriscos representam, respectivamente: dia atual, mês atual e ano atual.
- endExecution:String – Caso deseje mais de uma execução, informar data e hora para a última execução, no formato “dd,MM,yyyy,hh24,mi,ss”.
- secondsInterval: inteiro – define o intervalo em segundos entre cada execução dentro de um ciclo.
- when: ExecutionMoment – sinaliza o momento de execução do método na outra aplicação, em relação à que dispara a integração: antes (BEFORE) ou depois (AFTER – sendo este o valor padrão).
- finder: Class – classe que estende de ObjectFinder e é responsável por instanciar “clazz”. Uma classe padrão é fornecida.
- rule: String – expressão que define uma regra condicional para a execução do método.
@ScheduleFor
- clazz: Class – classe que contém o método a ser executado.
- method: String – nome do método a ser executado.
- startInHours: int – valor inteiro representando o número de horas para executar o método.
- startInMinutes: int – valor inteiro representando o número de minutos para executar o método. Se houver quantidade de horas informada, soma-se a ela.
- startInSeconds: int – valor inteiro representando o número de segundos para executar o método. Se houver quantidade de horas e minutos informada, soma-se a ela(s).
- secondsInterval: inteiro – define o intervalo em segundos entre cada execução dentro de um ciclo.
- times: inteiro – define o número de execuções, caso deseje mais de uma. O valor padrão é 1.
- when: ExecutionMoment – sinaliza o momento de execução do método na outra aplicação, em relação à que dispara a integração: antes (BEFORE) ou depois (AFTER – sendo este o valor padrão).
- finder: Class – classe que estende de ObjectFinder e é responsável por instanciar “clazz”. Uma classe padrão é fornecida.
- rule: String – expressão que define uma regra condicional para a execução do método.
@MessageRetriever
- IPandPort: String – IP e porta do servidor JMS
- target: String – identificador para o objeto-alvo que receberá o conteúdo da Message. O mesmo identificador será utilizado com @Param ou @ReturnName anotando o elemento com o mesmo identificador.
- destination: DestinationType – informa se a mensagem vem de um tópico (TOPIC) ou uma fila (QUEUE – que é o valor padrão) .
- destinationName: String – nome do tópico ou fila que irá enviar a mensagem.
- when: ExecutionMoment – sinaliza o momento de execução que a conexão será realizada para obtenção da mensagem, em relação ao instante que é chamado o método original: antes (BEFORE) ou depois (AFTER – sendo este o valor padrão).
- messageType: MessageType – indica o tipo do objeto enviado. Os tipos suportados são Objeto (OBJECT) e Texto ( TEXT – sendo este o valor padrão).
- timeoutInSeconds: long – representa o valor em segundos para configurar um time out, caso não exista mensagem no servidor para ser consumida. O padrão é 1 segundo.
@MessageSender
- IPandPort: String – IP e porta do servidor JMS
- target: String – identificador para o objeto-alvo que terá o conteúdo convertido para a Message. O mesmo identificador será utilizado com @Param ou @ReturnName anotando o elemento com o mesmo identificador.
- destination: DestinationType – informa se o destino é um tópico (TOPIC) ou uma fila (QUEUE – que é o valor padrão) .
- destinationName: String – nome do tópico ou fila para onde será enviada a mensagem.
- messageType: MessageType – indica o tipo do objeto enviado. Os tipos suportados são Objeto (OBJECT) e Texto (TEXT – sendo este o valor padrão). O objeto real deve implementar a interface Serializable.
Execução de Método
@Execute(clazz=ServicoCotacao.class, method="publicarSolicitacaoAprovada", when=ExecutionMoment.AFTER) public void aprovarSolicitacao(@param(“solicitacao”) SolicitacaoCompra solicitacao){ solicitacao.setAprovada(); }
Segue a classe que será invocada pelo framework:
public class ServicoCotacao{ public void publicarSolicitacaoAprovada(@param(“solicitacao”) SolicitacaoCompra solicitacao){ //implementação do método } }
AprovadorSolicitacaoCompra aprovador = (AprovadorSolicitacaoCompra) ProxyFactory.createProxy(new AprovadorSolicitacaoCompra()); aprovador.aprovarSolicitacao(solicitacao);
@Executions({ @Execute(clazz=ControleDispensario.class, method="verificarQuantidadeMedicamento", when=ExecutionMoment.AFTER), @Execute(clazz=ServicoReabastecimento.class,method="solicitacaoMedicamento", when=ExecutionMoment.AFTER rule="qtdPedida>=qtdPresente") )} public void prescrever(Medicamento medicamento, @Param("qtdPedida") double quantidade){ //implementação da prescrição }
Abaixo segue a classe ControleDispensario que será invocada:
public class ControleDispensario{ @ReturnName("qtdPresente") public double verificarQuantidadeMedicamento(Medicamento medicamento){ //retorna quantidade do medicamento } }
Abaixo segue a classe ServicoReabastecimento que será invocada de forma condicional:
public class ServicoReabastecimento{ public void solicitacaoMedicamento(Medicamento medicamento){ //solicita o reabastecimento do medicamento } }
Agendamento de uma Execução
@ScheduleFor(clazz=ServicoEntregas.class, method="registraPedido", startInHours=0, startInMinutes=15, startInSeconds=0, when=ExecutionMoment.AFTER) public void iniciaPreparacao(Pedido pedido) { //implementação do método }
@ScheduleAt(clazz=ServicoAgendaTransmissao.class, method="registraPedido", startExecution="*,*,*,22,0,0", when=ExecutionMoment.AFTER) public void confirmacaoPedido(Pedido pedido) { //implementação do método }
Envio e Recebimento de Mensagens
@MessageSender(target="veiculo", IPandPort="192.168.0.1:1099", destination=DestinationType.QUEUE, destinationName="queue/QueueBalancaCentral", messageType=MessageType.OBJECT) public void registrarEntradaVeiculo(@Param("veiculo") Veiculo veiculo) { //Implementação do método }
@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @MessageSender(target="veiculo", IPandPort="192.168.0.1:1099", destination=DestinationType.QUEUE, destinationName="queue/QueueBalancaCentral", messageType=MessageType.OBJECT) public @interface RegistraEntradaVeiculo{ }
Segue agora a classe que utiliza essa anotação:
@RegistraEntradaVeiculo public void registrarEntradaVeiculo(@Param("veiculo")Veiculo veiculo) { //Implementação do método }
Tratamento de erros
Apoio