JOrchestra

microserviço para execução distribuida com hazelcast à partir de endpoint websocket

License

License

GroupId

GroupId

com.github.jimsp
ArtifactId

ArtifactId

jorchestra
Last Version

Last Version

0.0.3
Release Date

Release Date

Type

Type

jar
Description

Description

JOrchestra
microserviço para execução distribuida com hazelcast à partir de endpoint websocket
Project URL

Project URL

https://github.com/JimSP/jorchestra
Source Code Management

Source Code Management

https://github.com/JimSP/jorchestra

Download jorchestra

How to add to project

<!-- https://jarcasting.com/artifacts/com.github.jimsp/jorchestra/ -->
<dependency>
    <groupId>com.github.jimsp</groupId>
    <artifactId>jorchestra</artifactId>
    <version>0.0.3</version>
</dependency>
// https://jarcasting.com/artifacts/com.github.jimsp/jorchestra/
implementation 'com.github.jimsp:jorchestra:0.0.3'
// https://jarcasting.com/artifacts/com.github.jimsp/jorchestra/
implementation ("com.github.jimsp:jorchestra:0.0.3")
'com.github.jimsp:jorchestra:jar:0.0.3'
<dependency org="com.github.jimsp" name="jorchestra" rev="0.0.3">
  <artifact name="jorchestra" type="jar" />
</dependency>
@Grapes(
@Grab(group='com.github.jimsp', module='jorchestra', version='0.0.3')
)
libraryDependencies += "com.github.jimsp" % "jorchestra" % "0.0.3"
[com.github.jimsp/jorchestra "0.0.3"]

Dependencies

compile (6)

Group / Artifact Type Version
com.github.jimsp : jorchestra-core jar 0.0.2-SNAPSHOT
com.github.jimsp : jorchestra-spring-boot-autoconfigure jar 0.0.2-SNAPSHOT
com.github.jimsp : spring-boot-starter-jorchestra jar 0.0.2-SNAPSHOT
com.github.jimsp » jorchestra-dto jar 0.0.2-SNAPSHOT
com.github.jimsp » jorchestra-client jar 0.0.2-SNAPSHOT
com.github.jimsp : jorchestra-example jar 0.0.2-SNAPSHOT

Project Modules

There are no modules declared in this project.

jorchestra

microcontainer para distribuição de execuções, eventos e notificaçes em tempo real, monitorado, administrável e documentado no hazelcast à partir de um endpoint webSocket.

  • Exemplo de Configuração DEFALT:

    @Configuration
    @EnableJOrchestra
    public class DefaultConfiguration {
    
    @Autowired
    private JOrchestraConfigurationProperties jorchestraConfigurationProperties;
    
    @Bean("hazelcastInstance")
    public HazelcastInstance hazelcastInstance() {
      return Hazelcast.getOrCreateHazelcastInstance(new Config(jorchestraConfigurationProperties.getClusterName()));
    }
    }
    
  • Exemplo de uso para mensagens distribuídas:

    @JOrchestra(path="endpoint") -- A1
    public class DistributedMessage{
    public Response executar(final Request request){ --A2
        ...
        return Response.create(); --A3
    }
    }
    

A1: durante a fase de loader da aplicação o microcontainer irá interceptar a anotação @JOrchestra e publicar os métodos da classe anotada em endpoints websocket.

A2: Os endpoint seguem o nome do path descrito em @JOrchestra como prefixo e o nome do método como sulfixo. Para que o método "Response DistributedMessage.executar(Request)" seja executado, é preciso estabelecer uma conexão websocket com endpoint ws://servername:port/endpoint-executar Ao enviar um payload json do Request, o método do bean java anotado será executado.

A3: Após o processamento do Request e o retorno do Response, será enviado para a conexão estabelecida um json de Response.

*Para Mensagens distribuídas não é obrigatório haver parâmetro ou retorno.

  • Exemplo de uso para eventos distribuídos:

    @JOrchestra(path = "events", jOrchestraSignal = JOrchestraSignal.EVENT) --B1
    public class DistributedEvent implements Consumer<EventType>{--B2
    
    @Autowired
    private HazelcastInstance hazelcastInstance; --B3
    
    @Override
    public void accept(final EventType eventType) { --B4
        final ITopic<EventType> topic = hazelcastInstance.getTopic("/events-accept"); -- B5
    topic.publish(eventType); --B6
    }
    }
    

B1: quando a anotação @JOrchestra possui o atributo jOrchestraSignal = JOrchestraSignal.EVENT o java bean é será registrado para escutar determinados tipos de evento. Quando esse evento ocorrer, o microcontainer irá chamar o método accept passando o eventType como parâmetro.

B2: É preciso que a classe java implemente a interface funcional java.util.function.Consumer, pois o microcontainer irá sempre executar o método accept.

B3: Para que seu evento seja distribuído para outras instancias de JOrchestra na infraestrutura privada é preciso submeter o evento para o Hazelcast, o Hazelcast já possui uma configuração DEFAULT que pode ser utilizada com @Autowired.

