├── LICENSE ├── README.mediawiki ├── hornetq-server ├── NOTE ├── checkout-hornetq.sh ├── config │ ├── hornetq-beans.xml │ ├── hornetq-configuration.xml │ ├── hornetq-jms.xml │ ├── hornetq-users.xml │ ├── jndi.properties │ ├── log4j.properties │ └── logging.properties └── hornetq-groupon.patch ├── mbus-java ├── README.mediawiki ├── RELEASE_NOTE ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── groupon │ │ │ ├── messagebus │ │ │ ├── api │ │ │ │ ├── Consumer.java │ │ │ │ ├── ConsumerAckType.java │ │ │ │ ├── ConsumerConfig.java │ │ │ │ ├── DestinationType.java │ │ │ │ ├── HostParams.java │ │ │ │ ├── Log.java │ │ │ │ ├── Message.java │ │ │ │ ├── Producer.java │ │ │ │ ├── ProducerConfig.java │ │ │ │ └── exceptions │ │ │ │ │ ├── AckFailedException.java │ │ │ │ │ ├── BrokerConnectionCloseFailedException.java │ │ │ │ │ ├── BrokerConnectionFailedException.java │ │ │ │ │ ├── InvalidConfigException.java │ │ │ │ │ ├── InvalidDestinationException.java │ │ │ │ │ ├── InvalidStatusException.java │ │ │ │ │ ├── KeepAliveFailedException.java │ │ │ │ │ ├── MessageBusException.java │ │ │ │ │ ├── NackFailedException.java │ │ │ │ │ ├── ReceiveTimeoutException.java │ │ │ │ │ ├── SendFailedException.java │ │ │ │ │ └── TooManyConnectionRetryAttemptsException.java │ │ │ ├── client │ │ │ │ ├── ConsumerImpl.java │ │ │ │ ├── ProducerImpl.java │ │ │ │ ├── StompServerFetcher.java │ │ │ │ ├── Utils.java │ │ │ │ └── examples │ │ │ │ │ ├── ConsumerAckExample.java │ │ │ │ │ ├── ConsumerExample.java │ │ │ │ │ ├── DLQHandleExample.java │ │ │ │ │ ├── ProducerBenchmark.java │ │ │ │ │ ├── ProducerExample.java │ │ │ │ │ ├── ProducerQueueExample_test.java │ │ │ │ │ ├── SimpleClientIntegration.java │ │ │ │ │ ├── SimpleProducerIntegration.java │ │ │ │ │ ├── consumer_example.properties │ │ │ │ │ ├── log4j.properties.sample │ │ │ │ │ └── producer_example.properties │ │ │ └── util │ │ │ │ └── DynamicServerListGetter.java │ │ │ └── stomp │ │ │ ├── ByteArrayInputStream.java │ │ │ ├── ByteArrayOutputStream.java │ │ │ ├── ByteSequence.java │ │ │ ├── Command.java │ │ │ ├── CommandVisitor.java │ │ │ ├── DataByteArrayInputStream.java │ │ │ ├── DataByteArrayOutputStream.java │ │ │ ├── DataStructure.java │ │ │ ├── Endpoint.java │ │ │ ├── MarshallingSupport.java │ │ │ ├── ProtocolException.java │ │ │ ├── Stomp.java │ │ │ ├── StompConnection.java │ │ │ ├── StompFrame.java │ │ │ ├── StompFrameError.java │ │ │ ├── StompWireFormat.java │ │ │ ├── WireFormat.java │ │ │ └── examples │ │ │ ├── ExampleStompTopicConsumer.java │ │ │ ├── StompConsumer.java │ │ │ └── StompProducer.java │ └── thrift-gen │ │ └── com │ │ └── groupon │ │ └── messagebus │ │ └── thrift │ │ └── api │ │ ├── MessageInternal.java │ │ ├── MessagePayload.java │ │ └── MessagePayloadType.java │ └── test │ └── java │ └── com │ └── groupon │ └── messagebus │ ├── client │ └── test │ │ ├── ConsumerImplTest.java │ │ ├── ProducerImplTest.java │ │ └── StompServerFetcherTest.java │ └── util │ └── test │ └── DynamicServerListGetterTest.java ├── mbus-ruby ├── Gemfile ├── README.mediawiki ├── Rakefile ├── bin │ ├── console │ └── messagebus_swarm ├── config │ ├── messagebus.yml │ └── messagebus_with_drone.yml ├── examples │ ├── README │ ├── consumer_example.rb │ ├── consumer_topic_example.rb │ ├── encoding_example.rb │ ├── producer_example.rb │ ├── producer_reload_config_example.rb │ ├── producer_schedule_example.rb │ ├── producer_topic_example.rb │ ├── swarm_example.rb │ ├── swarm_example.sh │ └── swarm_example.yml ├── lib │ ├── messagebus.rb │ └── messagebus │ │ ├── client.rb │ │ ├── cluster_map.rb │ │ ├── connection.rb │ │ ├── consumer.rb │ │ ├── custom_errors.rb │ │ ├── dottable_hash.rb │ │ ├── error_status.rb │ │ ├── logger.rb │ │ ├── message.rb │ │ ├── messagebus_types.rb │ │ ├── producer.rb │ │ ├── swarm.rb │ │ ├── swarm │ │ ├── controller.rb │ │ ├── drone.rb │ │ └── drone │ │ │ └── logging_worker.rb │ │ ├── validations.rb │ │ └── version.rb ├── log │ └── .gitkeep ├── messagebus.gemspec ├── script │ └── ci │ │ └── rspec.sh ├── spec │ ├── messagebus │ │ ├── client_spec.rb │ │ ├── cluster_map_spec.rb │ │ ├── consumer_spec.rb │ │ ├── dottable_hash_spec.rb │ │ ├── message_spec.rb │ │ ├── producer_spec.rb │ │ ├── swarm │ │ │ └── controller_spec.rb │ │ └── validations_spec.rb │ └── spec_helper.rb ├── test_driver │ ├── test1_publish_consume_queue.rb │ ├── test2_delayed_ack.rb │ ├── test3_publish_consume_topic.rb │ └── test4_failed_connection_reconnect.rb └── vendor │ └── gems │ ├── stomp.rb │ └── stomp │ ├── client.rb │ ├── connection.rb │ ├── errors.rb │ ├── ext │ └── hash.rb │ └── message.rb └── pom.xml /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, Groupon, Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | 11 | Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | Neither the name of GROUPON nor the names of its contributors may be 16 | used to endorse or promote products derived from this software without 17 | specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 22 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 25 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /hornetq-server/NOTE: -------------------------------------------------------------------------------- 1 | This server patch contains modifications to HornetQ server including: 2 | 1. JMX to HTML porting. 3 | 2. Exposes consumer server list as JMX HTTP RPC. 4 | 3. Have the server periodically recycles unacknowledged messages instead of waiting for connection reset to free the resource. This is bound to the client's pull-like API. 5 | 4. Retrieve real message count from PageStore. -------------------------------------------------------------------------------- /hornetq-server/checkout-hornetq.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | git clone https://github.com/hornetq/hornetq.git 3 | cd hornetq 4 | git checkout HornetQ_2_2_22_AS7_Final 5 | patch -p0 < ../hornetq-groupon.patch -------------------------------------------------------------------------------- /hornetq-server/config/hornetq-beans.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | ${jnp.port:1099} 13 | ${jnp.host:localhost} 14 | ${jnp.rmiPort:1098} 15 | ${jnp.host:localhost} 16 | 17 | 18 | 19 | 20 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /hornetq-server/config/hornetq-configuration.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | false 6 | 7 | true 8 | 9 | /var/hornetq/paging 10 | 11 | /var/hornetq/bindings 12 | 13 | /var/hornetq/journal 14 | 15 | 10 16 | 17 | -1 18 | 19 | 5242880 20 | 21 | ASYNCIO 22 | 23 | 30 24 | 25 | /var/hornetq/large-messages 26 | 27 | jms.queue.hornetq.management 28 | 29 | 300000 30 | 31 | true 32 | 33 | 34 | 35 | org.hornetq.core.remoting.impl.netty.NettyConnectorFactory 36 | 37 | 38 | 39 | 40 | 41 | org.hornetq.core.remoting.impl.netty.NettyConnectorFactory 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory 51 | 52 | 53 | 54 | 55 | 56 | org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | jms.queue.DLQ 89 | jms.queue.ExpiryQueue 90 | 3 91 | 0 92 | 5000 93 | 54857600 94 | 10485760 95 | 10 96 | PAGE 97 | 100 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /hornetq-server/config/hornetq-jms.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | true 8 | true 9 | 60000 10 | true 11 | -1 12 | 13 | true 14 | true 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | true 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | false 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /hornetq-server/config/hornetq-users.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /hornetq-server/config/jndi.properties: -------------------------------------------------------------------------------- 1 | java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory 2 | java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces -------------------------------------------------------------------------------- /hornetq-server/config/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.appender.jmx=org.apache.log4j.RollingFileAppender 2 | log4j.appender.jmx.File=/var/hornetq/log/jmx.log 3 | log4j.appender.jmx.MaxFileSize=10MB 4 | log4j.appender.jmx.MaxBackupIndex=10 5 | log4j.appender.jmx.layout.ConversionPattern=%-5p %d [%t] %c: %m%n 6 | log4j.appender.jmx.layout = org.apache.log4j.PatternLayout 7 | log4j.logger.com.admc=TRACE, jmx 8 | -------------------------------------------------------------------------------- /hornetq-server/config/logging.properties: -------------------------------------------------------------------------------- 1 | ############################################################ 2 | # Default Logging Configuration File 3 | # 4 | # You can use a different file by specifying a filename 5 | # with the java.util.logging.config.file system property. 6 | # For example java -Djava.util.logging.config.file=myfile 7 | ############################################################ 8 | 9 | ############################################################ 10 | # Global properties 11 | ############################################################ 12 | 13 | # "handlers" specifies a comma separated list of log Handler 14 | # classes. These handlers will be installed during VM startup. 15 | # Note that these classes must be on the system classpath. 16 | # By default we only configure a ConsoleHandler, which will only 17 | # show messages at the INFO and above levels. 18 | handlers=java.util.logging.ConsoleHandler,java.util.logging.FileHandler 19 | java.util.logging.ConsoleHandler.formatter=org.hornetq.integration.logging.HornetQLoggerFormatter 20 | java.util.logging.FileHandler.level=INFO 21 | java.util.logging.FileHandler.formatter=org.hornetq.integration.logging.HornetQLoggerFormatter 22 | java.util.logging.FileHandler.pattern=../logs/hornetq.log 23 | # Default global logging level. 24 | # This specifies which kinds of events are logged across 25 | # all loggers. For any given facility this global level 26 | # can be overriden by a facility specific level 27 | # Note that the ConsoleHandler also has a separate level 28 | # setting to limit messages printed to the console. 29 | .level= INFO 30 | 31 | ############################################################ 32 | # Handler specific properties. 33 | # Describes specific configuration info for Handlers. 34 | ############################################################ 35 | -------------------------------------------------------------------------------- /mbus-java/README.mediawiki: -------------------------------------------------------------------------------- 1 | =messagebus-client= 2 | 3 | Java client for MessageBus. 4 | 5 | ==Build== 6 | Prerequisite: 7 | *Java 6 or higher 8 | *Maven 2 9 | 10 | $ mvn package 11 | 12 | The binaries will be built under target/. 13 | 14 | uber-mbus-client-x.x.x.jar is a jar that includes all dependencies and can be included to your classpath for usage. This may result in dependency conflict with other dependencies in your project. messagebus-client-x.x.x.jar doesn't include dependencies. We have also published the jar to public maven repository. Search for messagebus-client there to get the latest version to include to your project (via pom.xml). 15 | 16 | ==Usage== 17 | ===Include messagebus-client to your Maven project=== 18 | messagebus-client is deployed to Maven Central. Add following dependency to your pom.xml. 19 | 20 | 21 | com.groupon.messagebus 22 | messagebus-client 23 | x.x.x 24 | 25 | 26 | ===Quick start with ProducerExample and ConsumerExample=== 27 | You can try publishing and consuming example messages with com.groupon.messagebus.client.examples.ProducerExample/ConsumerExample. Note that this example publishes generated messages. It can be used to test connection with your servers. See next section for guidance of implementing your publisher/consumer. 28 | 29 | *Create producer_example.properties as: 30 | 31 | server={Host name. DNS to your load balancer if you use one.} 32 | port={Port number. default:61613} 33 | dest_type=TOPIC 34 | dest_name=jms.topic.{A Topic} 35 | msg_count=30000 36 | msg_size=10000 37 | 38 | *Create consumer_example.properties as: 39 | 40 | server={Host name. DNS to your load balancer if you use one.} 41 | port={Port number. default:61613} 42 | dest_type=TOPIC 43 | dest_name=jms.topic.{A Topic} 44 | msg_count=2000000 45 | msg_size=1024 46 | subscription_id={A subscription identifier.} 47 | rcv_timeout=5000 48 | use_dynamic_servers={true if your servers are running in cluster mode. false otherwise.} 49 | 50 | *To publish: 51 | $java -cp uber-mbus-client-xxx.jar com.groupon.messagebus.client.examples.ProducerExample producer_example.properties 52 | 53 | *To consume: 54 | $java -cp uber-mbus-client-xxx.jar com.groupon.messagebus.client.examples.ConsumerExample consumer_example.properties 55 | 56 | ===Publish Message=== 57 | To publish messages, you need to use com.groupon.messagebus.api.ProducerConfig and com.groupon.messagebus.client.ProducerImpl. Simple example: 58 | 59 | import com.groupon.messagebus.api.*; 60 | import com.groupon.messagebus.client.*; 61 | ... 62 | ProducerConfig config = new ProducerConfig(); 63 | HostParams host = new HostParams("hornetq-server-lb", 61613); 64 | config.setBroker(host); 65 | config.setDestinationType(DestinationType.TOPIC); 66 | config.setDestinationName("jms.topic.testTopic1"); 67 | Producer producer = new ProducerImpl(); 68 | producer.start(config); 69 | Message message = Message.createStringMessage( "All work and no play makes jack a dull boy" ); 70 | try { 71 | producer.sendSafe(message, headers); 72 | } catch (Exception e) { 73 | e.printStackTrace(); 74 | } 75 | producer.stop(); 76 | 77 | You can also check out com.groupon.messagebus.client.examples.ProducerExample for more sophisticated example. 78 | 79 | ===Consumer Message=== 80 | To consume messages, you config with com.groupon.messagebus.api.ConsumerConfig and uses com.groupon.messagebus.client.ConsumerConfig. You usually put consumer.Receive method inside a while loop and handle messages when one comes. Simple example: 81 | 82 | import com.groupon.messagebus.api.*; 83 | import com.groupon.messagebus.client.*; 84 | ... 85 | ConsumerConfig config = new ConsumerConfig(); 86 | //Although the consumers connects to all hosts in the cluster, you only need to set the LB here. 87 | HostParams host = new HostParams("hornetq-server-lb", 61613); 88 | Set hostsList = new HashSet(); 89 | hostsList.add(host); 90 | config.setHostParams(hostsList); 91 | Consumer con = new ConsumerImpl(); 92 | con.start(config); 93 | try{ 94 | while(true){ 95 | Message tmp = con.receive(); 96 | MessagePayloadType type = tmp.getMessagePayloadType(); 97 | switch(type){ 98 | case MessagePayloadType.BINARY) 99 | System.out.println(new String(tmp.getBinaryPayload())); 100 | break; 101 | case MessagePayloadType.JSON: 102 | System.out.println(tmp.getJSONStringPayload()); 103 | break; 104 | case MessagePayloadType.STRING: 105 | System.out.println(tmp.getStringPayload()); 106 | break; 107 | } 108 | } 109 | }finally{ 110 | con.stop(); 111 | } 112 | } 113 | }finally{ 114 | con.stop(); 115 | } 116 | 117 | You can also check out com.groupon.messagebus.client.examples.ConsumerExample for more sophisticated example. 118 | -------------------------------------------------------------------------------- /mbus-java/RELEASE_NOTE: -------------------------------------------------------------------------------- 1 | 1.2.5 2 | 3 | - Adds useDynamicServerList flag for ConsumerConfig. If this flag is true and dynamicServerListFetchURL is not present, the latter will be generated from hostParamSet. Default is true. -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/api/ConsumerAckType.java: -------------------------------------------------------------------------------- 1 | package com.groupon.messagebus.api; 2 | 3 | /* 4 | * Copyright (c) 2013, Groupon, Inc. 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are 9 | * met: 10 | * 11 | * Redistributions of source code must retain the above copyright notice, 12 | * this list of conditions and the following disclaimer. 13 | * 14 | * Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in the 16 | * documentation and/or other materials provided with the distribution. 17 | * 18 | * Neither the name of GROUPON nor the names of its contributors may be 19 | * used to endorse or promote products derived from this software without 20 | * specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 23 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 24 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 25 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 28 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 29 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 31 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | */ 34 | public enum ConsumerAckType{ 35 | AUTO_CLIENT_ACK, 36 | CLIENT_ACK; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/api/DestinationType.java: -------------------------------------------------------------------------------- 1 | package com.groupon.messagebus.api; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | public enum DestinationType{ 34 | QUEUE, 35 | TOPIC 36 | } 37 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/api/HostParams.java: -------------------------------------------------------------------------------- 1 | package com.groupon.messagebus.api; 2 | 3 | /** 4 | * Encapsulates broker host 5 | * 6 | * Copyright (c) 2013, Groupon, Inc. 7 | * All rights reserved. 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions are 11 | * met: 12 | * 13 | * Redistributions of source code must retain the above copyright notice, 14 | * this list of conditions and the following disclaimer. 15 | * 16 | * Redistributions in binary form must reproduce the above copyright 17 | * notice, this list of conditions and the following disclaimer in the 18 | * documentation and/or other materials provided with the distribution. 19 | * 20 | * Neither the name of GROUPON nor the names of its contributors may be 21 | * used to endorse or promote products derived from this software without 22 | * specific prior written permission. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 25 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 26 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 27 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 28 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 30 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 31 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 32 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | public class HostParams { 37 | private String host; 38 | private int port; 39 | 40 | public HostParams(String aHost, int aPort) { 41 | host = aHost; 42 | port = aPort; 43 | } 44 | 45 | public String getHost() { 46 | return host; 47 | } 48 | 49 | public void setHost(String host) { 50 | this.host = host; 51 | } 52 | 53 | public int getPort() { 54 | return port; 55 | } 56 | 57 | public void setPort(int port) { 58 | this.port = port; 59 | } 60 | 61 | public String toString() { 62 | return host + ":" + port; 63 | } 64 | 65 | @Override 66 | public int hashCode() { 67 | String hostName = host + ":" + port; 68 | return hostName.hashCode(); 69 | } 70 | 71 | @Override 72 | public boolean equals(Object o) { 73 | 74 | if (o instanceof HostParams) { 75 | HostParams other = (HostParams) o; 76 | 77 | return ((host + ":" + port).equalsIgnoreCase((other.getHost() + ":" + other.getPort()))); 78 | } 79 | 80 | return false; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/api/Log.java: -------------------------------------------------------------------------------- 1 | package com.groupon.messagebus.api; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | public class Log { 34 | public static void log(String message){ 35 | System.out.println(message); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/api/ProducerConfig.java: -------------------------------------------------------------------------------- 1 | package com.groupon.messagebus.api; 2 | 3 | /* 4 | * Copyright (c) 2013, Groupon, Inc. 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are 9 | * met: 10 | * 11 | * Redistributions of source code must retain the above copyright notice, 12 | * this list of conditions and the following disclaimer. 13 | * 14 | * Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in the 16 | * documentation and/or other materials provided with the distribution. 17 | * 18 | * Neither the name of GROUPON nor the names of its contributors may be 19 | * used to endorse or promote products derived from this software without 20 | * specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 23 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 24 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 25 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 28 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 29 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 31 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | */ 34 | 35 | import com.groupon.messagebus.api.DestinationType; 36 | import com.groupon.messagebus.api.HostParams; 37 | 38 | public class ProducerConfig { 39 | 40 | private HostParams broker; 41 | private long connectionLifetime = 300000; 42 | private String destinationName; 43 | private DestinationType destinationType = DestinationType.QUEUE; 44 | private String userName = "guest"; 45 | private String password = "guest"; 46 | private int publishMaxRetryAttempts = 3; 47 | private boolean verboseLog = false; 48 | 49 | public boolean isVerboseLog() { 50 | return verboseLog; 51 | } 52 | 53 | public void setVerboseLog(boolean verboseLog) { 54 | this.verboseLog = verboseLog; 55 | } 56 | 57 | public int getPublishMaxRetryAttempts() { 58 | return publishMaxRetryAttempts; 59 | } 60 | 61 | public void setPublishMaxRetryAttempts(int publishMaxRetryAttempts) { 62 | this.publishMaxRetryAttempts = publishMaxRetryAttempts; 63 | } 64 | 65 | public HostParams getBroker() { 66 | return broker; 67 | } 68 | 69 | public void setBroker(HostParams broker) { 70 | this.broker = broker; 71 | } 72 | 73 | public long getConnectionLifetime() { 74 | return connectionLifetime; 75 | } 76 | 77 | public void setConnectionLifetime(long connectionLifetime) { 78 | this.connectionLifetime = connectionLifetime; 79 | } 80 | 81 | public String getDestinationName() { 82 | return destinationName; 83 | } 84 | 85 | public void setDestinationName(String destinationName) { 86 | this.destinationName = destinationName; 87 | } 88 | 89 | public DestinationType getDestinationType() { 90 | return destinationType; 91 | } 92 | 93 | public void setDestinationType(DestinationType destinationType) { 94 | this.destinationType = destinationType; 95 | } 96 | 97 | public String getUserName() { 98 | return userName; 99 | } 100 | 101 | public void setUserName(String userName) { 102 | this.userName = userName; 103 | } 104 | 105 | public String getPassword() { 106 | return password; 107 | } 108 | 109 | public void setPassword(String password) { 110 | this.password = password; 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/api/exceptions/AckFailedException.java: -------------------------------------------------------------------------------- 1 | package com.groupon.messagebus.api.exceptions; 2 | 3 | /* 4 | * Copyright (c) 2013, Groupon, Inc. 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are 9 | * met: 10 | * 11 | * Redistributions of source code must retain the above copyright notice, 12 | * this list of conditions and the following disclaimer. 13 | * 14 | * Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in the 16 | * documentation and/or other materials provided with the distribution. 17 | * 18 | * Neither the name of GROUPON nor the names of its contributors may be 19 | * used to endorse or promote products derived from this software without 20 | * specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 23 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 24 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 25 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 28 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 29 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 31 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | */ 34 | @SuppressWarnings("serial") 35 | public class AckFailedException extends MessageBusException { 36 | public AckFailedException(Exception e){ 37 | super(e); 38 | } 39 | 40 | public AckFailedException(String message) { 41 | super(message); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/api/exceptions/BrokerConnectionCloseFailedException.java: -------------------------------------------------------------------------------- 1 | package com.groupon.messagebus.api.exceptions; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | @SuppressWarnings("serial") 34 | public class BrokerConnectionCloseFailedException extends MessageBusException { 35 | public BrokerConnectionCloseFailedException(Exception e){ 36 | super(e); 37 | } 38 | 39 | public BrokerConnectionCloseFailedException(String message){ 40 | super(message); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/api/exceptions/BrokerConnectionFailedException.java: -------------------------------------------------------------------------------- 1 | package com.groupon.messagebus.api.exceptions; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | @SuppressWarnings("serial") 34 | public class BrokerConnectionFailedException extends MessageBusException { 35 | public BrokerConnectionFailedException(String message) { 36 | super(message); 37 | } 38 | 39 | public BrokerConnectionFailedException(Exception e){ 40 | super(e); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/api/exceptions/InvalidConfigException.java: -------------------------------------------------------------------------------- 1 | package com.groupon.messagebus.api.exceptions; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | @SuppressWarnings("serial") 34 | public class InvalidConfigException extends MessageBusException{ 35 | public InvalidConfigException(String message){ 36 | super(message); 37 | } 38 | } 39 | 40 | 41 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/api/exceptions/InvalidDestinationException.java: -------------------------------------------------------------------------------- 1 | package com.groupon.messagebus.api.exceptions; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | @SuppressWarnings("serial") 34 | public class InvalidDestinationException extends RuntimeException{ 35 | public InvalidDestinationException(Exception e){ 36 | super(e); 37 | } 38 | 39 | public InvalidDestinationException(String msg) { 40 | super(msg); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/api/exceptions/InvalidStatusException.java: -------------------------------------------------------------------------------- 1 | package com.groupon.messagebus.api.exceptions; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | @SuppressWarnings("serial") 34 | public class InvalidStatusException extends RuntimeException { 35 | 36 | public InvalidStatusException(String message) { 37 | super(message); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/api/exceptions/KeepAliveFailedException.java: -------------------------------------------------------------------------------- 1 | package com.groupon.messagebus.api.exceptions; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | @SuppressWarnings("serial") 34 | public class KeepAliveFailedException extends MessageBusException{ 35 | 36 | public KeepAliveFailedException(Exception e) { 37 | super(e); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/api/exceptions/MessageBusException.java: -------------------------------------------------------------------------------- 1 | package com.groupon.messagebus.api.exceptions; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | @SuppressWarnings("serial") 34 | public class MessageBusException extends Exception { 35 | public MessageBusException(Exception e){ 36 | super(e); 37 | } 38 | 39 | public MessageBusException(String message){ 40 | super(message); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/api/exceptions/NackFailedException.java: -------------------------------------------------------------------------------- 1 | package com.groupon.messagebus.api.exceptions; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | @SuppressWarnings("serial") 34 | public class NackFailedException extends MessageBusException{ 35 | 36 | public NackFailedException(Exception e) { 37 | super(e); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/api/exceptions/ReceiveTimeoutException.java: -------------------------------------------------------------------------------- 1 | package com.groupon.messagebus.api.exceptions; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | @SuppressWarnings("serial") 34 | public class ReceiveTimeoutException extends MessageBusException{ 35 | public ReceiveTimeoutException(Exception e) { 36 | super(e); 37 | } 38 | 39 | public ReceiveTimeoutException(String message){ 40 | super(message); 41 | } 42 | 43 | 44 | } 45 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/api/exceptions/SendFailedException.java: -------------------------------------------------------------------------------- 1 | package com.groupon.messagebus.api.exceptions; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | public class SendFailedException extends MessageBusException{ 34 | public SendFailedException(String message) { 35 | super(message); 36 | } 37 | 38 | public SendFailedException(Exception e) { 39 | super(e); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/api/exceptions/TooManyConnectionRetryAttemptsException.java: -------------------------------------------------------------------------------- 1 | package com.groupon.messagebus.api.exceptions; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | * 33 | */ 34 | @SuppressWarnings("serial") 35 | public class TooManyConnectionRetryAttemptsException extends BrokerConnectionFailedException { 36 | 37 | public TooManyConnectionRetryAttemptsException(String message) { 38 | super(message); 39 | } 40 | 41 | public TooManyConnectionRetryAttemptsException(Exception e) { 42 | super(e); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/client/Utils.java: -------------------------------------------------------------------------------- 1 | package com.groupon.messagebus.client; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | import java.io.UnsupportedEncodingException; 34 | import org.apache.commons.codec.binary.Base64; 35 | import org.apache.log4j.Logger; 36 | import org.apache.thrift.TDeserializer; 37 | import org.apache.thrift.TException; 38 | import org.apache.thrift.TSerializer; 39 | import com.groupon.messagebus.api.Message; 40 | import com.groupon.messagebus.thrift.api.MessageInternal; 41 | 42 | public class Utils{ 43 | 44 | private static int MESSAGE_LOG_MAX_LENGTH = 100; 45 | private static TDeserializer deserializer = new TDeserializer(); 46 | private static TSerializer serializer = new TSerializer(); 47 | private static Logger log = Logger.getLogger(Utils.class); 48 | private final static String charset = "US-ASCII"; 49 | 50 | public static final String NULL_STRING = "null"; 51 | 52 | 53 | static String encode( String clearText){ 54 | String ret = ""; 55 | try { 56 | byte[] bytes = clearText.getBytes(charset); 57 | ret = new String(Base64.encodeBase64(bytes), charset); 58 | } catch (UnsupportedEncodingException e) { 59 | log.error("Failed to encode message. Non alphanumeric char?"); 60 | ret = clearText; 61 | } 62 | 63 | return ret; 64 | } 65 | 66 | static String decode( String codedText){ 67 | String ret = ""; 68 | try { 69 | byte[] bytes = codedText.getBytes(charset); 70 | 71 | ret = new String(Base64.decodeBase64(bytes), charset); 72 | } catch (UnsupportedEncodingException e) { 73 | log.error("Failed to encode message. Non alphanumeric char?"); 74 | ret = codedText; 75 | } 76 | 77 | return ret; 78 | } 79 | public static Message getMessageFromBytes(byte[] bytes) { 80 | try { 81 | MessageInternal messageInternal = new MessageInternal(); 82 | bytes = Base64.decodeBase64(bytes); 83 | synchronized(deserializer){ 84 | deserializer.deserialize(messageInternal, bytes); 85 | } 86 | return new Message(messageInternal); 87 | } catch (Exception e) { 88 | throw new RuntimeException("Failed to read thrift message correctly.", e); 89 | } 90 | } 91 | 92 | 93 | public static byte[] getThriftDataAsBytes(Message message) throws TException, UnsupportedEncodingException { 94 | byte[] bytes = null; 95 | synchronized(serializer){ 96 | bytes = serializer.serialize(message.getMessageInternal()); 97 | } 98 | 99 | bytes = Base64.encodeBase64(bytes); 100 | return bytes; 101 | 102 | } 103 | 104 | 105 | public static String getMessageInternalForLogging(MessageInternal messageInternal) { 106 | String str = messageInternal.toString(); 107 | if (str.length() > MESSAGE_LOG_MAX_LENGTH) 108 | str = str.substring(0, MESSAGE_LOG_MAX_LENGTH -1); 109 | 110 | return str; 111 | } 112 | 113 | public static void sleep(long millis) { 114 | try { 115 | Thread.sleep(millis); 116 | } catch (InterruptedException ie) { 117 | log.error("Error occurred while resting...", ie); 118 | } 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/client/examples/DLQHandleExample.java: -------------------------------------------------------------------------------- 1 | package com.groupon.messagebus.client.examples; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | import java.util.ArrayList; 34 | import java.util.HashSet; 35 | import java.util.Set; 36 | 37 | import org.apache.log4j.BasicConfigurator; 38 | 39 | import com.groupon.messagebus.api.Consumer; 40 | import com.groupon.messagebus.api.ConsumerAckType; 41 | import com.groupon.messagebus.api.ConsumerConfig; 42 | import com.groupon.messagebus.api.DestinationType; 43 | import com.groupon.messagebus.api.HostParams; 44 | import com.groupon.messagebus.api.Log; 45 | import com.groupon.messagebus.api.Message; 46 | import com.groupon.messagebus.api.exceptions.InvalidConfigException; 47 | import com.groupon.messagebus.api.exceptions.InvalidStatusException; 48 | import com.groupon.messagebus.client.ConsumerImpl; 49 | 50 | public class DLQHandleExample { 51 | 52 | /** 53 | * @param args 54 | * @throws InterruptedException 55 | * @throws InvalidStatusException 56 | */ 57 | public static void main(String[] args) throws InterruptedException, InvalidStatusException { 58 | // TODO Auto-generated method stub 59 | ConsumerConfig config = new ConsumerConfig(); 60 | config.setConnectionLifetime(300000); 61 | 62 | // default host to connect to 63 | HostParams host = new HostParams("localhost", 6661); 64 | Set hostsList = new HashSet(); 65 | hostsList.add(host); 66 | 67 | //config.setDynamicServerListFetchURL("http://mbus-consumers-list.tm:8081/jmx?command=get_attribute&args=org.hornetq%3Amodule%3DCore%2Ctype%3DServer%20ListOfBrokers"); 68 | config.setDestinationType(DestinationType.QUEUE); 69 | config.setHostParams(hostsList); 70 | config.setDestinationName("jms.queue.DLQ"); 71 | config.setAckType(ConsumerAckType.CLIENT_ACK); 72 | config.setConnectionLifetime(300000); 73 | config.setSubscriptionId("client-xxx"); 74 | 75 | BasicConfigurator.configure(); 76 | 77 | Consumer con = new ConsumerImpl(); 78 | try { 79 | con.start(config); 80 | } catch (InvalidConfigException e) { 81 | e.printStackTrace(); 82 | } 83 | Thread.sleep(500); 84 | Log.log("connected"); 85 | long startTime = System.currentTimeMillis(); 86 | ArrayList ackIDs = new ArrayList(); 87 | for (int i = 0; i<10; i++) { 88 | 89 | try{ 90 | Message tmp = con.receive(); 91 | Thread.sleep(1); 92 | if(tmp == null) { 93 | Log.log("received null."); 94 | continue; 95 | } 96 | else 97 | Log.log("received something."+tmp.getMessagePayloadType()); 98 | 99 | if(i%2 == 0) 100 | ackIDs.add(tmp.getAckId()); 101 | // con.ack(); 102 | switch(tmp.getMessagePayloadType()){ 103 | case STRING: 104 | Log.log(tmp.getStringPayload()); 105 | break; 106 | case JSON: 107 | Log.log(tmp.getJSONStringPayload()); 108 | break; 109 | case BINARY: 110 | Log.log(new String(tmp.getBinaryPayload())); 111 | break; 112 | } 113 | 114 | }catch( Exception e) 115 | { 116 | Log.log( "receive expired"); 117 | } 118 | System.out.println(); 119 | // if not in auto ack mode 120 | } 121 | } 122 | 123 | } 124 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/client/examples/ProducerBenchmark.java: -------------------------------------------------------------------------------- 1 | package com.groupon.messagebus.client.examples; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | * 33 | */ 34 | import org.apache.log4j.BasicConfigurator; 35 | import org.apache.log4j.Level; 36 | import org.apache.log4j.Logger; 37 | 38 | import com.groupon.messagebus.api.DestinationType; 39 | import com.groupon.messagebus.api.HostParams; 40 | import com.groupon.messagebus.api.Message; 41 | import com.groupon.messagebus.api.Producer; 42 | import com.groupon.messagebus.api.ProducerConfig; 43 | import com.groupon.messagebus.api.exceptions.BrokerConnectionCloseFailedException; 44 | import com.groupon.messagebus.api.exceptions.InvalidConfigException; 45 | import com.groupon.messagebus.api.exceptions.MessageBusException; 46 | import com.groupon.messagebus.api.exceptions.TooManyConnectionRetryAttemptsException; 47 | import com.groupon.messagebus.client.ProducerImpl; 48 | 49 | public class ProducerBenchmark { 50 | public static void main(String[] args) throws InvalidConfigException, MessageBusException{ 51 | BasicConfigurator.configure(); 52 | Logger.getRootLogger().setLevel(Level.ERROR); 53 | 54 | ProducerConfig config = new ProducerConfig(); 55 | int msgCount = 1000; 56 | if(args.length >0 ) 57 | msgCount = Integer.parseInt(args[0]); 58 | // 61613 is default port for connecting over stomp. Here we either 59 | // provide direct broker name as host, or DNS name space 60 | 61 | HostParams host = new HostParams("localhost", 6662); 62 | 63 | config.setBroker(host); 64 | config.setConnectionLifetime(300000); 65 | 66 | // chose between topic (one to many) or queue (one to one) 67 | config.setDestinationType(DestinationType.TOPIC); 68 | config.setDestinationName("jms.topic.testTopic2"); 69 | 70 | Producer producer = new ProducerImpl(); 71 | 72 | producer.start(config); 73 | 74 | 75 | StringBuffer messageStr = new StringBuffer("Hello this is an awesome message!"); 76 | 77 | for( int i =0; i < 100; ++i) 78 | messageStr.append("Hello this is an awesome message!"); 79 | Message message = Message.createStringMessage("id-", messageStr.toString()); 80 | 81 | System.out.println( messageStr.length()); 82 | long start = System.currentTimeMillis(); 83 | for (int i = 0; i < msgCount; i++) { 84 | 85 | try { 86 | producer.sendSafe(message, null); 87 | } catch (Exception e) { 88 | e.printStackTrace(); 89 | } 90 | 91 | //System.out.println("Sent:" + message.getStringPayload()); 92 | } 93 | 94 | long end = System.currentTimeMillis(); 95 | 96 | System.out.println("Time used in mili: " + (end-start)); 97 | producer.stop(); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/client/examples/ProducerExample.java: -------------------------------------------------------------------------------- 1 | package com.groupon.messagebus.client.examples; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | * 33 | */ 34 | 35 | import java.io.FileInputStream; 36 | import java.io.FileNotFoundException; 37 | import java.io.IOException; 38 | import java.math.BigInteger; 39 | import java.security.SecureRandom; 40 | import java.util.HashMap; 41 | import java.util.Properties; 42 | 43 | import org.apache.log4j.BasicConfigurator; 44 | 45 | import com.groupon.messagebus.api.DestinationType; 46 | import com.groupon.messagebus.api.HostParams; 47 | import com.groupon.messagebus.api.Message; 48 | import com.groupon.messagebus.api.Producer; 49 | import com.groupon.messagebus.api.ProducerConfig; 50 | import com.groupon.messagebus.api.exceptions.InvalidConfigException; 51 | import com.groupon.messagebus.api.exceptions.MessageBusException; 52 | import com.groupon.messagebus.client.ProducerImpl; 53 | 54 | public class ProducerExample { 55 | 56 | public static void main(String[] args) throws InvalidConfigException, MessageBusException, FileNotFoundException, IOException { 57 | 58 | if (args.length < 1) { 59 | System.out.println("Usage: java -cp uber-mbus-client.jar com.groupon.messagebus.client.examples.ProducerExample config.properties"); 60 | System.exit(1); 61 | } 62 | 63 | Properties properties = new Properties(); 64 | properties.load(new FileInputStream(args[0])); 65 | 66 | BasicConfigurator.configure(); 67 | 68 | ProducerConfig config = new ProducerConfig(); 69 | 70 | // 61613 is default port for connecting over stomp. Here we either 71 | // provide direct broker name as host, or DNS name space 72 | 73 | HostParams host = new HostParams(properties.getProperty("server"), Integer.parseInt(properties.getProperty("port"))); 74 | 75 | config.setBroker(host); 76 | config.setConnectionLifetime(300000); 77 | 78 | // chose between topic (one to many) or queue (one to one) 79 | config.setDestinationType(DestinationType.valueOf(properties.getProperty("dest_type"))); 80 | config.setDestinationName(properties.getProperty("dest_name")); 81 | 82 | Producer producer = new ProducerImpl(); 83 | 84 | producer.start(config); 85 | SecureRandom random = new SecureRandom(); 86 | 87 | HashMap headers = null; 88 | int priority = 4; 89 | if(properties.getProperty("priority")!=null) 90 | { 91 | priority = Integer.parseInt(properties.getProperty("priority")); 92 | headers = new HashMap(); 93 | headers.put("priority", "" + priority); 94 | 95 | } 96 | 97 | 98 | 99 | for (int i = 0; i < Integer.parseInt(properties.getProperty("msg_count")); i++) { 100 | String messageStr = "Count-" + i + " priority=" + priority + " random-data(" + new BigInteger(Integer.parseInt(properties.getProperty("msg_size")), random).toString(32) + ")"; 101 | Message message = Message.createStringMessage( messageStr); 102 | 103 | try { 104 | producer.sendSafe(message, headers); 105 | } catch (Exception e) { 106 | e.printStackTrace(); 107 | } 108 | 109 | System.out.println("Sent:" + message.getStringPayload()); 110 | } 111 | 112 | producer.stop(); 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/client/examples/SimpleClientIntegration.java: -------------------------------------------------------------------------------- 1 | package com.groupon.messagebus.client.examples; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | 34 | import java.util.HashSet; 35 | import java.util.Set; 36 | 37 | import org.apache.log4j.BasicConfigurator; 38 | 39 | import com.groupon.messagebus.api.Consumer; 40 | import com.groupon.messagebus.api.ConsumerAckType; 41 | import com.groupon.messagebus.api.ConsumerConfig; 42 | import com.groupon.messagebus.api.DestinationType; 43 | import com.groupon.messagebus.api.HostParams; 44 | import com.groupon.messagebus.api.Log; 45 | import com.groupon.messagebus.api.exceptions.InvalidConfigException; 46 | import com.groupon.messagebus.api.exceptions.MessageBusException; 47 | import com.groupon.messagebus.client.ConsumerImpl; 48 | import com.groupon.messagebus.api.Message; 49 | 50 | public class SimpleClientIntegration { 51 | 52 | /** 53 | * @param args 54 | * @throws InterruptedException 55 | * @throws MessageBusException 56 | */ 57 | public static void main(String[] args) throws InterruptedException, MessageBusException { 58 | ConsumerConfig config = new ConsumerConfig(); 59 | config.setConnectionLifetime(300000); 60 | HostParams host = new HostParams("localhost", 61613); 61 | Set hostsList = new HashSet(); 62 | hostsList.add(host); 63 | 64 | config.setDestinationType(DestinationType.TOPIC); 65 | //config.setDestinationType(DestinationType.QUEUE); 66 | config.setDestinationName("jms.topic.testTopic2"); 67 | //config.setDestinationName("jms.queue.testQueue1"); 68 | 69 | config.setHostParams(hostsList); 70 | config.setSubscriptionId("client-1"); 71 | config.setAckType(ConsumerAckType.CLIENT_ACK); 72 | config.setConnectionLifetime(40000); 73 | 74 | BasicConfigurator.configure(); 75 | 76 | Consumer con = new ConsumerImpl(); 77 | try { 78 | con.start(config); 79 | } catch (InvalidConfigException e) { 80 | e.printStackTrace(); 81 | } 82 | 83 | 84 | 85 | Log.log("connected"); 86 | long startTime = System.currentTimeMillis(); 87 | for(int i =0 ; i< 100; i++){ 88 | Message tmp = con.receive(); 89 | con.ackSafe(); 90 | //con.nack() - discards last sent message and adds it back to the queue 91 | //con.nack(message.getAckId()) - discards 'message' and adds it back to the queue 92 | Log.log(tmp.getMessageId()); 93 | 94 | if((i%200)==0){ 95 | //Log.log(new String(tmp)); 96 | double difference = System.currentTimeMillis() - startTime; 97 | startTime = System.currentTimeMillis(); 98 | if(difference != 0){ 99 | double took = 200 * 1000/ (difference); 100 | Log.log("Consumed 200 messages in "+ difference+ " ms at "+ took + "messages/second Total Consumed="+i); 101 | } 102 | } 103 | } 104 | 105 | con.stop(); 106 | System.exit(0); 107 | 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/client/examples/SimpleProducerIntegration.java: -------------------------------------------------------------------------------- 1 | package com.groupon.messagebus.client.examples; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | import com.groupon.messagebus.api.DestinationType; 34 | import com.groupon.messagebus.api.HostParams; 35 | import com.groupon.messagebus.api.Producer; 36 | import com.groupon.messagebus.api.ProducerConfig; 37 | import com.groupon.messagebus.api.exceptions.BrokerConnectionCloseFailedException; 38 | import com.groupon.messagebus.api.exceptions.BrokerConnectionFailedException; 39 | import com.groupon.messagebus.api.exceptions.InvalidConfigException; 40 | import com.groupon.messagebus.api.exceptions.InvalidStatusException; 41 | import com.groupon.messagebus.api.exceptions.SendFailedException; 42 | import com.groupon.messagebus.api.exceptions.TooManyConnectionRetryAttemptsException; 43 | import com.groupon.messagebus.client.ProducerImpl; 44 | import com.groupon.messagebus.api.Message; 45 | 46 | public class SimpleProducerIntegration { 47 | 48 | 49 | public static void main(String[] args) throws TooManyConnectionRetryAttemptsException, InvalidConfigException, BrokerConnectionCloseFailedException, BrokerConnectionFailedException, SendFailedException, InvalidStatusException{ 50 | 51 | ProducerConfig config = new ProducerConfig(); 52 | HostParams host = new HostParams("localhost", 61613); 53 | 54 | 55 | config.setBroker(host); 56 | config.setConnectionLifetime(10000); 57 | config.setDestinationType(DestinationType.TOPIC); 58 | //config.setDestinationType(DestinationType.QUEUE); 59 | config.setDestinationName("jms.topic.testTopic2"); 60 | //config.setDestinationName("jms.queue.testQueue1"); 61 | 62 | Producer producer = new ProducerImpl(); 63 | 64 | 65 | producer.start(config); 66 | StringBuilder sb = new StringBuilder(); 67 | for(int i = 0 ; i<1000; i++) 68 | sb.append(Math.random()); 69 | for(int i = 0 ; i < 5000 ; i ++ ){ 70 | 71 | String messageStr = sb.toString() + i; 72 | Message message = Message.createBinaryMessage("id-" + i, messageStr.getBytes()); 73 | 74 | 75 | producer.sendSafe(message, null); 76 | System.out.println("Sent:"+ message.getMessageId()); 77 | } 78 | 79 | producer.stop(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/client/examples/consumer_example.properties: -------------------------------------------------------------------------------- 1 | server=localhost 2 | port=61613 3 | dest_type=QUEUE 4 | dest_name=jms.queue.testQueue1 5 | msg_count=10 6 | msg_size=1024 7 | subscription_id=lin 8 | rcv_timeout=10 -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/client/examples/log4j.properties.sample: -------------------------------------------------------------------------------- 1 | # This file needs to be changed appropriatedly as required 2 | # Also ENSURE that this file is in the classpath of the application 3 | # Root logger option 4 | log4j.rootLogger=INFO, file 5 | 6 | # Direct log messages to a log file 7 | log4j.appender.file=org.apache.log4j.RollingFileAppender 8 | log4j.appender.file.File=/var/groupon/hornetq/mbus_client.log 9 | log4j.appender.file.MaxFileSize=5MB 10 | log4j.appender.file.MaxBackupIndex=1 11 | log4j.appender.file.layout=org.apache.log4j.PatternLayout 12 | log4j.appender.file.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss}] %c{1}:%L - %m%n 13 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/client/examples/producer_example.properties: -------------------------------------------------------------------------------- 1 | server=localhost 2 | port=61613 3 | dest_type=QUEUE 4 | dest_name=jms.queue.testQueue1 5 | msg_count=10 6 | msg_size=1024 7 | rcv_timeout=1 -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/messagebus/util/DynamicServerListGetter.java: -------------------------------------------------------------------------------- 1 | package com.groupon.messagebus.util; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | import java.io.IOException; 34 | import java.net.MalformedURLException; 35 | import java.net.URISyntaxException; 36 | import java.net.URL; 37 | import java.net.URLConnection; 38 | import java.util.HashSet; 39 | import java.util.Scanner; 40 | import java.util.Set; 41 | import java.util.regex.Matcher; 42 | import java.util.regex.Pattern; 43 | 44 | import org.apache.http.client.utils.URIBuilder; 45 | import org.apache.log4j.BasicConfigurator; 46 | import org.apache.log4j.Logger; 47 | 48 | import com.groupon.messagebus.api.HostParams; 49 | 50 | public class DynamicServerListGetter { 51 | 52 | private static Logger log = Logger.getLogger(DynamicServerListGetter.class); 53 | private static final int MAX_READ_TIMEOUT = 5000; 54 | private static final int MAX_CONNECT_TIMEOUT = 1000; 55 | 56 | public static String buildDynamicServersURL(String hostname, int port) throws URISyntaxException{ 57 | URIBuilder builder = new URIBuilder(); 58 | builder.setHost(hostname); 59 | builder.setPort(port); 60 | builder.setPath("/jmx"); 61 | builder.addParameter("command", "get_attribute"); 62 | builder.addParameter("args", "org.hornetq:module=Core,type=Server ListOfBrokers"); 63 | builder.setScheme("http"); 64 | return builder.build().toASCIIString(); 65 | } 66 | 67 | protected static String fetch(String aURL) throws MalformedURLException, IOException { 68 | String content = null; 69 | URLConnection connection = null; 70 | 71 | connection = new URL(aURL).openConnection(); 72 | connection.setConnectTimeout(MAX_CONNECT_TIMEOUT); 73 | connection.setReadTimeout(MAX_READ_TIMEOUT); 74 | Scanner scanner = new Scanner(connection.getInputStream()); 75 | scanner.useDelimiter("\\Z"); 76 | content = scanner.next(); 77 | 78 | 79 | return content; 80 | } 81 | 82 | public static Set parseAndReturnHosts(String content) { 83 | Set serverSet = new HashSet(); 84 | 85 | if (content == null || content.trim().length() == 0){ 86 | return serverSet; 87 | } 88 | 89 | String[] servers = content.split(","); 90 | for (String host : servers) { 91 | String[] hostParam = host.split(":"); 92 | serverSet.add(new HostParams(hostParam[0], Integer.parseInt(hostParam[1]))); 93 | } 94 | 95 | return serverSet; 96 | } 97 | 98 | /** 99 | * Fetches XML from given URL, 100 | * parses list of brokers and returns the brokers 101 | * as set of HostParams objects 102 | * @param aURL 103 | * @return 104 | * @throws IOException 105 | * @throws MalformedURLException 106 | */ 107 | public static Set fetchHostList(String aURL) throws MalformedURLException, IOException { 108 | return parseAndReturnHosts(fetch(aURL)); 109 | } 110 | 111 | public static void main(String[] args) throws MalformedURLException, IOException { 112 | 113 | 114 | String aURL = "http://localhost:18081/jmx?command=get_attribute&args=org.hornetq%3Amodule%3DCore%2Ctype%3DServer%20ListOfBrokers"; 115 | BasicConfigurator.configure(); 116 | 117 | 118 | Set hosts = parseAndReturnHosts(DynamicServerListGetter.fetch(aURL)); 119 | 120 | 121 | if(hosts!=null){ 122 | for(HostParams host: hosts){ 123 | System.out.println(host); 124 | } 125 | } 126 | 127 | if (hosts.size() == 0 || hosts == null) 128 | System.out.println("No servers found"); 129 | 130 | 131 | } 132 | 133 | 134 | } 135 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/stomp/ByteArrayInputStream.java: -------------------------------------------------------------------------------- 1 | package com.groupon.stomp; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | 6 | 7 | /** 8 | * Very similar to the java.io.ByteArrayInputStream but this version is not 9 | * thread safe. 10 | * Copyright (c) 2013, Groupon, Inc. 11 | * All rights reserved. 12 | * 13 | * Redistribution and use in source and binary forms, with or without 14 | * modification, are permitted provided that the following conditions are 15 | * met: 16 | * 17 | * Redistributions of source code must retain the above copyright notice, 18 | * this list of conditions and the following disclaimer. 19 | * 20 | * Redistributions in binary form must reproduce the above copyright 21 | * notice, this list of conditions and the following disclaimer in the 22 | * documentation and/or other materials provided with the distribution. 23 | * 24 | * Neither the name of GROUPON nor the names of its contributors may be 25 | * used to endorse or promote products derived from this software without 26 | * specific prior written permission. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 29 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 30 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 31 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 34 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 35 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 36 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 37 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 38 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 | * */ 40 | public class ByteArrayInputStream extends InputStream { 41 | 42 | byte buffer[]; 43 | int limit; 44 | int pos; 45 | int mark; 46 | 47 | public ByteArrayInputStream(byte data[]) { 48 | this(data, 0, data.length); 49 | } 50 | 51 | public ByteArrayInputStream(ByteSequence sequence) { 52 | this(sequence.getData(), sequence.getOffset(), sequence.getLength()); 53 | } 54 | 55 | public ByteArrayInputStream(byte data[], int offset, int size) { 56 | this.buffer = data; 57 | this.mark = offset; 58 | this.pos = offset; 59 | this.limit = offset + size; 60 | } 61 | 62 | public int read() throws IOException { 63 | if (pos < limit) { 64 | return buffer[pos++] & 0xff; 65 | } else { 66 | return -1; 67 | } 68 | } 69 | 70 | public int read(byte[] b) throws IOException { 71 | return read(b, 0, b.length); 72 | } 73 | 74 | public int read(byte b[], int off, int len) { 75 | if (pos < limit) { 76 | len = Math.min(len, limit - pos); 77 | if (len > 0) { 78 | System.arraycopy(buffer, pos, b, off, len); 79 | pos += len; 80 | } 81 | return len; 82 | } else { 83 | return -1; 84 | } 85 | } 86 | 87 | public long skip(long len) throws IOException { 88 | if (pos < limit) { 89 | len = Math.min(len, limit - pos); 90 | if (len > 0) { 91 | pos += len; 92 | } 93 | return len; 94 | } else { 95 | return -1; 96 | } 97 | } 98 | 99 | public int available() { 100 | return limit - pos; 101 | } 102 | 103 | public boolean markSupported() { 104 | return true; 105 | } 106 | 107 | public void mark(int markpos) { 108 | mark = pos; 109 | } 110 | 111 | public void reset() { 112 | pos = mark; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/stomp/ByteArrayOutputStream.java: -------------------------------------------------------------------------------- 1 | package com.groupon.stomp; 2 | 3 | import java.io.OutputStream; 4 | 5 | 6 | 7 | /** 8 | * Very similar to the java.io.ByteArrayOutputStream but this version 9 | * is not thread safe and the resulting data is returned in a ByteSequence 10 | * to avoid an extra byte[] allocation. 11 | * 12 | * Copyright (c) 2013, Groupon, Inc. 13 | * All rights reserved. 14 | * 15 | * Redistribution and use in source and binary forms, with or without 16 | * modification, are permitted provided that the following conditions are 17 | * met: 18 | * 19 | * Redistributions of source code must retain the above copyright notice, 20 | * this list of conditions and the following disclaimer. 21 | * 22 | * Redistributions in binary form must reproduce the above copyright 23 | * notice, this list of conditions and the following disclaimer in the 24 | * documentation and/or other materials provided with the distribution. 25 | * 26 | * Neither the name of GROUPON nor the names of its contributors may be 27 | * used to endorse or promote products derived from this software without 28 | * specific prior written permission. 29 | * 30 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 31 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 32 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 33 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 34 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 35 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 36 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 37 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 38 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 39 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 40 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41 | */ 42 | public class ByteArrayOutputStream extends OutputStream { 43 | 44 | byte buffer[]; 45 | int size; 46 | 47 | public ByteArrayOutputStream() { 48 | this(1028); 49 | } 50 | public ByteArrayOutputStream(int capacity) { 51 | buffer = new byte[capacity]; 52 | } 53 | 54 | public void write(int b) { 55 | int newsize = size + 1; 56 | checkCapacity(newsize); 57 | buffer[size] = (byte) b; 58 | size = newsize; 59 | } 60 | 61 | public void write(byte b[], int off, int len) { 62 | int newsize = size + len; 63 | checkCapacity(newsize); 64 | System.arraycopy(b, off, buffer, size, len); 65 | size = newsize; 66 | } 67 | 68 | /** 69 | * Ensures the the buffer has at least the minimumCapacity specified. 70 | * @param i 71 | */ 72 | private void checkCapacity(int minimumCapacity) { 73 | if (minimumCapacity > buffer.length) { 74 | byte b[] = new byte[Math.max(buffer.length << 1, minimumCapacity)]; 75 | System.arraycopy(buffer, 0, b, 0, size); 76 | buffer = b; 77 | } 78 | } 79 | 80 | public void reset() { 81 | size = 0; 82 | } 83 | 84 | public ByteSequence toByteSequence() { 85 | return new ByteSequence(buffer, 0, size); 86 | } 87 | 88 | public byte[] toByteArray() { 89 | byte rc[] = new byte[size]; 90 | System.arraycopy(buffer, 0, rc, 0, size); 91 | return rc; 92 | } 93 | 94 | public int size() { 95 | return size; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/stomp/ByteSequence.java: -------------------------------------------------------------------------------- 1 | package com.groupon.stomp; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | public class ByteSequence { 34 | 35 | public byte[] data; 36 | public int offset; 37 | public int length; 38 | 39 | public ByteSequence(byte data[]) { 40 | this.data = data; 41 | this.offset = 0; 42 | this.length = data.length; 43 | } 44 | 45 | public ByteSequence(byte data[], int offset, int length) { 46 | this.data = data; 47 | this.offset = offset; 48 | this.length = length; 49 | } 50 | 51 | public byte[] getData() { 52 | return data; 53 | } 54 | 55 | public int getLength() { 56 | return length; 57 | } 58 | 59 | public int getOffset() { 60 | return offset; 61 | } 62 | 63 | public void setData(byte[] data) { 64 | this.data = data; 65 | } 66 | 67 | public void setLength(int length) { 68 | this.length = length; 69 | } 70 | 71 | public void setOffset(int offset) { 72 | this.offset = offset; 73 | } 74 | 75 | public void compact() { 76 | if (length != data.length) { 77 | byte t[] = new byte[length]; 78 | System.arraycopy(data, offset, t, 0, length); 79 | data = t; 80 | offset = 0; 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/stomp/Command.java: -------------------------------------------------------------------------------- 1 | package com.groupon.stomp; 2 | 3 | /** 4 | * Licensed to the Apache Software Foundation (ASF) under one or more 5 | * contributor license agreements. See the NOTICE file distributed with 6 | * this work for additional information regarding copyright ownership. 7 | * The ASF licenses this file to You under the Apache License, Version 2.0 8 | * (the "License"); you may not use this file except in compliance with 9 | * the License. You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | 21 | /** 22 | * The Command Pattern so that we can send and receive commands on the different 23 | * transports 24 | * 25 | * Copyright (c) 2013, Groupon, Inc. 26 | * All rights reserved. 27 | * 28 | * Redistribution and use in source and binary forms, with or without 29 | * modification, are permitted provided that the following conditions are 30 | * met: 31 | * 32 | * Redistributions of source code must retain the above copyright notice, 33 | * this list of conditions and the following disclaimer. 34 | * 35 | * Redistributions in binary form must reproduce the above copyright 36 | * notice, this list of conditions and the following disclaimer in the 37 | * documentation and/or other materials provided with the distribution. 38 | * 39 | * Neither the name of GROUPON nor the names of its contributors may be 40 | * used to endorse or promote products derived from this software without 41 | * specific prior written permission. 42 | * 43 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 44 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 45 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 46 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 47 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 48 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 49 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 50 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 51 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 52 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 53 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 54 | * 55 | */ 56 | public interface Command extends DataStructure { 57 | 58 | void setCommandId(int value); 59 | 60 | /** 61 | * @return the unique ID of this request used to map responses to requests 62 | */ 63 | int getCommandId(); 64 | 65 | void setResponseRequired(boolean responseRequired); 66 | 67 | boolean isResponseRequired(); 68 | 69 | boolean isResponse(); 70 | 71 | boolean isMessageDispatch(); 72 | 73 | boolean isBrokerInfo(); 74 | 75 | boolean isWireFormatInfo(); 76 | 77 | boolean isMessage(); 78 | 79 | boolean isMessageAck(); 80 | 81 | boolean isMessageDispatchNotification(); 82 | 83 | boolean isShutdownInfo(); 84 | 85 | boolean isConnectionControl(); 86 | 87 | //Response visit(CommandVisitor visitor) throws Exception; 88 | 89 | /** 90 | * The endpoint within the transport where this message came from which 91 | * could be null if the transport only supports a single endpoint. 92 | */ 93 | Endpoint getFrom(); 94 | 95 | void setFrom(Endpoint from); 96 | 97 | /** 98 | * The endpoint within the transport where this message is going to - null 99 | * means all endpoints. 100 | */ 101 | Endpoint getTo(); 102 | 103 | void setTo(Endpoint to); 104 | } 105 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/stomp/CommandVisitor.java: -------------------------------------------------------------------------------- 1 | package com.groupon.stomp; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | public interface CommandVisitor { 34 | 35 | } 36 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/stomp/DataStructure.java: -------------------------------------------------------------------------------- 1 | package com.groupon.stomp; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | public interface DataStructure { 34 | 35 | /** 36 | * @return The type of the data structure 37 | */ 38 | byte getDataStructureType(); 39 | boolean isMarshallAware(); 40 | 41 | } 42 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/stomp/Endpoint.java: -------------------------------------------------------------------------------- 1 | package com.groupon.stomp; 2 | 3 | /** 4 | * Licensed to the Apache Software Foundation (ASF) under one or more 5 | * contributor license agreements. See the NOTICE file distributed with 6 | * this work for additional information regarding copyright ownership. 7 | * The ASF licenses this file to You under the Apache License, Version 2.0 8 | * (the "License"); you may not use this file except in compliance with 9 | * the License. You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | 21 | /** 22 | * Represents the logical endpoint where commands come from or are sent to. 23 | * 24 | * For connection based transports like TCP / VM then there is a single endpoint 25 | * for all commands. For transports like multicast there could be different 26 | * endpoints being used on the same transport. 27 | * 28 | * Copyright (c) 2013, Groupon, Inc. 29 | * All rights reserved. 30 | * 31 | * Redistribution and use in source and binary forms, with or without 32 | * modification, are permitted provided that the following conditions are 33 | * met: 34 | * 35 | * Redistributions of source code must retain the above copyright notice, 36 | * this list of conditions and the following disclaimer. 37 | * 38 | * Redistributions in binary form must reproduce the above copyright 39 | * notice, this list of conditions and the following disclaimer in the 40 | * documentation and/or other materials provided with the distribution. 41 | * 42 | * Neither the name of GROUPON nor the names of its contributors may be 43 | * used to endorse or promote products derived from this software without 44 | * specific prior written permission. 45 | * 46 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 47 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 48 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 49 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 50 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 51 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 52 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 53 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 54 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 55 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 56 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 57 | * 58 | */ 59 | public interface Endpoint { 60 | 61 | /** 62 | * Returns the name of the endpoint. 63 | */ 64 | String getName(); 65 | 66 | /** 67 | * Returns the broker ID for this endpoint, if the endpoint is a broker or 68 | * null 69 | */ 70 | 71 | } 72 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/stomp/ProtocolException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013, Groupon, Inc. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are 7 | * met: 8 | * 9 | * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 12 | * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 16 | * Neither the name of GROUPON nor the names of its contributors may be 17 | * used to endorse or promote products derived from this software without 18 | * specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 21 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 23 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 26 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | */ 32 | package com.groupon.stomp; 33 | 34 | 35 | import java.io.IOException; 36 | 37 | /** 38 | * @author chirino 39 | */ 40 | public class ProtocolException extends IOException { 41 | 42 | private static final long serialVersionUID = -2869735532997332242L; 43 | 44 | private final boolean fatal; 45 | 46 | public ProtocolException() { 47 | this(null); 48 | } 49 | 50 | public ProtocolException(String s) { 51 | this(s, false); 52 | } 53 | 54 | public ProtocolException(String s, boolean fatal) { 55 | this(s, fatal, null); 56 | } 57 | 58 | public ProtocolException(String s, boolean fatal, Throwable cause) { 59 | super(s); 60 | this.fatal = fatal; 61 | initCause(cause); 62 | } 63 | 64 | public boolean isFatal() { 65 | return fatal; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/stomp/StompFrameError.java: -------------------------------------------------------------------------------- 1 | package com.groupon.stomp; 2 | 3 | /** 4 | * Copyright (c) 2013, Groupon, Inc. 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are 9 | * met: 10 | * 11 | * Redistributions of source code must retain the above copyright notice, 12 | * this list of conditions and the following disclaimer. 13 | * 14 | * Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in the 16 | * documentation and/or other materials provided with the distribution. 17 | * 18 | * Neither the name of GROUPON nor the names of its contributors may be 19 | * used to endorse or promote products derived from this software without 20 | * specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 23 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 24 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 25 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 28 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 29 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 31 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | */ 34 | public class StompFrameError extends StompFrame { 35 | 36 | private final ProtocolException exception; 37 | 38 | public StompFrameError(ProtocolException exception) { 39 | this.exception = exception; 40 | } 41 | 42 | public ProtocolException getException() { 43 | return exception; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/stomp/WireFormat.java: -------------------------------------------------------------------------------- 1 | package com.groupon.stomp; 2 | 3 | import java.io.DataInput; 4 | import java.io.DataOutput; 5 | import java.io.IOException; 6 | 7 | /** 8 | * Provides a mechanism to marshal commands into and out of packets 9 | * or into and out of streams, Channels and Datagrams. 10 | * 11 | * Copyright (c) 2013, Groupon, Inc. 12 | * All rights reserved. 13 | * 14 | * Redistribution and use in source and binary forms, with or without 15 | * modification, are permitted provided that the following conditions are 16 | * met: 17 | * 18 | * Redistributions of source code must retain the above copyright notice, 19 | * this list of conditions and the following disclaimer. 20 | * 21 | * Redistributions in binary form must reproduce the above copyright 22 | * notice, this list of conditions and the following disclaimer in the 23 | * documentation and/or other materials provided with the distribution. 24 | * 25 | * Neither the name of GROUPON nor the names of its contributors may be 26 | * used to endorse or promote products derived from this software without 27 | * specific prior written permission. 28 | * 29 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 30 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 31 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 32 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 35 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 36 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 37 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 38 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 39 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 | */ 41 | public interface WireFormat { 42 | 43 | /** 44 | * Packet based marshaling 45 | */ 46 | ByteSequence marshal(Object command) throws IOException; 47 | 48 | /** 49 | * Packet based un-marshaling 50 | */ 51 | Object unmarshal(ByteSequence packet) throws IOException; 52 | 53 | /** 54 | * Stream based marshaling 55 | */ 56 | void marshal(Object command, DataOutput out) throws IOException; 57 | 58 | /** 59 | * Packet based un-marshaling 60 | */ 61 | Object unmarshal(DataInput in) throws IOException; 62 | 63 | /** 64 | * @param the version of the wire format 65 | */ 66 | void setVersion(int version); 67 | 68 | /** 69 | * @return the version of the wire format 70 | */ 71 | int getVersion(); 72 | 73 | } 74 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/stomp/examples/ExampleStompTopicConsumer.java: -------------------------------------------------------------------------------- 1 | package com.groupon.stomp.examples; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | import java.util.HashMap; 34 | 35 | import com.groupon.stomp.Stomp.Headers.Subscribe; 36 | import com.groupon.stomp.Stomp; 37 | import com.groupon.stomp.StompConnection; 38 | import com.groupon.stomp.StompFrame; 39 | 40 | public class ExampleStompTopicConsumer { 41 | public static void main(String []args) throws Exception{ 42 | stayConnected(); 43 | 44 | } 45 | private static void stayConnected() throws Exception{ 46 | String queueName = "jms.topic.TestQueue2"; 47 | 48 | StompConnection connection = new StompConnection(); 49 | connection.open("localhost", 61613); 50 | connection.connect("guest", "guest", "client-2"); 51 | System.out.println(System.currentTimeMillis()); 52 | HashMap headers = new HashMap(); 53 | headers.put("durable-subscriber-name", "test2"); 54 | headers.put("id", "id2"); 55 | headers.put("client-id" , "client-2"); 56 | 57 | connection.subscribe(queueName, Subscribe.AckModeValues.CLIENT, headers); 58 | 59 | try{ 60 | for(int i=0; i< 100000; i++){ 61 | StompFrame message = connection.receive(); 62 | System.out.println("Message " + message.getBody()); 63 | connection.ack(message.getHeaders().get(Stomp.Headers.Message.MESSAGE_ID), null, null, null, null); 64 | } 65 | }catch (Exception e){ 66 | 67 | System.out.println(System.currentTimeMillis()); 68 | e.printStackTrace(); 69 | connection.close(); 70 | stayConnected(); 71 | } 72 | 73 | connection.disconnect(); 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/stomp/examples/StompConsumer.java: -------------------------------------------------------------------------------- 1 | package com.groupon.stomp.examples; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | import com.groupon.messagebus.api.Message; 34 | import com.groupon.messagebus.client.Utils; 35 | import com.groupon.stomp.Stomp; 36 | import com.groupon.stomp.Stomp.Headers.Subscribe; 37 | import com.groupon.stomp.StompConnection; 38 | import com.groupon.stomp.StompFrame; 39 | 40 | public class StompConsumer { 41 | public static void main(String []args) throws Exception{ 42 | String queueName = "jms.queue.testQueue1"; 43 | 44 | StompConnection connection = new StompConnection(); 45 | connection.open("localhost", 61613); 46 | connection.connect("guest", "guest"); 47 | System.out.println(System.currentTimeMillis()); 48 | connection.subscribe(queueName, Subscribe.AckModeValues.CLIENT); 49 | try{ 50 | for(int i=0; i< 100000; i++){ 51 | StompFrame frame = connection.receive(); 52 | System.out.println("Message consumed" + frame.getBody()); 53 | Message message = Utils.getMessageFromBytes(frame.getBody().getBytes()); 54 | System.out.println(message.getMessageInternal().toString()); 55 | connection.ack(frame.getHeaders().get(Stomp.Headers.Message.MESSAGE_ID), null, null, null, null); 56 | } 57 | }catch (Exception e){ 58 | 59 | System.out.println(System.currentTimeMillis()); 60 | System.out.println(e.getMessage()); 61 | } 62 | 63 | connection.disconnect(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /mbus-java/src/main/java/com/groupon/stomp/examples/StompProducer.java: -------------------------------------------------------------------------------- 1 | package com.groupon.stomp.examples; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | import com.groupon.messagebus.api.Message; 34 | import com.groupon.messagebus.client.Utils; 35 | import com.groupon.stomp.StompConnection; 36 | 37 | public class StompProducer { 38 | public static void main(String []args) throws Exception{ 39 | String queueName = "jms.queue.testQueue1"; 40 | 41 | StompConnection connection = new StompConnection(); 42 | connection.open("localhost", 61613); 43 | connection.connect("guest", "guest"); 44 | 45 | double log_interval = 1000; 46 | double startTime = System.currentTimeMillis(); 47 | for(int i=0;i<1000;i++){ 48 | 49 | Message message = Message.createStringMessage("id-" + i , "hello world-" + i); 50 | connection.sendSafe(queueName, new String(Utils.getThriftDataAsBytes(message)), null); 51 | 52 | if((i%log_interval)==0){ 53 | double took = log_interval / ((System.currentTimeMillis() - startTime)/1000); 54 | System.out.println("Counter:" + i +" Messages per second = "+took); 55 | startTime = System.currentTimeMillis(); 56 | } 57 | 58 | } 59 | 60 | connection.disconnect(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /mbus-java/src/main/thrift-gen/com/groupon/messagebus/thrift/api/MessagePayloadType.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Autogenerated by Thrift 3 | * 4 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | */ 6 | package com.groupon.messagebus.thrift.api; 7 | /* 8 | * Copyright (c) 2013, Groupon, Inc. 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without 12 | * modification, are permitted provided that the following conditions are 13 | * met: 14 | * 15 | * Redistributions of source code must retain the above copyright notice, 16 | * this list of conditions and the following disclaimer. 17 | * 18 | * Redistributions in binary form must reproduce the above copyright 19 | * notice, this list of conditions and the following disclaimer in the 20 | * documentation and/or other materials provided with the distribution. 21 | * 22 | * Neither the name of GROUPON nor the names of its contributors may be 23 | * used to endorse or promote products derived from this software without 24 | * specific prior written permission. 25 | * 26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 27 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 29 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 32 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 33 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 34 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 35 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 36 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | */ 38 | 39 | import java.util.Map; 40 | import java.util.HashMap; 41 | import org.apache.thrift.TEnum; 42 | 43 | public enum MessagePayloadType implements TEnum { 44 | JSON(1), 45 | BINARY(2), 46 | STRING(3); 47 | 48 | private final int value; 49 | 50 | private MessagePayloadType(int value) { 51 | this.value = value; 52 | } 53 | 54 | /** 55 | * Get the integer value of this enum value, as defined in the Thrift IDL. 56 | */ 57 | public int getValue() { 58 | return value; 59 | } 60 | 61 | /** 62 | * Find a the enum type by its integer value, as defined in the Thrift IDL. 63 | * @return null if the value is not found. 64 | */ 65 | public static MessagePayloadType findByValue(int value) { 66 | switch (value) { 67 | case 1: 68 | return JSON; 69 | case 2: 70 | return BINARY; 71 | case 3: 72 | return STRING; 73 | default: 74 | return null; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /mbus-java/src/test/java/com/groupon/messagebus/util/test/DynamicServerListGetterTest.java: -------------------------------------------------------------------------------- 1 | package com.groupon.messagebus.util.test; 2 | /* 3 | * Copyright (c) 2013, Groupon, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * Neither the name of GROUPON nor the names of its contributors may be 18 | * used to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | import java.net.MalformedURLException; 34 | import java.net.URISyntaxException; 35 | import java.net.URL; 36 | import java.util.Set; 37 | 38 | import junit.framework.TestCase; 39 | 40 | import org.apache.commons.codec.DecoderException; 41 | import org.apache.commons.codec.binary.Hex; 42 | import org.apache.log4j.BasicConfigurator; 43 | import org.junit.Test; 44 | 45 | import com.groupon.messagebus.api.HostParams; 46 | import com.groupon.messagebus.util.DynamicServerListGetter; 47 | 48 | public class DynamicServerListGetterTest extends TestCase{ 49 | 50 | public void setUp() { 51 | BasicConfigurator.resetConfiguration(); 52 | BasicConfigurator.configure(); 53 | } 54 | 55 | @Test 56 | public void test0_noServersFound() { 57 | 58 | String dataStr = ""; 59 | 60 | Set hosts = DynamicServerListGetter.parseAndReturnHosts(dataStr); 61 | assertEquals(0, hosts.size()); 62 | } 63 | 64 | public void testHex() throws DecoderException { 65 | byte[] bytes = "dfdfgfddfgfdgdgg".getBytes(); 66 | 67 | byte[] hex = new Hex().encode(bytes); 68 | System.out.println(new String(hex)); 69 | assertEquals(new String(bytes), new String(new Hex().decode(hex))); 70 | } 71 | 72 | @Test 73 | public void test2_ServersFound() { 74 | 75 | String dataStr = "hornetq1:61613,hornetq2:61613"; 76 | 77 | Set hosts = DynamicServerListGetter.parseAndReturnHosts(dataStr); 78 | 79 | 80 | int idx = 0; 81 | for(com.groupon.messagebus.api.HostParams host : hosts){ 82 | if(idx == 0){ 83 | System.out.println(host); 84 | assertEquals(host.getHost(), "hornetq2"); 85 | assertEquals(host.getPort(), 61613); 86 | } 87 | if(idx == 1){ 88 | System.out.println(host); 89 | assertEquals(host.getHost(), "hornetq1"); 90 | assertEquals(host.getPort(), 61613); 91 | } 92 | idx++; 93 | } 94 | assertEquals(2, hosts.size()); 95 | } 96 | 97 | @Test 98 | public void test3_BuildServersURL() throws URISyntaxException, MalformedURLException { 99 | 100 | String host = "dummy"; 101 | int port = 8081; 102 | String url = DynamicServerListGetter.buildDynamicServersURL(host, port); 103 | String reference = "http://dummy:8081/jmx?command=get_attribute&args=org.hornetq%3Amodule%3DCore%2Ctype%3DServer+ListOfBrokers"; 104 | assert(new URL(url).equals( new URL(reference))); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /mbus-ruby/Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | gemspec 4 | -------------------------------------------------------------------------------- /mbus-ruby/Rakefile: -------------------------------------------------------------------------------- 1 | require "rubygems" 2 | require "rubygems/package_task" 3 | require "rspec/core/rake_task" 4 | 5 | SPEC = begin 6 | file = File.expand_path(File.dirname(__FILE__) + '/messagebus.gemspec') 7 | eval(File.read(file), binding, file) 8 | end 9 | 10 | Gem::PackageTask.new(SPEC) {} 11 | 12 | desc "Run all specs" 13 | RSpec::Core::RakeTask.new(:spec) do |t| 14 | t.rspec_opts = %w[--color --format=progress] 15 | t.pattern = 'spec/**/*_spec.rb' 16 | end 17 | 18 | desc "Run code coverage" 19 | RSpec::Core::RakeTask.new(:coverage) do |t| 20 | t.rspec_opts = %w[--color --format=progress] 21 | t.rcov = true 22 | t.rcov_opts = %w[--exclude='gems,spec'] 23 | t.pattern = 'spec/**/*_spec.rb' 24 | end 25 | -------------------------------------------------------------------------------- /mbus-ruby/bin/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | base = File.dirname(__FILE__) 4 | $:.unshift File.expand_path(File.join(base, "..", "lib")) 5 | 6 | require "irb" 7 | require "yaml" 8 | require "messagebus" 9 | 10 | IRB.start 11 | 12 | -------------------------------------------------------------------------------- /mbus-ruby/bin/messagebus_swarm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require "optparse" 4 | 5 | require 'messagebus' 6 | require 'messagebus/swarm/controller' 7 | 8 | options = { 9 | :requires => [], 10 | :configuration_source => Messagebus::Swarm::Controller::ConfigurationSource.new(:default, nil) 11 | } 12 | 13 | parser = OptionParser.new do |opts| 14 | opts.banner = "Usage: swarm [options] COMMAND" 15 | 16 | opts.separator "" 17 | opts.separator "Options:" 18 | 19 | opts.on("--config_path PATH", "A path to a yaml configuration file") do |config_path| 20 | options[:configuration_source] = Messagebus::Swarm::Controller::ConfigurationSource.new(:path, config_path) 21 | end 22 | 23 | opts.on("--config_eval RUBY_CODE", "Ruby that evaluates to a configuration hash. This is ran after any requires") do |config_eval| 24 | options[:configuration_source] = Messagebus::Swarm::Controller::ConfigurationSource.new(:eval, config_eval) 25 | end 26 | 27 | opts.on("-h", "--help", "Show help message") do 28 | puts opts 29 | end 30 | 31 | opts.on("-r", "--require FILE", "A file to require before starting the swarm. Repeatable.") do |file| 32 | options[:requires] << file 33 | end 34 | 35 | opts.on("--pidfile PID_FILE", "A file to write the PID to") do |file| 36 | options[:pidfile] = file 37 | end 38 | 39 | opts.separator "" 40 | opts.separator "Commands:" 41 | opts.separator " start Start all workers in the configuration" 42 | opts.separator " start DESTINATION COUNT Start COUNT workers for DESTINATION swarm listeners" 43 | opts.separator " stop pid Kill a swarm" 44 | opts.separator "" 45 | end 46 | 47 | parser.parse! 48 | 49 | Messagebus::Swarm::Controller.require_files(options[:requires]) 50 | if pidfile = options[:pidfile] 51 | pid = Process.pid 52 | Messagebus::Swarm::Controller.write_pid(pidfile) 53 | at_exit do 54 | # we need this check to make sure we only bother doing this if 55 | # we are the parent process that's shutting down 56 | # at_exit is carried down when forking 57 | Messagebus::Swarm::Controller.delete_pid(pidfile) if Process.pid == pid 58 | end 59 | end 60 | 61 | case ARGV[0] 62 | when 'start' 63 | destination_name, drone_count = ARGV[1], ARGV[2] 64 | 65 | log_file = options[:configuration_source].configuration_hash["worker_log_file"] 66 | logger = log_file ? Logger.new(log_file) : Messagebus::Client.logger 67 | 68 | Messagebus::Swarm::Controller.start(options[:configuration_source], logger, destination_name, drone_count) 69 | exit(0) 70 | when 'stop' 71 | pid = ARGV[1] or raise "Must specify a pid of the process to stop" 72 | Messagebus::Swarm::Controller.stop(pid.to_i) 73 | exit(0) 74 | else 75 | puts parser.help 76 | exit(1) 77 | end 78 | -------------------------------------------------------------------------------- /mbus-ruby/config/messagebus.yml: -------------------------------------------------------------------------------- 1 | enable_auto_init_connections: true 2 | log_file: log/messagebus-client.log 3 | 4 | user: guest 5 | passwd: guest 6 | receipt_wait_timeout_ms: 1500 7 | conn_lifetime_sec: 300 8 | 9 | clusters: 10 | - 11 | name: orders-messagebus-cluster 12 | producer_address: "localhost:61613" 13 | consumer_address: "localhost:8081" 14 | destinations: 15 | - jms.queue.testQueue1 16 | - jms.queue.testQueue2 17 | - jms.topic.testTopic1 18 | -------------------------------------------------------------------------------- /mbus-ruby/config/messagebus_with_drone.yml: -------------------------------------------------------------------------------- 1 | enable_auto_init_connections: true 2 | log_file: log/messagebus-client.log 3 | 4 | :swarm_config: 5 | # :fork: true 6 | 7 | :workers: 8 | - 9 | :destination: jms.topic.testTopic2 10 | :worker: SimpleDroneRunSpecWorker 11 | :subscription_id: swarm_drone_run_spec_id 12 | 13 | :ack_on_error: false 14 | :drones: 2 15 | 16 | :cluster_defaults: 17 | :user: guest 18 | :passwd: guest 19 | :receipt_wait_timeout_ms: 1500 20 | :conn_lifetime_sec: 300 21 | :enable_dynamic_serverlist_fetch: true 22 | 23 | clusters: 24 | - 25 | name: orders-messagebus-cluster 26 | producer_address: localhost:61613 27 | consumer_address: localhost:61613 28 | destinations: 29 | - jms.topic.testTopic2 30 | -------------------------------------------------------------------------------- /mbus-ruby/examples/README: -------------------------------------------------------------------------------- 1 | For the tests to run in your local environment, please make sure you have Ruby 1.8.7 2 | Also message.rb must have: 3 | require "rubygems" 4 | -------------------------------------------------------------------------------- /mbus-ruby/examples/consumer_example.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # Example Consumer 4 | # This is primitive consumer for messagebus. It uses messagebus library to consume messages from Messagebus 5 | # Unlike producer, this is basic version. Just update your configs in "options" below, And you are good to start 6 | require 'rubygems' 7 | base = File.dirname(__FILE__) 8 | $:.unshift File.expand_path(File.join(base, "..", "lib")) 9 | 10 | require "messagebus" 11 | require "yaml" 12 | 13 | options = { 14 | :user => 'guest', 15 | :passwd => 'guest', 16 | :subscription_id => 'lin', 17 | :ack_type => Messagebus::ACK_TYPE_CLIENT, 18 | :destination_name => 'jms.topic.testTopic2', 19 | :dynamic_fetch_timeout_ms => 1000, 20 | :enable_dynamic_serverlist_fetch => true, 21 | :conn_lifetime_sec => 30 22 | } 23 | 24 | 25 | #config = YAML.load_file("../config/messagebus.yml") 26 | #client = Messagebus::Client.new(config.merge(:logger => Logger.new("../mbus.log"))) 27 | 28 | 29 | # Change this - to meet your local environemnt 30 | cons = Messagebus::Consumer.new("localhost:61613", options) 31 | 32 | 33 | print "\n starting connection" 34 | cons.start 35 | while true 36 | 37 | print "\n receiving.." 38 | message = cons.receive 39 | puts message.payload 40 | cons.ack() 41 | end 42 | # Required, if not in autoClient mode 43 | # cons.ack() 44 | 45 | cons.stop 46 | 47 | 48 | -------------------------------------------------------------------------------- /mbus-ruby/examples/consumer_topic_example.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | require "rubygems" 4 | 5 | $:.unshift(File.join(File.dirname(__FILE__), "..", "lib")) 6 | $:.unshift(File.join(File.dirname(__FILE__), "..", "vendor/gems")) 7 | 8 | require "stomp" 9 | require 'messagebus' 10 | require 'thrift' 11 | require 'json' 12 | 13 | 14 | options= { 15 | :user => 'guest', 16 | :passwd => 'guest', 17 | :subscription_id => 'lin', 18 | :ack_type => Messagebus::ACK_TYPE_CLIENT, 19 | 20 | :destination_name => 'jms.topic.testTopic2', 21 | :dynamic_fetch_timeout_ms => 1000, 22 | :enable_dynamic_serverlist_fetch => false, 23 | :conn_lifetime_sec => 5 24 | 25 | } 26 | 27 | 28 | #config = YAML.load_file("../config/messagebus.yml") 29 | #client = Messagebus::Client.new(config.merge(:logger => Logger.new("../mbus.log"))) 30 | 31 | 32 | # Change this - to meet your local environemnt 33 | cons = Messagebus::Consumer.new("localhost:61613", options) 34 | 35 | print "\n starting connection" 36 | cons.start() 37 | print "\n receiving.." 38 | sleep 1 39 | (1..10000).each do |i| 40 | message = cons.receive 41 | sleep 0.001 42 | 43 | if message != nil 44 | print "#{message.payload}\n." 45 | cons.ack() 46 | else 47 | puts 'message not found.' 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /mbus-ruby/examples/encoding_example.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | require "rubygems" 3 | base = File.dirname(__FILE__) 4 | $:.unshift File.expand_path(File.join(base, "..", "lib")) 5 | 6 | require "irb" 7 | require "yaml" 8 | require "messagebus" 9 | 10 | body = 11 | 12 | { 13 | "source_name"=>"google_places", 14 | "name"=>"Goodman Distribution", 15 | "location"=> 16 | { 17 | "address"=>"12552 Texas 3", 18 | "address_extended"=>nil, 19 | "locality"=>"Webster", 20 | "postcode"=>"77598", 21 | "region"=>"TX", 22 | "country"=>"US", 23 | "lon_lat"=>{ 24 | "lon"=>-95.167307, 25 | "lat"=>29.58916} 26 | }, 27 | "phone_numbers" =>["281 480 5100"], 28 | "website"=>"http://www.goodmanmfg.com/", 29 | "hours"=>['Monday 7:30 am – 5:00 pm,Tuesday 7:30 am – 5:00 pm,Wednesday 7:30 am – 5:00 pm,Thursday 7:30 am – 5:00 pm,Friday 7:30 am – 5:00 pm,Saturday Closed,Sunday Closed'], 30 | #"hours"=>['Thorbjørn'], 31 | "status"=>nil, 32 | "categories"=>nil, 33 | "external_references"=> 34 | { 35 | "google_places"=> 36 | { 37 | "external_access_timestamp"=>"2012-07-20T20:18:22+0000", 38 | "content"=> 39 | { 40 | "source_categories"=>["Construction","Air Conditioning Distribution","Air Conditioning Contractor","HVAC Distribution"] 41 | }, 42 | "external_url"=>"http://maps.google.com/maps/place?cid=", 43 | "external_id"=>nil 44 | } 45 | }, 46 | "menus"=>nil, 47 | "email_contact"=>nil,"chain_name"=>nil, 48 | "year_established"=>nil 49 | } 50 | def nullify_hash(hash) 51 | if (hash.is_a? Hash) 52 | hash.keys.each do |key| 53 | hash[key] = nullify_hash(hash[key]) 54 | end 55 | else 56 | return nil if hash == "" 57 | end 58 | hash 59 | end 60 | body = nullify_hash(body) 61 | 62 | config = YAML.load_file("../config/messagebus.yml") 63 | client = Messagebus::Client.new(config.merge(:logger => Logger.new("../mbus.log"))) 64 | client.start 65 | success=client.publish("jms.topic.testTopic2", body) 66 | puts success 67 | client.stop 68 | =begin 69 | { 70 | "source_name" => m3_entry["sources"][0]["source_name"], 71 | "name" => m3_entry["name"], 72 | "location" => { 73 | "address" => m3_entry["location"]["street_address"], 74 | "address_extended" => nil, 75 | "locality" => m3_entry["location"]["city"], 76 | "postcode" => m3_entry["location"]["postal_code"], 77 | "region" => m3_entry["location"]["state"], 78 | "country" => m3_entry["location"]["country"], 79 | "lon_lat" => m3_entry["location"]["lon_lat"], 80 | }, 81 | "phone_numbers" => [m3_entry["phone_number"]], 82 | "website" => m3_entry["website"], 83 | "hours" => [m3_entry["hours_open"]], 84 | "status" => m3_entry["status"], 85 | "categories" => m3_entry["categories"], 86 | "external_references" => {m3_entry["sources"][0]["source_name"] => external_ref}, 87 | "menus" => m3_entry["external_references"][0]["menus"], 88 | "email_contact" => m3_entry["email_contact"], 89 | "chain_name" => m3_entry["chain_name"], 90 | "year_established" => m3_entry["year_established"], 91 | } 92 | =end 93 | -------------------------------------------------------------------------------- /mbus-ruby/examples/producer_example.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "rubygems" 3 | base = File.dirname(__FILE__) 4 | $:.unshift File.expand_path(File.join(base, "..", "lib")) 5 | 6 | require "irb" 7 | require "yaml" 8 | require "messagebus" 9 | 10 | binary_to_publish = "\xfe\x3e\x5e" 11 | config = YAML.load_file("../config/messagebus.yml") 12 | client = Messagebus::Client.new(config.merge(:logger => Logger.new("../mbus.log"))) 13 | client.start 14 | puts "publish as binary" 15 | (1..1000).each do |i| 16 | client.publish "jms.topic.testTopic1", binary_to_publish, 0, true, true {"priority" => "4"} 17 | end 18 | print "first round finished!\n" 19 | 20 | puts "Publishing as strings" 21 | if RUBY_VERSION.to_f >= 1.9 22 | binary_to_publish.force_encoding("GB2312") 23 | end 24 | 25 | (1..1000).each do |i| 26 | client.publish "jms.topic.testTopic1", binary_to_publish 27 | end 28 | 29 | client.stop 30 | -------------------------------------------------------------------------------- /mbus-ruby/examples/producer_reload_config_example.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "rubygems" 3 | base = File.dirname(__FILE__) 4 | $:.unshift File.expand_path(File.join(base, "..", "lib")) 5 | 6 | require "irb" 7 | require "yaml" 8 | require "messagebus" 9 | 10 | binary_to_publish = "\xfe\x3e\x5e" 11 | config = YAML.load_file("../config/messagebus.yml") 12 | client = Messagebus::Client.new(config.merge(:logger => Logger.new("../mbus.log"))) 13 | client.start 14 | (1..10).each do |i| 15 | client.publish "jms.topic.testTopic1", binary_to_publish 16 | end 17 | print "first round finished!\n" 18 | sleep 5 19 | config = YAML.load_file("../config/messagebus_modified.yml") 20 | client.reload_config_on_interval(config, 0) 21 | print "second round starting!\n" 22 | 23 | (1..10).each do |i| 24 | client.publish "jms.topic.testTopic2", binary_to_publish 25 | end 26 | 27 | client.stop 28 | -------------------------------------------------------------------------------- /mbus-ruby/examples/producer_schedule_example.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | require "rubygems" 4 | 5 | $:.unshift(File.join(File.dirname(__FILE__), "..", "lib")) 6 | $:.unshift(File.join(File.dirname(__FILE__), "..", "vendor/gems")) 7 | 8 | require "stomp" 9 | require 'messagebus' 10 | require 'thrift' 11 | require 'json' 12 | 13 | options = { 14 | :user => 'guest', 15 | :passwd => 'guest', 16 | :subscription_id => 'test' 17 | } 18 | 19 | producer = Messagebus::Producer.new("localhost:61613", options) 20 | 21 | producer.start 22 | 23 | (1..10).each do |i| 24 | print "\n sending #{i}" 25 | msg = Messagebus::Message.create_string_message("hello world " + i.to_s , nil) 26 | t1 = Time.now.to_f * 1000 + i * 5000 27 | producer.publish_safe("jms.topic.testTopic1","topic", msg, { 28 | Messagebus::Producer::SCHEDULED_DELIVERY_TIME_MS_HEADER => t1.to_i.to_s 29 | }); 30 | end 31 | 32 | producer.stop 33 | -------------------------------------------------------------------------------- /mbus-ruby/examples/producer_topic_example.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | require "rubygems" 4 | 5 | $:.unshift(File.join(File.dirname(__FILE__), "..", "lib")) 6 | $:.unshift(File.join(File.dirname(__FILE__), "..", "vendor/gems")) 7 | 8 | require "stomp" 9 | require 'messagebus' 10 | require 'thrift' 11 | require 'json' 12 | 13 | 14 | 15 | options = { 16 | 17 | :user => 'guest', 18 | :passwd => 'guest', 19 | 20 | } 21 | 22 | producer = Messagebus::Producer.new("localhost:61613", options) 23 | 24 | producer.start 25 | 26 | (1..1000).each do |i| 27 | 28 | msg = Messagebus::Message.create("hello world " + i.to_s , nil) 29 | 30 | producer.publish("jms.topic.testTopic2", "topic", msg); 31 | 32 | sleep 0.100 33 | 34 | end 35 | 36 | 37 | producer.stop 38 | -------------------------------------------------------------------------------- /mbus-ruby/examples/swarm_example.rb: -------------------------------------------------------------------------------- 1 | class SimpleWorker 2 | def self.perform(message_payload) 3 | # success 4 | puts message_payload.inspect 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /mbus-ruby/examples/swarm_example.sh: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/bash 2 | 3 | ../bin/messagebus_swarm start --config_path swarm_example.yml -r ./swarm_example.rb -------------------------------------------------------------------------------- /mbus-ruby/examples/swarm_example.yml: -------------------------------------------------------------------------------- 1 | enable_auto_init_connections: true 2 | log_file: log/messagebus-client.log 3 | 4 | :swarm_config: 5 | # :fork: true 6 | 7 | :workers: 8 | - 9 | :destination: jms.topic.testTopic2 10 | :worker: SimpleWorker 11 | :subscription_id: lin 12 | 13 | :ack_on_error: false 14 | :drones: 2 15 | 16 | :cluster_defaults: 17 | :user: guest 18 | :passwd: guest 19 | :receipt_wait_timeout_ms: 1500 20 | :conn_lifetime_sec: 300 21 | :enable_dynamic_serverlist_fetch: true 22 | 23 | clusters: 24 | - 25 | name: orders-messagebus-cluster 26 | producer_address: bus-lb1:61613 27 | consumer_address: bus-lb1:61613 28 | destinations: 29 | - jms.topic.testTopic2 30 | -------------------------------------------------------------------------------- /mbus-ruby/lib/messagebus.rb: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, Groupon, Inc. 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions 6 | # are met: 7 | # 8 | # Redistributions of source code must retain the above copyright notice, 9 | # this list of conditions and the following disclaimer. 10 | # 11 | # Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # 15 | # Neither the name of GROUPON nor the names of its contributors may be 16 | # used to endorse or promote products derived from this software without 17 | # specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 | # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 | # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 22 | # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 25 | # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | $:.unshift(File.join(File.dirname(__FILE__), "..", "vendor/gems")) 32 | 33 | require "messagebus/version" 34 | require 'messagebus/logger' 35 | require 'messagebus/message' 36 | require "messagebus/messagebus_types" 37 | require 'messagebus/custom_errors' 38 | require 'messagebus/error_status' 39 | require 'messagebus/validations' 40 | require 'messagebus/connection' 41 | require 'messagebus/producer' 42 | require 'messagebus/consumer' 43 | require 'messagebus/cluster_map' 44 | require 'messagebus/client' 45 | 46 | require 'thrift' 47 | require 'base64' 48 | require 'stomp' 49 | 50 | module Messagebus 51 | # These are deprecated and not used anymore 52 | DEST_TYPE_QUEUE = 'queue' 53 | DEST_TYPE_TOPIC = 'topic' 54 | 55 | ACK_TYPE_AUTO_CLIENT = 'autoClient' 56 | ACK_TYPE_CLIENT = 'client' 57 | 58 | LOG_DEFAULT_FILE = '/tmp/messagebus_client.log' 59 | 60 | SERVER_REGEX = /^[a-zA-Z0-9\_.-]+:[0-9]+$/ 61 | end 62 | 63 | -------------------------------------------------------------------------------- /mbus-ruby/lib/messagebus/connection.rb: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, Groupon, Inc. 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions 6 | # are met: 7 | # 8 | # Redistributions of source code must retain the above copyright notice, 9 | # this list of conditions and the following disclaimer. 10 | # 11 | # Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # 15 | # Neither the name of GROUPON nor the names of its contributors may be 16 | # used to endorse or promote products derived from this software without 17 | # specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 | # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 | # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 22 | # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 25 | # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | require "messagebus/validations" 32 | require "messagebus/dottable_hash" 33 | 34 | module Messagebus 35 | class Connection 36 | 37 | STARTED = "STARTED" 38 | STOPPED = "STOPPED" 39 | 40 | attr_accessor :host_params, :options 41 | 42 | include Validations 43 | 44 | def initialize(host_params, passed_options = {}) 45 | @host_params = host_params 46 | @host_params = [@host_params] unless @host_params.is_a?(Array) 47 | 48 | @options = DottableHash.new({ 49 | :user => '', :passwd => '', 50 | :conn_lifetime_sec => 300, :receipt_wait_timeout_ms => 5000, 51 | :destination_name => nil, :destination_type => nil, 52 | :ack_type => Messagebus::ACK_TYPE_AUTO_CLIENT, :num_threads_per_server => 1, 53 | :enable_dynamic_serverlist_fetch => false, :dynamic_fetch_timeout_ms => 1000, 54 | :dynamic_serverlist_fetch_url_override => nil 55 | }).merge(passed_options) 56 | 57 | @state = STOPPED 58 | end 59 | 60 | def started? 61 | @state == STARTED 62 | end 63 | 64 | def stopped? 65 | @state == STOPPED 66 | end 67 | 68 | def do_with_timeout(timeout_ms) 69 | if not block_given? 70 | raise "do_with_timeout expects a block to be run" 71 | end 72 | 73 | start_time = Time.now 74 | while (Time.now - start_time) * 1000 < timeout_ms 75 | yield 76 | end 77 | end 78 | 79 | def start_server(host_params, user, passwd, subscription_id=nil) 80 | case host_params 81 | when Array 82 | host_param = host_params[rand(host_params.length)] 83 | when String 84 | host_param = host_params 85 | end 86 | 87 | host, port = host_param.split(':') 88 | 89 | connect_headers = {} 90 | connect_headers.merge!("client-id" => subscription_id) if subscription_id 91 | 92 | stomp = Stomp::Client.new(user, passwd, host, port, logger, connect_headers) 93 | logger.info "Started client for host_param:#{host_param} stomp-client:#{stomp} user:#{user}" 94 | @state = STARTED 95 | 96 | return stomp 97 | end 98 | 99 | def stop_server(stomp) 100 | Client.logger.info "Stopping stomp-client:#{stomp}" 101 | stomp.close if stomp 102 | @state = STOPPED 103 | end 104 | 105 | def host_params=(host_params) 106 | @host_params = host_params 107 | end 108 | 109 | def options=(options) 110 | @options = options 111 | end 112 | private 113 | 114 | def logger 115 | @logger ||= Client.logger 116 | end 117 | end 118 | end 119 | -------------------------------------------------------------------------------- /mbus-ruby/lib/messagebus/custom_errors.rb: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, Groupon, Inc. 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions 6 | # are met: 7 | # 8 | # Redistributions of source code must retain the above copyright notice, 9 | # this list of conditions and the following disclaimer. 10 | # 11 | # Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # 15 | # Neither the name of GROUPON nor the names of its contributors may be 16 | # used to endorse or promote products derived from this software without 17 | # specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 | # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 | # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 22 | # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 25 | # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | module Messagebus 32 | class InvalidAcknowledgementType < StandardError; end 33 | class InvalidDestination < StandardError; end 34 | class InvalidHost < StandardError; end 35 | class MessageReceiveTimeout < RuntimeError; end 36 | class ErrorFrameReceived < RuntimeError; end 37 | end 38 | -------------------------------------------------------------------------------- /mbus-ruby/lib/messagebus/dottable_hash.rb: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, Groupon, Inc. 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions 6 | # are met: 7 | # 8 | # Redistributions of source code must retain the above copyright notice, 9 | # this list of conditions and the following disclaimer. 10 | # 11 | # Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # 15 | # Neither the name of GROUPON nor the names of its contributors may be 16 | # used to endorse or promote products derived from this software without 17 | # specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 | # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 | # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 22 | # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 25 | # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | module Messagebus 32 | class DottableHash < Hash 33 | 34 | def initialize(plain_old_hash={}) 35 | merge!(plain_old_hash) 36 | end 37 | 38 | def respond_to?(method) 39 | true 40 | end 41 | 42 | def method_missing(method, *arguments, &block) 43 | key = method.to_s 44 | if key.match(/\=$/) 45 | self[key.chop] = arguments.first 46 | elsif self.has_key?(key) 47 | self[key] 48 | end 49 | end 50 | 51 | def [](key) 52 | super(key.to_s) 53 | end 54 | 55 | def []=(key, value) 56 | super(key.to_s, deep_stringify(value)) 57 | end 58 | 59 | def merge!(hash) 60 | super(stringify_keys(hash)) 61 | end 62 | 63 | def replace(hash) 64 | super(stringify_keys(hash)) 65 | end 66 | 67 | def delete(key) 68 | super(key.to_s) 69 | end 70 | 71 | def has_key?(key) 72 | super(key.to_s) 73 | end 74 | 75 | def fetch(key) 76 | super(key.to_s) 77 | end 78 | 79 | def assoc(key) 80 | super(key.to_s) 81 | end 82 | 83 | def values_at(*args) 84 | super(*args.collect(&:to_s)) 85 | end 86 | 87 | alias :store :[]= 88 | alias :update :merge! 89 | alias :merge :merge! 90 | alias :key? :has_key? 91 | alias :include? :has_key? 92 | 93 | private 94 | 95 | def stringify_keys(hash) 96 | hash.inject({}) do |acc, (key, value)| 97 | acc[key.to_s] = deep_stringify(hash[key]) 98 | acc 99 | end 100 | end 101 | 102 | def deep_stringify(element) 103 | case element 104 | when Array 105 | element.collect {|value| deep_stringify(value)} 106 | when Hash 107 | self.class.new(stringify_keys(element)) 108 | else 109 | element 110 | end 111 | end 112 | end 113 | end 114 | -------------------------------------------------------------------------------- /mbus-ruby/lib/messagebus/error_status.rb: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, Groupon, Inc. 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions 6 | # are met: 7 | # 8 | # Redistributions of source code must retain the above copyright notice, 9 | # this list of conditions and the following disclaimer. 10 | # 11 | # Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # 15 | # Neither the name of GROUPON nor the names of its contributors may be 16 | # used to endorse or promote products derived from this software without 17 | # specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 | # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 | # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 22 | # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 25 | # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | module Messagebus 32 | class MessageStatus 33 | CODES = { 34 | "1000" => "Invalid Acknowledgement Type", 35 | "1010" => "Invalid Host", 36 | "1020" => "Invalid Destination" 37 | } 38 | 39 | def initialize(code, message, backtrace = nil) 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /mbus-ruby/lib/messagebus/logger.rb: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, Groupon, Inc. 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions 6 | # are met: 7 | # 8 | # Redistributions of source code must retain the above copyright notice, 9 | # this list of conditions and the following disclaimer. 10 | # 11 | # Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # 15 | # Neither the name of GROUPON nor the names of its contributors may be 16 | # used to endorse or promote products derived from this software without 17 | # specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 | # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 | # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 22 | # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 25 | # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | require 'logger' 32 | 33 | module Messagebus 34 | module Logging 35 | class MyLogger < Logger 36 | def error(message, exception=nil) 37 | if exception 38 | message += "\n" + exception.message + "\n" + exception.backtrace.join("\n") 39 | end 40 | 41 | super(message) 42 | end 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /mbus-ruby/lib/messagebus/messagebus_types.rb: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, Groupon, Inc. 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions 6 | # are met: 7 | # 8 | # Redistributions of source code must retain the above copyright notice, 9 | # this list of conditions and the following disclaimer. 10 | # 11 | # Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # 15 | # Neither the name of GROUPON nor the names of its contributors may be 16 | # used to endorse or promote products derived from this software without 17 | # specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 | # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 | # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 22 | # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 25 | # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | # 32 | # Autogenerated by Thrift 33 | # 34 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 35 | # 36 | 37 | 38 | module Messagebus 39 | module Thrift 40 | module MessagePayloadType 41 | JSON = 1 42 | BINARY = 2 43 | STRING = 3 44 | VALUE_MAP = {1 => "JSON", 2 => "BINARY", 3 => "STRING"} 45 | VALID_VALUES = Set.new([JSON, BINARY, STRING]).freeze 46 | end 47 | 48 | class MessagePayload 49 | include ::Thrift::Struct, ::Thrift::Struct_Union 50 | MESSAGEFORMAT = 1 51 | STRINGPAYLOAD = 2 52 | BINARYPAYLOAD = 3 53 | 54 | FIELDS = { 55 | MESSAGEFORMAT => {:type => ::Thrift::Types::I32, :name => 'messageFormat', :enum_class => Messagebus::Thrift::MessagePayloadType}, 56 | STRINGPAYLOAD => {:type => ::Thrift::Types::STRING, :name => 'stringPayload', :optional => true}, 57 | BINARYPAYLOAD => {:type => ::Thrift::Types::STRING, :name => 'binaryPayload', :binary => true, :optional => true} 58 | } 59 | 60 | def struct_fields; FIELDS; end 61 | 62 | def binary? 63 | @messageFormat == Messagebus::Thrift::MessagePayloadType::BINARY 64 | end 65 | 66 | def json? 67 | @messageFormat == Messagebus::Thrift::MessagePayloadType::JSON 68 | end 69 | 70 | def string? 71 | @messageFormat == Messagebus::Thrift::MessagePayloadType::STRING 72 | end 73 | 74 | def validate 75 | raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Required field messageFormat is unset!') unless @messageFormat 76 | unless @messageFormat.nil? || Messagebus::Thrift::MessagePayloadType::VALID_VALUES.include?(@messageFormat) 77 | raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Invalid value of field messageFormat!') 78 | end 79 | end 80 | 81 | ::Thrift::Struct.generate_accessors self 82 | end 83 | 84 | class MessageInternal 85 | include ::Thrift::Struct, ::Thrift::Struct_Union 86 | MESSAGEID = 1 87 | PAYLOAD = 2 88 | PROPERTIES = 3 89 | 90 | FIELDS = { 91 | MESSAGEID => {:type => ::Thrift::Types::STRING, :name => 'messageId'}, 92 | PAYLOAD => {:type => ::Thrift::Types::STRUCT, :name => 'payload', :class => Messagebus::Thrift::MessagePayload}, 93 | PROPERTIES => {:type => ::Thrift::Types::MAP, :name => 'properties', :key => {:type => ::Thrift::Types::STRING}, :value => {:type => ::Thrift::Types::STRING}, :optional => true} 94 | } 95 | 96 | def struct_fields; FIELDS; end 97 | 98 | def validate 99 | raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Required field messageId is unset!') unless @messageId 100 | raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Required field payload is unset!') unless @payload 101 | end 102 | 103 | ::Thrift::Struct.generate_accessors self 104 | end 105 | 106 | end 107 | end 108 | -------------------------------------------------------------------------------- /mbus-ruby/lib/messagebus/swarm.rb: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, Groupon, Inc. 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions 6 | # are met: 7 | # 8 | # Redistributions of source code must retain the above copyright notice, 9 | # this list of conditions and the following disclaimer. 10 | # 11 | # Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # 15 | # Neither the name of GROUPON nor the names of its contributors may be 16 | # used to endorse or promote products derived from this software without 17 | # specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 | # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 | # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 22 | # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 25 | # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | module Messagebus 32 | module Swarm 33 | def self.logger=(logger) 34 | @logger = logger 35 | end 36 | 37 | def self.logger 38 | @logger 39 | end 40 | 41 | def self.default_configuration=(default_configuration) 42 | @default_configuration = default_configuration 43 | end 44 | 45 | def self.default_configuration 46 | @default_configuration 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /mbus-ruby/lib/messagebus/swarm/drone/logging_worker.rb: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, Groupon, Inc. 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions 6 | # are met: 7 | # 8 | # Redistributions of source code must retain the above copyright notice, 9 | # this list of conditions and the following disclaimer. 10 | # 11 | # Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # 15 | # Neither the name of GROUPON nor the names of its contributors may be 16 | # used to endorse or promote products derived from this software without 17 | # specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 | # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 | # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 22 | # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 25 | # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | require 'json' 32 | 33 | module Messagebus 34 | module Swarm 35 | class Drone 36 | ## 37 | # Use this for easy testing that a messagebus message is received. 38 | # Example config: 39 | # - 40 | # :destination: jms.topic.some_destination_you_want_to_debug 41 | # :subscription_id: 42 | # :worker: Messagebus::Swarm::Drone::LoggingWorker 43 | # :drones: 1 44 | class LoggingWorker 45 | def self.perform_on_destination(message, destination) 46 | log_message = %|received a message. destination=#{destination}, message=#{message.inspect}| 47 | Rails.logger.info(log_message) if defined?(Rails.logger) 48 | puts log_message 49 | end 50 | end 51 | end 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /mbus-ruby/lib/messagebus/validations.rb: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, Groupon, Inc. 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions 6 | # are met: 7 | # 8 | # Redistributions of source code must retain the above copyright notice, 9 | # this list of conditions and the following disclaimer. 10 | # 11 | # Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # 15 | # Neither the name of GROUPON nor the names of its contributors may be 16 | # used to endorse or promote products derived from this software without 17 | # specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 | # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 | # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 22 | # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 25 | # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | module Messagebus 32 | # :nodoc:all 33 | module Validations 34 | def valid_host?(string) 35 | Messagebus::SERVER_REGEX.match(string) 36 | end 37 | 38 | def validate_destination_config(name, is_consumer = false, options = {}) 39 | raise InvalidDestination.new("destination name is nil") unless name 40 | 41 | if is_consumer && name.match(/^jms.topic/) && options[:subscription_id].nil? 42 | raise InvalidDestination.new("destination type TOPIC requires a subscription_id") 43 | end 44 | end 45 | 46 | def validate_connection_config(host_params, options = {}) 47 | if options[:ack_type] && 48 | options[:ack_type] != Messagebus::ACK_TYPE_AUTO_CLIENT && 49 | options[:ack_type] != Messagebus::ACK_TYPE_CLIENT 50 | raise InvalidAcknowledgementType.new(options[:ack_type]) 51 | end 52 | 53 | if host_params.nil? 54 | raise InvalidHost.new(host_params) 55 | end 56 | 57 | if host_params.is_a?(Array) 58 | host_params.each do |string| 59 | unless valid_host?(string) 60 | raise InvalidHost.new("host should be defined as :, received: #{host_params}") 61 | end 62 | end 63 | else 64 | raise InvalidHost.new("host should be defined as :, received #{host_params}") 65 | end 66 | end 67 | end 68 | end 69 | -------------------------------------------------------------------------------- /mbus-ruby/lib/messagebus/version.rb: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, Groupon, Inc. 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions 6 | # are met: 7 | # 8 | # Redistributions of source code must retain the above copyright notice, 9 | # this list of conditions and the following disclaimer. 10 | # 11 | # Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # 15 | # Neither the name of GROUPON nor the names of its contributors may be 16 | # used to endorse or promote products derived from this software without 17 | # specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 | # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 | # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 22 | # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 25 | # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | module Messagebus 32 | MAJOR = 1 33 | MINOR = 0 34 | PATCH = 0 35 | VERSION = "#{MAJOR}.#{MINOR}.#{PATCH}" 36 | end 37 | -------------------------------------------------------------------------------- /mbus-ruby/log/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/groupon/Message-Bus/aa51179b4a1a207ce26d1d8d9ce66ce35409df7b/mbus-ruby/log/.gitkeep -------------------------------------------------------------------------------- /mbus-ruby/messagebus.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | require "#{File.dirname(__FILE__)}/lib/messagebus/version" 3 | 4 | Gem::Specification.new do |gem| 5 | gem.authors = ["Pradeep Jawahar", "Lin Zhao", "Erik Weathers"] 6 | gem.email = ["pjawahar@groupon.com", "lin@groupon.com", "eweathers@groupon.com"] 7 | gem.description = %q{Messagebus integration gem} 8 | gem.summary = %q{Messagebus Client} 9 | gem.homepage = "https://github.com/groupon/Message-Bus" 10 | 11 | gem.executables = %w(messagebus_swarm) 12 | gem.files = Dir['bin/*'] + Dir["lib/**/*.rb"] + Dir["vendor/**/*"] + %w(README.mediawiki Rakefile messagebus.gemspec) 13 | gem.test_files = Dir["spec*/**/*.rb"] 14 | gem.name = "mbus" 15 | gem.require_paths = ["vendor/gems", "lib"] 16 | gem.version = Messagebus::VERSION 17 | gem.license = 'BSD' 18 | 19 | gem.required_rubygems_version = ">= 1.3.6" 20 | 21 | if RUBY_VERSION < "1.9" 22 | # json is built into ruby 1.9 23 | gem.add_dependency "json" 24 | end 25 | gem.add_dependency "thrift", "0.9.0" 26 | 27 | gem.add_development_dependency "rspec" 28 | gem.add_development_dependency "simplecov" 29 | end 30 | -------------------------------------------------------------------------------- /mbus-ruby/script/ci/rspec.sh: -------------------------------------------------------------------------------- 1 | gem install bundler 2 | bundle install --without nothing 3 | rake spec 4 | -------------------------------------------------------------------------------- /mbus-ruby/spec/messagebus/dottable_hash_spec.rb: -------------------------------------------------------------------------------- 1 | require 'messagebus/dottable_hash' 2 | 3 | describe Messagebus::DottableHash do 4 | let (:dottable_hash) { Messagebus::DottableHash.new } 5 | 6 | it "is a wrapper of Hash" do 7 | Messagebus::DottableHash.ancestors.should include(Hash) 8 | end 9 | 10 | it "optionally takes a hash in the constructor" do 11 | Messagebus::DottableHash.new({:this => "works"}) 12 | end 13 | 14 | it "allows dot assignment" do 15 | dottable_hash.foo = "bar" 16 | dottable_hash.should == {"foo" => "bar"} 17 | end 18 | 19 | it "allows dot access" do 20 | dottable_hash.foo = "baz" 21 | dottable_hash.foo.should == "baz" 22 | end 23 | 24 | it "allows bracket assignment with a String key" do 25 | dottable_hash["merica"] = "the free" 26 | dottable_hash.should == {"merica" => "the free"} 27 | end 28 | 29 | it "allows bracket access with a String key" do 30 | dottable_hash["foo"] = "hey" 31 | dottable_hash["foo"].should == "hey" 32 | end 33 | 34 | it "allows bracket assignment with a Symbol key" do 35 | dottable_hash[:patrick] = "gombert" 36 | dottable_hash.should == {"patrick" => "gombert"} 37 | end 38 | 39 | it "allows bracket access with a Symbol key" do 40 | dottable_hash[:patrick] = "gombert" 41 | dottable_hash[:patrick].should == "gombert" 42 | end 43 | 44 | it "converts keys for Hashes upon bracket assignment" do 45 | dottable_hash[:dave] = {:surname => {:original => "moore"}} 46 | dottable_hash.dave.surname.original.should == "moore" 47 | end 48 | 49 | it "remains dottable after merging a plain ruby Hash" do 50 | dottable_hash.merge!({:some => "plain old hash"}) 51 | dottable_hash.some.should == "plain old hash" 52 | end 53 | 54 | it "converts all keys in nested Hashes of any depth" do 55 | dottable_hash.merge!({:some => {:plain => {:old => "hash"}}}) 56 | dottable_hash.should == {"some" => {"plain" => {"old" => "hash"}}} 57 | end 58 | 59 | it "converts all keys nested in an Array to Strings" do 60 | dottable_hash.merge!({:some => [{:plain => "old hash"}]}) 61 | dottable_hash.should == {"some" => [{"plain" => "old hash"}]} 62 | end 63 | 64 | it "converts all keys in nested Arrays of any depth" do 65 | dottable_hash.merge!({:some => [[{:plain => "old hash"}], "foo"]}) 66 | dottable_hash.should == {"some" => [[{"plain" => "old hash"}], "foo"]} 67 | end 68 | 69 | it "ignores elements which are not Hashes or Arrays" do 70 | dottable_hash.merge!({:some => [{:plain => "old hash"}, "foo"]}) 71 | dottable_hash.should == {"some" => [{"plain" => "old hash"}, "foo"]} 72 | end 73 | 74 | it "makes deeply-nested hash structures dottable upon initialization" do 75 | dottable_hash = Messagebus::DottableHash.new({:some => {:plain => {:old => "hash"}}}) 76 | dottable_hash.some.plain.old.should == "hash" 77 | end 78 | 79 | it "makes deeply Array-nested Hash structures dottable upon initialization" do 80 | dottable_hash = Messagebus::DottableHash.new({:some => [[{:plain => "old hash"}]]}) 81 | dottable_hash.some[0][0].plain.should == "old hash" 82 | end 83 | 84 | it "#replace converts a plain old ruby hash to a dottable hash" do 85 | replacement = {:dave => {:moore => "awesome"}} 86 | result = Messagebus::DottableHash.new({ "foo" => "bar" }).replace(replacement) 87 | result.dave.moore.should == "awesome" 88 | result.has_key?("foo").should == false 89 | end 90 | 91 | it "#update converts a plain old ruby hash to a dottable hash" do 92 | result = Messagebus::DottableHash.new({ "foo" => "bar" }).update({:something => :else}) 93 | result.should == {"something" => :else, "foo" => "bar"} 94 | end 95 | 96 | it "#merge converts a plain old ruby hash to a dottable hash" do 97 | result = Messagebus::DottableHash.new({ "foo" => "bar" }).merge({:something => :else}) 98 | result.should == {"something" => :else, "foo" => "bar"} 99 | end 100 | 101 | it "#delete accepts Symbol as an argument" do 102 | dottable_hash["foo"] = { "bar" => "bar", "baz" => "baz" } 103 | dottable_hash.foo.delete(:bar) 104 | dottable_hash.should == { "foo" => { "baz" => "baz" } } 105 | end 106 | 107 | it "#has_key? accepts Symbol as an argument" do 108 | Messagebus::DottableHash.new({ "foo" => "bar" }).has_key?(:foo).should == true 109 | end 110 | 111 | it "#key? accepts a Symbol as an argument" do 112 | Messagebus::DottableHash.new({ "foo" => "bar" }).key?(:foo).should == true 113 | end 114 | 115 | it "#fetch accepts a Symbol as an argument" do 116 | Messagebus::DottableHash.new({ "foo" => "bar" }).fetch(:foo).should == "bar" 117 | end 118 | 119 | it "#include? accepts a Symbol as an argument" do 120 | Messagebus::DottableHash.new({ "foo" => "bar" }).include?(:foo).should == true 121 | end 122 | 123 | it "#store accepts a Symbol as an argument" do 124 | hash = Messagebus::DottableHash.new({ "foo" => "bar" }) 125 | hash.store(:bears, "scare me") 126 | hash.bears.should == "scare me" 127 | end 128 | 129 | it "#values_at accepts Symbols as arguments" do 130 | dottable_hash.merge({ "foo" => "bar", "zen" => "cool", "hey" => "now" }) 131 | dottable_hash.values_at(:foo, :zen).should =~ ["bar", "cool"] 132 | end 133 | 134 | it "#respond_to? returns true for everything" do 135 | dottable_hash.respond_to?(:whatever).should == true 136 | end 137 | end 138 | -------------------------------------------------------------------------------- /mbus-ruby/spec/messagebus/message_spec.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | require File.join(File.dirname(__FILE__), '..', 'spec_helper') 3 | 4 | describe Messagebus::Message do 5 | describe "when checking non-ascii payload" do 6 | describe "when checking conversions" do 7 | before(:each) do 8 | @msg_string_data1 = 'am – 5:00 pm,' 9 | @gb2312_string = "\xC4\xE3\xBA\xC3" 10 | @msg_string_data2 = 'ASCII String' 11 | @msg_json_object = {:a=> '1', :b => {:x => 'Thorbjørn am – 5:00 pm,'}} 12 | @msg_binary_data = "\xE5\xA5\xBD" 13 | end 14 | 15 | it "check non-ascii string" do 16 | message = Messagebus::Message.create(@msg_string_data1) 17 | message2 = Messagebus::Message.get_message_from_thrift_binary(message.to_thrift_binary) 18 | @msg_string_data1.bytes.to_a.should == message2.payload.bytes.to_a 19 | end 20 | 21 | it "check ASCII string" do 22 | if RUBY_VERSION.to_f >= 1.9 23 | @msg_string_data2.force_encoding("ASCII") 24 | end 25 | message = Messagebus::Message.create(@msg_string_data2) 26 | message2 = Messagebus::Message.get_message_from_thrift_binary(message.to_thrift_binary) 27 | @msg_string_data2.bytes.to_a.should == message2.payload.bytes.to_a 28 | 29 | end 30 | 31 | it "check gb2312 string" do 32 | if RUBY_VERSION.to_f >= 1.9 33 | @gb2312_string.force_encoding("GB2312") 34 | end 35 | message = Messagebus::Message.create(@gb2312_string) 36 | message2 = Messagebus::Message.get_message_from_thrift_binary(message.to_thrift_binary) 37 | @gb2312_string.bytes.to_a.should == message2.payload.bytes.to_a 38 | end 39 | 40 | it "check json thrift conversions" do 41 | message = Messagebus::Message.create(@msg_json_object) 42 | message2 = Messagebus::Message.get_message_from_thrift_binary(message.to_thrift_binary) 43 | json_string = @msg_json_object.to_json 44 | json_string.bytes.to_a.should == message2.payload.bytes.to_a 45 | end 46 | 47 | it "check binary thrift equality" do 48 | message = Messagebus::Message.create(@msg_binary_data, nil, true) 49 | message2 = Messagebus::Message.get_message_from_thrift_binary(message.to_thrift_binary) 50 | @msg_binary_data.bytes.to_a == message2.payload.bytes.to_a 51 | 52 | end 53 | 54 | it "check message id are unique" do 55 | message_ids = Set.new 56 | (1..100).each do |i| 57 | message = Messagebus::Message.create(@msg_binary_data) 58 | message_ids.include?(message.message_id).should == false 59 | message_ids.add(message.message_id) 60 | end 61 | end 62 | end 63 | end 64 | describe "#create" do 65 | describe "with a hash" do 66 | it "returns a message of json type" do 67 | Messagebus::Message.create({:benjamin => :franklins}). 68 | raw_message.payload.should be_json 69 | end 70 | end 71 | 72 | describe "with an object that responds to to_json" do 73 | it "returns a message of json type" do 74 | Messagebus::Message.create(Object.new). 75 | raw_message.payload.should be_json 76 | end 77 | end 78 | 79 | describe "with a binary string and binary arg" do 80 | it "returns a message of binary type" do 81 | Messagebus::Message.create("\xE5", nil, true). 82 | raw_message.payload.should be_binary 83 | end 84 | end 85 | 86 | describe "with a string" do 87 | it "returns a message of string type" do 88 | Messagebus::Message.create("benjamins"). 89 | raw_message.payload.should be_string 90 | end 91 | end 92 | end 93 | end 94 | -------------------------------------------------------------------------------- /mbus-ruby/spec/messagebus/swarm/controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | describe Messagebus::Swarm::Controller do 4 | describe ".after_fork" do 5 | class SampleWorker ; end 6 | 7 | module AfterForkSpecHelpers 8 | def temp_file_base 9 | "after-fork-spec.tmp" 10 | end 11 | 12 | def create_temp_file(id) 13 | `touch #{temp_file_base}#{id}` 14 | end 15 | 16 | def cleanup_temp_files 17 | `rm #{temp_file_base}* > /dev/null 2>&1` 18 | end 19 | 20 | def temp_files_count 21 | `ls -l #{temp_file_base}* | wc -l`.to_i 22 | end 23 | end 24 | include AfterForkSpecHelpers 25 | 26 | before do 27 | Messagebus::Swarm::Drone.any_instance.stub(:processing_loop => nil) 28 | end 29 | 30 | around do |example| 31 | cleanup_temp_files 32 | 33 | original_logger = Messagebus::Swarm::Controller.swarm_control_logger 34 | @logger = Logger.new(StringIO.new) 35 | Messagebus::Swarm::Controller.swarm_control_logger = @logger 36 | 37 | example.run 38 | 39 | Messagebus::Swarm::Controller.swarm_control_logger = original_logger 40 | 41 | cleanup_temp_files 42 | end 43 | 44 | it "executes the after_fork block once per drone started" do 45 | config = { 46 | :swarm_config => {:fork => true}, 47 | :workers => [ 48 | { 49 | :destination => "jms.topic.SampleTopic", 50 | :worker => "SampleWorker", 51 | :ack_on_error => false, 52 | :subscription_id => "sample-subscriber-id", 53 | :drones => 4 54 | } 55 | ], 56 | :clusters => [ 57 | { 58 | "consumer_address" => "localhost:61613", 59 | "destinations" => ["jms.topic.SampleTopic"] 60 | } 61 | ] 62 | } 63 | 64 | Messagebus::Swarm::Controller.after_fork do 65 | create_temp_file(rand) 66 | end 67 | 68 | Messagebus::Swarm::Controller.start(config, @logger, "jms.topic.SampleTopic") 69 | 70 | temp_files_count.should == config[:workers].first[:drones] 71 | end 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /mbus-ruby/spec/messagebus/validations_spec.rb: -------------------------------------------------------------------------------- 1 | require File.join(File.dirname(__FILE__), '..', 'spec_helper') 2 | 3 | describe Messagebus::Validations do 4 | describe "#validate_destination_config" do 5 | before do 6 | @object = Object.new 7 | @object.extend Messagebus::Validations 8 | end 9 | 10 | it "requires a destination name" do 11 | lambda { 12 | @object.validate_destination_config(nil) 13 | }.should raise_error(Messagebus::InvalidDestination) 14 | end 15 | 16 | it "requires a topic to include a subscription_id" do 17 | lambda { 18 | @object.validate_destination_config("jms.topic.testTopic1", true) 19 | }.should raise_error(Messagebus::InvalidDestination) 20 | end 21 | 22 | it "validates when a topic includes a subscription_id" do 23 | lambda { 24 | @object.validate_destination_config("jms.topic.testTopic1", true, :subscription_id => "test1") 25 | }.should_not raise_error(Messagebus::InvalidDestination) 26 | end 27 | end 28 | 29 | describe "#validate_connection_config" do 30 | before do 31 | @object = Object.new 32 | @object.extend Messagebus::Validations 33 | end 34 | 35 | it "does not recognize an acknowledgement type other than AUTO_CLIENT AND CLIENT" do 36 | lambda { 37 | @object.validate_connection_config("localhost:61613", :ack_type => "") 38 | }.should raise_error(Messagebus::InvalidAcknowledgementType) 39 | end 40 | 41 | it "requires host parameters" do 42 | lambda { 43 | @object.validate_connection_config(nil) 44 | }.should raise_error(Messagebus::InvalidHost) 45 | end 46 | 47 | it "requires an array of host parameters" do 48 | lambda { 49 | @object.validate_connection_config("localhost:61613") 50 | }.should raise_error(Messagebus::InvalidHost) 51 | end 52 | 53 | it "fails if the host is missing from the host parameters" do 54 | lambda { 55 | @object.validate_connection_config([":61613"]) 56 | }.should raise_error(Messagebus::InvalidHost) 57 | end 58 | 59 | it "fails if the port is missing from the host parameters" do 60 | lambda { 61 | @object.validate_connection_config(["localhost"]) 62 | }.should raise_error(Messagebus::InvalidHost) 63 | end 64 | 65 | it "should not fail if host contains a zero" do 66 | lambda { 67 | @object.validate_connection_config(["somehost-001:61613"]) 68 | }.should_not raise_error(Messagebus::InvalidHost) 69 | end 70 | end 71 | end 72 | -------------------------------------------------------------------------------- /mbus-ruby/spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require "rspec" 2 | 3 | $:.unshift(File.join(File.dirname(__FILE__), "..", "lib")) 4 | $:.unshift(File.join(File.dirname(__FILE__), "..", "vendor/gems")) 5 | 6 | require "stomp" 7 | require 'messagebus' 8 | require 'messagebus/swarm/controller' 9 | require 'thrift' 10 | require 'json' 11 | -------------------------------------------------------------------------------- /mbus-ruby/test_driver/test1_publish_consume_queue.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | base = File.dirname(__FILE__) 4 | $:.unshift File.expand_path(File.join(base, "..", "lib")) 5 | 6 | require "irb" 7 | require "yaml" 8 | require "messagebus" 9 | require "thrift" 10 | require "json" 11 | 12 | 13 | def display(data) 14 | puts "\n #{data}" 15 | end 16 | 17 | # ADJUST PARAMS HERE 18 | @queue_name = "jms.queue.testQueue1" 19 | @connection_string = "localhost:61613" 20 | 21 | def prepare_configs(ack_type) 22 | @config = YAML.load_file("../config/messagebus.yml") 23 | @config["enable_auto_init_connections"] = "true" 24 | 25 | @options = { 26 | :user => 'guest', 27 | :passwd => 'guest', 28 | :subscription_id => 'test2', 29 | #:ack_type => Messagebus::ACK_TYPE_CLIENT 30 | #:ack_type => 'client', 31 | #:ack_type => 'autoClient', 32 | :ack_type => ack_type, 33 | :destination_name => 'jms.queue.testQueue1', 34 | :dynamic_fetch_timeout_ms => 1000, 35 | :enable_dynamic_serverlist_fetch => true, 36 | :conn_lifetime_sec => 30 37 | } 38 | end 39 | 40 | def basic_pub_consume 41 | binary_to_publish = "\xfe\x3e\x5e" 42 | string_message = "first string message" 43 | 44 | json_message = @config.to_json 45 | cluster = @config["clusters"] 46 | 47 | cluster[0]["producer_address"] = @connection_string 48 | display "Config: address: #{@queue_name}" 49 | 50 | client = Messagebus::Client.new(@config.merge(:logger => Logger.new("../mbus.log"))) 51 | client.start 52 | 53 | sent_success = client.publish @queue_name, string_message 54 | if sent_success == true 55 | display "successfully published the string message" 56 | end 57 | 58 | if client.publish @queue_name, binary_to_publish 59 | display "successfully published the binary message" 60 | end 61 | 62 | if client.publish @queue_name, json_message 63 | display "successfully published the json message" 64 | end 65 | 66 | display "Consuming messages now ..." 67 | cons = Messagebus::Consumer.new(@connection_string, @options) 68 | cons.start 69 | print "\n receiving.." 70 | for i in (1..3) do 71 | print "\n receiving(#{i}).." 72 | message = cons.receive 73 | payload = message.payload 74 | case i 75 | when 1 76 | if payload == string_message 77 | display "successfully received string message" 78 | else 79 | display "failure while receiving string message" 80 | end 81 | when 2 82 | if payload == binary_to_publish 83 | display "successfully received binary message" 84 | else 85 | display "failure while receiving binary message" 86 | end 87 | when 3 88 | if payload == @config.to_json 89 | display "successfully received json messsage" 90 | else 91 | display "failure while receiving json message" 92 | end 93 | end 94 | if(@options[:ack_type] == "client") 95 | display "Acking..." 96 | cons.ack() 97 | end 98 | end 99 | 100 | client.stop 101 | cons.stop() 102 | end 103 | 104 | # Script 105 | 106 | prepare_configs('autoClient') 107 | basic_pub_consume 108 | 109 | prepare_configs('client') 110 | basic_pub_consume 111 | -------------------------------------------------------------------------------- /mbus-ruby/test_driver/test2_delayed_ack.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | base = File.dirname(__FILE__) 4 | $:.unshift File.expand_path(File.join(base, "..", "lib")) 5 | 6 | require "irb" 7 | require "yaml" 8 | require "messagebus" 9 | require "thrift" 10 | require "json" 11 | 12 | 13 | def display(data) 14 | puts "\n #{data}" 15 | end 16 | 17 | # ADJUST PARAMS HERE 18 | @queue_name = "jms.queue.testQueue1" 19 | @connection_string = "localhost:61613" 20 | @redelivery_delay = 5000 21 | 22 | def prepare_configs(ack_type) 23 | @config = YAML.load_file("../config/messagebus.yml") 24 | @config["enable_auto_init_connections"] = "true" 25 | 26 | @options = { 27 | :user => 'guest', 28 | :passwd => 'guest', 29 | :subscription_id => 'test2', 30 | #:ack_type => Messagebus::ACK_TYPE_CLIENT 31 | #:ack_type => 'client', 32 | #:ack_type => 'autoClient', 33 | :ack_type => ack_type, 34 | :destination_name => 'jms.queue.testQueue1', 35 | :dynamic_fetch_timeout_ms => 1000, 36 | :enable_dynamic_serverlist_fetch => true, 37 | :conn_lifetime_sec => 30 38 | } 39 | end 40 | 41 | def basic_pub_consume 42 | string_message = "first string message" 43 | 44 | cluster = @config["clusters"] 45 | cluster[0]["producer_address"] = @connection_string 46 | display "Config: address: #{@queue_name}" 47 | 48 | cons = Messagebus::Consumer.new(@connection_string, @options) 49 | cons.start 50 | 51 | client = Messagebus::Client.new(@config.merge(:logger => Logger.new("../mbus.log"))) 52 | client.start 53 | 54 | if client.publish @queue_name, string_message 55 | display "successfully published the string message" 56 | end 57 | 58 | display "Consuming messages now ..." 59 | print "\n receiving.." 60 | 61 | 62 | display "receicing message without ack..." 63 | message = cons.receive 64 | payload = message.payload 65 | 66 | if payload == string_message 67 | display "successfully received string message" 68 | else 69 | display "failure while receiving string message" 70 | end 71 | 72 | # not acking the first time 73 | 74 | display "trying to receieve again..." 75 | should_be_empty = cons.receive_immediate() 76 | 77 | if !should_be_empty.nil? 78 | display "Error occurred, message came back immediately" 79 | else 80 | display "Receive immediate worked successfully" 81 | end 82 | 83 | display "Waiting for #{@redelivery_delay} ms..." 84 | delay = @redelivery_delay/1000 85 | sleep (delay + 1) 86 | 87 | display "receicing message with ack now..." 88 | messgae = cons.receive() 89 | cons.ack() 90 | payload = message.payload 91 | 92 | if payload == string_message 93 | display "successfully received string message" 94 | else 95 | display "failure while receiving string message" 96 | end 97 | 98 | display "Waiting for #{@redelivery_delay} ms..." 99 | sleep (delay + 1) 100 | should_be_empty = cons.receive_immediate() 101 | 102 | if !should_be_empty.nil? 103 | display "Error occurred, message came back immediately" 104 | return false 105 | end 106 | 107 | client.stop 108 | cons.stop() 109 | true 110 | end 111 | 112 | # Script 113 | 114 | prepare_configs('client') 115 | success = basic_pub_consume 116 | 117 | if success 118 | display "Test completed successfully" 119 | end 120 | -------------------------------------------------------------------------------- /mbus-ruby/test_driver/test3_publish_consume_topic.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | base = File.dirname(__FILE__) 4 | $:.unshift File.expand_path(File.join(base, "..", "lib")) 5 | 6 | require "irb" 7 | require "yaml" 8 | require "messagebus" 9 | require "thrift" 10 | require "json" 11 | 12 | def display(data) 13 | puts "\n #{data}" 14 | end 15 | 16 | # ADJUST PARAMS HERE 17 | @queue_name = "jms.topic.testTopic1" 18 | @connection_string = "localhost:61613" 19 | 20 | def prepare_configs(ack_type) 21 | @config = YAML.load_file("../config/messagebus.yml") 22 | @config["enable_auto_init_connections"] = "true" 23 | 24 | client = Messagebus::Client.new(@config.merge(:logger => Logger.new("../mbus.log"))) 25 | client.start 26 | 27 | @options = { 28 | :user => 'guest', 29 | :passwd => 'guest', 30 | :subscription_id => 'test4', 31 | #:ack_type => Messagebus::ACK_TYPE_CLIENT 32 | #:ack_type => 'client', 33 | #:ack_type => 'autoClient', 34 | :ack_type => ack_type, 35 | :destination_name => @queue_name, 36 | :dynamic_fetch_timeout_ms => 1000, 37 | :enable_dynamic_serverlist_fetch => true, 38 | :conn_lifetime_sec => 30 39 | } 40 | end 41 | 42 | def basic_pub_consume 43 | cons = Messagebus::Consumer.new(@connection_string, @options) 44 | cons.start 45 | 46 | string_message = "test message" 47 | 48 | puts "created subsc #{@options[:subscription_id]}" 49 | 50 | client = Messagebus::Client.new(@config.merge(:logger => Logger.new("../mbus.log"))) 51 | client.start 52 | 53 | sent_success = client.publish @queue_name, string_message 54 | if sent_success == true 55 | display "successfully published the string message" 56 | end 57 | 58 | message = cons.receive 59 | payload = message.payload 60 | 61 | if payload == string_message 62 | display "successfully received string message" 63 | else 64 | display "failure while receiving string message" 65 | end 66 | 67 | if(@options[:ack_type] == "client") 68 | display "Acking..." 69 | cons.ack() 70 | end 71 | 72 | cons.stop() 73 | client.stop() 74 | end 75 | 76 | # Script 77 | prepare_configs('client') 78 | basic_pub_consume 79 | -------------------------------------------------------------------------------- /mbus-ruby/test_driver/test4_failed_connection_reconnect.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | base = File.dirname(__FILE__) 4 | $:.unshift File.expand_path(File.join(base, "..", "lib")) 5 | 6 | require "irb" 7 | require "yaml" 8 | require "messagebus" 9 | require "thrift" 10 | require "json" 11 | 12 | def display(data) 13 | puts "\n #{data}" 14 | end 15 | 16 | # ADJUST PARAMS HERE 17 | @queue_name = "jms.queue.testQueue1" 18 | @connection_string = "localhost:61613" 19 | 20 | def prepare_configs(ack_type) 21 | @config = YAML.load_file("../config/messagebus.yml") 22 | @config["enable_auto_init_connections"] = "true" 23 | 24 | @options = { 25 | :user => 'guest', 26 | :passwd => 'guest', 27 | :subscription_id => 'test2', 28 | #:ack_type => Messagebus::ACK_TYPE_CLIENT 29 | #:ack_type => 'client', 30 | #:ack_type => 'autoClient', 31 | :ack_type => ack_type, 32 | :destination_name => 'jms.queue.testQueue1', 33 | :dynamic_fetch_timeout_ms => 1000, 34 | :enable_dynamic_serverlist_fetch => true, 35 | :conn_lifetime_sec => 30 36 | } 37 | end 38 | 39 | def basic_pub_consume 40 | binary_to_publish = "\xfe\x3e\x5e" 41 | string_message = "first string message" 42 | success = false 43 | 44 | json_message = @config.to_json 45 | cluster = @config["clusters"] 46 | 47 | cluster[0]["producer_address"] = @connection_string 48 | display "Config: address: #{@queue_name}" 49 | 50 | puts "This test needs manual intervention.." 51 | puts "kill the broker at localhost:61613" 52 | puts "waiting for 20 seconds..." 53 | sleep (20) 54 | 55 | client = Messagebus::Client.new(@config.merge(:logger => Logger.new("../mbus.log"))) 56 | client.start 57 | 58 | puts "Now start the broker again, waiting for 30 seconds..." 59 | sleep(30) 60 | 61 | if client.publish @queue_name, string_message 62 | display "successfully published the string message" 63 | else 64 | display "failed to publish" 65 | end 66 | 67 | display "Consuming messages now ..." 68 | cons = Messagebus::Consumer.new(@connection_string, @options) 69 | cons.start 70 | print "\n receiving.." 71 | message = cons.receive() 72 | payload = message.payload 73 | 74 | if payload == string_message 75 | display "successfully received string message" 76 | success = true 77 | else 78 | display "failure while receiving string message" 79 | end 80 | 81 | client.stop 82 | cons.stop() 83 | sucess 84 | end 85 | 86 | # Script 87 | 88 | prepare_configs('autoClient') 89 | if basic_pub_consume 90 | puts "Test complete successfully" 91 | end 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /mbus-ruby/vendor/gems/stomp.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2005-2006 Brian McCallister 2 | # Copyright 2006 LogicBlaze Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | require 'stomp/ext/hash' 17 | require 'stomp/connection' 18 | require 'stomp/client' 19 | require 'stomp/message' 20 | require 'stomp/errors' 21 | 22 | module Stomp 23 | end 24 | -------------------------------------------------------------------------------- /mbus-ruby/vendor/gems/stomp/errors.rb: -------------------------------------------------------------------------------- 1 | module Stomp 2 | module Error 3 | class InvalidFormat < RuntimeError 4 | def message 5 | "Invalid message - invalid format" 6 | end 7 | end 8 | 9 | class InvalidServerCommand < RuntimeError 10 | def message 11 | "Invalid command from server" 12 | end 13 | end 14 | 15 | class InvalidMessageLength < RuntimeError 16 | def message 17 | "Invalid content length received" 18 | end 19 | end 20 | 21 | class PacketParsingTimeout < RuntimeError 22 | def message 23 | "Packet parsing timeout" 24 | end 25 | end 26 | 27 | class PacketReceiptTimeout < RuntimeError 28 | def message 29 | "Packet receiving timeout" 30 | end 31 | end 32 | 33 | class MaxReconnectAttempts < RuntimeError 34 | def message 35 | "Maximum number of reconnection attempts reached" 36 | end 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /mbus-ruby/vendor/gems/stomp/ext/hash.rb: -------------------------------------------------------------------------------- 1 | class ::Hash 2 | def uncamelize_and_symbolize_keys 3 | self.uncamelize_and_stringify_keys.symbolize_keys 4 | end 5 | 6 | def uncamelize_and_stringify_keys 7 | uncamelized = {} 8 | self.each_pair do |key, value| 9 | new_key = key.to_s.split(/(?=[A-Z])/).join('_').downcase 10 | uncamelized[new_key] = value 11 | end 12 | 13 | uncamelized 14 | end 15 | 16 | def symbolize_keys 17 | symbolized = {} 18 | self.each_pair do |key, value| 19 | symbolized[key.to_sym] = value 20 | end 21 | 22 | symbolized 23 | end unless self.method_defined?(:symbolize_keys) 24 | end 25 | -------------------------------------------------------------------------------- /mbus-ruby/vendor/gems/stomp/message.rb: -------------------------------------------------------------------------------- 1 | module Stomp 2 | 3 | # Container class for frames, misnamed technically 4 | class Message 5 | attr_accessor :command, :headers, :body, :original 6 | 7 | @@allowed_commands = [ 'CONNECTED', 'MESSAGE', 'RECEIPT', 'ERROR' ] 8 | 9 | def initialize(frame) 10 | # p frame 11 | # Set default empty values 12 | self.command = '' 13 | self.headers = {} 14 | self.body = '' 15 | self.original = frame 16 | return self if is_blank?(frame) 17 | # Figure out where individual parts of the frame begin and end. 18 | command_index = frame.index("\n") 19 | raise Stomp::Error::InvalidFormat, 'command index' unless command_index 20 | # 21 | headers_index = frame.index("\n\n", command_index+1) 22 | raise Stomp::Error::InvalidFormat, 'headers index' unless headers_index 23 | # 24 | lastnull_index = frame.rindex("\0") 25 | raise Stomp::Error::InvalidFormat, 'lastnull index' unless lastnull_index 26 | 27 | # Extract working copies of each frame part 28 | work_command = frame[0..command_index-1] 29 | raise Stomp::Error::InvalidServerCommand, "invalid command: #{work_command.inspect}" unless @@allowed_commands.include?(work_command) 30 | # 31 | work_headers = frame[command_index+1..headers_index-1] 32 | raise Stomp::Error::InvalidFormat, 'nil headers' unless work_headers 33 | # 34 | work_body = frame[headers_index+2..lastnull_index-1] 35 | raise Stomp::Error::InvalidFormat, 'nil body' unless work_body 36 | # Set the frame values 37 | self.command = work_command 38 | work_headers.split("\n").map do |value| 39 | parsed_value = value.match /^([\w|-]*):(.*)$/ 40 | raise Stomp::Error::InvalidFormat, 'parsed header value' unless parsed_value 41 | self.headers[parsed_value[1].strip] = parsed_value[2].strip if parsed_value 42 | end 43 | 44 | body_length = -1 45 | 46 | if self.headers['content-length'] 47 | body_length = self.headers['content-length'].to_i 48 | raise Stomp::Error::InvalidMessageLength if work_body.length != body_length 49 | end 50 | self.body = work_body[0..body_length] 51 | 52 | end 53 | 54 | def to_s 55 | "" 56 | end 57 | 58 | def empty? 59 | is_blank?(command) && is_blank?(headers) && is_blank?(body) 60 | end 61 | 62 | private 63 | def is_blank?(value) 64 | value.nil? || (value.respond_to?(:empty?) && value.empty?) 65 | end 66 | end 67 | 68 | end 69 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | com.groupon.messagebus 5 | MessageBus 6 | 1.0.1-SNAPSHOT 7 | A distributed messaging platform 8 | 9 | MessageBus 10 | pom 11 | http://engineering.groupon.com 12 | 13 | 14 | 15 | The BSD 3-Clause License 16 | http://opensource.org/licenses/BSD-3-Clause 17 | repo 18 | 19 | 20 | 21 | 22 | org.sonatype.oss 23 | oss-parent 24 | 7 25 | 26 | 27 | 28 | https://github.com/groupon/Message-Bus 29 | scm:git:git@github.com:groupon/Message-Bus.git 30 | scm:git:git@github.com:groupon/Message-Bus.git 31 | 32 | 33 | 34 | 35 | lin 36 | Lin Zhao 37 | lin@groupon.com 38 | 39 | 40 | pjawahar 41 | Pradeep Jawahar 42 | pjawahar@groupon.com 43 | 44 | 45 | eweathers 46 | Erik Weathers 47 | eweathers@groupon.com 48 | 49 | 50 | 51 | 52 | mbus-java 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | --------------------------------------------------------------------------------