Coder Social home page Coder Social logo

iron_mq_java's Introduction

IronMQ Java Client

Note: There are some differences from the previous version of IronMQ. For more information please go to Iron.io Dev Center.

Getting Started

There are three ways to get this package.

1. Add it as a Maven dependency Your pom.xml will look something like:

    <dependencies>
        <!-- IronMQ message queue client -->
        <dependency>
            <groupId>io.iron.ironmq</groupId>
            <artifactId>ironmq</artifactId>
            <version>LATEST</version>
        </dependency>
    </dependencies>

2. Download the jar from Maven Repo.

Note: You also need to have several dependencies added to classpath: com.google.code.gson 2.1 or later and org.apache.commons 3.3.1 or later.

For example following commands could be used to run your simple test program:

src$ javac -cp ".:ironmq.jar:gson-2.2.4.jar:commons-lang3-3.1.jar" org/ironmq_test/Program.java
src$ java -cp  ".:ironmq.jar:gson-2.2.4.jar:commons-lang3-3.1.jar" org.ironmq_test.Program

3. Build from source with Apache Buildr:

buildr package

The .jar file will appear under the target directory.

Configure

Initialize a client and get a queue object:

Using iron.json file

Put all settings in iron.json file. At least token and project_id. But host, port, scheme are also supported.

{
  "token": "m6000000000000000000RJ",
  "project_id": "54000000000000000000000d",
  "scheme": "http",
  "host": "mq-aws-us-east-1-1.iron.io",
  "port": 80
}

Then you need to instantiate a Client:

Client client = new Client();

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.

In case of using Maven put your iron.json in the root of project (near the pom.xml file) or in home directory.

It's also possible to look for iron.json file in parent directories:

lookUpLimit = 3;
Client client = new Client(<projectId or null>, <token or null>, <cloud or null>, 1, lookUpLimit);

In example above IronMq library will try to find iron.json file in 3 levels of parent folders of executing file.

Specifying configuration in initializer

Client client = new Client("my project", "my token", Cloud.ironAWSUSEast);
Queue queue = client.queue("test-queue");

It's also possible to specify more parameters:

int apiVersion = 3;
Client client = new Client(projectId, token, new Cloud("http", "localhost", 8080), apiVersion);

Keystone 2.0 authorization

iron.json

Add keystone section to your iron.json file

{
  "project_id": "000000000000000000000005",
  "keystone": {
    "server": "http://your.keystone.server/somepath/",
    "tenant": "some_tenant",
    "username": "bob",
    "password": "secret123",
  }
}

Initialize Client with empty token:

client = new Client(projectId, "", new Cloud(scheme, host, port), 3);

Or:

Assumed that IronMQ On-Premise runs on localhost:8080

{
  "scheme":"http",
  "host":"localhost",
  "port":8080,
  "project_id": "000000000000000000000005",
  "keystone": {
    "server": "http://your.keystone.server/somepath/",
    "tenant": "some_tenant",
    "username": "bob",
    "password": "secret123",
  }
}
client = new Client();
In code
client = new Client(projectId, new KeystoneIdentity(server, tenant, username, password), new Cloud(scheme, host, port), 3);

Token in iron.json file will be ignored.

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:

Client client = new Client("my project", null);

The Basics

Client client = new Client("my project", "my token", Cloud.ironAWSUSEast);

Post a Message to the Queue

queue.push("Hello, IronMQ!");

More complex example:

String body = "Hello, IronMQ!";
int delay = 0;
String messageId = queue.push(body, delay);

Post multiple messages in one API call:

String[] messages = {"c", "d"};
Ids ids = queue.pushMessages(messages);

--

Get a Message off the Queue

Message msg = queue.reserve();

When you reserve a message from the queue, it will NOT be deleted. It will eventually go back onto the queue after a timeout if you don't delete it (default timeout is 60 seconds).

Get multiple messages in one API call:

Messages messages = queue.reserve(2);

--

Delete a Message from the Queue

Message msg = queue.reserve();
queue.deleteMessage(msg);

Delete a message from the queue when you're done with it.

Delete multiple messages

1. Deleting Messages collection

Messages messages = queue.reserve(4);
queue.deleteMessages(messages);

2. Deleting by Ids

String[] messages = {"hello", "world"};
Ids ids = queue.pushMessages(messages);
queue.deleteMessages();

--

Queues

List Queues