B4: assinatura padrão de evento, esse método será chamado pelo microcontainer.

B5: O ITopic "/events-accept" foi criado pelo microcontainer durante a fase de loader e possuí um MessageListener já registrado. Esse MessageListener atende no endpoint websocket "/events-accept". Quando é estabelicida uma conexão websocket nesse endpoint, será "empurrado" para a conexão estabelecida o evento publicado no ITopic "/events-accept".

B6: publíca o evento no ITopic "/events-accept", todas as conexões websocket estabelecidas no endpoint "/events-accept" nesse momento irão receber um json do EventType.

  • Exemplo de uso para notificacões distribuídas:

    @JOrchestra(path = "notification", jOrchestraSignal = JOrchestraSignal.NOTIFICATION) --C1
    public class DistributedNotification{
    
    @Autowired
    private HazelcastInstance hazelcastInstance; --C2
    
    public void onNotify(final Notification notification) { --C3
      final ITopic<JOrchestraNotification> topic = hazelcastInstance.getTopic("/notification-onNotify"); --C4
      topic.publish(new JOrchestraNotification(TransferResponse.class.getName(), messageData)); --C5
    }
    }
    

C1: registrando o bean como notificação distribuída, O java bean DistributedNotification deve ser chamado em pontos específicos da sua aplicação para que as conexes websocket estabelicidas no dado endpoint recebam o json da Notification.

C2: recebendo instancia default do Hazelcast.

C3: método para enviar a notificação.

C4: ITopic criado pelo loader do microcontainer.

C5: publicação da notificação para o endpoint "/notification-onNotify".

  • Documentação automática. Deve ser estabelecida uma conexão com o endpoint "/jorchestra-beans", ao enviar uma mensagem "vazia" o microcontainer irá responder com os endpoints disponiveis e templates das mensagens.

Abaixo o template do projeto jorchestra-example, disponível nesse repositório:

  [{"jOrchestraBeanName":"trustService","jOrchestraPath":"/jOrchestra-trust","requestTemplate":null,"responseTemplate":"\"JOrchestra :-)\"","message":null},{"jOrchestraBeanName":"JOrchestraBeans","jOrchestraPath":"/jOrchestra-beans","requestTemplate":null,"responseTemplate":"[]","message":null},{"jOrchestraBeanName":"JOrchestraHelloWordSystemEvent","jOrchestraPath":"/events-accept","requestTemplate":null,"responseTemplate":"\"\"","message":null},{"jOrchestraBeanName":"JOrchestraNotificationEletronicTransferAccount","jOrchestraPath":"/notification-account","requestTemplate":"{\"transferIdentification\":\"7fffffff-ffff-ffff-7fff-ffffffffffff\",\"statusWithdraw\":\"ERROR\",\"statusTransfer\":\"ERROR\",\"transferRequest\":{\"transferIdentification\":\"740bc938-e0a2-4165-8de0-4c8ee4ff5ffe\",\"from\":{\"accountNumber\":9223372036854775807},\"to\":{\"accountNumber\":9223372036854775807},\"value\":9223372036854775807}}","responseTemplate":"\"ERROR\"","message":null},{"jOrchestraBeanName":"electronicTransferOfFundsExample","jOrchestraPath":"/account-transfer","requestTemplate":"{\"transferIdentification\":\"11a877dc-e5cb-42e0-b359-ef0fc5d8eca6\",\"from\":{\"accountNumber\":9223372036854775807},\"to\":{\"accountNumber\":9223372036854775807},\"value\":9223372036854775807}","responseTemplate":"{\"transferIdentification\":\"7fffffff-ffff-ffff-7fff-ffffffffffff\",\"statusWithdraw\":\"ERROR\",\"statusTransfer\":\"ERROR\",\"transferRequest\":{\"transferIdentification\":\"b5a52596-4f0e-4cb3-9f49-89cb02beb595\",\"from\":{\"accountNumber\":9223372036854775807},\"to\":{\"accountNumber\":9223372036854775807},\"value\":9223372036854775807}}","message":null},{"jOrchestraBeanName":"extractRequestByEmail","jOrchestraPath":"/extractByEmail-send","requestTemplate":"{\"account\":{\"accountNumber\":9223372036854775807},\"period\":{\"from\":1524274465373,\"to\":1524274465377}}","responseTemplate":"\"\"","message":null}]

*Os valores prenchidos no template são meramente exemplos do tipo de dado, não devem ser utilizados.

  • Monitoramento automático: Todas as conexões websocket estabelecidas e mensagens distribuídas enviadas no microcontainer são gerenciadas e seus estados são classificados como:

    SESSION_OPEN - conexão estabelecida DATA_WAITING - payload aguardando processamento. DATA_PROCESSING - payload em processamento. DATA_SUCCESS - payload processado com sucesso. DATA_ERROR - erro ao tentar processar payload. SESSION_CLOSE - conexão fechada.

