Preloader image

Código

Os serviços JMS: Message, Queue, MessageProducer, MessageConsumer``

Aqui temos um endpoint REST, uma classe com a anotação @Path("/ message") que indica a rota correspondente a classe CustomJmsService. Portanto, definimos sendMessage() como @POST e acceptMessage() como @GET para a rota /message.

Além disso, diretamente relacionado a este exemplo, você pode ver 2 elementos: uma fila: Queue'' e uma fábrica de conexão: ConnectionFactory'' anotada com ``@Resource''

Finalmente, interagindo com instâncias de Connection'', Session'' e Queue'', você pode ver instâncias de MessageProducer'' e MessageConsumer'', responsáveis ​​por escrever e ler de/para o fila: Queue`` respectivamente.

@Stateless
@Path("message")
public class CustomJmsService {

    @Resource(name = "messageQueue")
    private Queue messageQueue;

    @Resource
    private ConnectionFactory connectionFactory;

    @POST
    public void sendMessage(final String message) {
        sendMessage(messageQueue, message);
    }

    @GET
    public String receiveMessage() throws JMSException {
        final TextMessage textMessage = receiveMessage(messageQueue, 1000);
        if (textMessage == null) {
            return null;
        }

        return textMessage.getText();
    }

    private void sendMessage(final Queue queue, final String message) {
        try (final Connection connection = connectionFactory.createConnection();
             final Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
             final MessageProducer producer = session.createProducer(queue)) {

            connection.start();

            final Message jmsMessage = session.createTextMessage(message);

            // Isso enfileira mensagens com êxito com 8.0.0-M3 e 8.0.0
            producer.send(jmsMessage);
        } catch (final Exception e) {
            throw new RuntimeException("Caught exception from JMS when sending a message", e);
        }
    }

    private TextMessage receiveMessage(final Queue queue, final long receiveTimeoutMillis) {
        try (final Connection connection = connectionFactory.createConnection();
             final Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
             final MessageConsumer messageConsumer = session.createConsumer(queue)) {

            connection.start();

            final Message jmsMessage = messageConsumer.receive(receiveTimeoutMillis);

            if (jmsMessage == null) {
                return null;
            }

            return (TextMessage) jmsMessage;
        } catch (final Exception e) {
            throw new RuntimeException("Caught exception from JMS when receiving a message", e);
        }
    }
}

Testando

Teste para o serviço JMS

O teste é trivial. A ideia é primeiro fazer uma solicitação POST que contenha a mensagem do serviço. Isso é feito usando instâncias das classes ClientBuilder'' e WebTarget''.

Em seguida, semelhante à solicitação POST, é feita uma solicitação GET que consome a mensagem anterior.

Por fim, verifica-se o status HTTP das respostas para que sejam equivalentes aos códigos HTTP esperados (204/200), bem como que o conteúdo da mensagem recebida seja igual ao da mensagem enviada.

@RunWith(Arquillian.class)
@RunAsClient
public class CustomJmsServiceTest {

    @Deployment
    public static Archive<?> deployment() {
        return Mvn.war();
    }

    @ArquillianResource
    private URL baseUrl;

    @Test
    public void test() throws Exception {
        // POST
        {
            final WebTarget webTarget = ClientBuilder.newClient().target(baseUrl.toURI());
            final Response response = webTarget.path("message").request().post(Entity.text("This is a test"));

            assertEquals(204, response.getStatus());
        }

        // GET
        {
            final WebTarget webTarget = ClientBuilder.newClient().target(baseUrl.toURI());
            final Response response = webTarget.path("message").request().get();
            assertEquals(200, response.getStatus());

            final String content = response.readEntity(String.class);
            assertEquals("This is a test", content);
        }
    }
}

Executando o teste de serviço JMS

Construir e testar o exemplo é simples. No diretório simple-jms você deve executar:

$ mvn clean install

Isso criará uma saída semelhante à seguinte:

INFO [http-nio-6586-exec-2] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.deployApplication Using writers:
INFO [http-nio-6586-exec-2] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.deployApplication      org.apache.johnzon.jaxrs.WadlDocumentMessageBodyWriter@7a6a8b01
INFO [http-nio-6586-exec-2] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.deployApplication      org.apache.cxf.jaxrs.nio.NioMessageBodyWriter@58be749c
INFO [http-nio-6586-exec-2] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.deployApplication      org.apache.cxf.jaxrs.provider.StringTextProvider@2740b6d6
INFO [http-nio-6586-exec-2] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.deployApplication      org.apache.cxf.jaxrs.provider.JAXBElementTypedProvider@e08fc09
INFO [http-nio-6586-exec-2] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.deployApplication      org.apache.cxf.jaxrs.provider.PrimitiveTextProvider@139e9988
INFO [http-nio-6586-exec-2] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.deployApplication      org.apache.cxf.jaxrs.provider.FormEncodingProvider@3cee7c7e
INFO [http-nio-6586-exec-2] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.deployApplication      org.apache.cxf.jaxrs.provider.MultipartProvider@2513f485
INFO [http-nio-6586-exec-2] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.deployApplication      org.apache.cxf.jaxrs.provider.SourceProvider@778a8c93
INFO [http-nio-6586-exec-2] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.deployApplication      org.apache.cxf.jaxrs.provider.JAXBElementProvider@414a7c3a
INFO [http-nio-6586-exec-2] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.deployApplication      org.apache.openejb.server.cxf.rs.johnzon.TomEEJsonbProvider@1b4e4173
INFO [http-nio-6586-exec-2] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.deployApplication      org.apache.openejb.server.cxf.rs.johnzon.TomEEJsonpProvider@3f1bfc2e
INFO [http-nio-6586-exec-2] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.deployApplication      org.apache.cxf.jaxrs.provider.BinaryDataProvider@7dc57a14
INFO [http-nio-6586-exec-2] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.deployApplication      org.apache.cxf.jaxrs.provider.DataSourceProvider@1af0fefd
INFO [http-nio-6586-exec-2] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.deployApplication Using exception mappers:
INFO [http-nio-6586-exec-2] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.deployApplication      org.apache.cxf.jaxrs.impl.WebApplicationExceptionMapper@8e6f08b
INFO [http-nio-6586-exec-2] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.deployApplication      org.apache.openejb.server.cxf.rs.EJBExceptionMapper@2fcd3c
INFO [http-nio-6586-exec-2] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.deployApplication      org.apache.cxf.jaxrs.validation.ValidationExceptionMapper@1979c922
INFO [http-nio-6586-exec-2] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.logEndpoints REST Application: http://localhost:6586/test/        -> org.apache.openejb.server.rest.InternalApplication@2653d780
INFO [http-nio-6586-exec-2] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.logEndpoints      Service URI: http://localhost:6586/test/message ->  EJB org.superbiz.jms.CustomJmsService
INFO [http-nio-6586-exec-2] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.logEndpoints               GET http://localhost:6586/test/message ->      String receiveMessage() throws JMSException
INFO [http-nio-6586-exec-2] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.logEndpoints              POST http://localhost:6586/test/message ->      void sendMessage(String)
INFO [http-nio-6586-exec-5] org.apache.activemq.broker.TransportConnector.start Connector vm://localhost started
org.apache.openejb.client.EventLogger log
INFO: RemoteInitialContextCreated{providerUri=http://localhost:6586/tomee/ejb}
INFO [http-nio-6586-exec-8] org.apache.openejb.assembler.classic.Assembler.destroyApplication Undeploying app: /tomee/examples/simple-jms/target/arquillian-test-working-dir/0/test
WARNING [http-nio-6586-exec-8] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [test] appears to have started a thread named [PoolIdleReleaseTimer]
WARNING [http-nio-6586-exec-8] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [test] appears to have started a thread named [ActiveMQ VMTransport: vm://localhost#0-1]
WARNING [http-nio-6586-exec-8] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [test] appears to have started a thread named [ActiveMQ VMTransport: vm://localhost#0-2]
org.apache.openejb.arquillian.common.TomEEContainer undeploy
INFO: cleaning /tomee/examples/simple-jms/target/arquillian-test-working-dir/0/test.war
org.apache.openejb.arquillian.common.TomEEContainer undeploy
INFO: cleaning /tomee/examples/simple-jms/target/arquillian-test-working-dir/0/test
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 27.962 sec
INFO [main] sun.reflect.DelegatingMethodAccessorImpl.invoke A valid shutdown command was received via the shutdown port. Stopping the Server instance.
INFO [main] sun.reflect.DelegatingMethodAccessorImpl.invoke Pausing ProtocolHandler ["http-nio-6586"]
INFO [main] sun.reflect.DelegatingMethodAccessorImpl.invoke Pausing ProtocolHandler ["ajp-nio-8009"]
INFO [main] sun.reflect.DelegatingMethodAccessorImpl.invoke Stopping service [Catalina]
INFO [main] sun.reflect.DelegatingMethodAccessorImpl.invoke Stopping ProtocolHandler ["http-nio-6586"]
INFO [main] sun.reflect.DelegatingMethodAccessorImpl.invoke Stopping ProtocolHandler ["ajp-nio-8009"]
INFO [main] org.apache.openejb.server.SimpleServiceManager.stop Stopping server services
INFO [main] org.apache.openejb.assembler.classic.Assembler.destroyApplication Undeploying app: openejb
SEVERE [main] org.apache.openejb.core.singleton.SingletonInstanceManager.undeploy Unable to unregister MBean openejb.management:J2EEServer=openejb,J2EEApplication=<empty>,EJBModule=openejb,SingletonSessionBean=openejb/Deployer,name=openejb/Deployer,j2eeType=Invocations
SEVERE [main] org.apache.openejb.core.singleton.SingletonInstanceManager.undeploy Unable to unregister MBean openejb.management:J2EEServer=openejb,J2EEApplication=<empty>,EJBModule=openejb,SingletonSessionBean=openejb/Deployer,name=openejb/Deployer,j2eeType=Invocations
INFO [main] org.apache.openejb.assembler.classic.Assembler.doResourceDestruction Closing DataSource: Default Unmanaged JDBC Database
INFO [main] org.apache.openejb.assembler.classic.Assembler.doResourceDestruction Stopping ResourceAdapter: Default JMS Resource Adapter
INFO [main] org.apache.openejb.resource.activemq.ActiveMQResourceAdapter.stop Stopping ActiveMQ
INFO [108] org.apache.openejb.resource.activemq.ActiveMQResourceAdapter.stopImpl Stopped ActiveMQ broker
INFO [main] sun.reflect.DelegatingMethodAccessorImpl.invoke Destroying ProtocolHandler ["http-nio-6586"]
INFO [main] sun.reflect.DelegatingMethodAccessorImpl.invoke Destroying ProtocolHandler ["ajp-nio-8009"]

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO]
[INFO] --- maven-war-plugin:2.4:war (default-war) @ simple-jms ---
[INFO] Packaging webapp
[INFO] Assembling webapp [simple-jms] in [/tomee/examples/simple-jms/target/simple-jms-8.0.1-SNAPSHOT]
[INFO] Processing war project
[INFO] Webapp assembled in [2118 msecs]
[INFO] Building war: /tomee/examples/simple-jms/target/simple-jms-8.0.1-SNAPSHOT.war
[INFO]
[INFO] --- maven-install-plugin:2.4:install (default-install) @ simple-jms ---
[INFO] Installing /tomee/examples/simple-jms/target/simple-jms-8.0.1-SNAPSHOT.war to /.m2/repository/org/superbiz/simple-jms/8.0.1-SNAPSHOT/simple-jms-8.0.1-SNAPSHOT.war
[INFO] Installing /tomee/examples/simple-jms/pom.xml to /.m2/repository/org/superbiz/simple-jms/8.0.1-SNAPSHOT/simple-jms-8.0.1-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  50.089 s

Executando a aplicação

Executar o exemplo é simples. No diretório simple-jms digite:

$ mvn tomee:run

Isso criará uma saída semelhante à seguinte.

[main] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.logEndpoints REST Application: http://localhost:8080/simple-jms-8.0.1-SNAPSHOT/        -> org.apache.openejb.server.rest.InternalApplication@3b8b5b40
[main] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.logEndpoints      Service URI: http://localhost:8080/simple-jms-8.0.1-SNAPSHOT/message ->  EJB org.superbiz.jms.CustomJmsService
[main] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.logEndpoints               GET http://localhost:8080/simple-jms-8.0.1-SNAPSHOT/message ->      String receiveMessage() throws JMSException
[main] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.logEndpoints              POST http://localhost:8080/simple-jms-8.0.1-SNAPSHOT/message ->      void sendMessage(String)
[main] sun.reflect.DelegatingMethodAccessorImpl.invoke Deployment of web application archive [\tomee\examples\simple-jms\target\apache-tomee\webapps\simple-jms-8.0.1-SNAPSHOT.war] has finished in [8,264] ms
[main] org.apache.catalina.core.StandardContext.setClassLoaderProperty Unable to set the web application class loader property [clearReferencesRmiTargets] to [true] as the property does not exist.
[main] org.apache.catalina.core.StandardContext.setClassLoaderProperty Unable to set the web application class loader property [clearReferencesObjectStreamClassCaches] to [true] as the property does not exist.
[main] org.apache.catalina.core.StandardContext.setClassLoaderProperty Unable to set the web application class loader property [clearReferencesObjectStreamClassCaches] to [true] as the property does not exist.
[main] org.apache.catalina.core.StandardContext.setClassLoaderProperty Unable to set the web application class loader property [clearReferencesThreadLocals] to [true] as the property does not exist.
[main] sun.reflect.DelegatingMethodAccessorImpl.invoke Starting ProtocolHandler ["http-nio-8080"]
[main] sun.reflect.DelegatingMethodAccessorImpl.invoke Starting ProtocolHandler ["ajp-nio-8009"]
[main] sun.reflect.DelegatingMethodAccessorImpl.invoke Server startup in [8,367] milliseconds
É possível usar o comando CURL`` (ou uma ferramenta cliente) para enviar uma solicitação POST e então uma solicitação GET para a URL do serviço equivalente a:
http://localhost:8080/simple-jms<-TOMEE-VERSION>/message

Finalmente, você pode sair ou recarregar o exemplo digitando um dos comandos disponíveis: quit, exit, reload.

[WARNING] Command '' not understood. Use one of [quit, exit, reload]