| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.apache.cxf.systest.jaxrs.jms; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.InputStream; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.Properties; |
| |
| import javax.jms.BytesMessage; |
| import javax.jms.Connection; |
| import javax.jms.ConnectionFactory; |
| import javax.jms.Destination; |
| import javax.jms.JMSException; |
| import javax.jms.Message; |
| import javax.jms.MessageConsumer; |
| import javax.jms.MessageProducer; |
| import javax.jms.Session; |
| import javax.naming.Context; |
| import javax.naming.InitialContext; |
| import javax.ws.rs.core.Response; |
| import javax.xml.bind.JAXBContext; |
| import javax.xml.bind.Marshaller; |
| import javax.xml.bind.Unmarshaller; |
| |
| import org.apache.cxf.interceptor.LoggingInInterceptor; |
| import org.apache.cxf.jaxrs.client.JAXRSClientFactory; |
| import org.apache.cxf.jaxrs.client.WebClient; |
| import org.apache.cxf.jaxrs.model.AbstractResourceInfo; |
| import org.apache.cxf.systest.jaxrs.Book; |
| import org.apache.cxf.systest.jaxrs.JMSBookStore; |
| import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase; |
| import org.apache.cxf.testutil.common.EmbeddedJMSBrokerLauncher; |
| |
| import org.junit.BeforeClass; |
| import org.junit.Test; |
| |
| public class JAXRSJmsTest extends AbstractBusClientServerTestBase { |
| protected static boolean serversStarted; |
| static final String JMS_PORT = EmbeddedJMSBrokerLauncher.PORT; |
| |
| @BeforeClass |
| public static void startServers() throws Exception { |
| if (serversStarted) { |
| return; |
| } |
| AbstractResourceInfo.clearAllMaps(); |
| Map<String, String> props = new HashMap<String, String>(); |
| if (System.getProperty("org.apache.activemq.default.directory.prefix") != null) { |
| props.put("org.apache.activemq.default.directory.prefix", |
| System.getProperty("org.apache.activemq.default.directory.prefix")); |
| } |
| props.put("java.util.logging.config.file", |
| System.getProperty("java.util.logging.config.file")); |
| |
| assertTrue("server did not launch correctly", |
| launchServer(EmbeddedJMSBrokerLauncher.class, props, null)); |
| assertTrue("server did not launch correctly", |
| launchServer(JMSServer.class, true)); |
| serversStarted = true; |
| } |
| |
| @Test |
| public void testGetBookFromWebClient() throws Exception { |
| // setup the the client |
| String endpointAddressUrlEncoded = "jms:jndi:dynamicQueues/test.jmstransport.text" |
| + "?replyToName=dynamicQueues/test.jmstransport.response" |
| + "&jndiInitialContextFactory=org.apache.activemq.jndi.ActiveMQInitialContextFactory" |
| + "&jndiURL=tcp://localhost:" + JMS_PORT; |
| |
| WebClient client = WebClient.create(endpointAddressUrlEncoded); |
| WebClient.getConfig(client).getInInterceptors().add(new LoggingInInterceptor()); |
| WebClient.getConfig(client).getRequestContext() |
| .put(org.apache.cxf.message.Message.REQUEST_URI, "/bookstore/books/123"); |
| |
| Book book = client.get(Book.class); |
| assertEquals("Get a wrong response code.", 200, client.getResponse().getStatus()); |
| assertEquals("Get a wrong book id.", 123, book.getId()); |
| } |
| |
| @Test |
| public void testPutBookOneWayWithWebClient() throws Exception { |
| // setup the the client |
| String endpointAddressUrlEncoded = "jms:jndi:dynamicQueues/test.jmstransport.text" |
| + "?replyToName=dynamicQueues/test.jmstransport.response" |
| + "&jndiInitialContextFactory=org.apache.activemq.jndi.ActiveMQInitialContextFactory" |
| + "&jndiURL=tcp://localhost:" + JMS_PORT; |
| |
| WebClient client = WebClient.create(endpointAddressUrlEncoded); |
| WebClient.getConfig(client).getRequestContext() |
| .put(org.apache.cxf.message.Message.REQUEST_URI, "/bookstore/oneway"); |
| client.header("OnewayRequest", "true"); |
| Response r = client.put(new Book("OneWay From WebClient", 129L)); |
| assertEquals(202, r.getStatus()); |
| assertFalse(r.hasEntity()); |
| |
| Context ctx = getContext(); |
| ConnectionFactory factory = (ConnectionFactory)ctx.lookup("ConnectionFactory"); |
| |
| Destination replyToDestination = (Destination)ctx.lookup("dynamicQueues/test.jmstransport.response"); |
| |
| Connection connection = null; |
| try { |
| connection = factory.createConnection(); |
| connection.start(); |
| Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); |
| checkBookInResponse(session, replyToDestination, 129L, "OneWay From WebClient"); |
| session.close(); |
| } finally { |
| try { |
| if (connection != null) { |
| connection.stop(); |
| connection.close(); |
| } |
| } catch (JMSException ex) { |
| // ignore |
| } |
| } |
| } |
| |
| @Test |
| public void testGetBookFromWebClientWithPath() throws Exception { |
| // setup the the client |
| String endpointAddressUrlEncoded = "jms:jndi:dynamicQueues/test.jmstransport.text" |
| + "?jndiInitialContextFactory=org.apache.activemq.jndi.ActiveMQInitialContextFactory" |
| + "&replyToName=dynamicQueues/test.jmstransport.response" |
| + "&jndiURL=tcp://localhost:" + JMS_PORT |
| + "&jndiConnectionFactoryName=ConnectionFactory"; |
| |
| WebClient client = WebClient.create(endpointAddressUrlEncoded); |
| client.path("bookstore").path("books").path("123"); |
| |
| Book book = client.get(Book.class); |
| assertEquals("Get a wrong response code.", 200, client.getResponse().getStatus()); |
| assertEquals("Get a wrong book id.", 123, book.getId()); |
| } |
| |
| @Test |
| public void testGetBookFromProxyClient() throws Exception { |
| // setup the the client |
| String endpointAddressUrlEncoded = "jms:jndi:dynamicQueues/test.jmstransport.text" |
| + "?jndiInitialContextFactory=org.apache.activemq.jndi.ActiveMQInitialContextFactory" |
| + "&replyToName=dynamicQueues/test.jmstransport.response" |
| + "&jndiURL=tcp://localhost:" + JMS_PORT |
| + "&jndiConnectionFactoryName=ConnectionFactory"; |
| |
| JMSBookStore client = JAXRSClientFactory.create(endpointAddressUrlEncoded, JMSBookStore.class); |
| Book book = client.getBook("123"); |
| assertEquals("Get a wrong response code.", 200, WebClient.client(client).getResponse().getStatus()); |
| assertEquals("Get a wrong book id.", 123, book.getId()); |
| } |
| |
| @Test |
| public void testGetBookFromSubresourceProxyClient() throws Exception { |
| // setup the the client |
| String endpointAddressUrlEncoded = "jms:jndi:dynamicQueues/test.jmstransport.text" |
| + "?jndiInitialContextFactory=org.apache.activemq.jndi.ActiveMQInitialContextFactory" |
| + "&replyToName=dynamicQueues/test.jmstransport.response" |
| + "&jndiURL=tcp://localhost:" + JMS_PORT |
| + "&jndiConnectionFactoryName=ConnectionFactory"; |
| |
| JMSBookStore client = JAXRSClientFactory.create(endpointAddressUrlEncoded, JMSBookStore.class); |
| Book bookProxy = client.getBookSubResource("123"); |
| Book book = bookProxy.retrieveState(); |
| assertEquals("Get a wrong response code.", 200, WebClient.client(bookProxy).getResponse().getStatus()); |
| assertEquals("Get a wrong book id.", 123, book.getId()); |
| } |
| |
| @Test |
| public void testGetBookFromProxyClientWithQuery() throws Exception { |
| // setup the the client |
| String endpointAddressUrlEncoded = "jms:jndi:dynamicQueues/test.jmstransport.text" |
| + "?jndiInitialContextFactory=org.apache.activemq.jndi.ActiveMQInitialContextFactory" |
| + "&replyToName=dynamicQueues/test.jmstransport.response" |
| + "&jndiURL=tcp://localhost:" + JMS_PORT |
| + "&jndiConnectionFactoryName=ConnectionFactory"; |
| |
| JMSBookStore client = JAXRSClientFactory.create(endpointAddressUrlEncoded, JMSBookStore.class); |
| Book book = client.getBookByURLQuery(new String[] {"1", "2", "3"}); |
| assertEquals("Get a wrong response code.", 200, WebClient.client(client).getResponse().getStatus()); |
| assertEquals("Get a wrong book id.", 123, book.getId()); |
| } |
| |
| @Test |
| public void testGetBook() throws Exception { |
| Context ctx = getContext(); |
| ConnectionFactory factory = (ConnectionFactory)ctx.lookup("ConnectionFactory"); |
| |
| Destination destination = (Destination)ctx.lookup("dynamicQueues/test.jmstransport.text"); |
| Destination replyToDestination = (Destination)ctx.lookup("dynamicQueues/test.jmstransport.response"); |
| |
| Connection connection = null; |
| try { |
| connection = factory.createConnection(); |
| connection.start(); |
| Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); |
| postGetMessage(session, destination, replyToDestination); |
| checkBookInResponse(session, replyToDestination, 123L, "CXF JMS Rocks"); |
| session.close(); |
| } finally { |
| try { |
| if (connection != null) { |
| connection.stop(); |
| connection.close(); |
| } |
| } catch (JMSException ex) { |
| // ignore |
| } |
| } |
| |
| } |
| |
| |
| @Test |
| public void testAddGetBook() throws Exception { |
| Context ctx = getContext(); |
| ConnectionFactory factory = (ConnectionFactory)ctx.lookup("ConnectionFactory"); |
| |
| Destination destination = (Destination)ctx.lookup("dynamicQueues/test.jmstransport.text"); |
| Destination replyToDestination = (Destination)ctx.lookup("dynamicQueues/test.jmstransport.response"); |
| |
| Connection connection = null; |
| try { |
| connection = factory.createConnection(); |
| connection.start(); |
| Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); |
| postBook(session, destination, replyToDestination); |
| checkBookInResponse(session, replyToDestination, 124L, "JMS"); |
| session.close(); |
| } finally { |
| try { |
| if (connection != null) { |
| connection.stop(); |
| connection.close(); |
| } |
| } catch (JMSException ex) { |
| // ignore |
| } |
| } |
| |
| } |
| |
| @Test |
| public void testOneWayBook() throws Exception { |
| Context ctx = getContext(); |
| ConnectionFactory factory = (ConnectionFactory)ctx.lookup("ConnectionFactory"); |
| |
| Destination destination = (Destination)ctx.lookup("dynamicQueues/test.jmstransport.text"); |
| Destination replyToDestination = (Destination)ctx.lookup("dynamicQueues/test.jmstransport.response"); |
| |
| Connection connection = null; |
| try { |
| connection = factory.createConnection(); |
| connection.start(); |
| Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); |
| postOneWayBook(session, destination); |
| checkBookInResponse(session, replyToDestination, 125L, "JMS OneWay"); |
| session.close(); |
| } finally { |
| try { |
| if (connection != null) { |
| connection.stop(); |
| connection.close(); |
| } |
| } catch (JMSException ex) { |
| // ignore |
| } |
| } |
| |
| } |
| |
| |
| private void checkBookInResponse(Session session, Destination replyToDestination, |
| long bookId, String bookName) throws Exception { |
| MessageConsumer consumer = session.createConsumer(replyToDestination); |
| BytesMessage jmsMessage = (BytesMessage)consumer.receive(5000); |
| if (jmsMessage == null) { |
| throw new RuntimeException("No response recieved on " + replyToDestination); |
| } |
| byte[] bytes = new byte[(int)jmsMessage.getBodyLength()]; |
| jmsMessage.readBytes(bytes); |
| InputStream is = new ByteArrayInputStream(bytes); |
| Book b = readBook(is); |
| assertEquals(bookId, b.getId()); |
| assertEquals(bookName, b.getName()); |
| } |
| |
| private Context getContext() throws Exception { |
| Properties props = new Properties(); |
| props.setProperty(Context.INITIAL_CONTEXT_FACTORY, |
| "org.apache.activemq.jndi.ActiveMQInitialContextFactory"); |
| props.setProperty(Context.PROVIDER_URL, "tcp://localhost:" + JMS_PORT); |
| return new InitialContext(props); |
| |
| } |
| |
| private void postGetMessage(Session session, Destination destination, Destination replyTo) |
| throws Exception { |
| MessageProducer producer = session.createProducer(destination); |
| Message message = session.createBytesMessage(); |
| message.setJMSReplyTo(replyTo); |
| message.setStringProperty("Accept", "application/xml"); |
| message.setStringProperty(org.apache.cxf.message.Message.REQUEST_URI, "/bookstore/books/123"); |
| message.setStringProperty(org.apache.cxf.message.Message.HTTP_REQUEST_METHOD, "GET"); |
| producer.send(message); |
| producer.close(); |
| } |
| |
| private void postOneWayBook(Session session, Destination destination) |
| throws Exception { |
| MessageProducer producer = session.createProducer(destination); |
| |
| byte[] payload = writeBook(new Book("JMS OneWay", 125L)); |
| BytesMessage message = session.createBytesMessage(); |
| message.writeBytes(payload); |
| message.setStringProperty("Content-Type", "application/xml"); |
| message.setStringProperty(org.apache.cxf.message.Message.REQUEST_URI, "/bookstore/oneway"); |
| message.setStringProperty(org.apache.cxf.message.Message.HTTP_REQUEST_METHOD, "PUT"); |
| |
| producer.send(message); |
| producer.close(); |
| } |
| |
| private void postBook(Session session, Destination destination, Destination replyTo) |
| throws Exception { |
| MessageProducer producer = session.createProducer(destination); |
| byte[] payload = writeBook(new Book("JMS", 3L)); |
| BytesMessage message = session.createBytesMessage(); |
| message.writeBytes(payload); |
| message.setJMSReplyTo(replyTo); |
| // or, if oneway, |
| // message.setStringProperty("OnewayRequest", "true"); |
| // we could've set this header in JMSDestination if no replyTo were set |
| // but in CXF one could also provide the replyTo in the configuration |
| // so it is just simpler to set this header if needed to avoid some |
| // complex logic on the server side |
| |
| // all these properties are optional |
| // CXF JAXRS and JMS Transport will default to |
| // Content-Type : text/xml |
| // Accept : */* |
| // POST |
| // Message.REQUEST_URI : "/" |
| |
| message.setStringProperty("Content-Type", "application/xml"); |
| message.setStringProperty("Accept", "text/xml"); |
| message.setStringProperty(org.apache.cxf.message.Message.REQUEST_URI, "/bookstore/books"); |
| message.setStringProperty(org.apache.cxf.message.Message.HTTP_REQUEST_METHOD, "POST"); |
| message.setStringProperty("custom.protocol.header", "custom.value"); |
| |
| producer.send(message); |
| producer.close(); |
| } |
| |
| private Book readBook(InputStream is) throws Exception { |
| JAXBContext c = JAXBContext.newInstance(new Class[]{Book.class}); |
| Unmarshaller u = c.createUnmarshaller(); |
| return (Book)u.unmarshal(is); |
| } |
| |
| private byte[] writeBook(Book b) throws Exception { |
| JAXBContext c = JAXBContext.newInstance(new Class[]{Book.class}); |
| Marshaller m = c.createMarshaller(); |
| ByteArrayOutputStream bos = new ByteArrayOutputStream(); |
| m.marshal(b, bos); |
| return bos.toByteArray(); |
| } |
| |
| } |