Ao estabelecer uma conexão com o endpoint websocket "/jOrchestra-monitor" é possivel receber do microcontainer o estado das conexões estabelecidas e payload enviados aos endpoints disponíveis à partir desse momento.

Abaixo o payload recebido pela conexão estabelecida no endpoint "/jOrchestra-monitor". Esse payload foi enviado quando uma conexão foi estabelecida no path "jOrchestra-beans", enviado um payload e encerrada a conexão.

  {"id":"jOcrhestra#JOrchestraExampleApp-Dev#2#4a4d39e6-4342-489e-8d21-e04d461ff815","clusterName":"jOcrhestra","jOcrhestrName":"JOrchestraExampleApp-Dev","sessionId":"2","requestId":"4a4d39e6-4342-489e-8d21-e04d461ff815","beginTimestamp":1515344992534,"endTimestamp":null,"jOrchestraState":"SESSION_OPEN","payload":null}
	
  {"id":"jOcrhestra#JOrchestraExampleApp-Dev#2#b78d1c6a-a080-4ffc-8fa8-8b872272897a","clusterName":"jOcrhestra","jOcrhestrName":"JOrchestraExampleApp-Dev","sessionId":"2","requestId":"b78d1c6a-a080-4ffc-8fa8-8b872272897a","beginTimestamp":null,"endTimestamp":null,"jOrchestraState":"DATA_WAITING","payload":""}
	
  {"id":"jOcrhestra#JOrchestraExampleApp-Dev#2#a230de4a-8aac-4953-8059-82783d26e672","clusterName":"jOcrhestra","jOcrhestrName":"JOrchestraExampleApp-Dev","sessionId":"2","requestId":"a230de4a-8aac-4953-8059-82783d26e672","beginTimestamp":1515344997551,"endTimestamp":null,"jOrchestraState":"DATA_PROCESSING","payload":""}

  {"id":"jOcrhestra#JOrchestraExampleApp-Dev#2#5bffcc48-d95b-470f-b4dd-6c4cfe34f605","clusterName":"jOcrhestra","jOcrhestrName":"JOrchestraExampleApp-Dev","sessionId":"2","requestId":"5bffcc48-d95b-470f-b4dd-6c4cfe34f605","beginTimestamp":null,"endTimestamp":1515344997691,"jOrchestraState":"DATA_SUCCESS","payload":""}

  {"id":"jOcrhestra#JOrchestraExampleApp-Dev#2#979f3728-1684-444e-9d05-880011ac889a","clusterName":"jOcrhestra","jOcrhestrName":"JOrchestraExampleApp-Dev","sessionId":"2","requestId":"979f3728-1684-444e-9d05-880011ac889a","beginTimestamp":null,"endTimestamp":1515345000688,"jOrchestraState":"SESSION_CLOSE","payload":null}
  • Gerenciamento do microcontainer. Para gerenciamento do JOrchestra basta estabelecer uma conexão com o endpoint websocket "/jOrchestra-admin".

Após estabelecida a conexão, é possível enviar comandos ao JOrchestra. Os comandos disponíveis são:

CANCEL_TASK_RUNNING - cancela uma execução de uma mensagem em execução.
CANCEL_TASK_NOT_RUNNING - cancela a execuão de uma mensagem que não esteja sendo executada.
SHELL - executa um comando no Shell da máquina da instância do JORchestra.

exemplos para cancelamento de uma mensagem:

  {"jOrchestaPath":"${CAMINHO_JORCHESTRA}","sessionId":"${SESSION_ID}","requestId":"${REQUEST_ID}","username":"${USERNAME}","password":"${PASSWORD}","extraData":null,"jOrchestraCommand":"CANCEL_TASK_RUNNING"}
  
onde:
	CAMINHO_JORCHESTRA - caminho utilizado para anotar o java bean @JOrchestra(path="/CAMINHO_JORCHESTRA").
	SESSION_ID - Id da sessão estabelecida na conexão com o endpoint websocket.
	USERNAME - nome do usuário configurado no arquivo application.properties do microcontainer JOrchestra.
	PASSWORD - senha do usuário configurado no arquivo application.properties do microcontainer JOrchestra.
	CANCEL_TASK_RUNNING - comando para cancelar a mensagem que está sendo executada no dado caminho, de requisição e sessão descritos acima.
	ou
	CANCEL_TASK_NOT_RUNNING - omando para cancelar a mensagem que não está em execução no dado caminho, de requisição e sessão descritos acima.


exemplos para execução de um comando em Shell:

	  {"jOrchestaPath":null,"sessionId":null,"requestId":null,"username":"JOrchestra","password":"JOrchestra","extraData":{"shelCommand":"${COMMAND}"},"jOrchestraCommand":"SHEL"}

onde:
	USERNAME - nome do usuário configurado no arquivo application.properties do microcontainer JOrchestra.
	PASSWORD - senha do usuário configurado no arquivo application.properties do microcontainer JOrchestra.
	COMMAND - comando que será executado na máquina onde da instância do JOrchestra.

Versions

Version
0.0.3
0.0.1