content: /*
   * 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.activemq;
  
  import javax.jms.BytesMessage;
  import javax.jms.ConnectionFactory;
  import javax.jms.DeliveryMode;
  import javax.jms.Destination;
  import javax.jms.JMSException;
  import javax.jms.MapMessage;
  import javax.jms.MessageConsumer;
  import javax.jms.MessageEOFException;
  import javax.jms.MessageProducer;
  import javax.jms.ObjectMessage;
  import javax.jms.Session;
  import javax.jms.StreamMessage;
  import javax.jms.TextMessage;
  import java.net.URISyntaxException;
  import java.util.Enumeration;
  import java.util.HashMap;
  import java.util.Map;
  import java.util.Vector;
  
  import junit.framework.Test;
  
  import org.apache.activemq.command.ActiveMQDestination;
  
  /**
   * Test cases used to test the JMS message consumer.
   */
  public class JMSMessageTest extends JmsTestSupport {
  
     public ActiveMQDestination destination;
     public int deliveryMode = DeliveryMode.NON_PERSISTENT;
     public int prefetch;
     public int ackMode;
     public byte destinationType = ActiveMQDestination.QUEUE_TYPE;
     public boolean durableConsumer;
     public String connectURL = "vm://localhost?marshal=false";
  
     /**
      * Run all these tests in both marshaling and non-marshaling mode.
      */
     public void initCombos() {
        addCombinationValues("connectURL", new Object[]{"vm://localhost?marshal=false", "vm://localhost?marshal=true"});
        addCombinationValues("deliveryMode", new Object[]{Integer.valueOf(DeliveryMode.NON_PERSISTENT), Integer.valueOf(DeliveryMode.PERSISTENT)});
        addCombinationValues("destinationType", new Object[]{Byte.valueOf(ActiveMQDestination.QUEUE_TYPE)});
     }
  
     public void testTextMessage() throws Exception {
  
        // Receive a message with the JMS API
        connection.start();
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        destination = createDestination(session, destinationType);
        MessageConsumer consumer = session.createConsumer(destination);
        MessageProducer producer = session.createProducer(destination);
  
        // Send the message.
        {
           TextMessage message = session.createTextMessage();
           message.setText("Hi");
           producer.send(message);
        }
  
        // Check the Message
        {
           TextMessage message = (TextMessage) consumer.receive(1000);
           assertNotNull(message);
           assertEquals("Hi", message.getText());
        }
  
        assertNull(consumer.receiveNoWait());
     }
  
     public static Test suite() {
        return suite(JMSMessageTest.class);
     }
  
     public static void main(String[] args) {
        junit.textui.TestRunner.run(suite());
     }
  
     @Override
     protected ConnectionFactory createConnectionFactory() throws URISyntaxException {
        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(connectURL);
        return factory;
     }
  
     public void testBytesMessageLength() throws Exception {
  
        // Receive a message with the JMS API
        connection.start();
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        destination = createDestination(session, destinationType);
        MessageConsumer consumer = session.createConsumer(destination);
        MessageProducer producer = session.createProducer(destination);
  
        // Send the message
        {
           BytesMessage message = session.createBytesMessage();
           message.writeInt(1);
           message.writeInt(2);
           message.writeInt(3);
           message.writeInt(4);
           producer.send(message);
        }
  
        // Check the message.
        {
           BytesMessage message = (BytesMessage) consumer.receive(1000);
           assertNotNull(message);
           assertEquals(16, message.getBodyLength());
        }
  
        assertNull(consumer.receiveNoWait());
     }
  
     public void testObjectMessage() throws Exception {
  
        // Receive a message with the JMS API
        connection.start();
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        destination = createDestination(session, destinationType);
        MessageConsumer consumer = session.createConsumer(destination);
        MessageProducer producer = session.createProducer(destination);
  
        // send the message.
        {
           ObjectMessage message = session.createObjectMessage();
           message.setObject("Hi");
           producer.send(message);
        }
  
        // Check the message
        {
           ObjectMessage message = (ObjectMessage) consumer.receive(1000);
           assertNotNull(message);
           assertEquals("Hi", message.getObject());
        }
        assertNull(consumer.receiveNoWait());
     }
  
     public void testBytesMessage() throws Exception {
  
        // Receive a message with the JMS API
        connection.start();
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        destination = createDestination(session, destinationType);
        MessageConsumer consumer = session.createConsumer(destination);
        MessageProducer producer = session.createProducer(destination);
  
        // Send the message
        {
           BytesMessage message = session.createBytesMessage();
           message.writeBoolean(true);
           producer.send(message);
        }
  
        // Check the message
        {
           BytesMessage message = (BytesMessage) consumer.receive(1000);
           assertNotNull(message);
           assertTrue(message.readBoolean());
  
           try {
              message.readByte();
              fail("Expected exception not thrown.");
           } catch (MessageEOFException e) {
           }
  
        }
        assertNull(consumer.receiveNoWait());
     }
  
     public void testStreamMessage() throws Exception {
  
        // Receive a message with the JMS API
        connection.start();
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        destination = createDestination(session, destinationType);
        MessageConsumer consumer = session.createConsumer(destination);
        MessageProducer producer = session.createProducer(destination);
  
        // Send the message.
        {
           StreamMessage message = session.createStreamMessage();
           message.writeString("This is a test to see how it works.");
           producer.send(message);
        }
  
        // Check the message.
        {
           StreamMessage message = (StreamMessage) consumer.receive(1000);
           assertNotNull(message);
  
           // Invalid conversion should throw exception and not move the stream
           // position.
           try {
              message.readByte();
              fail("Should have received NumberFormatException");
           } catch (NumberFormatException e) {
           }
  
           assertEquals("This is a test to see how it works.", message.readString());
  
           // Invalid conversion should throw exception and not move the stream
           // position.
           try {
              message.readByte();
              fail("Should have received MessageEOFException");
           } catch (MessageEOFException e) {
           }
        }
        assertNull(consumer.receiveNoWait());
     }
  
     public void testMapMessage() throws Exception {
  
        // Receive a message with the JMS API
        connection.start();
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        destination = createDestination(session, destinationType);
        MessageConsumer consumer = session.createConsumer(destination);
        MessageProducer producer = session.createProducer(destination);
  
        // send the message.
        {
           MapMessage message = session.createMapMessage();
           message.setBoolean("boolKey", true);
           producer.send(message);
        }
  
        // get the message.
        {
           MapMessage message = (MapMessage) consumer.receive(1000);
           assertNotNull(message);
           assertTrue(message.getBoolean("boolKey"));
        }
        assertNull(consumer.receiveNoWait());
     }
  
     static class ForeignMessage implements TextMessage {
  
        public int deliveryMode;
  
        private String messageId;
        private long timestamp;
        private String correlationId;
        private Destination replyTo;
        private Destination destination;
        private boolean redelivered;
        private String type;
        private long expiration;
        private int priority;
        private String text;
        private final Map<String, Object> props = new HashMap<>();
  
        @Override
        public String getJMSMessageID() throws JMSException {
           return messageId;
        }
  
        @Override
        public void setJMSMessageID(String arg0) throws JMSException {
           messageId = arg0;
        }
  
        @Override
        public long getJMSTimestamp() throws JMSException {
           return timestamp;
        }
  
        @Override
        public void setJMSTimestamp(long arg0) throws JMSException {
           timestamp = arg0;
        }
  
        @Override
        public byte[] getJMSCorrelationIDAsBytes() throws JMSException {
           return null;
        }
  
        @Override
        public void setJMSCorrelationIDAsBytes(byte[] arg0) throws JMSException {
        }
  
        @Override
        public void setJMSCorrelationID(String arg0) throws JMSException {
           correlationId = arg0;
        }
  
        @Override
        public String getJMSCorrelationID() throws JMSException {
           return correlationId;
        }
  
        @Override
        public Destination getJMSReplyTo() throws JMSException {
           return replyTo;
        }
  
        @Override
        public void setJMSReplyTo(Destination arg0) throws JMSException {
           replyTo = arg0;
        }
  
        @Override
        public Destination getJMSDestination() throws JMSException {
           return destination;
        }
  
        @Override
        public void setJMSDestination(Destination arg0) throws JMSException {
           destination = arg0;
        }
  
        @Override
        public int getJMSDeliveryMode() throws JMSException {
           return deliveryMode;
        }
  
        @Override
        public void setJMSDeliveryMode(int arg0) throws JMSException {
           deliveryMode = arg0;
        }
  
        @Override
        public boolean getJMSRedelivered() throws JMSException {
           return redelivered;
        }
  
        @Override
        public void setJMSRedelivered(boolean arg0) throws JMSException {
           redelivered = arg0;
        }
  
        @Override
        public String getJMSType() throws JMSException {
           return type;
        }
  
        @Override
        public void setJMSType(String arg0) throws JMSException {
           type = arg0;
        }
  
        @Override
        public long getJMSExpiration() throws JMSException {
           return expiration;
        }
  
        @Override
        public void setJMSExpiration(long arg0) throws JMSException {
           expiration = arg0;
        }
  
        @Override
        public int getJMSPriority() throws JMSException {
           return priority;
        }
  
        @Override
        public void setJMSPriority(int arg0) throws JMSException {
           priority = arg0;
        }
  
        @Override
        public void clearProperties() throws JMSException {
        }
  
        @Override
        public boolean propertyExists(String arg0) throws JMSException {
           return false;
        }
  
        @Override
        public boolean getBooleanProperty(String arg0) throws JMSException {
           return false;
        }
  
        @Override
        public byte getByteProperty(String arg0) throws JMSException {
           return 0;
        }
  
        @Override
        public short getShortProperty(String arg0) throws JMSException {
           return 0;
        }
  
        @Override
        public int getIntProperty(String arg0) throws JMSException {
           return 0;
        }
  
        @Override
        public long getLongProperty(String arg0) throws JMSException {
           return 0;
        }
  
        @Override
        public float getFloatProperty(String arg0) throws JMSException {
           return 0;
        }
  
        @Override
        public double getDoubleProperty(String arg0) throws JMSException {
           return 0;
        }
  
        @Override
        public String getStringProperty(String arg0) throws JMSException {
           return (String) props.get(arg0);
        }
  
        @Override
        public Object getObjectProperty(String arg0) throws JMSException {
           return props.get(arg0);
        }
  
        @Override
        public Enumeration<?> getPropertyNames() throws JMSException {
           return new Vector<>(props.keySet()).elements();
        }
  
        @Override
        public void setBooleanProperty(String arg0, boolean arg1) throws JMSException {
        }
  
        @Override
        public void setByteProperty(String arg0, byte arg1) throws JMSException {
        }
  
        @Override
        public void setShortProperty(String arg0, short arg1) throws JMSException {
        }
  
        @Override
        public void setIntProperty(String arg0, int arg1) throws JMSException {
        }
  
        @Override
        public void setLongProperty(String arg0, long arg1) throws JMSException {
        }
  
        @Override
        public void setFloatProperty(String arg0, float arg1) throws JMSException {
        }
  
        @Override
        public void setDoubleProperty(String arg0, double arg1) throws JMSException {
        }
  
        @Override
        public void setStringProperty(String arg0, String arg1) throws JMSException {
           props.put(arg0, arg1);
        }
  
        @Override
        public void setObjectProperty(String arg0, Object arg1) throws JMSException {
           props.put(arg0, arg1);
        }
  
        @Override
        public void acknowledge() throws JMSException {
        }
  
        @Override
        public void clearBody() throws JMSException {
        }
  
        @Override
        public void setText(String arg0) throws JMSException {
           text = arg0;
        }
  
        @Override
        public String getText() throws JMSException {
           return text;
        }
  
        @Override
        public long getJMSDeliveryTime() throws JMSException {
           return 0;
        }
  
        @Override
        public void setJMSDeliveryTime(long deliveryTime) throws JMSException {
        }
  
        @Override
        public <T> T getBody(Class<T> c) throws JMSException {
           throw new UnsupportedOperationException("Test class does not implement getBody");
        }
  
        @Override
        public boolean isBodyAssignableTo(Class c) throws JMSException {
           throw new UnsupportedOperationException("Test class does not implement isBodyAssignableTo");
        }
     }
  
     public void testForeignMessage() throws Exception {
  
        // Receive a message with the JMS API
        connection.start();
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        destination = createDestination(session, destinationType);
        MessageConsumer consumer = session.createConsumer(destination);
        MessageProducer producer = session.createProducer(destination);
  
        // Send the message.
        {
           ForeignMessage message = new ForeignMessage();
           message.text = "Hello";
           message.setStringProperty("test", "value");
           long timeToLive = 10000L;
           long start = System.currentTimeMillis();
           producer.send(message, Session.AUTO_ACKNOWLEDGE, 7, timeToLive);
           long end = System.currentTimeMillis();
  
           //validate jms spec 1.1 section 3.4.11 table 3.1
           // JMSDestination, JMSDeliveryMode,  JMSExpiration, JMSPriority, JMSMessageID, and JMSTimestamp
           //must be set by sending a message.
  
           assertNotNull(message.getJMSDestination());
           assertEquals(Session.AUTO_ACKNOWLEDGE, message.getJMSDeliveryMode());
           assertTrue(start + timeToLive <= message.getJMSExpiration());
           assertTrue(end + timeToLive >= message.getJMSExpiration());
           assertEquals(7, message.getJMSPriority());
           assertNotNull(message.getJMSMessageID());
           assertTrue(start <= message.getJMSTimestamp());
           assertTrue(end >= message.getJMSTimestamp());
        }
  
        // Validate message is OK.
        {
           TextMessage message = (TextMessage) consumer.receive(1000);
           assertNotNull(message);
           assertEquals("Hello", message.getText());
           assertEquals("value", message.getStringProperty("test"));
        }
  
        assertNull(consumer.receiveNoWait());
     }
  
  }
  