ArrayList<QueueModel> allQueues = Queues.getQueues(client);

Additional Parameters:

  • per\_page - number of elements in response, default is 30.
  • 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
  • prefix - an optional queue prefix to search on. e.g., prefix=ca could return queues ["cars", "cats", etc.]

Request below will return 20 queues started with "na" but lexicographically greater than "name_of_previous_queue".

int perPage = 20;
String previous = "name_of_previous_queue";
String prefix = "na";
ArrayList<QueueModel> allQueues = Queues.getQueues(client, previous, perPage, prefix);

--

Retrieve Queue Information

QueueModel infoAboutQueue = queue.getInfoAboutQueue();

--

Delete a Message Queue

queue.destroy();

--

Post Messages to a Queue

Single message:

queue.pushMessage(body);

Multiple messages:

String[] messages = {"c", "d"};
Ids ids = queue.pushMessages(messages);

Optional parameters (3rd, array of key-value pairs):

  • delay: The item will not be available on the queue until this many seconds have passed. Default is 0 seconds. Maximum is 604,800 seconds (7 days).

--

Get Messages from a Queue

Single message:

Message msg = queue.reserve();

Multiple messages:

int count = 5;
Messages messages = queue.reserve(count);

Optional parameters:

  • count: The maximum number of messages to get. Default is 1. Maximum is 100.

--

Touch a Message on a Queue

Touching a reserved message extends its timeout by the duration specified when the message was created, which is 60 seconds by default.

Message message = queue.reserve();
queue.touchMessage(message);

--

Release Message

Message message = queue.reserve();
int delay = 1;
queue.releaseMessage(message, delay);

Optional parameters:

  • delay: The item will not be available on the queue until this many seconds have passed. Default is 0 seconds. Maximum is 604,800 seconds (7 days).

--

Delete a Message from a Queue

Message message = queue.get();
queue.deleteMessage(message);

--

Peek Messages from a Queue

Peeking at a queue returns the next messages on the queue, but it does not reserve them.

Single message:

Messages msg = queue.peek();

Multiple messages:

int count = 2;
Messages msg = queue.peek(count);

--

Clear a Queue

queue.clear();

--

Add alerts to a queue. This is for Pull Queue only.

ArrayList<Alert> alerts = new ArrayList<Alert>();
alerts.add(new Alert(Alert.typeProgressive, Alert.directionAscending, 5, "some_q"));
QueueModel info = queue.updateAlerts(alerts);

--

Push Queues

IronMQ push queues allow you to setup a queue that will push to an endpoint, rather than having to poll the endpoint. Here's the announcement for an overview.

Update a Message Queue

ArrayList<Subscriber> subscribers = new ArrayList<Subscriber>() {{ add(new Subscriber(url)); }};
QueueModel payload = new QueueModel(new QueuePushModel(subscribers, "multicast", 4, 7, "test_err"));
queue.update(payload);

The following parameters are all related to Push Queues:

  • subscribers: An array of subscriber hashes containing url field. This set of subscribers will replace the existing subscribers.
  • retries: How many times to retry on failure. Default is 3. Maximum is 100.
  • retries_delay: Delay between each retry in seconds. Default is 60.

--

Update Queue Subscribers

ArrayList<Subscriber> subscribers = new ArrayList<Subscriber>();
subscribers.add(new Subscriber("http://localhost:3000"));
subscribers.add(new Subscriber("http://localhost:3030"));
queue.updateSubscribers(subscribers);

--

Get Message Push Status

String[] messages = {"test1", "test2"};
Ids ids = queue.pushMessages(messages);
SubscribersInfo subscribersInfo = queue.getPushStatusForMessage(ids.getId(0));

Returns an array of subscribers with status.

--

Acknowledge / Delete Message Push Status

String[] messages = {"test1", "test2"};
Ids ids = queue.pushMessages(messages);
SubscribersInfo subscribersInfo = queue.getPushStatusForMessage(ids.getId(0));
queue.deletePushMessageForSubscriber(ids.getId(0), subscribersInfo.getSubscribers().get(0).id);

--

Further Links


В© 2011 - 2014 Iron.io Inc. All Rights Reserved.

iron_mq_java's People

Contributors

alex-litvak avatar aluedeke avatar arschles avatar brianmc avatar bupychuk avatar d-kononov avatar dependabot[bot] avatar edsrzf avatar featalion avatar iced avatar jcodagnone avatar jtjeferreira avatar mauricioaniche avatar mikecaspar avatar orrgal1 avatar pax95 avatar pyeremenko avatar rkononov avatar schwartzdev avatar stephanos avatar stkaushal avatar sunloverz avatar treeder avatar vasilev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

