├── .gitignore ├── LICENSE.txt ├── README.md ├── buildfile ├── iron.json.example ├── pom.xml └── src ├── main └── java │ └── io │ └── iron │ └── ironmq │ ├── Alert.java │ ├── Alerts.java │ ├── Client.java │ ├── Cloud.java │ ├── EmptyQueueException.java │ ├── HTTPException.java │ ├── HttpClient.java │ ├── Ids.java │ ├── IronReader.java │ ├── IronTokenContainer.java │ ├── Message.java │ ├── MessageContainer.java │ ├── MessageOptions.java │ ├── MessagePushModel.java │ ├── Messages.java │ ├── MessagesArrayList.java │ ├── MessagesOptions.java │ ├── MessagesReservationModel.java │ ├── Queue.java │ ├── QueueContainer.java │ ├── QueueModel.java │ ├── QueuePushModel.java │ ├── Queues.java │ ├── QueuesContainer.java │ ├── SubscribedMessageOptions.java │ ├── Subscriber.java │ ├── Subscribers.java │ ├── SubscribersInfo.java │ ├── TokenContainer.java │ └── keystone │ ├── Access.java │ ├── Auth.java │ ├── KeystoneGetTokenPayload.java │ ├── KeystoneGetTokenResponse.java │ ├── KeystoneIdentity.java │ ├── PasswordCredentials.java │ ├── Tenant.java │ ├── Token.java │ └── User.java └── test └── java ├── client └── iron │ └── ironmq │ └── ClientIronMQTest.java └── io └── iron └── ironmq ├── CloudTest.java ├── IronMQLongRunningTest.java ├── IronMQTest.java └── MockTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | reports 2 | target 3 | /.classpath 4 | /.project 5 | /.settings 6 | config.properties 7 | 8 | #ignore intelliJ files 9 | /.idea 10 | *.iml 11 | /iron.json 12 | /.iron.json 13 | config/ 14 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012, Iron.io, Inc. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, 7 | this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright notice, 9 | this list of conditions and the following disclaimer in the documentation 10 | and/or other materials provided with the distribution. 11 | 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 13 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 14 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 15 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 16 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 17 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 18 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 19 | OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 20 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 21 | OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 22 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | IronMQ Java Client 2 | ---------------- 3 | 4 | **Note:** There are some differences from the previous version of IronMQ. For more information please go to [Iron.io Dev Center](http://dev.iron.io/mq/3/reference/api/#basics). 5 | 6 | 7 | Getting Started 8 | =============== 9 | There are three ways to get this package. 10 | 11 | 1\. Add it as a Maven dependency 12 | Your pom.xml will look something like: 13 | 14 | ```xml 15 | 16 | 17 | 18 | io.iron.ironmq 19 | ironmq 20 | LATEST 21 | 22 | 23 | ``` 24 | 25 | 2\. [Download the jar from Maven Repo](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22io.iron.ironmq%22). 26 | 27 | **Note**: You also need to have several dependencies added to classpath: [com.google.code.gson 2.1 or later](https://code.google.com/p/google-gson/downloads/list?can=1) and [org.apache.commons 3.3.1 or later](http://commons.apache.org/proper/commons-lang/download_lang.cgi). 28 | 29 | For example following commands could be used to run your simple test program: 30 | 31 | ```sh 32 | src$ javac -cp ".:ironmq.jar:gson-2.2.4.jar:commons-lang3-3.1.jar" org/ironmq_test/Program.java 33 | src$ java -cp ".:ironmq.jar:gson-2.2.4.jar:commons-lang3-3.1.jar" org.ironmq_test.Program 34 | ``` 35 | 36 | 3\. Build from source with [Apache Buildr](http://buildr.apache.org): 37 | 38 | buildr package 39 | 40 | The .jar file will appear under the target directory. 41 | 42 | ### Configure 43 | 44 | **Initialize** a client and get a queue object: 45 | 46 | #### Using iron.json file 47 | 48 | Put all settings in iron.json file. At least token and project_id. But `host`, `port`, `scheme` are also supported. 49 | 50 | ```js 51 | { 52 | "token": "m6000000000000000000RJ", 53 | "project_id": "54000000000000000000000d", 54 | "scheme": "http", 55 | "host": "mq-aws-us-east-1-1.iron.io", 56 | "port": 80 57 | } 58 | ``` 59 | 60 | Then you need to instantiate a `Client`: 61 | 62 | ```java 63 | Client client = new Client(); 64 | ``` 65 | 66 | iron.json file could be placed in home directory, in current directory of executing program or in ./config/ directory. File also could be hidden, i.e. to start with `.` symbol. 67 | 68 | In case of using Maven put your iron.json in the root of project (near the pom.xml file) or in home directory. 69 | 70 | It's also possible to look for iron.json file in parent directories: 71 | 72 | ```java 73 | lookUpLimit = 3; 74 | Client client = new Client(, , , 1, lookUpLimit); 75 | ``` 76 | In example above IronMq library will try to find iron.json file in 3 levels of parent folders of executing file. 77 | 78 | #### Specifying configuration in initializer 79 | 80 | ```java 81 | Client client = new Client("my project", "my token", Cloud.ironAWSUSEast); 82 | Queue queue = client.queue("test-queue"); 83 | ``` 84 | 85 | It's also possible to specify more parameters: 86 | 87 | ```java 88 | int apiVersion = 3; 89 | Client client = new Client(projectId, token, new Cloud("http", "localhost", 8080), apiVersion); 90 | ``` 91 | 92 | #### Keystone 2.0 authorization 93 | 94 | ##### iron.json 95 | 96 | Add `keystone` section to your iron.json file 97 | 98 | ```javascript 99 | { 100 | "project_id": "000000000000000000000005", 101 | "keystone": { 102 | "server": "http://your.keystone.server/somepath/", 103 | "tenant": "some_tenant", 104 | "username": "bob", 105 | "password": "secret123", 106 | } 107 | } 108 | ``` 109 | 110 | Initialize `Client` with empty token: 111 | 112 | ```java 113 | client = new Client(projectId, "", new Cloud(scheme, host, port), 3); 114 | ``` 115 | 116 | **Or**: 117 | 118 | Assumed that IronMQ On-Premise runs on localhost:8080 119 | 120 | ```javascript 121 | { 122 | "scheme":"http", 123 | "host":"localhost", 124 | "port":8080, 125 | "project_id": "000000000000000000000005", 126 | "keystone": { 127 | "server": "http://your.keystone.server/somepath/", 128 | "tenant": "some_tenant", 129 | "username": "bob", 130 | "password": "secret123", 131 | } 132 | } 133 | ``` 134 | 135 | ```java 136 | client = new Client(); 137 | ``` 138 | 139 | ##### In code 140 | 141 | ```java 142 | client = new Client(projectId, new KeystoneIdentity(server, tenant, username, password), new Cloud(scheme, host, port), 3); 143 | ``` 144 | 145 | Token in iron.json file will be ignored. 146 | 147 | You can combine using of .json config file and initializer. In the example below Client will be initialized with token from config file and project_id specified in code: 148 | 149 | ```java 150 | Client client = new Client("my project", null); 151 | ``` 152 | 153 | ## The Basics 154 | 155 | ```java 156 | Client client = new Client("my project", "my token", Cloud.ironAWSUSEast); 157 | ``` 158 | 159 | ### Post a Message to the Queue 160 | 161 | ```java 162 | queue.push("Hello, IronMQ!"); 163 | ``` 164 | 165 | More complex example: 166 | 167 | ```java 168 | String body = "Hello, IronMQ!"; 169 | int delay = 0; 170 | String messageId = queue.push(body, delay); 171 | ``` 172 | 173 | Post multiple messages in one API call: 174 | 175 | ```java 176 | String[] messages = {"c", "d"}; 177 | Ids ids = queue.pushMessages(messages); 178 | ``` 179 | 180 | -- 181 | 182 | ### Get a Message off the Queue 183 | 184 | ```java 185 | Message msg = queue.reserve(); 186 | ``` 187 | 188 | When you reserve a message from the queue, it will NOT be deleted. 189 | It will eventually go back onto the queue after a timeout if you don't delete it (default timeout is 60 seconds). 190 | 191 | Get multiple messages in one API call: 192 | 193 | ```java 194 | Messages messages = queue.reserve(2); 195 | ``` 196 | 197 | -- 198 | 199 | ### Delete a Message from the Queue 200 | 201 | ```java 202 | Message msg = queue.reserve(); 203 | queue.deleteMessage(msg); 204 | ``` 205 | 206 | Delete a message from the queue when you're done with it. 207 | 208 | ### Delete multiple messages 209 | 210 | 1\. Deleting Messages collection 211 | 212 | ```java 213 | Messages messages = queue.reserve(4); 214 | queue.deleteMessages(messages); 215 | ``` 216 | 217 | 2\. Deleting by Ids 218 | 219 | ```java 220 | String[] messages = {"hello", "world"}; 221 | Ids ids = queue.pushMessages(messages); 222 | queue.deleteMessages(); 223 | ``` 224 | 225 | -- 226 | 227 | ## Queues 228 | 229 | ### List Queues 230 | 231 | ```java 232 | ArrayList allQueues = Queues.getQueues(client); 233 | ``` 234 | 235 | **Additional Parameters:** 236 | 237 | * `per\_page` - number of elements in response, default is 30. 238 | * `previous` - this is the last queue on the previous page, it will start from the next one. If queue with specified name doesn’t exist result will contain first `per_page` queues that lexicographically greater than `previous` 239 | * `prefix` - an optional queue prefix to search on. e.g., prefix=ca could return queues ["cars", "cats", etc.] 240 | 241 | Request below will return 20 queues started with "na" but lexicographically greater than "name_of_previous_queue". 242 | 243 | ```java 244 | int perPage = 20; 245 | String previous = "name_of_previous_queue"; 246 | String prefix = "na"; 247 | ArrayList allQueues = Queues.getQueues(client, previous, perPage, prefix); 248 | ``` 249 | 250 | -- 251 | 252 | ### Retrieve Queue Information 253 | 254 | ```java 255 | QueueModel infoAboutQueue = queue.getInfoAboutQueue(); 256 | ``` 257 | 258 | -- 259 | 260 | ### Delete a Message Queue 261 | 262 | ```java 263 | queue.destroy(); 264 | ``` 265 | 266 | -- 267 | 268 | ### Post Messages to a Queue 269 | 270 | **Single message:** 271 | 272 | ```java 273 | queue.pushMessage(body); 274 | ``` 275 | 276 | **Multiple messages:** 277 | 278 | ```java 279 | String[] messages = {"c", "d"}; 280 | Ids ids = queue.pushMessages(messages); 281 | ``` 282 | 283 | **Optional parameters (3rd, `array` of key-value pairs):** 284 | 285 | * `delay`: The item will not be available on the queue until this many seconds have passed. 286 | Default is 0 seconds. Maximum is 604,800 seconds (7 days). 287 | 288 | -- 289 | 290 | ### Get Messages from a Queue 291 | 292 | **Single message:** 293 | 294 | ```java 295 | Message msg = queue.reserve(); 296 | ``` 297 | 298 | **Multiple messages:** 299 | 300 | ```java 301 | int count = 5; 302 | Messages messages = queue.reserve(count); 303 | ``` 304 | 305 | **Optional parameters:** 306 | 307 | * `count`: The maximum number of messages to get. Default is 1. Maximum is 100. 308 | 309 | -- 310 | 311 | ### Touch a Message on a Queue 312 | 313 | Touching a reserved message extends its timeout by the duration specified when the message was created, which is 60 seconds by default. 314 | 315 | ```java 316 | Message message = queue.reserve(); 317 | queue.touchMessage(message); 318 | ``` 319 | 320 | -- 321 | 322 | ### Release Message 323 | 324 | ```java 325 | Message message = queue.reserve(); 326 | int delay = 1; 327 | queue.releaseMessage(message, delay); 328 | ``` 329 | 330 | **Optional parameters:** 331 | 332 | * `delay`: The item will not be available on the queue until this many seconds have passed. 333 | Default is 0 seconds. Maximum is 604,800 seconds (7 days). 334 | 335 | -- 336 | 337 | ### Delete a Message from a Queue 338 | 339 | ```java 340 | Message message = queue.get(); 341 | queue.deleteMessage(message); 342 | ``` 343 | 344 | -- 345 | 346 | ### Peek Messages from a Queue 347 | 348 | Peeking at a queue returns the next messages on the queue, but it does not reserve them. 349 | 350 | **Single message:** 351 | 352 | ```java 353 | Messages msg = queue.peek(); 354 | ``` 355 | 356 | **Multiple messages:** 357 | 358 | ```java 359 | int count = 2; 360 | Messages msg = queue.peek(count); 361 | ``` 362 | 363 | -- 364 | 365 | ### Clear a Queue 366 | 367 | ```java 368 | queue.clear(); 369 | ``` 370 | 371 | -- 372 | 373 | ### Add alerts to a queue. This is for Pull Queue only. 374 | 375 | ```java 376 | ArrayList alerts = new ArrayList(); 377 | alerts.add(new Alert(Alert.typeProgressive, Alert.directionAscending, 5, "some_q")); 378 | QueueModel info = queue.updateAlerts(alerts); 379 | ``` 380 | 381 | -- 382 | 383 | 384 | ## Push Queues 385 | 386 | IronMQ push queues allow you to setup a queue that will push to an endpoint, rather than having to poll the endpoint. 387 | [Here's the announcement for an overview](http://blog.iron.io/2013/01/ironmq-push-queues-reliable-message.html). 388 | 389 | ### Update a Message Queue 390 | 391 | ```java 392 | ArrayList subscribers = new ArrayList() {{ add(new Subscriber(url)); }}; 393 | QueueModel payload = new QueueModel(new QueuePushModel(subscribers, "multicast", 4, 7, "test_err")); 394 | queue.update(payload); 395 | ``` 396 | 397 | **The following parameters are all related to Push Queues:** 398 | 399 | * `subscribers`: An array of subscriber hashes containing url field. 400 | This set of subscribers will replace the existing subscribers. 401 | * `retries`: How many times to retry on failure. Default is 3. Maximum is 100. 402 | * `retries_delay`: Delay between each retry in seconds. Default is 60. 403 | 404 | -- 405 | 406 | ### Update Queue Subscribers 407 | 408 | ```java 409 | ArrayList subscribers = new ArrayList(); 410 | subscribers.add(new Subscriber("http://localhost:3000")); 411 | subscribers.add(new Subscriber("http://localhost:3030")); 412 | queue.updateSubscribers(subscribers); 413 | ``` 414 | 415 | -- 416 | 417 | ### Get Message Push Status 418 | 419 | ```java 420 | String[] messages = {"test1", "test2"}; 421 | Ids ids = queue.pushMessages(messages); 422 | SubscribersInfo subscribersInfo = queue.getPushStatusForMessage(ids.getId(0)); 423 | ``` 424 | 425 | Returns an array of subscribers with status. 426 | 427 | -- 428 | 429 | ### Acknowledge / Delete Message Push Status 430 | 431 | ```java 432 | String[] messages = {"test1", "test2"}; 433 | Ids ids = queue.pushMessages(messages); 434 | SubscribersInfo subscribersInfo = queue.getPushStatusForMessage(ids.getId(0)); 435 | queue.deletePushMessageForSubscriber(ids.getId(0), subscribersInfo.getSubscribers().get(0).id); 436 | ``` 437 | 438 | -- 439 | 440 | ## Further Links 441 | 442 | * [IronMQ Overview](http://dev.iron.io/mq/3/) 443 | * [IronMQ v3 REST/HTTP API](http://dev.iron.io/mq/3/reference/api/) 444 | * [Other Client Libraries](http://dev.iron.io/mq/3/libraries/) 445 | 446 | ------------- 447 | В© 2011 - 2014 Iron.io Inc. All Rights Reserved. 448 | -------------------------------------------------------------------------------- /buildfile: -------------------------------------------------------------------------------- 1 | repositories.remote << 'http://repo1.maven.org/maven2' 2 | repositories.remote << 'http://iron-io.github.com/maven/repository' 3 | 4 | THIS_VERSION = "3.0.2" 5 | GROUP = 'ironmq' 6 | 7 | JUNIT = 'junit:junit:jar:4.10' 8 | 9 | DEPS = [ 10 | 'com.google.code.gson:gson:jar:2.1', 11 | 'org.apache.commons:commons-lang3:jar:3.1', 12 | ] 13 | 14 | define 'ironmq' do 15 | repositories.release_to[:url] = "file://#{base_dir}/../maven/repository" 16 | 17 | project.version = THIS_VERSION 18 | project.group = GROUP 19 | test.with JUNIT 20 | DEPS.each do |dep| 21 | compile.with transitive(dep) 22 | end 23 | compile.using(:source => '1.6', :target => '1.6') 24 | package :jar 25 | end 26 | -------------------------------------------------------------------------------- /iron.json.example: -------------------------------------------------------------------------------- 1 | { 2 | "token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", 3 | "project_id": "yyyyyyyyyyyyyyyyyyyyyyyy", 4 | "scheme": "https", 5 | "host": "mq-aws-us-east-1-1.iron.io", 6 | "port": 443, 7 | "keystone": { 8 | "server": "http://ec2-11-11-111-111.compute-1.amazonaws.com/v2.0/", 9 | "tenant": "some_tenant", 10 | "username": "some_username", 11 | "password": "some_password" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.sonatype.oss 4 | oss-parent 5 | 7 6 | 7 | 4.0.0 8 | io.iron.ironmq 9 | ironmq 10 | 3.0.6-SNAPSHOT 11 | jar 12 | ironmq 13 | An easy-to-use highly available message queuing service. Built for distributed 14 | cloud applications with critical messaging needs. Provides on-demand message 15 | queuing with HTTPS transport, one-time FIFO delivery, message persistence, 16 | and cloud-optimized performance. 17 | 18 | http://www.iron.io/mq 19 | 20 | 21 | The BSD 2-Clause License 22 | http://opensource.org/licenses/BSD-2-Clause 23 | repo 24 | 25 | 26 | 27 | scm:git:git@github.com:iron-io/iron_mq_java.git 28 | scm:git:git@github.com:iron-io/iron_mq_java.git 29 | scm:git:git@github.com:iron-io/iron_mq_java.git 30 | 31 | 32 | 33 | 34 | owner 35 | Iron.io 36 | office@iron.io 37 | UTC-8 38 | 39 | 40 | 41 | 42 | 43 | com.google.code.gson 44 | gson 45 | 2.8.9 46 | 47 | 48 | junit 49 | junit 50 | 4.10 51 | test 52 | 53 | 54 | org.apache.commons 55 | commons-lang3 56 | 3.1 57 | 58 | 59 | 60 | 61 | sign-artifacts 62 | 63 | 64 | performRelease 65 | true 66 | 67 | 68 | 69 | 70 | 71 | 72 | UTF-8 73 | 74 | 75 | 76 | 77 | 78 | maven-release-plugin 79 | 2.0 80 | 81 | 82 | org.apache.maven.plugins 83 | maven-compiler-plugin 84 | 3.1 85 | 86 | 1.6 87 | 1.6 88 | 89 | 90 | 91 | org.apache.maven.plugins 92 | maven-source-plugin 93 | 2.2.1 94 | 95 | 96 | attach-sources 97 | package 98 | 99 | jar 100 | 101 | 102 | 103 | 104 | 105 | 106 | org.apache.maven.plugins 107 | maven-javadoc-plugin 108 | 2.9 109 | 110 | 111 | attach-javadocs 112 | package 113 | 114 | jar 115 | 116 | 117 | 118 | 119 | 120 | org.apache.maven.plugins 121 | maven-gpg-plugin 122 | 1.4 123 | 124 | ${gpg.passphrase} 125 | 126 | 127 | 128 | sign-artifacts 129 | verify 130 | 131 | sign 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/Alert.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | public class Alert { 4 | private String type; 5 | private String direction; 6 | private int trigger; 7 | private Integer snooze; 8 | private String queue; 9 | private String id; 10 | 11 | public static final String typeFixed = "fixed"; 12 | public static final String typeProgressive = "progressive"; 13 | public static final String directionAscending = "asc"; 14 | public static final String directionDescending = "desc"; 15 | 16 | public Alert(String type, String direction, int trigger, int snooze, String queue) { 17 | 18 | this.type = type; 19 | this.direction = direction; 20 | this.trigger = trigger; 21 | this.snooze = snooze; 22 | this.queue = queue; 23 | } 24 | 25 | public Alert(String type, String direction, int trigger, String queue) { 26 | 27 | this.type = type; 28 | this.direction = direction; 29 | this.trigger = trigger; 30 | this.queue = queue; 31 | } 32 | 33 | public String getType() { 34 | return type; 35 | } 36 | 37 | public void setType(String type) { 38 | this.type = type; 39 | } 40 | 41 | public String getDirection() { 42 | return direction; 43 | } 44 | 45 | public void setDirection(String direction) { 46 | this.direction = direction; 47 | } 48 | 49 | public int getTrigger() { 50 | return trigger; 51 | } 52 | 53 | public void setTrigger(int trigger) { 54 | this.trigger = trigger; 55 | } 56 | 57 | public int getSnooze() { 58 | return snooze; 59 | } 60 | 61 | public void setSnooze(int snooze) { 62 | this.snooze = snooze; 63 | } 64 | 65 | public String getQueue() { 66 | return queue; 67 | } 68 | 69 | public void setQueue(String queue) { 70 | this.queue = queue; 71 | } 72 | 73 | public String getId() { 74 | return id; 75 | } 76 | 77 | public void setId(String id) { 78 | this.id = id; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/Alerts.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class Alerts { 6 | private ArrayList alerts; 7 | 8 | public Alerts(ArrayList alerts) { 9 | this.alerts = alerts; 10 | } 11 | 12 | public Alert getAlert(int i) { 13 | return alerts.get(i); 14 | } 15 | 16 | public ArrayList getAlerts() { 17 | return alerts; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/Client.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.File; 5 | import java.io.FileNotFoundException; 6 | import java.io.FileReader; 7 | import java.io.IOException; 8 | import java.io.InputStreamReader; 9 | import java.io.OutputStreamWriter; 10 | import java.io.Reader; 11 | import java.io.Serializable; 12 | import java.net.HttpURLConnection; 13 | import java.net.URL; 14 | import java.util.ArrayList; 15 | import java.util.HashMap; 16 | import java.util.List; 17 | import java.util.Map; 18 | import java.util.Random; 19 | 20 | import io.iron.ironmq.keystone.KeystoneIdentity; 21 | import org.apache.commons.lang3.ArrayUtils; 22 | 23 | import com.google.gson.Gson; 24 | import com.google.gson.JsonSyntaxException; 25 | import com.google.gson.stream.JsonWriter; 26 | import org.apache.commons.lang3.StringUtils; 27 | 28 | /** 29 | * The Client class provides access to the IronMQ service. 30 | */ 31 | public class Client { 32 | static final private String defaultApiVersion = "3"; 33 | static final private Gson gson = new Gson(); 34 | 35 | final private String apiVersion; 36 | 37 | static final Random rand = new Random(); 38 | 39 | static final private HashMap defaultOptions; 40 | 41 | static { 42 | defaultOptions = new HashMap(); 43 | defaultOptions.put("scheme", Cloud.ironAWSUSEast.getScheme()); 44 | defaultOptions.put("host", Cloud.ironAWSUSEast.getHost()); 45 | defaultOptions.put("port", Cloud.ironAWSUSEast.getPort()); 46 | } 47 | 48 | private String projectId; 49 | private TokenContainer tokenContainer; 50 | private Cloud cloud; 51 | 52 | private String[] optionsList; 53 | private Map options; 54 | private String env; 55 | private int connectionTimeOutMs = 60000; 56 | private int readTimeOutMs = 60000; 57 | 58 | /** 59 | * This constructor is equivalent to {@link #Client(String, String, Cloud, Integer) Client(null, null, null, null)}. 60 | */ 61 | public Client() { 62 | this(null, (String) null, null, null); 63 | } 64 | 65 | /** 66 | * This constructor is equivalent to {@link #Client(String, String, Cloud, Integer) Client(projectId, token, null, null)}. 67 | * 68 | * @param projectId A 24-character project ID. 69 | * @param token An OAuth token. 70 | */ 71 | public Client(String projectId, String token) { 72 | this(projectId, token, null, null); 73 | } 74 | 75 | /** 76 | * This constructor is equivalent to {@link #Client(String, String, Cloud, Integer) Client(projectId, token, cloud, null)}. 77 | * 78 | * @param projectId A 24-character project ID. 79 | * @param token An OAuth token. 80 | * @param cloud The cloud to use. 81 | */ 82 | public Client(String projectId, String token, Cloud cloud) { 83 | this(projectId, token, cloud, null); 84 | } 85 | 86 | /** 87 | * Constructs a new Client using the specified project ID and token. 88 | * A null projectId, token, or cloud will be filled in using the 89 | * filesystem and environment for configuration as described 90 | * here. 91 | * The network is not accessed during construction and this call 92 | * succeeds even if the credentials are invalid. 93 | * 94 | * @param projectId A 24-character project ID. 95 | * @param token An OAuth token. 96 | * @param cloud The cloud to use. 97 | * @param apiVersion Version of ironmq api to use, default is 3. 98 | */ 99 | public Client(String projectId, String token, Cloud cloud, Integer apiVersion) { 100 | Map userOptions = new HashMap(); 101 | userOptions.put("project_id", projectId); 102 | userOptions.put("token", token); 103 | if (cloud != null) { 104 | userOptions.put("cloud", cloud); 105 | } 106 | this.apiVersion = (apiVersion == null || apiVersion < 1) ? defaultApiVersion : apiVersion.toString(); 107 | 108 | loadConfiguration("iron", "mq", userOptions, new String[]{"project_id", "token", "cloud"}); 109 | } 110 | 111 | public Client(String projectId, KeystoneIdentity identity, Cloud cloud, Integer apiVersion) { 112 | Map userOptions = new HashMap(); 113 | userOptions.put("project_id", projectId); 114 | userOptions.put("keystone", identity.toHash()); 115 | if (cloud != null) { 116 | userOptions.put("cloud", cloud); 117 | } 118 | this.apiVersion = (apiVersion == null || apiVersion < 1) ? defaultApiVersion : apiVersion.toString(); 119 | 120 | loadConfiguration("iron", "mq", userOptions, new String[]{"project_id", "token", "cloud"}); 121 | } 122 | 123 | public Client(String projectId, String token, Cloud cloud, Integer apiVersion, int lookUpLimit) { 124 | Map userOptions = new HashMap(); 125 | userOptions.put("project_id", projectId); 126 | userOptions.put("token", token); 127 | if (cloud != null) { 128 | userOptions.put("cloud", cloud); 129 | } 130 | this.apiVersion = (apiVersion == null || apiVersion < 1) ? defaultApiVersion : apiVersion.toString(); 131 | 132 | loadConfiguration("iron", "mq", userOptions, new String[]{"project_id", "token", "cloud"}, lookUpLimit); 133 | } 134 | 135 | /** 136 | * Returns a Queue using the given name. 137 | * The network is not accessed during this call. 138 | * 139 | * @param name The name of the Queue to create. 140 | */ 141 | public Queue queue(String name) { 142 | return new Queue(this, name); 143 | } 144 | 145 | IronReader delete(String endpoint) throws IOException { 146 | return request("DELETE", endpoint, null); 147 | } 148 | 149 | IronReader delete(String endpoint, String body) throws IOException { 150 | return request("DELETE", endpoint, body); 151 | } 152 | 153 | IronReader get(String endpoint) throws IOException { 154 | return request("GET", endpoint, null); 155 | } 156 | 157 | IronReader post(String endpoint, String body) throws IOException { 158 | return request("POST", endpoint, body); 159 | } 160 | 161 | IronReader post(String endpoint, Object body) throws IOException { 162 | return request("POST", endpoint, body); 163 | } 164 | 165 | IronReader put(String endpoint, String body) throws IOException { 166 | return request("PUT", endpoint, body); 167 | } 168 | 169 | IronReader patch(String endpoint, String body) throws IOException { 170 | return request("PATCH", endpoint, body); 171 | } 172 | 173 | private IronReader request(String method, String endpoint, Object body) throws IOException { 174 | String path = "/" + apiVersion + "/projects/" + projectId + "/" + endpoint; 175 | URL url = new URL(cloud.scheme, cloud.host, cloud.port, cloud.pathPrefix + path); 176 | 177 | final int maxRetries = 5; 178 | int retries = 0; 179 | while (true) { 180 | try { 181 | return singleRequest(method, url, body); 182 | } catch (HTTPException e) { 183 | // ELB sometimes returns this when load is increasing. 184 | // We retry with exponential backoff. 185 | if (e.getStatusCode() != 503 || retries >= maxRetries) { 186 | throw e; 187 | } 188 | retries++; 189 | // random delay between 0 and 4^tries*100 milliseconds 190 | int pow = (1 << (2 * retries)) * 100; 191 | int delay = rand.nextInt(pow); 192 | try { 193 | Thread.sleep(delay); 194 | } catch (InterruptedException ie) { 195 | Thread.currentThread().interrupt(); 196 | } 197 | } 198 | } 199 | } 200 | 201 | static private class Error implements Serializable { 202 | String msg; 203 | } 204 | 205 | private IronReader singleRequest(String method, URL url, Object body) throws IOException { 206 | HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 207 | if (method.equals("DELETE") || method.equals("PATCH")) { 208 | conn.setRequestMethod("POST"); 209 | conn.setRequestProperty("X-HTTP-Method-Override", method); 210 | } else { 211 | conn.setRequestMethod(method); 212 | } 213 | conn.setRequestProperty("Authorization", "OAuth " + tokenContainer.getToken()); 214 | conn.setRequestProperty("User-Agent", "IronMQ Java Client"); 215 | 216 | if (body != null) { 217 | conn.setRequestProperty("Content-Type", "application/json"); 218 | conn.setDoOutput(true); 219 | } 220 | 221 | conn.setConnectTimeout(connectionTimeOutMs); 222 | conn.setReadTimeout(readTimeOutMs); 223 | 224 | conn.connect(); 225 | 226 | if (body != null) { 227 | OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8"); 228 | if (body instanceof String) { 229 | out.write((String)body); 230 | out.close(); 231 | } else { 232 | JsonWriter jwriter = new JsonWriter(out); 233 | gson.toJson(body, body.getClass(), jwriter); 234 | jwriter.close(); 235 | } 236 | } 237 | 238 | int status = conn.getResponseCode(); 239 | if (status < 200 || status >= 300) { 240 | String msg; 241 | if (conn.getContentLength() > 0 && conn.getContentType().equals("application/json")) { 242 | InputStreamReader reader = null; 243 | try { 244 | reader = new InputStreamReader(conn.getErrorStream()); 245 | Error error = gson.fromJson(reader, Error.class); 246 | msg = error.msg; 247 | } catch (JsonSyntaxException e) { 248 | msg = "IronMQ's response contained invalid JSON"; 249 | } finally { 250 | if (reader != null) 251 | reader.close(); 252 | } 253 | } else { 254 | msg = "Empty or non-JSON response"; 255 | } 256 | throw new HTTPException(status, msg); 257 | } 258 | 259 | return new IronReader(new InputStreamReader(conn.getInputStream()),conn); 260 | } 261 | 262 | public Map getOptions() { 263 | return options; 264 | } 265 | 266 | public Object getOption(String name) { 267 | return options.get(name); 268 | } 269 | 270 | public String getEnv() { 271 | return env; 272 | } 273 | 274 | private void loadConfiguration(String company, String product, Map userOptions, String[] extraOptionsList) { 275 | loadConfiguration(company, product, userOptions, extraOptionsList, 0); 276 | } 277 | 278 | private void loadConfiguration(String company, String product, Map userOptions, String[] extraOptionsList, int lookUpLimit) { 279 | optionsList = ArrayUtils.addAll(new String[]{"scheme", "host", "port", "user_agent", "keystone"}, extraOptionsList); 280 | 281 | options = new HashMap(); 282 | 283 | env = (String) userOptions.get("env"); 284 | 285 | if (env == null) { 286 | env = System.getenv(company.toUpperCase() + "_" + product.toUpperCase() + "_ENV"); 287 | } 288 | 289 | if (env == null) { 290 | env = System.getenv(company.toUpperCase() + "_ENV"); 291 | } 292 | 293 | if (env == null) { 294 | env = (String) defaultOptions.get("env"); 295 | } 296 | 297 | loadFromHash(userOptions); 298 | loadFromConfig(company, product, (String) userOptions.get("config")); 299 | 300 | loadFromConfig(company, product, System.getenv(company.toUpperCase() + "_" + product.toUpperCase() + "_CONFIG")); 301 | loadFromConfig(company, product, System.getenv(company.toUpperCase() + "_CONFIG")); 302 | 303 | loadFromEnv(company.toUpperCase() + "_" + product.toUpperCase()); 304 | loadFromEnv(company.toUpperCase()); 305 | 306 | List suffixes = new ArrayList(); 307 | 308 | if (env != null) { 309 | suffixes.add("-" + env); 310 | suffixes.add("_" + env); 311 | } 312 | 313 | suffixes.add(""); 314 | 315 | for (String suffix : suffixes) { 316 | for (String configBase : new String[]{company + "-" + product, company + "_" + product, company}) { 317 | if (lookUpLimit > 0) { 318 | File parent = new File(System.getProperty("user.dir")).getParentFile(); 319 | for (int i = lookUpLimit; i > 0 && parent !=null; i--) { 320 | String name = parent.getAbsolutePath(); 321 | loadFromConfig(company, product, name + "/" + configBase + suffix + ".json"); 322 | loadFromConfig(company, product, name + "/." + configBase + suffix + ".json"); 323 | parent = parent.getParentFile(); 324 | } 325 | } 326 | loadFromConfig(company, product, System.getProperty("user.dir") + "/" + configBase + suffix + ".json"); 327 | loadFromConfig(company, product, System.getProperty("user.dir") + "/." + configBase + suffix + ".json"); 328 | loadFromConfig(company, product, System.getProperty("user.dir") + "/config/" + configBase + suffix + ".json"); 329 | loadFromConfig(company, product, System.getProperty("user.dir") + "/config/." + configBase + suffix + ".json"); 330 | loadFromConfig(company, product, System.getProperty("user.home") + "/" + configBase + suffix + ".json"); 331 | loadFromConfig(company, product, System.getProperty("user.home") + "/." + configBase + suffix + ".json"); 332 | } 333 | } 334 | 335 | loadFromConfig(company, product, (String) defaultOptions.get("config")); 336 | loadFromHash(defaultOptions); 337 | 338 | projectId = (String) getOption("project_id"); 339 | String token = (String) getOption("token"); 340 | 341 | HashMap keystoneHash = (HashMap) getOption("keystone"); 342 | if (keystoneHash != null && keystoneHash.containsKey("server") && keystoneHash.containsKey("tenant") && 343 | keystoneHash.containsKey("username") && keystoneHash.containsKey("password")) { 344 | tokenContainer = KeystoneIdentity.fromHash(keystoneHash); 345 | } else if (StringUtils.isNotBlank(token)) { 346 | tokenContainer = new IronTokenContainer(token); 347 | } else { 348 | throw new IllegalArgumentException("You should specify Iron token or Keystone credentials"); 349 | } 350 | 351 | if (userOptions.containsKey("cloud")) { 352 | Object cloudOption = userOptions.get("cloud"); 353 | if (cloudOption != null && cloudOption instanceof Cloud) { 354 | cloud = (Cloud) cloudOption; 355 | } 356 | } else { 357 | cloud = new Cloud((String) getOption("scheme"), (String) getOption("host"), ((Number) getOption("port")).intValue()); 358 | } 359 | } 360 | 361 | private void setOption(String name, Object value) { 362 | if (ArrayUtils.contains(optionsList, name)) { 363 | if (options.get(name) == null && value != null) { 364 | options.put(name, value); 365 | } 366 | } 367 | } 368 | 369 | private Map getSubHash(Map hash, String[] subs) { 370 | Map result = hash; 371 | 372 | for (String sub : subs) { 373 | if (result.get(sub) == null) { 374 | return null; 375 | } 376 | 377 | result = (Map) result.get(sub); 378 | } 379 | 380 | return result; 381 | } 382 | 383 | private void loadFromHash(Map hash) { 384 | if (hash == null) { 385 | return; 386 | } 387 | 388 | for (String option : optionsList) { 389 | setOption(option, hash.get(option)); 390 | } 391 | } 392 | 393 | private void loadFromConfig(String company, String product, String configFile) { 394 | if (configFile == null) { 395 | return; 396 | } 397 | 398 | File config = new File(configFile); 399 | 400 | if (!config.exists()) { 401 | return; 402 | } 403 | 404 | Reader configReader; 405 | try { 406 | configReader = new FileReader(config); 407 | } catch (FileNotFoundException e) { 408 | return; 409 | } 410 | configReader = new BufferedReader(configReader); 411 | 412 | Map configHash; 413 | try { 414 | configHash = (Map) gson.fromJson(configReader, Map.class); 415 | } finally { 416 | try { 417 | configReader.close(); 418 | } catch (IOException e) { 419 | } 420 | } 421 | 422 | if (env != null) { 423 | loadFromHash(getSubHash(configHash, new String[]{env, company + "_" + product})); 424 | loadFromHash(getSubHash(configHash, new String[]{env, company, product})); 425 | loadFromHash(getSubHash(configHash, new String[]{env, product})); 426 | loadFromHash(getSubHash(configHash, new String[]{env, company})); 427 | 428 | loadFromHash(getSubHash(configHash, new String[]{company + "_" + product, env})); 429 | loadFromHash(getSubHash(configHash, new String[]{company, product, env})); 430 | loadFromHash(getSubHash(configHash, new String[]{product, env})); 431 | loadFromHash(getSubHash(configHash, new String[]{company, env})); 432 | 433 | loadFromHash(getSubHash(configHash, new String[]{env})); 434 | } 435 | 436 | loadFromHash(getSubHash(configHash, new String[]{company + "_" + product})); 437 | loadFromHash(getSubHash(configHash, new String[]{company, product})); 438 | loadFromHash(getSubHash(configHash, new String[]{product})); 439 | loadFromHash(getSubHash(configHash, new String[]{company})); 440 | loadFromHash(getSubHash(configHash, new String[]{})); 441 | } 442 | 443 | private void loadFromEnv(String prefix) { 444 | for (String option : optionsList) { 445 | setOption(option, System.getenv(prefix + "_" + option.toUpperCase())); 446 | } 447 | } 448 | 449 | public int getConnectionTimeOutMs() { 450 | return connectionTimeOutMs; 451 | } 452 | 453 | public void setConnectionTimeOutMs(final int connectionTimeOutMs) { 454 | this.connectionTimeOutMs = connectionTimeOutMs; 455 | } 456 | 457 | public int getReadTimeOutMs() { 458 | return readTimeOutMs; 459 | } 460 | 461 | public void setReadTimeOutMs(final int readTimeOutMs) { 462 | this.readTimeOutMs = readTimeOutMs; 463 | } 464 | 465 | } 466 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/Cloud.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import java.net.MalformedURLException; 4 | import java.net.URL; 5 | 6 | public class Cloud { 7 | String scheme; 8 | String host; 9 | int port; 10 | String pathPrefix = ""; 11 | 12 | public static final Cloud ironAWSUSEast = new Cloud("https", "mq-aws-us-east-1-1.iron.io", 443); 13 | 14 | public Cloud(String url) throws MalformedURLException { 15 | URL u = new URL(url); 16 | this.scheme = u.getProtocol(); 17 | this.host = u.getHost(); 18 | this.port = u.getPort() < 0 ? u.getDefaultPort() : u.getPort(); 19 | String path = u.getPath(); 20 | this.pathPrefix = path.endsWith("/") ? path.substring(0, path.length() - 1) : path; 21 | } 22 | 23 | public Cloud(String scheme, String host, int port) { 24 | this.scheme = scheme; 25 | this.host = host; 26 | this.port = port; 27 | } 28 | 29 | public String getScheme() { 30 | return scheme; 31 | } 32 | 33 | public String getHost() { 34 | return host; 35 | } 36 | 37 | public int getPort() { 38 | return port; 39 | } 40 | 41 | public String getPathPrefix() { 42 | return pathPrefix; 43 | } 44 | 45 | public void setPathPrefix(String pathPrefix) { 46 | this.pathPrefix = pathPrefix; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/EmptyQueueException.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import java.io.IOException; 4 | 5 | /** 6 | * The EmptyQueueException class represents a response from IronMQ indicating 7 | * the queue is empty. 8 | */ 9 | public class EmptyQueueException extends IOException { 10 | /** 11 | * Creates a new EmptyQueueException. 12 | */ 13 | public EmptyQueueException() { 14 | super("Queue is empty"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/HTTPException.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import java.io.IOException; 4 | 5 | /** 6 | * The HTTPException class represents an HTTP response status that is not 200 OK. 7 | */ 8 | public class HTTPException extends IOException { 9 | private int status; 10 | 11 | /** 12 | * Creates a new HTTPException. 13 | * 14 | * @param status The HTTP status code. 15 | * @param message The text of the HTTP status code. 16 | */ 17 | public HTTPException(int status, String message) { 18 | super(message); 19 | this.status = status; 20 | } 21 | 22 | /** 23 | * Returns the HTTP response's status code. 24 | */ 25 | public int getStatusCode() { return this.status; } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/HttpClient.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.JsonSyntaxException; 5 | 6 | import java.io.*; 7 | import java.net.HttpURLConnection; 8 | import java.net.URL; 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | 12 | public class HttpClient { 13 | private boolean forMq; 14 | 15 | private HttpClient() { } 16 | 17 | public HttpClient(boolean forMq) { 18 | this.forMq = forMq; 19 | } 20 | 21 | public static HttpClient create() { 22 | return new HttpClient(false); 23 | } 24 | 25 | public static HttpClient createForMq() { 26 | return new HttpClient(true); 27 | } 28 | 29 | static private class Error implements Serializable { 30 | String msg; 31 | } 32 | 33 | public Reader singleRequest(String method, URL url, String body, HashMap headers) throws IOException { 34 | HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 35 | 36 | if (method.equals("DELETE") || method.equals("PATCH")) { 37 | conn.setRequestMethod("POST"); 38 | conn.setRequestProperty("X-HTTP-Method-Override", method); 39 | } else { 40 | conn.setRequestMethod(method); 41 | } 42 | 43 | for (Map.Entry entry : headers.entrySet()) { 44 | conn.setRequestProperty(entry.getKey(), entry.getValue()); 45 | } 46 | 47 | if (body != null) { 48 | conn.setRequestProperty("Content-Type", "application/json"); 49 | conn.setDoOutput(true); 50 | } 51 | 52 | conn.connect(); 53 | 54 | if (body != null) { 55 | OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8"); 56 | out.write(body); 57 | out.close(); 58 | } 59 | 60 | int status = conn.getResponseCode(); 61 | if (status != 200) { 62 | if (forMq) { 63 | String msg; 64 | if (conn.getContentLength() > 0 && conn.getContentType().equals("application/json")) { 65 | InputStreamReader reader = null; 66 | try { 67 | reader = new InputStreamReader(conn.getErrorStream()); 68 | Gson gson = new Gson(); 69 | Error error = gson.fromJson(reader, Error.class); 70 | msg = error.msg; 71 | } catch (JsonSyntaxException e) { 72 | msg = "IronMQ's response contained invalid JSON"; 73 | } finally { 74 | if (reader != null) 75 | reader.close(); 76 | } 77 | } else { 78 | msg = "Empty or non-JSON response"; 79 | } 80 | throw new HTTPException(status, msg); 81 | } else { 82 | throw new HTTPException(status, conn.getResponseMessage()); 83 | } 84 | } 85 | 86 | return new InputStreamReader(conn.getInputStream()); 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/Ids.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | public class Ids { 4 | private String[] ids; 5 | 6 | protected Ids() { 7 | } 8 | 9 | protected Ids(Messages messages) { 10 | Message[] source = messages.getMessages(); 11 | ids = new String[source.length]; 12 | for (int i = source.length - 1; i >= 0; i--) { 13 | ids[i] = source[i].getId(); 14 | } 15 | } 16 | 17 | public String getId(int i) { 18 | return ids[i]; 19 | } 20 | 21 | public int getSize(){ 22 | return ids.length; 23 | } 24 | 25 | public String[] getIds() { 26 | return ids; 27 | } 28 | 29 | public MessageOptions[] toMessageOptions() { 30 | int length = ids.length; 31 | MessageOptions[] result = new MessageOptions[length]; 32 | for (int i = 0; i < length; i++) 33 | result[i] = new MessageOptions(ids[i], (String)null); 34 | return result; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/IronReader.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import java.io.IOException; 4 | import java.io.Reader; 5 | import java.net.HttpURLConnection; 6 | 7 | /** 8 | * Created by tom on 10/5/14. 9 | */ 10 | public class IronReader { 11 | Reader reader; 12 | HttpURLConnection connection; 13 | 14 | protected IronReader(Reader reader, HttpURLConnection connection) { 15 | this.reader = reader; 16 | this.connection = connection; 17 | } 18 | 19 | public void close(){ 20 | try { 21 | try { 22 | reader.close(); 23 | } catch (IOException e) { 24 | 25 | } 26 | connection.disconnect(); 27 | } catch (Exception e) { 28 | 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/IronTokenContainer.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | public class IronTokenContainer implements TokenContainer { 4 | String token; 5 | 6 | public IronTokenContainer(String token) { 7 | this.token = token; 8 | } 9 | 10 | public String getToken() { 11 | return token; 12 | } 13 | 14 | public void setToken(String token) { 15 | this.token = token; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/Message.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import java.io.Serializable; 4 | 5 | import com.google.gson.annotations.SerializedName; 6 | 7 | /** 8 | * The Message class represents a message retrieved from an IronMQ queue. 9 | */ 10 | public class Message extends MessageOptions implements Serializable { 11 | private String body; 12 | // Long, not long, so that it's nullable. Gson doesn't serialize null, 13 | // so we can use the default on the server and not have to know about 14 | // it. 15 | @SerializedName("expires_in") private Long expiresIn; 16 | @SerializedName("reserved_count") private long reservedCount; 17 | 18 | public Message() {} 19 | 20 | /** 21 | * Returns the Message's body contents. 22 | */ 23 | public String getBody() { return body; } 24 | 25 | /** 26 | * Sets the Message's body contents. 27 | * 28 | * @param body The new body contents. 29 | */ 30 | public void setBody(String body) { this.body = body; } 31 | 32 | /** 33 | * Returns the number of times the message has been reserved. 34 | */ 35 | public long getReservedCount() { return reservedCount; } 36 | 37 | /** 38 | * Returns the number of seconds in which the Message will be removed from the 39 | * queue. If the server default of 7 days will be used, 0 is returned. 40 | */ 41 | public long getExpiresIn() { 42 | if (this.expiresIn == null) { 43 | return 0; 44 | } 45 | return this.expiresIn.longValue(); 46 | } 47 | 48 | /** 49 | * Sets the number of seconds in which the Message will be removed from the 50 | * queue. 51 | * 52 | * @param expiresIn The new expiration offset in seconds. A value less than 53 | * or equal to 0 will cause the server default of 7 days to be used. 54 | */ 55 | public void setExpiresIn(long expiresIn) { 56 | if (expiresIn > 0) { 57 | this.expiresIn = Long.valueOf(expiresIn); 58 | } else { 59 | this.expiresIn = null; 60 | } 61 | } 62 | 63 | /** 64 | * Returns a string representation of the Message. 65 | */ 66 | public String toString() { return body; } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/MessageContainer.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | public class MessageContainer { 4 | private Message message; 5 | 6 | public MessageContainer(Message message) { 7 | this.message = message; 8 | } 9 | 10 | public Message getMessage() { 11 | return message; 12 | } 13 | 14 | public void setMessage(Message message) { 15 | this.message = message; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/MessageOptions.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * The Message class represents a message retrieved from an IronMQ queue. 9 | */ 10 | public class MessageOptions implements Serializable { 11 | protected String id; 12 | protected Long delay; 13 | private Long timeout; 14 | 15 | @SerializedName("reservation_id") 16 | protected String reservationId; 17 | 18 | public MessageOptions() { 19 | } 20 | 21 | public MessageOptions(String reservationId) { 22 | this.reservationId = reservationId; 23 | } 24 | 25 | public MessageOptions(String reservationId, Long delay) { 26 | this.delay = delay; 27 | this.reservationId = reservationId; 28 | } 29 | 30 | public MessageOptions(String id, String reservationId) { 31 | this.id = id; 32 | this.reservationId = reservationId; 33 | } 34 | 35 | public MessageOptions(String id, String reservationId, Long timeout) { 36 | this.id = id; 37 | this.reservationId = reservationId; 38 | this.timeout = timeout; 39 | } 40 | 41 | /** 42 | * Returns Id of the Message. 43 | */ 44 | public String getId() { 45 | return id; 46 | } 47 | 48 | /** 49 | * Returns reservation Id of the Message. 50 | */ 51 | public String getReservationId() { 52 | return reservationId; 53 | } 54 | 55 | /** 56 | * Returns the number of seconds after which the Message will be available. 57 | */ 58 | public long getDelay() { return delay; } 59 | 60 | /** 61 | * Returns the Message's timeout. 62 | */ 63 | public long getTimeout() { return timeout; } 64 | 65 | /** 66 | * Sets Id to the Message. 67 | * 68 | * @param id The new Id. 69 | */ 70 | public void setId(String id) { 71 | this.id = id; 72 | } 73 | 74 | /** 75 | * Sets reservation Id to the Message. 76 | * 77 | * @param reservationId Reservation Id of the Message. 78 | */ 79 | public void setReservationId(String reservationId) { 80 | this.reservationId = reservationId; 81 | } 82 | 83 | /** 84 | * Sets the number of seconds after which the Message will be available. 85 | * 86 | * @param delay The new delay. 87 | */ 88 | public void setDelay(long delay) { this.delay = delay; } 89 | 90 | /** 91 | * Sets the Message's timeout. 92 | * 93 | * @param timeout The new timeout. 94 | */ 95 | public void setTimeout(long timeout) { this.timeout = timeout; } 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/MessagePushModel.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | public class MessagePushModel { 4 | private int retries_delay; 5 | private int retries_remaining; 6 | private int status_code; 7 | private String status; 8 | private String url; 9 | private String id; 10 | 11 | public MessagePushModel(int retries_delay, int retries_remaining, int status_code, String status, String url, String id) { 12 | this.retries_delay = retries_delay; 13 | this.retries_remaining = retries_remaining; 14 | this.status_code = status_code; 15 | this.status = status; 16 | this.url = url; 17 | this.id = id; 18 | } 19 | 20 | public int getRetries_delay() { 21 | return retries_delay; 22 | } 23 | 24 | public void setRetries_delay(int retries_delay) { 25 | this.retries_delay = retries_delay; 26 | } 27 | 28 | public int getRetries_remaining() { 29 | return retries_remaining; 30 | } 31 | 32 | public void setRetries_remaining(int retries_remaining) { 33 | this.retries_remaining = retries_remaining; 34 | } 35 | 36 | public int getStatus_code() { 37 | return status_code; 38 | } 39 | 40 | public void setStatus_code(int status_code) { 41 | this.status_code = status_code; 42 | } 43 | 44 | public String getStatus() { 45 | return status; 46 | } 47 | 48 | public void setStatus(String status) { 49 | this.status = status; 50 | } 51 | 52 | public String getUrl() { 53 | return url; 54 | } 55 | 56 | public void setUrl(String url) { 57 | this.url = url; 58 | } 59 | 60 | public String getId() { 61 | return id; 62 | } 63 | 64 | public void setId(String id) { 65 | this.id = id; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/Messages.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | 6 | public class Messages { 7 | private ArrayList messages; 8 | 9 | public Messages(Message... msgs) { 10 | messages = new ArrayList(Arrays.asList(msgs)); 11 | } 12 | 13 | public Messages(ArrayList msgs) { 14 | messages = new ArrayList(msgs); 15 | } 16 | 17 | public Message getMessage(int i) { 18 | return messages.get(i); 19 | } 20 | 21 | public Message[] getMessages() { 22 | return messages.toArray(new Message[messages.size()]); 23 | } 24 | 25 | public int getSize() { 26 | return messages.size(); 27 | } 28 | 29 | public boolean add(Message m) { 30 | return messages.add(m); 31 | } 32 | 33 | public MessageOptions[] toMessageOptions() { 34 | int length = messages.size(); 35 | MessageOptions[] result = new MessageOptions[length]; 36 | for (int i = 0; i < length; i++) 37 | result[i] = new MessageOptions(messages.get(i).getId(), messages.get(i).getReservationId()); 38 | return result; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/MessagesArrayList.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class MessagesArrayList { 6 | private ArrayList messages; 7 | 8 | public MessagesArrayList(ArrayList messageArrayList) { 9 | this.messages = messageArrayList; 10 | } 11 | 12 | public Message getMessage(int i) { 13 | return messages.get(i); 14 | } 15 | 16 | public ArrayList getMessages() { 17 | return messages; 18 | } 19 | 20 | public int getSize() { 21 | return messages.size(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/MessagesOptions.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | import java.io.Serializable; 6 | 7 | public class MessagesOptions implements Serializable { 8 | private MessageOptions[] ids; 9 | 10 | public MessagesOptions(MessageOptions[] messages) { 11 | this.ids = messages; 12 | } 13 | 14 | public MessageOptions[] getMessages() { 15 | return ids; 16 | } 17 | 18 | public MessageOptions getMessage(int index) { 19 | return ids[index]; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/MessagesReservationModel.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class MessagesReservationModel { 6 | private Integer n; 7 | private Integer timeout; 8 | private Integer wait; 9 | 10 | public MessagesReservationModel(int n, int timeout) { 11 | this.setN(n); 12 | this.setTimeout(timeout); 13 | } 14 | 15 | public MessagesReservationModel(int n, int timeout, int wait) { 16 | this.setN(n); 17 | this.setTimeout(timeout); 18 | this.setWait(wait); 19 | } 20 | 21 | public int getN() { 22 | return n; 23 | } 24 | 25 | public void setN(int n) { 26 | this.n = n >= 1 ? n : null; 27 | } 28 | 29 | public int getTimeout() { 30 | return timeout; 31 | } 32 | 33 | public void setTimeout(int timeout) { 34 | this.timeout = timeout >= 0 ? timeout : null; 35 | } 36 | 37 | public Integer getWait() { 38 | return wait; 39 | } 40 | 41 | public void setWait(Integer wait) { 42 | this.wait = wait > 0 && wait <= 30 ? wait : null; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/Queue.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import java.io.IOException; 4 | import java.io.Reader; 5 | import java.util.ArrayList; 6 | 7 | import com.google.gson.Gson; 8 | 9 | /** 10 | * The Queue class represents a specific IronMQ queue bound to a client. 11 | */ 12 | public class Queue { 13 | final private Client client; 14 | final private String name; 15 | 16 | static final private Gson gson = new Gson(); 17 | 18 | public Queue(Client client, String name) { 19 | if (name == null) 20 | throw new NullPointerException("Queue name cannot be null"); 21 | this.client = client; 22 | this.name = name; 23 | } 24 | 25 | /** 26 | * Retrieves a Message from the queue and reserves it. If there are no items on the queue, an 27 | * EmptyQueueException is thrown. 28 | * 29 | * @throws io.iron.ironmq.EmptyQueueException If the queue is empty. 30 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 31 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 32 | * @deprecated Use Queue.reserve() instead 33 | */ 34 | @Deprecated 35 | public Message get() throws IOException { 36 | return reserve(); 37 | } 38 | 39 | /** 40 | * Retrieves a Message from the queue and reserves it. If there are no items on the queue, an 41 | * EmptyQueueException is thrown. 42 | * 43 | * @throws io.iron.ironmq.EmptyQueueException If the queue is empty. 44 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 45 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 46 | */ 47 | public Message reserve() throws IOException { 48 | Messages msgs = reserve(1); 49 | Message msg; 50 | try { 51 | msg = msgs.getMessage(0); 52 | } catch (IndexOutOfBoundsException e) { 53 | throw new EmptyQueueException(); 54 | } 55 | 56 | return msg; 57 | } 58 | 59 | /** 60 | * Retrieves Messages from the queue and reserves it. If there are no items on the queue, an 61 | * EmptyQueueException is thrown. 62 | * @param numberOfMessages The number of messages to receive. Max. is 100. 63 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 64 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 65 | * @deprecated Use Queue.reserve(int) instead 66 | */ 67 | @Deprecated 68 | public Messages get(int numberOfMessages) throws IOException { 69 | return reserve(numberOfMessages); 70 | } 71 | 72 | /** 73 | * Retrieves Messages from the queue and reserves it. If there are no items on the queue, an 74 | * EmptyQueueException is thrown. 75 | * @param numberOfMessages The number of messages to receive. Max. is 100. 76 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 77 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 78 | */ 79 | public Messages reserve(int numberOfMessages) throws IOException { 80 | return reserve(numberOfMessages, -1); 81 | } 82 | 83 | /** 84 | * Retrieves Messages from the queue and reserves it. If there are no items on the queue, an 85 | * EmptyQueueException is thrown. 86 | * @param numberOfMessages The number of messages to receive. Max. is 100. 87 | * @param timeout timeout in seconds. 88 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 89 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 90 | * @deprecated Use Queue.reserve(int, int) instead 91 | */ 92 | @Deprecated 93 | public Messages get(int numberOfMessages, int timeout) throws IOException { 94 | return reserve(numberOfMessages, timeout); 95 | } 96 | 97 | /** 98 | * Retrieves Messages from the queue and reserves it. If there are no items on the queue, an 99 | * EmptyQueueException is thrown. 100 | * @param numberOfMessages The number of messages to receive. Max. is 100. 101 | * @param timeout timeout in seconds. 102 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 103 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 104 | */ 105 | public Messages reserve(int numberOfMessages, int timeout) throws IOException { 106 | return reserve(numberOfMessages, timeout, 0); 107 | } 108 | 109 | /** 110 | * Retrieves Messages from the queue and reserves it. If there are no items on the queue, an 111 | * EmptyQueueException is thrown. 112 | * @param numberOfMessages The number of messages to receive. Max. is 100. 113 | * @param timeout timeout in seconds. 114 | * @param wait Time to long poll for messages, in seconds. Max is 30 seconds. Default 0. 115 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 116 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 117 | */ 118 | public Messages reserve(int numberOfMessages, int timeout, int wait) throws IOException { 119 | if (numberOfMessages < 1 || numberOfMessages > 100) { 120 | throw new IllegalArgumentException("numberOfMessages has to be within 1..100"); 121 | } 122 | 123 | MessagesReservationModel payload = new MessagesReservationModel(numberOfMessages, timeout, wait); 124 | String url = "queues/" + name + "/reservations"; 125 | IronReader reader = client.post(url, gson.toJson(payload)); 126 | Messages messages = gson.fromJson(reader.reader, Messages.class); 127 | reader.close(); 128 | return messages; 129 | } 130 | 131 | /** 132 | * Peeking at a queue returns the next messages on the queue, but it does not reserve them. 133 | * If there are no items on the queue, an EmptyQueueException is thrown. 134 | * 135 | * @throws io.iron.ironmq.EmptyQueueException If the queue is empty. 136 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 137 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 138 | */ 139 | public Message peek() throws IOException { 140 | Messages msgs = peek(1); 141 | Message msg; 142 | try { 143 | msg = msgs.getMessage(0); 144 | } catch (IndexOutOfBoundsException e) { 145 | throw new EmptyQueueException(); 146 | } 147 | 148 | return msg; 149 | } 150 | 151 | /** 152 | * Peeking at a queue returns the next messages on the queue, but it does not reserve them. 153 | * 154 | * @param numberOfMessages The maximum number of messages to peek. Default is 1. Maximum is 100. Note: You may not 155 | * receive all n messages on every request, the more sparse the queue, the less likely 156 | * you are to receive all n messages. 157 | * @throws io.iron.ironmq.EmptyQueueException If the queue is empty. 158 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 159 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 160 | */ 161 | public Messages peek(int numberOfMessages) throws IOException { 162 | if (numberOfMessages < 1 || numberOfMessages > 100) { 163 | throw new IllegalArgumentException("numberOfMessages has to be within 1..100"); 164 | } 165 | IronReader reader = client.get("queues/" + name + "/messages?n=" + numberOfMessages); 166 | try { 167 | return gson.fromJson(reader.reader, Messages.class); 168 | } finally { 169 | reader.close(); 170 | } 171 | } 172 | 173 | /** 174 | * Touching a reserved message extends its timeout to the duration specified when the message was created. 175 | * 176 | * @param message The message to delete. 177 | * 178 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 179 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 180 | */ 181 | public MessageOptions touchMessage(Message message) throws IOException { 182 | return touchMessage(message, null); 183 | } 184 | 185 | /** 186 | * Touching a reserved message extends its timeout to the specified duration. 187 | * 188 | * @param message The message to delete. 189 | * @param timeout After timeout (in seconds), item will be placed back onto queue. 190 | * 191 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 192 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 193 | */ 194 | public MessageOptions touchMessage(Message message, int timeout) throws IOException { 195 | return touchMessage(message, (long) timeout); 196 | } 197 | 198 | /** 199 | * Touching a reserved message extends its timeout to the duration specified when the message was created. 200 | * 201 | * @param message The message to delete. 202 | * @param timeout After timeout (in seconds), item will be placed back onto queue. 203 | * 204 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 205 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 206 | */ 207 | public MessageOptions touchMessage(Message message, Long timeout) throws IOException { 208 | MessageOptions messageOptions = touchMessage(message.getId(), message.getReservationId(), timeout); 209 | message.setReservationId(messageOptions.getReservationId()); 210 | return messageOptions; 211 | } 212 | 213 | /** 214 | * Touching a reserved message extends its timeout to the duration specified when the message was created. 215 | * 216 | * @param id The ID of the message to delete. 217 | * @param reservationId This id is returned when you reserve a message and must be provided to delete a message that is reserved. 218 | * 219 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 220 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 221 | */ 222 | public MessageOptions touchMessage(String id, String reservationId) throws IOException { 223 | return touchMessage(id, reservationId, null); 224 | } 225 | 226 | /** 227 | * Touching a reserved message extends its timeout to the specified duration. 228 | * 229 | * @param id The ID of the message to delete. 230 | * @param reservationId This id is returned when you reserve a message and must be provided to delete a message that is reserved. 231 | * @param timeout After timeout (in seconds), item will be placed back onto queue. 232 | * 233 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 234 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 235 | */ 236 | public MessageOptions touchMessage(String id, String reservationId, int timeout) throws IOException { 237 | return touchMessage(id, reservationId, (long) timeout); 238 | } 239 | 240 | /** 241 | * Touching a reserved message extends its timeout to the duration specified when the message was created. 242 | * 243 | * @param id The ID of the message to delete. 244 | * @param reservationId This id is returned when you reserve a message and must be provided to delete a message that is reserved. 245 | * @param timeout After timeout (in seconds), item will be placed back onto queue. 246 | * 247 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 248 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 249 | */ 250 | public MessageOptions touchMessage(String id, String reservationId, Long timeout) throws IOException { 251 | String payload = gson.toJson(new MessageOptions(null, reservationId, timeout)); 252 | IronReader reader = client.post("queues/" + name + "/messages/" + id + "/touch", payload); 253 | try { 254 | return gson.fromJson(reader.reader, MessageOptions.class); 255 | } finally { 256 | reader.close(); 257 | } 258 | } 259 | 260 | /** 261 | * Deletes a Message from the queue. 262 | * 263 | * @param id The ID of the message to delete. 264 | * 265 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 266 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 267 | */ 268 | public void deleteMessage(String id) throws IOException { 269 | deleteMessage(id, null); 270 | } 271 | 272 | /** 273 | * Deletes a Message from the queue. 274 | * 275 | * @param id The ID of the message to delete. 276 | * @param reservationId Reservation Id of the message. Reserved message could not be deleted without reservation Id. 277 | * 278 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 279 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 280 | */ 281 | public void deleteMessage(String id, String reservationId) throws IOException { 282 | deleteMessage(id, reservationId, null); 283 | } 284 | 285 | /** 286 | * Deletes a Message from the queue. 287 | * 288 | * @param id The ID of the message to delete. 289 | * @param reservationId Reservation Id of the message. Reserved message could not be deleted without reservation Id. 290 | * 291 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 292 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 293 | */ 294 | public void deleteMessage(String id, String reservationId, String subscriberName) throws IOException { 295 | String payload = gson.toJson(new SubscribedMessageOptions(reservationId, subscriberName)); 296 | IronReader reader = client.delete("queues/" + name + "/messages/" + id, payload); 297 | reader.close(); 298 | } 299 | 300 | /** 301 | * Deletes multiple messages from the queue. 302 | * 303 | * @param ids The IDs of the messages to delete. 304 | * 305 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 306 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 307 | */ 308 | public void deleteMessages(Ids ids) throws IOException { 309 | deleteMessages(ids.toMessageOptions()); 310 | } 311 | 312 | /** 313 | * Deletes multiple messages from the queue. 314 | * 315 | * @param messages The list of the messages to delete. 316 | * 317 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 318 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 319 | */ 320 | public void deleteMessages(Messages messages) throws IOException { 321 | deleteMessages(messages.toMessageOptions()); 322 | } 323 | 324 | private void deleteMessages(MessageOptions[] messages) throws IOException { 325 | String payload = gson.toJson(new MessagesOptions(messages)); 326 | IronReader reader = client.delete("queues/" + name + "/messages", payload); 327 | reader.close(); 328 | } 329 | 330 | /** 331 | * Destroy the queue. 332 | * 333 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 334 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 335 | */ 336 | public void destroy() throws IOException { 337 | IronReader reader = client.delete("queues/" + name); 338 | reader.close(); 339 | } 340 | 341 | /** 342 | * Deletes a Message from the queue. 343 | * 344 | * @param msg The message to delete. 345 | * 346 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 347 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 348 | */ 349 | public void deleteMessage(Message msg) throws IOException { 350 | deleteMessage(msg.getId(), msg.getReservationId()); 351 | } 352 | 353 | /** 354 | * Pushes a message onto the queue. 355 | * 356 | * @param msg The body of the message to push. 357 | * @return The new message's ID 358 | * 359 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 360 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 361 | */ 362 | public String push(String msg) throws IOException { 363 | return push(msg, 0); 364 | } 365 | 366 | /** 367 | * Pushes a messages onto the queue. 368 | * 369 | * @param msg The array of the messages to push. 370 | * @return The IDs of new messages 371 | * 372 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 373 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 374 | */ 375 | public Ids pushMessages(String[] msg) throws IOException { 376 | return pushMessages(msg, 0); 377 | } 378 | 379 | /** 380 | * Pushes a message onto the queue. 381 | * 382 | * @param msg The body of the message to push. 383 | * @param delay The message's delay in seconds. 384 | * @return The new message's ID 385 | * 386 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 387 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 388 | */ 389 | public String push(String msg, long delay) throws IOException { 390 | Message message = new Message(); 391 | message.setBody(msg); 392 | message.setDelay(delay); 393 | 394 | Messages msgs = new Messages(message); 395 | 396 | IronReader reader = client.post("queues/" + name + "/messages", msgs); 397 | Ids ids = gson.fromJson(reader.reader, Ids.class); 398 | reader.close(); 399 | return ids.getId(0); 400 | } 401 | 402 | /** 403 | * Pushes a messages onto the queue. 404 | * 405 | * @param msg The array of the messages to push. 406 | * @param delay The message's delay in seconds. 407 | * @return The IDs of new messages 408 | * 409 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 410 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 411 | */ 412 | public Ids pushMessages(String[] msg, long delay) throws IOException { 413 | ArrayList messages = new ArrayList(); 414 | for (String messageName: msg){ 415 | Message message = new Message(); 416 | message.setBody(messageName); 417 | message.setDelay(delay); 418 | messages.add(message); 419 | } 420 | 421 | MessagesArrayList msgs = new MessagesArrayList(messages); 422 | 423 | IronReader reader = client.post("queues/" + name + "/messages", msgs); 424 | Ids ids = gson.fromJson(reader.reader, Ids.class); 425 | reader.close(); 426 | return ids; 427 | } 428 | 429 | /** 430 | * Clears the queue off all messages 431 | * @throws java.io.IOException 432 | */ 433 | public void clear() throws IOException { 434 | IronReader reader = client.delete("queues/" + name + "/messages", "{}"); 435 | reader.close(); 436 | } 437 | 438 | /** 439 | * @return the name of this queue 440 | */ 441 | public String getName() { 442 | return name; 443 | } 444 | 445 | /** 446 | * Retrieves Info about queue. If there is no queue, an EmptyQueueException is thrown. 447 | * @throws io.iron.ironmq.EmptyQueueException If there is no queue. 448 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 449 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 450 | */ 451 | public QueueModel getInfoAboutQueue() throws IOException { 452 | IronReader reader = client.get("queues/" + name); 453 | QueueContainer queueContainer = gson.fromJson(reader.reader, QueueContainer.class); 454 | reader.close(); 455 | return queueContainer.getQueue(); 456 | } 457 | 458 | /** 459 | * Retrieves Message from the queue by message id. If there are no items on the queue, an 460 | * EmptyQueueException is thrown. 461 | * @param id The ID of the message to get. 462 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 463 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 464 | */ 465 | public Message getMessageById(String id) throws IOException { 466 | String url = "queues/" + name + "/messages/" + id; 467 | IronReader reader = client.get(url); 468 | MessageContainer container = gson.fromJson(reader.reader, MessageContainer.class); 469 | reader.close(); 470 | return container.getMessage(); 471 | } 472 | 473 | static class Delay { 474 | private int delay; 475 | public Delay(int delay) { 476 | this.delay = delay; 477 | } 478 | } 479 | 480 | /** 481 | * Release reserved message after specified time. If there is no message with such id on the queue, an 482 | * EmptyQueueException is thrown. 483 | * 484 | * @param message The message to release. 485 | * 486 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 487 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 488 | */ 489 | public void releaseMessage(Message message) throws IOException { 490 | releaseMessage(message.getId(), message.getReservationId(), null); 491 | } 492 | 493 | /** 494 | * Release reserved message after specified time. If there is no message with such id on the queue, an 495 | * EmptyQueueException is thrown. 496 | * 497 | * @param message The message to release. 498 | * @param delay The time after which the message will be released. 499 | * 500 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 501 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 502 | */ 503 | public void releaseMessage(Message message, int delay) throws IOException { 504 | releaseMessage(message.getId(), message.getReservationId(), new Long(delay)); 505 | } 506 | 507 | /** 508 | * Release reserved message after specified time. If there is no message with such id on the queue, an 509 | * EmptyQueueException is thrown. 510 | * 511 | * @param id The ID of the message to release. 512 | * @param delay The time after which the message will be released. 513 | * 514 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 515 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 516 | */ 517 | public void releaseMessage(String id, String reservationId, Long delay) throws IOException { 518 | String url = "queues/" + name + "/messages/" + id + "/release"; 519 | String payload = gson.toJson(new MessageOptions(reservationId, delay)); 520 | IronReader reader = client.post(url, payload); 521 | reader.close(); 522 | } 523 | 524 | /** 525 | * Add subscribers to Queue. If there is no queue, an EmptyQueueException is thrown. 526 | * @param subscribersList The array list of subscribers. 527 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 528 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 529 | */ 530 | public void addSubscribers(ArrayList subscribersList) throws IOException { 531 | addSubscribers(new Subscribers(subscribersList)); 532 | } 533 | 534 | /** 535 | * Add subscribers to Queue. If there is no queue, an EmptyQueueException is thrown. 536 | * @param subscribers The array of subscribers. 537 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 538 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 539 | */ 540 | public void addSubscribers(Subscriber[] subscribers) throws IOException { 541 | addSubscribers(new Subscribers(subscribers)); 542 | } 543 | 544 | /** 545 | * Add subscribers to Queue. If there is no queue, an EmptyQueueException is thrown. 546 | * @param subscribers The array of subscribers. 547 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 548 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 549 | */ 550 | public void addSubscribers(Subscribers subscribers) throws IOException { 551 | String payload = gson.toJson(subscribers); 552 | IronReader reader = client.post("queues/" + name + "/subscribers", payload); 553 | reader.close(); 554 | } 555 | 556 | /** 557 | * Update old or add new subscribers to Queue. If there is no queue, an EmptyQueueException is thrown. 558 | * @param subscribersList The array list of subscribers. 559 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 560 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 561 | */ 562 | public void updateSubscribers(ArrayList subscribersList) throws IOException { 563 | addSubscribers(subscribersList); 564 | } 565 | 566 | /** 567 | * Update old or add new subscribers to Queue. If there is no queue, an EmptyQueueException is thrown. 568 | * @param subscribers The array of subscribers. 569 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 570 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 571 | */ 572 | public void updateSubscribers(Subscriber[] subscribers) throws IOException { 573 | addSubscribers(subscribers); 574 | } 575 | 576 | /** 577 | * Update old or add new subscribers to Queue. If there is no queue, an EmptyQueueException is thrown. 578 | * @param subscribers The array of subscribers. 579 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 580 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 581 | */ 582 | public void updateSubscribers(Subscribers subscribers) throws IOException { 583 | addSubscribers(subscribers); 584 | } 585 | 586 | /** 587 | * Sets list of subscribers to a queue. Older subscribers will be removed. 588 | * If there is no queue, an EmptyQueueException is thrown. 589 | * @param subscribersList The array list of subscribers. 590 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 591 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 592 | */ 593 | public void replaceSubscribers(ArrayList subscribersList) throws IOException { 594 | replaceSubscribers(new Subscribers(subscribersList)); 595 | } 596 | 597 | /** 598 | * Sets list of subscribers to a queue. Older subscribers will be removed. 599 | * If there is no queue, an EmptyQueueException is thrown. 600 | * @param subscribers The array of subscribers. 601 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 602 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 603 | */ 604 | public void replaceSubscribers(Subscriber[] subscribers) throws IOException { 605 | replaceSubscribers(new Subscribers(subscribers)); 606 | } 607 | 608 | /** 609 | * Sets list of subscribers to a queue. Older subscribers will be removed. 610 | * If there is no queue, an EmptyQueueException is thrown. 611 | * @param subscribers The array of subscribers. 612 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 613 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 614 | */ 615 | public void replaceSubscribers(Subscribers subscribers) throws IOException { 616 | String payload = gson.toJson(subscribers); 617 | IronReader reader = client.put("queues/" + name + "/subscribers", payload); 618 | reader.close(); 619 | } 620 | 621 | /** 622 | * Remove subscribers from Queue. If there is no queue, an EmptyQueueException is thrown. 623 | * @param subscribersList The array list of subscribers. 624 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 625 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 626 | */ 627 | public void removeSubscribers(ArrayList subscribersList) throws IOException { 628 | removeSubscribers(new Subscribers(subscribersList)); 629 | } 630 | 631 | /** 632 | * Remove subscribers from Queue. If there is no queue, an EmptyQueueException is thrown. 633 | * @param subscribers The array list of subscribers. 634 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 635 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 636 | */ 637 | public void removeSubscribers(Subscriber[] subscribers) throws IOException { 638 | removeSubscribers(new Subscribers(subscribers)); 639 | } 640 | 641 | /** 642 | * Remove subscribers from Queue. If there is no queue, an EmptyQueueException is thrown. 643 | * @param subscribers The array list of subscribers. 644 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 645 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 646 | */ 647 | public void removeSubscribers(Subscribers subscribers) throws IOException { 648 | String url = "queues/" + name + "/subscribers"; 649 | String jsonMessages = gson.toJson(subscribers); 650 | IronReader reader = client.delete(url, jsonMessages); 651 | reader.close(); 652 | } 653 | 654 | /** 655 | * Get push info of message by message id. If there is no message, an EmptyQueueException is thrown. 656 | * @param messageId The Message ID. 657 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 658 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 659 | */ 660 | public SubscribersInfo getPushStatusForMessage(String messageId) throws IOException { 661 | String url = "queues/" + name + "/messages/" + messageId + "/subscribers"; 662 | IronReader reader = client.get(url); 663 | SubscribersInfo subscribersInfo = gson.fromJson(reader.reader, SubscribersInfo.class); 664 | reader.close(); 665 | return subscribersInfo; 666 | } 667 | 668 | /** 669 | * Delete push message for subscriber by subscriber ID and message ID. If there is no message or subscriber, 670 | * an EmptyQueueException is thrown. 671 | * @param subscriberName The name of Subscriber. 672 | * @param messageId The Message ID. 673 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 674 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 675 | */ 676 | public void deletePushMessageForSubscriber(String messageId, String reservationId, String subscriberName) throws IOException { 677 | deleteMessage(messageId, reservationId, subscriberName); 678 | } 679 | 680 | /** 681 | * Creates a queue for specified queue client. 682 | * If queue exists, it will be updated. 683 | */ 684 | public QueueModel create() throws IOException { 685 | String url = "queues/" + name; 686 | IronReader reader = client.put(url, "{}"); 687 | QueueContainer container = gson.fromJson(reader.reader, QueueContainer.class); 688 | reader.close(); 689 | return container.getQueue(); 690 | } 691 | 692 | /** 693 | * Creates a queue for specified queue client. 694 | * If queue exists, it will be updated. 695 | * @param subscribersList The subscribers list. 696 | * @param alertsList The alerts list. 697 | * @param pushType The push type - multicast or unicast. 698 | * @param errorQueue The name of the error queue to use (can be null) 699 | * @param retries The retries. 700 | * @param retriesDelay The retries delay. 701 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 702 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 703 | */ 704 | public QueueModel create(ArrayList subscribersList, ArrayList alertsList, String pushType, String errorQueue, int retries, int retriesDelay) throws IOException { 705 | QueueModel model = new QueueModel(); 706 | model.setPushInfo(new QueuePushModel(subscribersList, retries, retriesDelay, errorQueue)); 707 | model.setAlerts(alertsList); 708 | model.setType(pushType); 709 | return create(model); 710 | } 711 | 712 | /** 713 | * Creates a queue for specified queue client. 714 | * If queue exists, it will be updated. 715 | * @param subscribersList The subscribers list. 716 | * @param alertsList The alerts list. 717 | * @param pushType The push type - multicast or unicast. 718 | * @param retries The retries. 719 | * @param retriesDelay The retries delay. 720 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 721 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 722 | */ 723 | public QueueModel create(ArrayList subscribersList, ArrayList alertsList, String pushType, int retries, int retriesDelay) throws IOException { 724 | return create(subscribersList, alertsList, pushType, "", retries, retriesDelay); 725 | } 726 | 727 | /** 728 | * Creates a queue for specified queue client. 729 | * If queue exists, it will be updated. 730 | * @param model QueueModel instance with desired parameters of queue 731 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 732 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 733 | */ 734 | public QueueModel create(QueueModel model) throws IOException { 735 | String url = "queues/" + name; 736 | QueueContainer payload = new QueueContainer(model); 737 | 738 | IronReader reader = client.put(url, gson.toJson(payload)); 739 | QueueContainer container = gson.fromJson(reader.reader, QueueContainer.class); 740 | reader.close(); 741 | return container.getQueue(); 742 | } 743 | 744 | /** 745 | * Update queue. If there is no queue, an EmptyQueueException is thrown. 746 | * @param subscribersList The subscribers list. 747 | * @param alertsList The alerts list. 748 | * @param pushType The push type - multicast or unicast. 749 | * @param errorQueue The name of the error queue to use (can be null) 750 | * @param retries The retries. 751 | * @param retriesDelay The retries delay. 752 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 753 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 754 | */ 755 | public QueueModel updateQueue(ArrayList subscribersList, ArrayList alertsList, String pushType, String errorQueue, int retries, int retriesDelay) throws IOException { 756 | QueueModel model = new QueueModel(); 757 | model.setPushInfo(new QueuePushModel(subscribersList, retries, retriesDelay, errorQueue)); 758 | model.setAlerts(alertsList); 759 | model.setType(pushType); 760 | return update(model); 761 | } 762 | 763 | /** 764 | * Update queue. If there is no queue, an EmptyQueueException is thrown. 765 | * @param subscribersList The subscribers list. 766 | * @param alertsList The alerts list. 767 | * @param pushType The push type - multicast or unicast. 768 | * @param retries The retries. 769 | * @param retriesDelay The retries delay. 770 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 771 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 772 | */ 773 | public QueueModel updateQueue(ArrayList subscribersList, ArrayList alertsList, String pushType, int retries, int retriesDelay) throws IOException { 774 | return updateQueue(subscribersList, alertsList, pushType, "", retries,retriesDelay); 775 | } 776 | 777 | public QueueModel update(QueueModel model) throws IOException { 778 | String url = "queues/" + name; 779 | QueueContainer payload = new QueueContainer(model); 780 | 781 | IronReader reader = client.patch(url, gson.toJson(payload)); 782 | QueueContainer container = gson.fromJson(reader.reader, QueueContainer.class); 783 | reader.close(); 784 | return container.getQueue(); 785 | } 786 | 787 | /** 788 | * Add alerts to a queue. If there is no queue, an EmptyQueueException is thrown. 789 | * @param alerts The array list of alerts. 790 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 791 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 792 | */ 793 | public QueueModel addAlertsToQueue(ArrayList alerts) throws IOException { 794 | return this.updateAlerts(alerts); 795 | } 796 | 797 | /** 798 | * Replace current queue alerts with a given list of alerts. If there is no queue, an EmptyQueueException is thrown. 799 | * @param alerts The array list of alerts. 800 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 801 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 802 | */ 803 | public QueueModel updateAlertsToQueue(ArrayList alerts) throws IOException { 804 | return this.updateAlerts(alerts); 805 | } 806 | 807 | /** 808 | * Replace current queue alerts with a given list of alerts. If there is no queue, an EmptyQueueException is thrown. 809 | * @param alerts The array list of alerts. 810 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 811 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 812 | */ 813 | public QueueModel updateAlerts(ArrayList alerts) throws IOException { 814 | QueueModel payload = new QueueModel(alerts); 815 | return this.update(payload); 816 | } 817 | 818 | /** 819 | * Delete alerts from a queue. If there is no queue, an EmptyQueueException is thrown. 820 | * @param alert_ids The array list of alert ids. 821 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 822 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 823 | */ 824 | public void deleteAlertsFromQueue(ArrayList alert_ids) throws IOException { 825 | String url = "queues/" + name + "/alerts"; 826 | Alerts alert = new Alerts(alert_ids); 827 | String jsonMessages = gson.toJson(alert); 828 | IronReader reader = client.delete(url, jsonMessages); 829 | reader.close(); 830 | } 831 | 832 | /** 833 | * Delete alert from a queue by alert id. If there is no queue, an EmptyQueueException is thrown. 834 | * @param alert_id The alert id. 835 | * @throws io.iron.ironmq.HTTPException If the IronMQ service returns a status other than 200 OK. 836 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 837 | */ 838 | public void deleteAlertFromQueueById(String alert_id) throws IOException { 839 | String url = "queues/" + name + "/alerts/" + alert_id; 840 | IronReader reader = client.delete(url); 841 | reader.close(); 842 | } 843 | } 844 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/QueueContainer.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | public class QueueContainer { 4 | private QueueModel queue; 5 | 6 | public QueueContainer() { 7 | } 8 | 9 | public QueueContainer(QueueModel queue) { 10 | this.queue = queue; 11 | } 12 | 13 | public QueueModel getQueue() { 14 | return queue; 15 | } 16 | 17 | public void setQueue(QueueModel queue) { 18 | this.queue = queue; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/QueueModel.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | import java.util.ArrayList; 6 | 7 | public class QueueModel { 8 | private String id; 9 | private String name; 10 | private String type; 11 | private Long size; 12 | private String project_id; 13 | private Long total_messages; 14 | private QueuePushModel push; 15 | private ArrayList alerts; 16 | @SerializedName("message_timeout") private Integer messageTimeout; 17 | @SerializedName("message_expiration") private Integer messageExpiration; 18 | 19 | public QueueModel(String id, String name, Integer size, Integer total_messages, String project_id, Integer retries, String pushType, Integer retriesDelay, String errorQueue, ArrayList subscribers, ArrayList alerts) { 20 | this.id = id; 21 | this.name = name; 22 | this.size = (long)size; 23 | this.total_messages = (long)total_messages; 24 | this.project_id = project_id; 25 | this.alerts = alerts; 26 | } 27 | 28 | public QueueModel(int messageExpiration, int retries, String pushType, int retries_delay, String error_queue, ArrayList subscribers, ArrayList alerts, int messageTimeout) { 29 | this.messageExpiration = messageExpiration; 30 | this.alerts = alerts; 31 | this.messageTimeout = messageTimeout; 32 | } 33 | 34 | public QueueModel(int messageTimeout, int messageExpiration) { 35 | this.messageTimeout = messageTimeout; 36 | this.messageExpiration = messageExpiration; 37 | } 38 | 39 | public QueueModel(ArrayList alerts) { 40 | this.alerts = alerts; 41 | } 42 | 43 | public QueueModel(QueuePushModel push) { 44 | this.push = push; 45 | } 46 | 47 | public QueueModel() { 48 | } 49 | 50 | public String getId() { 51 | return id; 52 | } 53 | 54 | public void setId(String id) { 55 | this.id = id; 56 | } 57 | 58 | public String getName() { 59 | return name; 60 | } 61 | 62 | public void setName(String name) { 63 | this.name = name; 64 | } 65 | 66 | /** 67 | * Returns the size of the queue. 68 | * 69 | * @deprecated Use getSizeLong() instead. 70 | */ 71 | @Deprecated 72 | public int getSize() { 73 | return (int)(long)size; 74 | } 75 | 76 | /** 77 | * Returns the size of the queue. 78 | */ 79 | public long getSizeLong() { 80 | return size; 81 | } 82 | 83 | public void setSize(int size) { 84 | this.size = (long)size; 85 | } 86 | 87 | /** 88 | * Returns total count of messages ever placed to the queue. 89 | * 90 | * @deprecated Use getTotalMessages() instead. 91 | */ 92 | @Deprecated 93 | public int getTotal_messages() { 94 | return (int)(long)total_messages; 95 | } 96 | 97 | /** 98 | * Returns total count of messages ever placed to the queue. 99 | * 100 | * @deprecated Use getTotalMessagesLong() instead. 101 | */ 102 | @Deprecated 103 | public int getTotalMessages() { 104 | return (int)(long)total_messages; 105 | } 106 | 107 | /** 108 | * Returns total count of messages ever placed to the queue. 109 | */ 110 | public long getTotalMessagesLong() { 111 | return total_messages; 112 | } 113 | 114 | @Deprecated 115 | public void setTotal_messages(int total_messages) { 116 | throw new UnsupportedOperationException(); 117 | } 118 | 119 | /** 120 | * Returns Id of a project, which owns the Queue. 121 | * 122 | * @deprecated Use getProjectId() instead. 123 | */ 124 | @Deprecated 125 | public String getProject_id() { 126 | return project_id; 127 | } 128 | 129 | /** 130 | * Returns Id of a project, which owns the Queue. 131 | */ 132 | public String getProjectId() { 133 | return project_id; 134 | } 135 | 136 | @Deprecated 137 | public void setProject_id(String project_id) { 138 | throw new UnsupportedOperationException(); 139 | } 140 | 141 | @Deprecated 142 | public int getRetries() { 143 | throw new UnsupportedOperationException(); 144 | } 145 | 146 | @Deprecated 147 | public void setRetries(int retries) { 148 | throw new UnsupportedOperationException(); 149 | } 150 | 151 | @Deprecated 152 | public String getPushType() { 153 | throw new UnsupportedOperationException(); 154 | } 155 | 156 | @Deprecated 157 | public void setPushType(String pushType) { 158 | throw new UnsupportedOperationException(); 159 | } 160 | 161 | @Deprecated 162 | public int getRetriesDelay() { 163 | throw new UnsupportedOperationException(); 164 | } 165 | 166 | @Deprecated 167 | public void setRetriesDelay(int retriesDelay) { 168 | throw new UnsupportedOperationException(); 169 | } 170 | 171 | @Deprecated 172 | public String getErrorQueue() { 173 | throw new UnsupportedOperationException(); 174 | } 175 | 176 | @Deprecated 177 | public void setErrorQueue(String errorQueue) { 178 | throw new UnsupportedOperationException(); 179 | } 180 | 181 | public ArrayList getSubscribers() { 182 | return getPushInfo().getSubscribers(); 183 | } 184 | 185 | @Deprecated 186 | public void setSubscribers(ArrayList subscribers) { 187 | throw new UnsupportedOperationException(); 188 | } 189 | 190 | public ArrayList getAlerts() { 191 | return alerts; 192 | } 193 | 194 | public void setAlerts(ArrayList alerts) { 195 | this.alerts = alerts; 196 | } 197 | 198 | public int getMessageTimeout() { 199 | return messageTimeout; 200 | } 201 | 202 | public void setMessageTimeout(int messageTimeout) { 203 | this.messageTimeout = messageTimeout; 204 | } 205 | 206 | public int getMessageExpiration() { 207 | return messageExpiration; 208 | } 209 | 210 | public void setMessageExpiration(int messageExpiration) { 211 | this.messageExpiration = messageExpiration; 212 | } 213 | 214 | public String getType() { 215 | return type; 216 | } 217 | 218 | public void setType(String type) { 219 | this.type = type; 220 | } 221 | 222 | public QueuePushModel getPushInfo() { 223 | return push; 224 | } 225 | 226 | public void setPushInfo(QueuePushModel push) { 227 | this.push = push; 228 | } 229 | 230 | public void addSubscriber(Subscriber subscriber) { 231 | synchronized (this) { 232 | if (push == null) { 233 | push = new QueuePushModel(); 234 | } 235 | } 236 | push.addSubscriber(subscriber); 237 | } 238 | 239 | public void addSubscribers(ArrayList subscribers) { 240 | synchronized (this) { 241 | if (push == null) { 242 | push = new QueuePushModel(); 243 | } 244 | } 245 | push.addSubscribers(subscribers); 246 | } 247 | } 248 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/QueuePushModel.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | import java.util.ArrayList; 6 | 7 | public class QueuePushModel { 8 | private ArrayList subscribers; 9 | private Integer retries; 10 | @SerializedName("retries_delay") private Integer retriesDelay; 11 | @SerializedName("error_queue") private String errorQueue; 12 | 13 | public QueuePushModel(ArrayList subscribers, Integer retries, Integer retriesDelay, String errorQueue) { 14 | this.subscribers = subscribers; 15 | this.retries = retries; 16 | this.retriesDelay = retriesDelay; 17 | this.errorQueue = errorQueue; 18 | } 19 | 20 | public QueuePushModel(ArrayList subscribers) { 21 | this(subscribers, null, null, null); 22 | } 23 | 24 | public QueuePushModel() { 25 | this(null, null, null, null); 26 | } 27 | 28 | public ArrayList getSubscribers() { 29 | return subscribers; 30 | } 31 | 32 | public void setSubscribers(ArrayList subscribers) { 33 | this.subscribers = subscribers; 34 | } 35 | 36 | public Integer getRetries() { 37 | return retries; 38 | } 39 | 40 | public void setRetries(Integer retries) { 41 | this.retries = retries; 42 | } 43 | 44 | public Integer getRetriesDelay() { 45 | return retriesDelay; 46 | } 47 | 48 | public void setRetriesDelay(Integer retriesDelay) { 49 | this.retriesDelay = retriesDelay; 50 | } 51 | 52 | public String getErrorQueue() { 53 | return errorQueue; 54 | } 55 | 56 | public void setErrorQueue(String errorQueue) { 57 | this.errorQueue = errorQueue; 58 | } 59 | 60 | public void addSubscriber(Subscriber subscriber) { 61 | synchronized (this) { 62 | if (subscribers == null) { 63 | subscribers = new ArrayList(); 64 | } 65 | } 66 | subscribers.add(subscriber); 67 | } 68 | 69 | public void addSubscribers(ArrayList subscribers) { 70 | synchronized (this) { 71 | if (subscribers == null) { 72 | subscribers = new ArrayList(); 73 | } 74 | } 75 | subscribers.addAll(subscribers); 76 | } 77 | 78 | public void removeSubscribers() { 79 | if (subscribers != null) { 80 | subscribers.clear(); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/Queues.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.reflect.TypeToken; 5 | 6 | import java.io.IOException; 7 | import java.io.Reader; 8 | import java.net.URLEncoder; 9 | import java.util.ArrayList; 10 | 11 | public class Queues { 12 | final private Client client; 13 | 14 | public Queues(Client client) { 15 | this.client = client; 16 | } 17 | 18 | /** 19 | * Retrieves queues in alphabetical order. 20 | 21 | * @throws HTTPException If the IronMQ service returns a status other than 200 OK. 22 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 23 | * @deprecated Deprecated because of two reasons: It doesn't retrieve all queues and Queues.getQueues is more preferable. 24 | */ 25 | @Deprecated 26 | public ArrayList getAllQueues() throws IOException { 27 | return getQueues(this.client); 28 | } 29 | 30 | /** 31 | * Retrieves queues in alphabetical order. 32 | 33 | * @throws HTTPException If the IronMQ service returns a status other than 200 OK. 34 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 35 | */ 36 | public static ArrayList getQueues(Client client) throws IOException { 37 | return getQueues(client, null, null, null); 38 | } 39 | 40 | /** 41 | * Retrieves queues in alphabetical order. 42 | * 43 | * @param perPage number of elements in response, default for IronMQ is 30 44 | * 45 | * @throws HTTPException If the IronMQ service returns a status other than 200 OK. 46 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 47 | */ 48 | public static ArrayList getQueues(Client client, int perPage) throws IOException { 49 | return getQueues(client, null, perPage, null); 50 | } 51 | 52 | /** 53 | * Retrieves queues in alphabetical order. 54 | * 55 | * @param previousQueueName this is the last queue on the previous page, it will start from the next one. 56 | * If queue with specified name doesn't exist result will contain first per_page queues 57 | * that lexicographically greater than previous 58 | * 59 | * @throws HTTPException If the IronMQ service returns a status other than 200 OK. 60 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 61 | */ 62 | public static ArrayList getQueues(Client client, String previousQueueName) throws IOException { 63 | return getQueues(client, previousQueueName, null, null); 64 | } 65 | 66 | /** 67 | * Retrieves queues in alphabetical order. 68 | * 69 | * @param previousQueueName this is the last queue on the previous page, it will start from the next one. 70 | * If queue with specified name doesn't exist result will contain first per_page queues 71 | * that lexicographically greater than previous 72 | * @param perPage number of elements in response, default for IronMQ is 30 73 | * 74 | * @throws HTTPException If the IronMQ service returns a status other than 200 OK. 75 | * @throws java.io.IOException If there is an error accessing the IronMQ server. 76 | */ 77 | public static ArrayList getQueues(Client client, String previousQueueName, Integer perPage, String prefix) throws IOException { 78 | StringBuilder params = new StringBuilder(); 79 | if (previousQueueName != null && !previousQueueName.isEmpty()) { 80 | params.append(String.format("previous=%s", URLEncoder.encode(previousQueueName, "UTF-8"))); 81 | } 82 | if (prefix != null && !prefix.isEmpty()) { 83 | params.append(String.format("%sprefix=%s", params.length() > 0 ? "&" : "", URLEncoder.encode(prefix, "UTF-8"))); 84 | } 85 | if (perPage != null) { 86 | if (perPage < 1) { 87 | throw new IllegalArgumentException("perPage parameter should be greater than 0"); 88 | } 89 | params.append(String.format("%sper_page=%d", params.length() > 0 ? "&" : "", perPage)); 90 | } 91 | String url = "queues?" + params; 92 | 93 | IronReader reader = client.get(url); 94 | Gson gson = new Gson(); 95 | QueuesContainer queues = gson.fromJson(reader.reader, QueuesContainer.class); 96 | reader.close(); 97 | return queues.getQueues(); 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/QueuesContainer.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import java.io.Serializable; 4 | import java.util.ArrayList; 5 | 6 | public class QueuesContainer implements Serializable { 7 | private ArrayList queues; 8 | 9 | public QueuesContainer() { 10 | this.queues = new ArrayList(); 11 | } 12 | 13 | public QueuesContainer(ArrayList queues) { 14 | this.queues = queues; 15 | } 16 | 17 | /** 18 | * Returns the Array of QueueModels contained 19 | */ 20 | public ArrayList getQueues() { 21 | return queues; 22 | } 23 | 24 | /** 25 | * Returns the i'th element of queues list 26 | */ 27 | public QueueModel get(int index) { 28 | return queues.get(index); 29 | } 30 | 31 | /** 32 | * Returns the size of queues collection 33 | */ 34 | public int size() { 35 | return queues.size(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/SubscribedMessageOptions.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * The Message class represents a message retrieved from an IronMQ queue. 9 | */ 10 | public class SubscribedMessageOptions extends MessageOptions { 11 | @SerializedName("subscriber_name") 12 | protected String subscriberName; 13 | 14 | public SubscribedMessageOptions() { 15 | } 16 | 17 | public SubscribedMessageOptions(String reservationId, String subscriberName) { 18 | super(reservationId); 19 | this.subscriberName = subscriberName; 20 | } 21 | 22 | public SubscribedMessageOptions(String id, String reservationId, String subscriberName) { 23 | super(id, reservationId); 24 | this.subscriberName = subscriberName; 25 | } 26 | 27 | public SubscribedMessageOptions(String id, String reservationId, Long timeout, String subscriberName) { 28 | super(id, reservationId, timeout); 29 | this.subscriberName = subscriberName; 30 | } 31 | 32 | /** 33 | * Returns the name of Message's Subscriber. 34 | */ 35 | public String getSubscriberName() { 36 | return subscriberName; 37 | } 38 | 39 | /** 40 | * Sets the name of Message's Subscriber. 41 | */ 42 | public void setSubscriberName(String subscriberName) { 43 | this.subscriberName = subscriberName; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/Subscriber.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import java.util.HashMap; 4 | 5 | public class Subscriber { 6 | private String url; 7 | private String name; 8 | private HashMap headers; 9 | 10 | public Subscriber(String name) { 11 | this.name = name; 12 | } 13 | 14 | public Subscriber(String url, String name) { 15 | this.url = url; 16 | this.name = name; 17 | } 18 | 19 | public Subscriber(String url, String name, HashMap headers) { 20 | this.url = url; 21 | this.name = name; 22 | this.headers = headers; 23 | } 24 | 25 | public String getName() { 26 | return name; 27 | } 28 | 29 | public void setName(String name) { 30 | this.name = name; 31 | } 32 | 33 | public String getUrl() { 34 | return url; 35 | } 36 | 37 | public void setUrl(String url) { 38 | this.url = url; 39 | } 40 | 41 | public HashMap getHeaders() { 42 | if (headers == null) { 43 | headers = new HashMap(); 44 | } 45 | return headers; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/Subscribers.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | 6 | public class Subscribers { 7 | private ArrayList subscribers; 8 | 9 | public Subscribers(ArrayList subscribers) { 10 | this.subscribers = subscribers; 11 | } 12 | 13 | public Subscribers(Subscriber[] subscribers) { 14 | this.subscribers = new ArrayList(Arrays.asList(subscribers)); 15 | } 16 | 17 | public Subscriber getSubscriber(int i) { 18 | return subscribers.get(i); 19 | } 20 | 21 | public ArrayList getSubscribers() { 22 | return subscribers; 23 | } 24 | 25 | public Subscribers withoutNonIdAttributes() { 26 | ArrayList subscribers = new ArrayList(); 27 | for (int i = 0; i < subscribers.size(); i++) { 28 | subscribers.add(new Subscriber(this.subscribers.get(i).getName())); 29 | } 30 | return new Subscribers(subscribers); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/SubscribersInfo.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class SubscribersInfo { 6 | private ArrayList subscribers; 7 | 8 | public SubscribersInfo(ArrayList subscribers) { 9 | this.subscribers = subscribers; 10 | } 11 | 12 | public MessagePushModel getSubscriber(int i) { 13 | return subscribers.get(i); 14 | } 15 | 16 | public ArrayList getSubscribers() { 17 | return subscribers; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/TokenContainer.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import java.io.IOException; 4 | import java.net.MalformedURLException; 5 | 6 | public interface TokenContainer { 7 | String getToken() throws IOException; 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/keystone/Access.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq.keystone; 2 | 3 | public class Access { 4 | protected Token token; 5 | protected User user; 6 | 7 | public Access() { 8 | } 9 | 10 | public Access(Token token, User user) { 11 | this.token = token; 12 | this.user = user; 13 | } 14 | 15 | public Token getToken() { 16 | return token; 17 | } 18 | 19 | public void setToken(Token token) { 20 | this.token = token; 21 | } 22 | 23 | public User getUser() { 24 | return user; 25 | } 26 | 27 | public void setUser(User user) { 28 | this.user = user; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/keystone/Auth.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq.keystone; 2 | 3 | public class Auth { 4 | String tenantName; 5 | PasswordCredentials passwordCredentials; 6 | 7 | public Auth() { 8 | } 9 | 10 | public Auth(String tenantName, PasswordCredentials passwordCredentials) { 11 | this.tenantName = tenantName; 12 | this.passwordCredentials = passwordCredentials; 13 | } 14 | 15 | public String getTenantName() { 16 | return tenantName; 17 | } 18 | 19 | public void setTenantName(String tenantName) { 20 | this.tenantName = tenantName; 21 | } 22 | 23 | public PasswordCredentials getPasswordCredentials() { 24 | return passwordCredentials; 25 | } 26 | 27 | public void setPasswordCredentials(PasswordCredentials passwordCredentials) { 28 | this.passwordCredentials = passwordCredentials; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/keystone/KeystoneGetTokenPayload.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq.keystone; 2 | 3 | public class KeystoneGetTokenPayload { 4 | Auth auth; 5 | 6 | public KeystoneGetTokenPayload(Auth auth) { 7 | this.auth = auth; 8 | } 9 | 10 | public Auth getAuth() { 11 | return auth; 12 | } 13 | 14 | public void setAuth(Auth auth) { 15 | this.auth = auth; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/keystone/KeystoneGetTokenResponse.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq.keystone; 2 | 3 | public class KeystoneGetTokenResponse { 4 | Access access; 5 | 6 | public KeystoneGetTokenResponse() { 7 | } 8 | 9 | public KeystoneGetTokenResponse(Access access) { 10 | this.access = access; 11 | } 12 | 13 | public Access getAccess() { 14 | return access; 15 | } 16 | 17 | public void setAccess(Access access) { 18 | this.access = access; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/keystone/KeystoneIdentity.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq.keystone; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.GsonBuilder; 5 | import io.iron.ironmq.HttpClient; 6 | import io.iron.ironmq.TokenContainer; 7 | 8 | import java.io.IOException; 9 | import java.io.Reader; 10 | import java.net.URL; 11 | import java.util.HashMap; 12 | 13 | public class KeystoneIdentity implements TokenContainer { 14 | String server; 15 | String tenant; 16 | String username; 17 | String password; 18 | Token tokenInfo; 19 | 20 | protected KeystoneIdentity() { 21 | } 22 | 23 | public KeystoneIdentity(String server, String tenant, String username, String password) { 24 | this.server = server; 25 | this.tenant = tenant; 26 | this.username = username; 27 | this.password = password; 28 | } 29 | 30 | public String getUsername() { 31 | return username; 32 | } 33 | 34 | public void setUsername(String username) { 35 | this.username = username; 36 | } 37 | 38 | public String getPassword() { 39 | return password; 40 | } 41 | 42 | public void setPassword(String password) { 43 | this.password = password; 44 | } 45 | 46 | public String getToken() throws IOException { 47 | if (tokenInfo == null || tokenInfo.isExpired()) { 48 | Gson gson = new GsonBuilder() 49 | .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.S") 50 | .create(); 51 | 52 | KeystoneGetTokenPayload payload = new KeystoneGetTokenPayload( 53 | new Auth( 54 | tenant, 55 | new PasswordCredentials(username, password) 56 | ) 57 | ); 58 | String body = gson.toJson(payload); 59 | 60 | URL url = new URL(server + (server.endsWith("/") ? "" : "/") + "tokens"); 61 | 62 | String method = "POST"; 63 | 64 | HttpClient client = HttpClient.create(); 65 | HashMap headers = new HashMap() {{ 66 | put("Content-Type", "application/json"); 67 | put("Accept", "application/json"); 68 | }}; 69 | Reader response = client.singleRequest(method, url, body, headers); 70 | KeystoneGetTokenResponse tokenResponse = gson.fromJson(response, KeystoneGetTokenResponse.class); 71 | response.close(); 72 | 73 | tokenInfo = tokenResponse.getAccess().getToken(); 74 | } 75 | 76 | return tokenInfo.getId(); 77 | } 78 | 79 | public static String readFully(Reader reader) throws IOException { 80 | char[] arr = new char[8*1024]; // 8K at a time 81 | StringBuilder buf = new StringBuilder(); 82 | int numChars; 83 | 84 | while ((numChars = reader.read(arr, 0, arr.length)) > 0) { 85 | buf.append(arr, 0, numChars); 86 | } 87 | 88 | return buf.toString(); 89 | } 90 | 91 | public HashMap toHash() { 92 | return new HashMap() {{ 93 | put("server", server); 94 | put("tenant", tenant); 95 | put("username", username); 96 | put("password", password); 97 | }}; 98 | } 99 | 100 | public static KeystoneIdentity fromHash(HashMap hash) { 101 | return new KeystoneIdentity( 102 | (String) hash.get("server"), 103 | (String) hash.get("tenant"), 104 | (String) hash.get("username"), 105 | (String) hash.get("password")); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/keystone/PasswordCredentials.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq.keystone; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | import java.util.Date; 6 | 7 | public class PasswordCredentials { 8 | protected String username; 9 | protected String password; 10 | 11 | public PasswordCredentials() { 12 | } 13 | 14 | public PasswordCredentials(String username, String password) { 15 | this.username = username; 16 | this.password = password; 17 | } 18 | 19 | public String getUsername() { 20 | return username; 21 | } 22 | 23 | public void setUsername(String username) { 24 | this.username = username; 25 | } 26 | 27 | public String getPassword() { 28 | return password; 29 | } 30 | 31 | public void setPassword(String password) { 32 | this.password = password; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/keystone/Tenant.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq.keystone; 2 | 3 | public class Tenant { 4 | String description; 5 | String enabled; 6 | String id; 7 | String name; 8 | 9 | public Tenant() { 10 | } 11 | 12 | public Tenant(String description, String enabled, String id, String name) { 13 | this.description = description; 14 | this.enabled = enabled; 15 | this.id = id; 16 | this.name = name; 17 | } 18 | 19 | public String getDescription() { 20 | return description; 21 | } 22 | 23 | public void setDescription(String description) { 24 | this.description = description; 25 | } 26 | 27 | public String getEnabled() { 28 | return enabled; 29 | } 30 | 31 | public void setEnabled(String enabled) { 32 | this.enabled = enabled; 33 | } 34 | 35 | public String getId() { 36 | return id; 37 | } 38 | 39 | public void setId(String id) { 40 | this.id = id; 41 | } 42 | 43 | public String getName() { 44 | return name; 45 | } 46 | 47 | public void setName(String name) { 48 | this.name = name; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/keystone/Token.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq.keystone; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | import javax.sound.midi.MidiFileFormat; 6 | import java.util.Date; 7 | 8 | public class Token { 9 | protected Date localIssuedAt; 10 | protected Tenant tenant; 11 | protected String id; 12 | @SerializedName("issued_at") protected Date issuedAt; 13 | @SerializedName("expires") protected Date expiresAt; 14 | 15 | public Token() { 16 | localIssuedAt = new Date(); 17 | } 18 | 19 | public Tenant getTenant() { 20 | return tenant; 21 | } 22 | 23 | public void setTenant(Tenant tenant) { 24 | this.tenant = tenant; 25 | } 26 | 27 | public String getId() { 28 | return id; 29 | } 30 | 31 | public void setId(String id) { 32 | this.id = id; 33 | } 34 | 35 | public Date getIssuedAt() { 36 | return issuedAt; 37 | } 38 | 39 | public void setIssuedAt(Date issuedAt) { 40 | this.issuedAt = issuedAt; 41 | } 42 | 43 | public Date getExpiresAt() { 44 | return expiresAt; 45 | } 46 | 47 | public void setExpiresAt(Date expiresAt) { 48 | this.expiresAt = expiresAt; 49 | } 50 | 51 | /** 52 | * Indicated if token will expire after a few seconds. 53 | */ 54 | public boolean isExpired() { 55 | return isExpired(10); 56 | } 57 | 58 | /** 59 | * Indicated if token will expire after N seconds. 60 | * @param seconds Number of seconds 61 | */ 62 | public boolean isExpired(int seconds) { 63 | long diff = localIssuedAt.getTime() - issuedAt.getTime(); 64 | long localExpiresAtTime = expiresAt.getTime() + diff; 65 | return (new Date().getTime() - seconds * 1000) >= localExpiresAtTime; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/io/iron/ironmq/keystone/User.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq.keystone; 2 | 3 | public class User { 4 | protected String id; 5 | protected String username; 6 | 7 | public User() { 8 | } 9 | 10 | public User(String id, String username) { 11 | this.id = id; 12 | this.username = username; 13 | } 14 | 15 | public String getId() { 16 | return id; 17 | } 18 | 19 | public void setId(String id) { 20 | this.id = id; 21 | } 22 | 23 | public String getUsername() { 24 | return username; 25 | } 26 | 27 | public void setUsername(String username) { 28 | this.username = username; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/client/iron/ironmq/ClientIronMQTest.java: -------------------------------------------------------------------------------- 1 | package client.iron.ironmq; 2 | 3 | 4 | import io.iron.ironmq.*; 5 | import org.junit.Assert; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | 9 | import java.io.FileInputStream; 10 | import java.io.FileNotFoundException; 11 | import java.io.IOException; 12 | import java.io.InputStream; 13 | import java.util.Properties; 14 | import java.util.concurrent.Executors; 15 | import java.util.concurrent.ExecutorService; 16 | import java.util.concurrent.Callable; 17 | import java.util.concurrent.Future; 18 | import java.util.concurrent.ExecutionException; 19 | import java.lang.Thread; 20 | import java.util.ArrayList; 21 | 22 | public class ClientIronMQTest { 23 | private static class SubmitCallable implements Callable { 24 | private String msg; 25 | private Queue queue; 26 | 27 | public SubmitCallable(Queue queue, String msg) { 28 | this.queue = queue; 29 | this.msg = msg; 30 | } 31 | public QueueModel call() throws IOException, InterruptedException { 32 | queue.push(this.msg, 10); 33 | return queue.getInfoAboutQueue(); 34 | } 35 | } 36 | 37 | private String queueName = "java-testing-queue"; 38 | private String token = ""; 39 | private String projectId = ""; 40 | private Client client; 41 | 42 | @Before 43 | public void setUp() throws Exception { 44 | client = new Client(); 45 | } 46 | 47 | @Test 48 | public void testPostMultipleMessagesAndIdsShouldNotBeNull() throws IOException { 49 | Queue queue = new Queue(client, queueName); 50 | String body = "Hello, IronMQ!"; 51 | queue.push(body, 10); 52 | QueueModel infoAboutQueue = queue.getInfoAboutQueue(); 53 | int queueSize = infoAboutQueue.getSize(); 54 | 55 | String[] messages = {"c", "d"}; 56 | Ids ids = queue.pushMessages(messages); 57 | 58 | infoAboutQueue = queue.getInfoAboutQueue(); 59 | Assert.assertEquals(messages.length, ids.getSize()); 60 | Assert.assertEquals(queueSize + 2, infoAboutQueue.getSize()); 61 | 62 | queue.deleteMessages(ids); 63 | 64 | infoAboutQueue = queue.getInfoAboutQueue(); 65 | Assert.assertEquals(queueSize, infoAboutQueue.getSize()); 66 | queue.destroy(); 67 | } 68 | 69 | @Test 70 | public void testPostConcurrently() throws IOException, InterruptedException, ExecutionException { 71 | ExecutorService ex = Executors.newFixedThreadPool(10); 72 | ArrayList> futures = new ArrayList>(); 73 | Queue queue = new Queue(client, queueName); 74 | for (int i = 0; i < 10; i++) { 75 | Future submitted = ex.submit(new SubmitCallable(queue, "Hello, IronMQ # " + i + "!")); 76 | futures.add(submitted); 77 | } 78 | Thread.sleep(1000); 79 | Boolean found = false; 80 | for (Future fut : futures) { 81 | QueueModel qModel = fut.get(); 82 | if (qModel.getSize() == 10) { 83 | found = true; 84 | } 85 | } 86 | Assert.assertEquals(found, true); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/test/java/io/iron/ironmq/CloudTest.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | import java.io.FileInputStream; 7 | import java.io.FileNotFoundException; 8 | import java.io.IOException; 9 | import java.io.InputStream; 10 | import java.net.MalformedURLException; 11 | import java.util.ArrayList; 12 | import java.util.Properties; 13 | 14 | public class CloudTest { 15 | @Test 16 | public void testBasic() throws MalformedURLException { 17 | Cloud c = new Cloud("http://test.net:8080/some/path"); 18 | Assert.assertEquals("test.net", c.getHost()); 19 | Assert.assertEquals("http", c.getScheme()); 20 | Assert.assertEquals(8080, c.getPort()); 21 | Assert.assertEquals("/some/path", c.getPathPrefix()); 22 | } 23 | 24 | @Test 25 | public void testHttp() throws MalformedURLException { 26 | Cloud c = new Cloud("http://test.net:3445/"); 27 | Assert.assertEquals("test.net", c.getHost()); 28 | Assert.assertEquals("http", c.getScheme()); 29 | Assert.assertEquals(3445, c.getPort()); 30 | } 31 | 32 | @Test 33 | public void testHttpDefaultPort() throws MalformedURLException { 34 | Cloud c = new Cloud("http://test.net/"); 35 | Assert.assertEquals("http", c.getScheme()); 36 | Assert.assertEquals(80, c.getPort()); 37 | } 38 | 39 | @Test 40 | public void testHttps() throws MalformedURLException { 41 | Cloud c = new Cloud("https://test.net:3445/"); 42 | Assert.assertEquals("test.net", c.getHost()); 43 | Assert.assertEquals("https", c.getScheme()); 44 | Assert.assertEquals(3445, c.getPort()); 45 | } 46 | 47 | @Test 48 | public void testHttpsDefaultPort() throws MalformedURLException { 49 | Cloud c = new Cloud("https://test.net/"); 50 | Assert.assertEquals("https", c.getScheme()); 51 | Assert.assertEquals(443, c.getPort()); 52 | } 53 | 54 | @Test 55 | public void testEmptyPath() throws MalformedURLException { 56 | Cloud c = new Cloud("http://test.net"); 57 | Assert.assertEquals("", c.getPathPrefix()); 58 | } 59 | 60 | @Test 61 | public void testEmptyClosedPath() throws MalformedURLException { 62 | Cloud c = new Cloud("http://test.net/"); 63 | Assert.assertEquals("", c.getPathPrefix()); 64 | } 65 | 66 | @Test 67 | public void testClosedPath() throws MalformedURLException { 68 | Cloud c = new Cloud("http://test.net/my/cool/path/"); 69 | Assert.assertEquals("/my/cool/path", c.getPathPrefix()); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/test/java/io/iron/ironmq/IronMQLongRunningTest.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Before; 5 | import org.junit.Ignore; 6 | import org.junit.Test; 7 | 8 | import javax.sound.midi.VoiceStatus; 9 | import java.io.FileInputStream; 10 | import java.io.FileNotFoundException; 11 | import java.io.IOException; 12 | import java.io.InputStream; 13 | import java.util.ArrayList; 14 | import java.util.Date; 15 | import java.util.Properties; 16 | 17 | public class IronMQLongRunningTest { 18 | private String queueName = "java-testing-queue"; 19 | private Client client; 20 | private Queue queue; 21 | 22 | @Before 23 | public void setUp() throws Exception { 24 | client = new Client(null, null, null, 3, 1); 25 | queue = new Queue(client, "my_queue_" + ts()); 26 | } 27 | 28 | /** 29 | * Test shows how to increase time of message reservation 30 | * Expected that: 31 | * - message will be available after 30 seconds (initial timeout is 30 seconds) 32 | * @throws IOException 33 | * @throws InterruptedException 34 | */ 35 | @Test 36 | public void testReserveMessageWithTimeout() throws IOException, InterruptedException { 37 | queue.push("Test message"); 38 | Message reservedFirstTime = queue.reserve(1, 30).getMessage(0); 39 | 40 | Thread.sleep(32000); 41 | Messages reservedAgain = queue.reserve(1); 42 | Assert.assertEquals(1, reservedAgain.getSize()); 43 | Assert.assertEquals(reservedAgain.getMessage(0).getId(), reservedFirstTime.getId()); 44 | } 45 | 46 | /** 47 | * Test shows how to increase time of message reservation 48 | * Expected that: 49 | * - message will not be available after 35 seconds (initial timeout is 30 seconds) 50 | * @throws IOException 51 | * @throws InterruptedException 52 | */ 53 | @Test 54 | public void testTouchMessage() throws IOException, InterruptedException { 55 | queue.push("Test message"); 56 | Message message = queue.reserve(1, 30).getMessage(0); 57 | 58 | Thread.sleep(25000); 59 | queue.touchMessage(message); 60 | Thread.sleep(10000); 61 | Assert.assertEquals(0, queue.reserve(1).getSize()); 62 | } 63 | 64 | /** 65 | * Test shows how to increase time of message reservation by specified amount of seconds 66 | * Expected that: 67 | * - message will be available only after specified amount of seconds. 68 | * @throws IOException 69 | * @throws InterruptedException 70 | */ 71 | @Test 72 | public void testTouchMessageWithTimeout() throws IOException, InterruptedException { 73 | queue.push("Test message"); 74 | Message message = queue.reserve(1, 30).getMessage(0); 75 | queue.touchMessage(message, 40); 76 | 77 | Thread.sleep(35000); 78 | Assert.assertEquals(0, queue.reserve(1).getSize()); 79 | Thread.sleep(10000); 80 | Assert.assertEquals(1, queue.reserve(1).getSize()); 81 | } 82 | 83 | /** 84 | * Test shows how to touch a message multiple times. 85 | * Expected that: 86 | * - after second touch call message will have new reservation id 87 | * - new reservation id will not equal to old one 88 | * @throws IOException 89 | * @throws InterruptedException 90 | */ 91 | @Test 92 | public void testTouchMessageTwice() throws IOException, InterruptedException { 93 | queue.push("Test message"); 94 | Message message = queue.reserve(1, 5).getMessage(0); 95 | 96 | Thread.sleep(3500); 97 | MessageOptions options1 = queue.touchMessage(message); 98 | Thread.sleep(3500); 99 | MessageOptions options2 = queue.touchMessage(message); 100 | 101 | Assert.assertFalse(options1.getReservationId().equals(options2.getReservationId())); 102 | Assert.assertEquals(message.getReservationId(), options2.getReservationId()); 103 | } 104 | 105 | private long ts() { 106 | return new Date().getTime(); 107 | } 108 | 109 | private Queue createQueueWithMessage(String queueName) throws IOException { 110 | Queue queue = new Queue(client, queueName); 111 | queue.push("Test message"); 112 | return queue; 113 | } 114 | 115 | private String repeatString(String s, int times) { 116 | return new String(new char[times]).replace("\0", s); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/test/java/io/iron/ironmq/IronMQTest.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Before; 5 | import org.junit.Ignore; 6 | import org.junit.Test; 7 | 8 | import javax.sound.midi.VoiceStatus; 9 | import java.io.FileInputStream; 10 | import java.io.FileNotFoundException; 11 | import java.io.IOException; 12 | import java.io.InputStream; 13 | import java.util.ArrayList; 14 | import java.util.Date; 15 | import java.util.Properties; 16 | 17 | public class IronMQTest { 18 | private String queueName = "java-testing-queue"; 19 | private Client client; 20 | private Queue queue; 21 | 22 | @Before 23 | public void setUp() throws Exception { 24 | client = new Client(null, null, null, 3, 1); 25 | queue = new Queue(client, "my_queue_" + ts()); 26 | } 27 | 28 | /** 29 | * This test tries to connect to an ironmq server using an invalid project_id and token 30 | * Expected result is HTTPException 31 | */ 32 | @Test(expected = HTTPException.class) 33 | public void testErrorResponse() throws IOException { 34 | // intentionally invalid project/token combination 35 | Client client = new Client("4444444444444", "aaaaaa"); 36 | Queue queue = client.queue("test-queue"); 37 | queue.push("test"); 38 | } 39 | 40 | /** 41 | * This is the simplest way of posting a message 42 | * Expected that server will respond with id of the message 43 | * @throws IOException 44 | */ 45 | @Test 46 | public void testPostMessage() throws IOException { 47 | String messageId = queue.push("Test message"); 48 | Assert.assertTrue(messageId.length() > 0); 49 | } 50 | 51 | /** 52 | * This test shows old way of reserving a message using queue.get() 53 | * Test placed here to check backward compatibility 54 | * @throws IOException 55 | */ 56 | @Test 57 | public void testReserveMessageViaGet() throws IOException { 58 | String messageText = "Test message " + ts(); 59 | String messageId = queue.push(messageText); 60 | Message message = queue.get(); 61 | 62 | Assert.assertTrue(message.getReservationId().length() > 0); 63 | Assert.assertEquals(messageId, message.getId()); 64 | Assert.assertEquals(messageText, message.getBody()); 65 | Assert.assertEquals(1, message.getReservedCount()); 66 | } 67 | 68 | /** 69 | * Queue.reserve() should raise exception if queue is empty 70 | * Expected result is EmptyQueueException 71 | * @throws IOException 72 | */ 73 | @Test(expected = EmptyQueueException.class) 74 | public void testReserveMessageFromEmptyQueue() throws IOException { 75 | queue.push(""); 76 | queue.clear(); 77 | Message message = queue.reserve(); 78 | } 79 | 80 | /** 81 | * Reservation of several messages should not raise exception if queue is empty 82 | * Expected result: empty collection of messages 83 | * @throws IOException 84 | */ 85 | @Test 86 | public void testReserveMessagesFromEmptyQueue() throws IOException { 87 | queue.push(""); 88 | queue.clear(); 89 | Messages messages = queue.reserve(4); 90 | Assert.assertEquals(0, messages.getSize()); 91 | Assert.assertEquals(0, messages.getMessages().length); 92 | } 93 | 94 | /** 95 | * This test shows the easiest way to reserve a message 96 | * Expected: 97 | * - Message has id and reservation id 98 | * - Message has information that it has been reserved one time 99 | * @throws IOException 100 | */ 101 | @Test 102 | public void testReserveMessage() throws IOException { 103 | String messageText = "Test message " + ts(); 104 | String messageId = queue.push(messageText); 105 | Message message = queue.reserve(); 106 | 107 | Assert.assertTrue(message.getReservationId().length() > 0); 108 | Assert.assertEquals(messageId, message.getId()); 109 | Assert.assertEquals(messageText, message.getBody()); 110 | Assert.assertEquals(1, message.getReservedCount()); 111 | } 112 | 113 | /** 114 | * This test shows how to reserve multiple messages from a queue 115 | * Expected: 116 | * - Each message in result collection has id and reservation id 117 | * - Each message in result collection has information that it has been reserved one time 118 | * @throws IOException 119 | */ 120 | @Test 121 | public void testReserveMessages() throws IOException { 122 | String messageText = "Test message " + ts(); 123 | Ids ids = queue.pushMessages(new String[]{messageText + "0", messageText + "1", messageText + "2"}); 124 | Messages messages = queue.reserve(4); 125 | 126 | Assert.assertTrue(messages.getSize() > 0); 127 | Assert.assertTrue(messages.getSize() < 4); // count of messages could be less than 4 in two cases: 128 | // - there are less than 4 messages in queue (not in this test) 129 | // - messages were pushed with big intervals between and IronMQ 130 | // can't find all within acceptable interval of time. 131 | // for more info look at 132 | // http://dev.iron.io/mq-onpremise/reference/api/#reserve-messages 133 | 134 | for (int i = 0; i < messages.getSize(); i++) { 135 | Assert.assertTrue(messages.getMessage(i).getReservationId().length() > 0); 136 | Assert.assertEquals(ids.getId(i), messages.getMessage(i).getId()); 137 | Assert.assertEquals(messageText + i, messages.getMessage(i).getBody()); 138 | Assert.assertEquals(1, messages.getMessage(i).getReservedCount()); 139 | } 140 | } 141 | 142 | /** 143 | * This test shows how to use long-polling. 144 | * Expected that response time will be greater than long-polling interval (`wait` parameter) 145 | * because queue is empty 146 | * You can add the message in separate thread 2 seconds after the `queue.reserve(...);` call 147 | * and queue reserve will finish immediately 148 | * @throws IOException 149 | */ 150 | @Test 151 | public void testReserveMessageWithWait() throws IOException { 152 | queue.push("test"); 153 | queue.clear(); 154 | 155 | int intervalInSeconds = 3; 156 | 157 | long start = new Date().getTime(); 158 | Messages messages = queue.reserve(4, 60, intervalInSeconds); 159 | long finish = new Date().getTime(); 160 | 161 | Assert.assertEquals(0, messages.getSize()); 162 | System.out.println(finish - start); 163 | Assert.assertTrue(finish - start > intervalInSeconds * 1000); 164 | Assert.assertTrue(finish - start < intervalInSeconds * 2 * 1000); 165 | } 166 | 167 | /** 168 | * This test shows how to peek a message from a queue 169 | * Expected that 170 | * - Messsage has id and body 171 | * - Count of reservations is equal to 0 and reservation id is empty because peek doesn't reserve the message 172 | * - Second call of peek will return the same message because peek doesn't reserve the message 173 | * @throws IOException 174 | */ 175 | @Test 176 | public void testPeekMessage() throws IOException { 177 | String messageText = "Test message " + ts(); 178 | String messageId = queue.push(messageText); 179 | Message message = queue.peek(); 180 | 181 | Assert.assertNull(message.getReservationId()); 182 | Assert.assertEquals(messageId, message.getId()); 183 | Assert.assertEquals(messageText, message.getBody()); 184 | Assert.assertEquals(0, message.getReservedCount()); 185 | 186 | Message sameMessage = queue.peek(); 187 | Assert.assertEquals(message.getId(), sameMessage.getId()); 188 | } 189 | 190 | /** 191 | * This test shows how to get a message using its id. 192 | * Please note that: 193 | * - Message would not be reserved with this command 194 | * - You wouldn't be able to delete it if the message is reserved by another user (because you havent reservation id) 195 | * Expected that: 196 | * - Messsage has id and body 197 | * - Count of reservations is equal to 0 and reservation id is empty because peek doesn't reserve the message 198 | * @throws IOException 199 | */ 200 | @Test 201 | public void testGetMessageById() throws IOException { 202 | String messageText = "Test message " + ts(); 203 | String messageId = queue.push(messageText); 204 | Message message = queue.getMessageById(messageId); 205 | 206 | Assert.assertNull(message.getReservationId()); 207 | Assert.assertEquals(messageId, message.getId()); 208 | Assert.assertEquals(messageText, message.getBody()); 209 | Assert.assertEquals(0, message.getReservedCount()); 210 | } 211 | 212 | /** 213 | * This test shows 2 ways that a reserved message can be deleted 214 | * Please note that 215 | * - Size of queue will not change after reservation. It will decrease only when message has been deleted. 216 | * Expected that 217 | * - Size of queue will decrease 218 | * @throws IOException 219 | */ 220 | @Test 221 | public void testDeleteReservedMessage() throws IOException { 222 | Queue queue = createQueueWithMessage("my_queue_" + ts()); 223 | queue.clear(); 224 | queue.push("Test message"); 225 | Message message = queue.reserve(); 226 | 227 | Assert.assertEquals(1, queue.getInfoAboutQueue().getSize()); 228 | queue.deleteMessage(message); 229 | // or second way: 230 | // queue.deleteMessage(message.getId(), message.getReservationId()); 231 | Assert.assertEquals(0, queue.getInfoAboutQueue().getSize()); 232 | } 233 | 234 | /** 235 | * This test shows how you should not delete a reserved message 236 | * Expected: 237 | * - Exception, because way of deleting non-reserved message (by id) is not acceptable 238 | * for deleting reserved messages 239 | * Note: 240 | * Method queue.deleteMessage(Message) is more convenient because it deletes reserved messages with 241 | * reservation id and non-reserved messages without it. 242 | * @throws IOException 243 | */ 244 | @Test(expected = HTTPException.class) 245 | public void testDeleteReservedMessageWithoutReservationId() throws IOException { 246 | queue.clear(); 247 | queue.push("Test message"); 248 | Message message = queue.reserve(); 249 | 250 | // this way of deleting is acceptable for non reserved messages, 251 | // for example for messages which was got by id 252 | queue.deleteMessage(message.getId()); 253 | Assert.assertEquals(0, queue.getInfoAboutQueue().getSize()); 254 | } 255 | 256 | /** 257 | * This test shows how to delete reserved messages 258 | * Please note that 259 | * - Size of queue will not change after reservation. It will decrease only when messages have been deleted. 260 | * Expected that 261 | * - Size of queue will decrease 262 | * @throws IOException 263 | */ 264 | @Test 265 | public void testDeleteReservedMessages() throws IOException { 266 | Queue queue = createQueueWithMessage("my_queue_" + ts()); 267 | queue.clear(); 268 | queue.push("Test message 1"); 269 | queue.push("Test message 2"); 270 | Messages messages = queue.reserve(2); 271 | 272 | Assert.assertEquals(2, queue.getInfoAboutQueue().getSize()); 273 | queue.deleteMessages(messages); 274 | Assert.assertEquals(0, queue.getInfoAboutQueue().getSize()); 275 | } 276 | 277 | /** 278 | * This test shows how to delete a partial set of the reserved messages. 279 | * Use case: 280 | * User gets a bunch of messages and processes these messages. Some messages could not be processed 281 | * with current consumer script. Unprocessed messages should not be removed, rather released back to queue. 282 | * User wants to delete processed with single request to increase performance. 283 | * @throws IOException 284 | */ 285 | @Test 286 | public void testDeleteReservedMessagesPartially() throws IOException { 287 | Queue queue = createQueueWithMessage("my_queue_" + ts()); 288 | queue.clear(); 289 | queue.pushMessages(new String[]{"Test message 1", "Test message 2", "Test message 3", "Test message 4"}); 290 | Messages messages = queue.reserve(4); 291 | 292 | Assert.assertEquals(4, queue.getInfoAboutQueue().getSize()); 293 | 294 | Messages messagesToDelete = new Messages(); 295 | messagesToDelete.add(messages.getMessage(1)); 296 | messagesToDelete.add(messages.getMessage(3)); 297 | queue.deleteMessages(messagesToDelete); 298 | 299 | Assert.assertEquals(2, queue.getInfoAboutQueue().getSize()); 300 | } 301 | 302 | /** 303 | * This test just verifies that deleteMessages method should raise an exception for 304 | * reserved messages without reservation ids 305 | * Expected: 306 | * - HTTPException 307 | * @throws IOException 308 | */ 309 | @Test(expected = HTTPException.class) 310 | public void testDeleteReservedMessagesWithoutReservationId() throws IOException { 311 | queue.clear(); 312 | queue.push("Test message 1"); 313 | queue.push("Test message 2"); 314 | Messages messages = queue.reserve(2); 315 | 316 | messages.getMessage(0).setReservationId(null); 317 | queue.deleteMessages(messages); 318 | } 319 | 320 | /** 321 | * This test shows how to release a message back to queue if, for example, it could not be processed 322 | * Expected that: 323 | * - Message should return to the queue and be available for reserving 324 | * @throws IOException 325 | * @throws InterruptedException 326 | */ 327 | @Test 328 | public void testReleaseMessage() throws IOException, InterruptedException { 329 | queue.push("Test message"); 330 | Message message = queue.reserve(1).getMessage(0); 331 | 332 | Thread.sleep(500); 333 | queue.releaseMessage(message); 334 | 335 | Message sameMessage = queue.reserve(); 336 | Assert.assertEquals(message.getId(), sameMessage.getId()); 337 | } 338 | 339 | /** 340 | * This test shows old way of listing queues. Don't use it. 341 | * @throws IOException 342 | */ 343 | @Test 344 | public void testListQueuesOldWay() throws IOException { 345 | createQueueWithMessage("my_queue_" + ts()); 346 | Queues queues = new Queues(client); 347 | ArrayList allQueues = queues.getAllQueues(); 348 | 349 | Assert.assertTrue(allQueues.size() > 0); 350 | Assert.assertTrue(allQueues.get(0).getName().length() > 0); 351 | Assert.assertNull("Expect json with only names", allQueues.get(0).getProject_id()); 352 | Assert.assertNull("Expect json with only names", allQueues.get(0).getId()); 353 | } 354 | 355 | /** 356 | * This test shows the easiest way to get a list of queues 357 | * Expected 358 | * - list of names of queues 359 | * @throws IOException 360 | */ 361 | @Test 362 | public void testListQueues() throws IOException { 363 | createQueueWithMessage("my_queue_" + ts()); 364 | ArrayList allQueues = Queues.getQueues(client); 365 | 366 | Assert.assertTrue(allQueues.size() > 0); 367 | Assert.assertTrue(allQueues.get(0).getName().length() > 0); 368 | Assert.assertNull("Expect json with only names", allQueues.get(0).getProject_id()); 369 | Assert.assertNull("Expect json with only names", allQueues.get(0).getId()); 370 | } 371 | 372 | /** 373 | * This test checks listing of queues with default pagination 374 | * More information available here: http://dev.iron.io/mq-onpremise/reference/api/#list-queues 375 | * and here: http://dev.iron.io/mq-onpremise/reference/api/#changes 376 | * @throws IOException 377 | */ 378 | @Test 379 | public void testListQueuesDefaultPagination() throws IOException { 380 | int defaultPageSize = 30; 381 | for (int i = 0; i < defaultPageSize + 3; i++) { 382 | createQueueWithMessage(repeatString("z", i + 1)); 383 | } 384 | ArrayList queues = Queues.getQueues(client); 385 | 386 | Assert.assertTrue(queues.size() > 0); 387 | Assert.assertTrue(queues.size() <= defaultPageSize); 388 | Assert.assertTrue(queues.get(queues.size() - 1).getName().compareTo(repeatString("z", defaultPageSize + 2)) < 0); 389 | } 390 | 391 | /** 392 | * This test shows how to list queues with pagination 393 | * More information available here: http://dev.iron.io/mq-onpremise/reference/api/#list-queues 394 | * and here: http://dev.iron.io/mq-onpremise/reference/api/#changes 395 | * @throws IOException 396 | */ 397 | @Test 398 | public void testListQueuesPagination() throws IOException { 399 | int pageSize = 4; 400 | for (int i = 0; i < pageSize * 2; i++) { 401 | createQueueWithMessage(repeatString("a", i + 1)); 402 | } 403 | ArrayList queues = Queues.getQueues(client, "aa", pageSize, null); 404 | 405 | Assert.assertTrue(queues.size() == pageSize); 406 | for (int i = 0; i < queues.size(); i++) { 407 | Assert.assertEquals(repeatString("a", i + 3), queues.get(i).getName()); 408 | } 409 | 410 | Assert.assertEquals(2, Queues.getQueues(client, "aaaaaaa", 2, null).size()); 411 | Assert.assertEquals("aaaaaaaa", Queues.getQueues(client, "aaaaaaa").get(0).getName()); 412 | Assert.assertEquals(3, Queues.getQueues(client, 3).size()); 413 | } 414 | 415 | /** 416 | * This test shows how to list queues with filtering 417 | * More information available here: http://dev.iron.io/mq-onpremise/reference/api/#list-queues 418 | * and here: http://dev.iron.io/mq-onpremise/reference/api/#changes 419 | * @throws IOException 420 | */ 421 | @Test 422 | public void testListQueuesFiltering() throws IOException { 423 | String[] queueNames = new String[]{"abba", "abbca", "abbcb", "abbcd", "abbdd"}; 424 | for (int i = 0; i < queueNames.length; i++) 425 | createQueueWithMessage(queueNames[i]); 426 | 427 | ArrayList queues = Queues.getQueues(client, null, null, "abbc"); 428 | 429 | Assert.assertTrue(queues.size() == 3); 430 | for (int i = 0; i < queues.size(); i++) { 431 | Assert.assertEquals(queueNames[i + 1], queues.get(i).getName()); 432 | } 433 | } 434 | 435 | /** 436 | * This test shows how to retrieve information about a queue 437 | * Expected that: 438 | * - Queue will have name, size and total messages count 439 | * @throws IOException 440 | */ 441 | @Test 442 | public void testGetQueueInfo() throws IOException { 443 | String queueName = "my_queue_" + ts(); 444 | Queue queue = new Queue(client, queueName); 445 | for (int i = 0; i < 3; i++) 446 | queue.push("Some message"); 447 | QueueModel info = queue.getInfoAboutQueue(); 448 | 449 | Assert.assertEquals(queueName, info.getName()); 450 | Assert.assertFalse(info.getProjectId().isEmpty()); 451 | Assert.assertEquals(3, info.getSize()); 452 | Assert.assertEquals(3, info.getTotalMessages()); 453 | } 454 | 455 | /** 456 | * This test shows how to clear all messages from a queue 457 | * Expected that: 458 | * - after cleaning queue will contain no messages 459 | * @throws IOException 460 | */ 461 | @Test 462 | public void testClearQueue() throws IOException { 463 | queue.push("Some message"); 464 | Assert.assertTrue(queue.getInfoAboutQueue().getSize() > 0); 465 | queue.clear(); 466 | Assert.assertEquals(0, queue.getInfoAboutQueue().getSize()); 467 | } 468 | 469 | /** 470 | * This test shows that a queue can't be cleared until it has been created 471 | * Expected 472 | * - HTTPException (404) Queue not found 473 | * @throws IOException 474 | */ 475 | @Test(expected = HTTPException.class) 476 | public void testGetInfoBeforeQueueCreated() throws IOException { 477 | queue.getInfoAboutQueue(); 478 | } 479 | 480 | /** 481 | * This test shows the easist way to create a queue 482 | * @throws IOException 483 | */ 484 | @Test 485 | public void testCreateQueue() throws IOException { 486 | String name = "my_queue_" + ts(); 487 | Queue queue = new Queue(client, name); 488 | 489 | QueueModel response = queue.create(); 490 | Assert.assertEquals(name, response.getName()); 491 | Assert.assertEquals(60, response.getMessageTimeout()); 492 | 493 | QueueModel info = queue.getInfoAboutQueue(); 494 | Assert.assertEquals(name, info.getName()); 495 | } 496 | 497 | /** 498 | * This test shows how to create a queue and specify it's parameters 499 | * Using the QueueModel class is preferred way of specifying parameters of queue 500 | * Expected that: 501 | * - Created queue will have all specified parameters 502 | * @throws IOException 503 | */ 504 | @Test 505 | public void testCreateQueueWithParams() throws IOException { 506 | String name = "my_queue_" + ts(); 507 | Queue queue = new Queue(client, name); 508 | 509 | QueueModel payload = new QueueModel(); 510 | payload.setMessageTimeout(69); 511 | payload.setMessageExpiration(404); 512 | QueueModel info = queue.create(payload); 513 | 514 | Assert.assertEquals(69, info.getMessageTimeout()); 515 | Assert.assertEquals(404, info.getMessageExpiration()); 516 | } 517 | 518 | /** 519 | * This test shows how to create a push queue 520 | * To create a queue we need to pass array-list of subscribers, specify queue type, retries count and retries delay 521 | * @throws IOException 522 | */ 523 | @Test 524 | public void testCreateQueueOverload2() throws IOException { 525 | String name = "my_queue_" + ts(); 526 | Queue queue = new Queue(client, name); 527 | 528 | ArrayList subs = new ArrayList(){{ add(new Subscriber("http://localhost:3000/", "test")); }}; 529 | 530 | QueueModel response = queue.create(subs, null, "multicast", 5, 3); 531 | Assert.assertEquals(name, response.getName()); 532 | Assert.assertEquals(60, response.getMessageTimeout()); 533 | Assert.assertEquals("multicast", response.getType()); 534 | Assert.assertEquals(5, response.getPushInfo().getRetries().intValue()); 535 | Assert.assertEquals(3, response.getPushInfo().getRetriesDelay().intValue()); 536 | Assert.assertEquals(1, response.getPushInfo().getSubscribers().size()); 537 | 538 | QueueModel info = queue.getInfoAboutQueue(); 539 | Assert.assertEquals(name, info.getName()); 540 | } 541 | 542 | /** 543 | * This test shows how to create a push queue 544 | * To create a queue we need to pass array-list of subscribers, specify queue type, name of error-queue, 545 | * retries count and retries delay 546 | * @throws IOException 547 | */ 548 | @Test 549 | public void testCreateQueueOverload3() throws IOException { 550 | String name = "my_queue_" + ts(); 551 | Queue queue = new Queue(client, name); 552 | 553 | ArrayList subs = new ArrayList(){{ add(new Subscriber("http://localhost:3000/", "test")); }}; 554 | 555 | QueueModel response = queue.create(subs, null, "multicast", "err_q", 5, 3); 556 | Assert.assertEquals(name, response.getName()); 557 | Assert.assertEquals(60, response.getMessageTimeout()); 558 | Assert.assertEquals("multicast", response.getType()); 559 | Assert.assertEquals(5, response.getPushInfo().getRetries().intValue()); 560 | Assert.assertEquals(3, response.getPushInfo().getRetriesDelay().intValue()); 561 | Assert.assertEquals("err_q", response.getPushInfo().getErrorQueue()); 562 | Assert.assertEquals(1, response.getPushInfo().getSubscribers().size()); 563 | 564 | QueueModel info = queue.getInfoAboutQueue(); 565 | Assert.assertEquals(name, info.getName()); 566 | } 567 | 568 | /** 569 | * This test shows how to update a queue 570 | * Feel free to use the QueueModel class to specify other parameters of queue 571 | * @throws IOException 572 | */ 573 | @Test 574 | public void testUpdateQueue() throws IOException { 575 | queue.create(); 576 | QueueModel payload = new QueueModel(); 577 | payload.setMessageTimeout(69); 578 | QueueModel info = queue.update(payload); 579 | 580 | Assert.assertEquals(69, info.getMessageTimeout()); 581 | } 582 | 583 | /** 584 | * This test shows how to replace subscribers of a queue 585 | * Expected: 586 | * - old subscribers should be replaced by new subscribers 587 | * @throws IOException 588 | */ 589 | @Test 590 | public void testReplaceQueueSubscribers() throws IOException { 591 | QueueModel payload = new QueueModel(); 592 | payload.addSubscriber(new Subscriber("http://localhost:3000", "test01")); 593 | payload.addSubscriber(new Subscriber("http://localhost:3030", "test02")); 594 | payload.addSubscriber(new Subscriber("http://localhost:3333", "test03")); 595 | QueueModel info = queue.create(payload); 596 | 597 | Assert.assertEquals(3, info.getPushInfo().getSubscribers().size()); 598 | 599 | ArrayList subscribers = new ArrayList(); 600 | subscribers.add(new Subscriber("http://localhost:3000", "test04")); 601 | subscribers.add(new Subscriber("http://localhost:3030", "test05")); 602 | queue.replaceSubscribers(subscribers); 603 | 604 | QueueModel info2 = queue.getInfoAboutQueue(); 605 | Assert.assertEquals(2, info2.getPushInfo().getSubscribers().size()); 606 | } 607 | 608 | /** 609 | * This test shows how to update subscribers of a queue 610 | * Expected: 611 | * - old subscribers should be updated 612 | * - one of 3 subscribers not affected by update should stay the same 613 | * @throws IOException 614 | */ 615 | @Test 616 | public void testUpdateQueueSubscribers() throws IOException { 617 | QueueModel payload = new QueueModel(); 618 | payload.addSubscriber(new Subscriber("http://localhost:3000", "test01")); 619 | payload.addSubscriber(new Subscriber("http://localhost:3030", "test02")); 620 | payload.addSubscriber(new Subscriber("http://localhost:3333", "test03")); 621 | QueueModel info = queue.create(payload); 622 | 623 | Assert.assertEquals(3, info.getPushInfo().getSubscribers().size()); 624 | 625 | ArrayList subscribers = new ArrayList(); 626 | subscribers.add(new Subscriber("http://localhost:3030", "test01")); 627 | subscribers.add(new Subscriber("http://localhost:3030", "test03")); 628 | queue.updateSubscribers(subscribers); 629 | 630 | QueueModel info2 = queue.getInfoAboutQueue(); 631 | Assert.assertEquals(3, info2.getPushInfo().getSubscribers().size()); 632 | for (int i = 0; i < info2.getSubscribers().size(); i++) { 633 | Assert.assertEquals(info2.getSubscribers().get(i).getUrl(), "http://localhost:3030"); 634 | } 635 | } 636 | 637 | /** 638 | * This test shows how to update parameters of a push queue 639 | * @throws IOException 640 | */ 641 | @Test 642 | public void testUpdateQueuePushParameters() throws IOException { 643 | // TODO: perform real udate 644 | final String url = "http://localhost:3000"; 645 | 646 | ArrayList subscribers = new ArrayList() {{ add(new Subscriber(url, "test")); }}; 647 | QueueModel payload = new QueueModel(new QueuePushModel(subscribers, 4, 7, "test_err")); 648 | QueueModel info = queue.create(payload); 649 | 650 | Assert.assertEquals("test_err", info.getPushInfo().getErrorQueue()); 651 | Assert.assertEquals("multicast", info.getType()); 652 | Assert.assertEquals(4, info.getPushInfo().getRetries().intValue()); 653 | Assert.assertEquals(7, info.getPushInfo().getRetriesDelay().intValue()); 654 | 655 | Assert.assertEquals(1, info.getPushInfo().getSubscribers().size()); 656 | Assert.assertEquals(url, info.getPushInfo().getSubscribers().get(0).getUrl()); 657 | } 658 | 659 | /** 660 | * This test shows how to update alerts of a queue 661 | * Expected that: 662 | * - new alert will be available after update 663 | * @throws IOException 664 | */ 665 | @Test 666 | public void testUpdateQueueAlerts() throws IOException { 667 | queue.create(); 668 | ArrayList alerts = new ArrayList(); 669 | alerts.add(new Alert(Alert.typeProgressive, Alert.directionAscending, 5, "some_q")); 670 | QueueModel info = queue.updateAlerts(alerts); 671 | 672 | Assert.assertEquals(5, info.getAlerts().get(0).getTrigger()); 673 | Assert.assertEquals(Alert.directionAscending, info.getAlerts().get(0).getDirection()); 674 | Assert.assertEquals(Alert.typeProgressive, info.getAlerts().get(0).getType()); 675 | Assert.assertEquals("some_q", info.getAlerts().get(0).getQueue()); 676 | } 677 | 678 | /** 679 | * This test shows how to delete a queue 680 | * Expected: 681 | * - HTTPException (404), because queue is no longer available after deleting, so, getInfoAboutQueue 682 | * should raise an exception 683 | * @throws IOException 684 | * @throws InterruptedException 685 | */ 686 | @Test(expected = HTTPException.class) 687 | public void testDeleteQueue() throws IOException, InterruptedException { 688 | queue.push("Some message"); 689 | queue.destroy(); 690 | Queue sameQueue = new Queue(client, queue.getName()); 691 | 692 | sameQueue.getInfoAboutQueue(); 693 | } 694 | 695 | /** 696 | * This test shows how to add subscribers to a queue. 697 | * @throws IOException 698 | */ 699 | @Test 700 | public void testAddSubscribers() throws IOException { 701 | QueueModel payload = new QueueModel(); 702 | payload.addSubscriber(new Subscriber("http://localhost:3001", "test01")); 703 | queue.create(payload); 704 | queue.addSubscribers(new Subscriber[]{new Subscriber("http://localhost:3002", "test02")}); 705 | 706 | QueueModel info = queue.getInfoAboutQueue(); 707 | 708 | Assert.assertEquals(2, info.getSubscribers().size()); 709 | Subscriber subscriber = info.getSubscribers().get(1); 710 | Assert.assertEquals("test02", subscriber.getName()); 711 | Assert.assertEquals("http://localhost:3002", subscriber.getUrl()); 712 | } 713 | 714 | /** 715 | * This test shows another way of replacing subscribers. First one is update() with setting new subscribers 716 | * via new QueueModel(new QueuePushModel(subscribersArrayList)) 717 | * Expected: 718 | * - old subscribers to be deleted 719 | * - new subscribers to appear in the queue-info 720 | * @throws IOException 721 | */ 722 | @Test 723 | public void testReplaceSubscribers() throws IOException { 724 | QueueModel payload = new QueueModel(); 725 | payload.addSubscriber(new Subscriber("http://localhost:3001", "test01")); 726 | queue.create(payload); 727 | queue.replaceSubscribers(new Subscriber[]{new Subscriber("http://localhost:3002", "test02")}); 728 | 729 | QueueModel info = queue.getInfoAboutQueue(); 730 | Assert.assertEquals(1, info.getSubscribers().size()); 731 | Subscriber subscriber = info.getSubscribers().get(0); 732 | Assert.assertEquals("test02", subscriber.getName()); 733 | Assert.assertEquals("http://localhost:3002", subscriber.getUrl()); 734 | } 735 | 736 | @Test 737 | @Ignore // there is a bug in implementation of ironmq 738 | public void testRemoveSubscribers() throws IOException { 739 | QueueModel payload = new QueueModel(); 740 | Subscriber[] subscribers = new Subscriber[]{ 741 | new Subscriber("http://localhost:3001", "test01"), 742 | new Subscriber("http://localhost:3002", "test02"), 743 | }; 744 | payload.addSubscriber(subscribers[0]); 745 | payload.addSubscriber(subscribers[1]); 746 | queue.update(payload); 747 | queue.removeSubscribers(new Subscriber[]{subscribers[0]}); 748 | 749 | QueueModel info = queue.getInfoAboutQueue(); 750 | Assert.assertEquals(1, info.getSubscribers().size()); 751 | Subscriber subscriber = info.getSubscribers().get(0); 752 | Assert.assertEquals(subscribers[1].getName(), subscriber.getName()); 753 | Assert.assertEquals(subscribers[1].getUrl(), subscriber.getUrl()); 754 | } 755 | 756 | private long ts() { 757 | return new Date().getTime(); 758 | } 759 | 760 | private Queue createQueueWithMessage(String queueName) throws IOException { 761 | Queue queue = new Queue(client, queueName); 762 | queue.push("Test message"); 763 | return queue; 764 | } 765 | 766 | private String repeatString(String s, int times) { 767 | return new String(new char[times]).replace("\0", s); 768 | } 769 | // 770 | // private void createAQueue() 771 | } 772 | -------------------------------------------------------------------------------- /src/test/java/io/iron/ironmq/MockTest.java: -------------------------------------------------------------------------------- 1 | package io.iron.ironmq; 2 | 3 | import com.google.gson.Gson; 4 | 5 | import org.junit.Assert; 6 | import org.junit.Test; 7 | 8 | public class MockTest { 9 | /** 10 | * This test makes sure that we don't get overflow errors when queue size 11 | * or total_messages exceeds max int. 12 | */ 13 | @Test 14 | public void testDeserializeQueue() { 15 | final Gson gson = new Gson(); 16 | final long big = 3000000000L; // exceeds max int 17 | final String json = String.format("{\"total_messages\": %d, \"size\": %d}", big, big); 18 | QueueModel queue = gson.fromJson(json, QueueModel.class); 19 | //Assert.assertEquals(queue.getSizeLong(), big); 20 | //Assert.assertEquals(queue.getTotalMessagesLong(), big); 21 | } 22 | } 23 | --------------------------------------------------------------------------------