iron_mq_java's Issues

QueueModel does not have public accessors

Hi there,

Perhaps I'm misunderstanding the usage but I'm not sure what you can do with the QueueModel object returned from queue.getInfoAboutQueue() since there are no public accessors. I would like to return information about the queue in my own API which uses IronMQ internally.

Same for queues.getAllQueues() arraylist of QueueModel objects.

Many Thanks,

Brian

do i need to explicitly close connections?

hi
sometimes i notice that my process starts leaving many tcp connections in CLOSE_WAITING state. usually this happens when its processing a lot of messages off the queue. on a bad day this easily climbs up to the thousands. is there anything i should be doing to close the connections? is there something missing in the client to make sure the connections are closed?
thanks

Out of date instructions

The maven version you specify is really old. The latest is 3.0.1. Does the rest of the documentation match that version?

neverending connection on pull

Took me a lot of time to tracked this bug. Here we go:

I used threads to pull from specific queue and all the time, after some random time, my pullers stopped working accidentally. I thought that was the problem with pool thread in Java, but I was wrong. In thread dump I've seen that all my pulling-threads are stuck in same line of code - IronMqJava library Client.java:

int status = conn.getResponseCode();

In above code we make request to ironMq server, but we haven't set timeout param which by default is 0 - inifinty. So if an error happen on IronMq server our code is waiting for the response forever!

That's why I added following lines:

conn.setConnectTimeout(this.httpTimeout);
conn.setReadTimeout(this.httpTimeout);

After this now I get familiar error:

 java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:152)
    at java.net.SocketInputStream.read(SocketInputStream.java:122)
    at sun.security.ssl.InputRecord.readFully(InputRecord.java:442)
    at sun.security.ssl.InputRecord.read(InputRecord.java:480)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:934)
    at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:891)
    at sun.security.ssl.AppInputStream.read(AppInputStream.java:102)
    at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
    at java.io.BufferedInputStream.read1(BufferedInputStream.java:275)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:334)
    at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:689)
    at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:633)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1324)
    at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:468)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:338)
    at io.iron.ironmq.Client.singleRequest(Client.java:255)
    at io.iron.ironmq.Client.request(Client.java:204)
    at io.iron.ironmq.Client.post(Client.java:185)
    at io.iron.ironmq.Queue.reserve(Queue.java:148)

I'm using forked code so I couldn't prepare fix straight.

V3 inconsistency

Add getName() to Queue

A very minor request, but it would be convenient to have a getName() accessor on Queue to retrieve the name that was passed in on queue construction.

Wrong error with bad auth info

A customer reported in the support room that he received an HTTPException with the message "Empty or non-JSON response". The problem turned out to be that he had miscopied his project ID or token. This is an incorrect and poor error message.

Queue.get() NPEs if queue doesn't exist

If a queue doesn't exist, Queue.get() throws an NPE – which is not a very helpful error. Actually, the semantics of queue existence is a little slippery, because from the API, it queues are treated sort of like namespaces for messages, rather than first-class things themselves (for example, you can't really create a queue other than posting a message to a queue).

At the very least, seems like you should replace the NPE with a more helpful message.

Add an error queue to a queue object

Look like you can do this through the API but not the java SDK:

Post to your push queue a message with the "error_queue" option defined.

{"push_type":"multicast/unicast",
"subscribers": [
{"url": "http://thiswebsitewillthrowanerror.com"}
],
"error_queue": "MY_EXAMPLE_ERROR_QUEUE"}

Android?

Hi,

is the java client android compatible? Need this information as decision to proceed with any further evaluation steps.

NullPointerException in io.iron.ironmq.Client.singleRequest

I am trying to push a test message up to an ironmq queue from some Java code.
I can see all our queues, I can create queue, I can dequeue a message.
However when attempting to push a message I am getting a nullpointer exception:

Exception in thread "main" java.lang.NullPointerException
at java.io.Reader.(Unknown Source)
at java.io.InputStreamReader.(Unknown Source)
at io.iron.ironmq.Client.singleRequest(Client.java:218)
at io.iron.ironmq.Client.request(Client.java:164)
at io.iron.ironmq.Client.post(Client.java:145)
at io.iron.ironmq.Queue.push(Queue.java:367)
at io.iron.ironmq.Queue.push(Queue.java:329)
at io.iron.ironmq.Queue.push(Queue.java:302)
at testing.test.testIronMq(test.java:36)
at testing.test.main(test.java:15)

My code:
Client ironClient = new Client();
Queue queue = ironClient.queue("my-test-queue");
queue.push("Hello, IronMQ!");

Code for io.iron.ironmq.Client.singleRequest(..):

private Reader singleRequest(String method, URL url, String body) throws IOException {
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    if (method.equals("DELETE") || method.equals("PATCH")) {
        conn.setRequestMethod("POST");
        conn.setRequestProperty("X-HTTP-Method-Override", method);
    } else {
        conn.setRequestMethod(method);
    }
    conn.setRequestProperty("Authorization", "OAuth " + token);
    conn.setRequestProperty("User-Agent", "IronMQ Java Client");

    if (body != null) {
        conn.setRequestProperty("Content-Type", "application/json");
        conn.setDoOutput(true);
    }

    conn.connect();

    if (body != null) {
        OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
        out.write(body);
        out.close();
    }

    int status = conn.getResponseCode();
    if (status != 200) {
        String msg;
        if (conn.getContentLength() > 0 && conn.getContentType().equals("application/json")) {
            InputStreamReader reader = null;
            try {
                reader = new InputStreamReader(conn.getErrorStream());
                Gson gson = new Gson();
                Error error = gson.fromJson(reader, Error.class);
                msg = error.msg;
            } catch (JsonSyntaxException e) {
                msg = "IronMQ's response contained invalid JSON";
            } finally {
                if (reader != null)
                    reader.close();
            }
        } else {
            msg = "Empty or non-JSON response";
        }
        throw new HTTPException(status, msg);
    }

    return new InputStreamReader(conn.getInputStream());
}

From the stack trace: io.iron.ironmq.Client.singleRequest(Client.java:218)
Contains this line: reader = new InputStreamReader(conn.getErrorStream());
conn.getErrorStream() is returning null, thus the NullPointerException.
I put a breakpoint in and the response code is 201 on the 'conn'.
From the JavaDoc on HttpUrlConnection conn.getErrorStream() only returns a non-null
when the connection fails, but a 201 status does not indicate an error.
So is this a bug? I tested it against ironmq v 3.0.0 and 3.0.1.

I have to think I must be doing something incorrectly, or everyone would be running across this. Any ideas?
Thx

Ironmq v3 initializes messages array with null on empty queues

Just ran a test against a new v3 queue.
It seems that when the queue i empty the reserve method https://github.com/iron-io/iron_mq_java/blob/v3/src/main/java/io/iron/ironmq/Queue.java#L125
will cause Gson to read/initialise the Messages.messages array as null.
The https://github.com/iron-io/iron_mq_java/blob/v3/src/main/java/io/iron/ironmq/Messages.java is not prepared for this since there is no null checks on getters causing NPE.
Seems that there has been som IronMQ server changes that returns a empty json body causing Gson not being able to serialise the messages array properly.

OSGi Compliance

Please publish IronMQ Java in an OSGi compliant way, e.g. change package type from JAR to bundle and leverage a bundle plugin in maven to build instead of a plain JAR. This will make the JAR usable in OSGi containers like Karaf.

Possible out of bounds exception

Following code does not deal with Array of length zero...

public Message get() throws IOException {
JSONObject jsonObj = client.get("queues/" + name + "/messages");
JSONArray array = jsonObj.getJSONArray("messages");
JSONObject jsonMsg = array.getJSONObject(0);

    Message msg = new Message();
    msg.setId(jsonMsg.getString("id"));
    msg.setBody(jsonMsg.getString("body"));
    if (jsonMsg.has("timeout")) {
        msg.setTimeout(jsonMsg.getLong("timeout"));
    }
    return msg;
}

Push message is very slow

Hi

I'm testing on local, it takes 500+ or even 1000+ms to push a message, very slow.

How can I improve the speed? or using connection pool? Thanks.

6141522235577319120 : 1655
6141522235577461809 : 537
6141522235577461812 : 1107
6141522239872429113 : 1645
6141522239872350360 : 990
6141522239872350374 : 1653
6141522239872207044 : 1016
6141522239872207029 : 711
6141522239872350377 : 525
6141522239872429134 : 1675

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.