Skip to content

Commit

Permalink
Added more content
Browse files Browse the repository at this point in the history
  • Loading branch information
nidhibhammar committed Sep 9, 2024
1 parent e960e75 commit 2559801
Showing 1 changed file with 268 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,274 @@ queue.setEdbQueueTbl(queueTable);
queue.start();
```

## Client-side example
## Setting up JMS application

After creating the queue table and queue for the message types and starting the queue, you can follow these steps to set up your JMS Application:

1. Create a [Connection Factory](#connection-factory).
1. Create a [Connection](#connection) using the connection factory.
1. Create a [Session](#session) using the connection.
1. Get the Queue from the session.
1. Create a message producer using the session and queue.
1. Send messages.
1. Create a message consumer using the session and queue.
1. Receive messages.


### Connection factory

The Connection Factory is used to create connections. EDBJmsConnectionFactory is an implementation of ConnectionFactory and QueueConnectionFactory, used to create Connection and QueueConnection. A connection factory can be created using one of the constructors of the EDBJmsConnectionFactory class. All three constructors can be used to create either a ConnectionFactory or QueueConnectionFactory.

```java
//Constructor with connection related properties.
public EDBJmsConnectionFactory(String host, int port, String database,
String username, String password);
//Constructor with connection string, user name and password.
public EDBJmsConnectionFactory(String connectionString,
String username, String password);
//Constructor with SQL Connection.
public EDBJmsConnectionFactory(java.sql.Connection connection);
```

This example shows how to create a ConnectionFactory using an existing `java.sql.Connection`:

```java
javax.jms.ConnectionFactory connFactory = new EDBJmsConnectionFactory(connection);
```

This example shows how to create a QueueConnectionFactory using a connection string, username, and password:

```java
javax.jms.QueueConnectionFactory connFactory = new EDBJmsConnectionFactory
("jdbc:edb//localhost:5444/edb", "enterprisedb", "edb");
```

### Connection

A Connection is a client's active connection that can be created from the ConnectionFactory and used to create sessions. EDBJmsConnection is an implementation of Connection, while EDBJmsQueueConnection is an implementation of QueueConnection and extends EDBJmsConnection. A Connection can be created using ConnectionFactory, while QueueConnection can be created from QueueConnectionFactory.

This example shows how to create a Connection and a QueueConnection:

```java
//Connection from ConnectionFactory. Assuming connFactory is ConnectionFactory.
javax.jms.Connection connection = connFactory.createConnection();

////Connection from QueueConnectionFactory. Assuming connFactory is QueueConnectionFactory.
javax.jms.QueueConnection queueConnection = connFactory.createQueueConnection();
```

A connection must be started in order for the consumer to receive messages. On the other hand, a producer can send messages without starting the connection. To start a connection, use the following code:

```java
queueConnection.start();
```

A connection can be stopped at any time to cease receiving messages, and can be restarted when needed. However, a closed connection cannot be restarted.

To stop and close the connection, use the following code:

```java
queueConnection.stop();
queueConnection.close();
```

### Session

The Session in EDBJms is used for creating producers and consumers, and for sending and receiving messages. EDBJmsSession implements the basic Session functionality, while EDBJmsQueueSession extends EDBJmsSession and implements QueueSession. A session can be created from a Connection.

This example shows how to create a Session and a QueueSession:

```java
// Session
javax.jms.Session session = connection.createSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE);
// QueueSession
javax.jms.QueueSession session = queueConnection.createQueueSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE);
```

A Session or QueueSession is also used to create queues. It's important to note that in this context, "creating a queue" does not refer to physically creating the queue. As discussed earlier, the queue needs to be created and started as part of the server-side setup. In this context, creating a queue means getting the queue, related queue table, and payload type that have already been created.

This example shows how to create a queue:

```java
javax.jms.Queue queue = session.createQueue("MSG_QUEUE");
```

### Message producer

A message producer is responsible for creating and sending messages. It is created using a session and queue. EDBJmsMessageProducer is an implementation of MessageProducer, but in most cases, you will be using the standard MessageProducer.

This example shows how to create a message producer, create a message, and send it. Creating messages of different types will be discussed in the following sections.

```java
javax.jms.MessageProducer messageProducer = session.createProducer(queue);

javax.jms.Message msg = session.createMessage();
msg.setStringProperty("myprop1", "test value 1");

messageProducer.send(msg);
```

### Message consumer

A Message consumer is used to receive messages. It is created using a session and a queue. EDBJmsMessageConsumer is an implementation of MessageConsumer, but you will most often use the standard MessageConsumer.

This example shows how to create a message consumer and receive a message:

```java
javax.jms.MessageConsumer messageConsumer = session.createConsumer(queue);

javax.jms.Message message = messageConsumer.receive();
```

### Message acknowledgement

Acknowledgement of messages is controlled by the two arguments to the createSession() and createQueueSession() methods:

```java
EDBJmsConnection.createSession(boolean transacted, int acknowledgeMode)

EDBJmsQueueConnection.createQueueSession(boolean transacted, int acknowledgeMode)
```

If the first argument is true, it indicates that the session mode is transacted, and the second argument is ignored. However, if the first argument is false, then the second argument comes into play, and the client can specify different acknowledgment modes. These acknowledgment modes include,
- Session.AUTO_ACKNOWLEDGE
- Session.CLIENT_ACKNOWLEDGE
- Session.DUPS_OK_ACKNOWLEDGE

The following sections describe different modes of acknowledgement:

### Transacted session

In transacted sessions, messages are both sent and received during a transaction. These messages are acknowledged by making an explicit call to commit(). If rollback() is called, all received messages will be marked as not acknowledged.

A transacted session always has an active transaction. When a client calls the commit() or rollback() method, the current transaction is either committed or rolled back, and a new transaction is started.

This example explains how the transacted session works:

```java
MessageProducer messageProducer = (MessageProducer) session.createProducer(queue);

//Send a message in transacted session and commit it.

//Send message
TextMessage msg1 = session.createTextMessage();
String messageText1 = "Hello 1";
msg1.setText(messageText1);
messageProducer.send(msg1);

//Commit the transaction.
session.commit();

//Now we have one message in the queue.

//Next, we want to send and receive in the same transaction.

MessageConsumer messageConsumer = (MessageConsumer) session.createConsumer(queue);

//Send a Message in transaction.
TextMessage msg2 = session.createTextMessage();
String messageText2 = "Hello 2";
msg2.setText(messageText2);
messageProducer.send(msg2);

//Receive message in the same transaction. There should be 1 message available.
Message message1 = messageConsumer.receive();
TextMessage txtMsg1 = (TextMessage) message1;

//Send another Message in transaction.
TextMessage msg3 = session.createTextMessage();
String messageText3 = "Hello 3";
msg3.setText(messageText3);
messageProducer.send(msg3);

//Commit the transaction.
//This should remove the one message we sent initially and received above and send 2 messages.
session.commit();

//2 messages are in the queue so we can receive these 2 messages.

//Receive 1
Message message2 = messageConsumer.receive();
TextMessage txtMsg2 = (TextMessage) message2;

//Receive 2
Message message3 = messageConsumer.receive();
TextMessage txtMsg3 = (TextMessage) message3;

//Commit the transaction. This will consume the two messages.
session.commit();

//Receive should fail now as there should be no messages available.
Message message4 = messageConsumer.receive();
//message4 will be null here.
```

#### AUTO_ACKNOWLEDGE mode

If the first argument to createSession() or createQueueSession() is false and the second argument is Session.AUTO_ACKNOWLEDGE, the messages are automatically acknowledged.

#### DUPS_OK_ACKNOWLEDGE mode

This mode instructs the session to lazily acknowledge the message, and it is okay if some messages are redelivered. However, in EDB JMS, this option is implemented the same way as Session.AUTO_ACKNOWLEDGE, where messages will be acknowledged automatically.

#### CLIENT_ACKNOWLEDGE mode

If the first argument to createSession() or createQueueSession() is false and the second argument is Session.CLIENT_ACKNOWLEDGE, the messages are acknowledged when the client acknowledges the message by calling the acknowledge() method on a message. Acknowledging happens at the session level, and acknowledging one message will cause all the received messages to be acknowledged.

For example, if we send 5 messages and then receive the 5 messages, acknowledging the 5th message will cause all 5 messages to be acknowledged.

```java
MessageProducer messageProducer = (MessageProducer) session.createProducer(queue);

//Send 5 messages
for(int i=1; i<=5; i++) {
TextMessage msg = session.createTextMessage();
String messageText = "Hello " + i;
msg.setText(messageText);
messageProducer.send(msg);
}

MessageConsumer messageConsumer = (MessageConsumer) session.createConsumer(queue);

//Receive 4
for(int i=1; i<=4; i++) {
Message message = messageConsumer.receive();
TextMessage txtMsg = (TextMessage) message;
}

//Receive the 5th message
Message message5 = messageConsumer.receive();
TextMessage txtMsg5 = (TextMessage) message5;

//Now acknowledge it and all the messages will be acknowledged.
txtMsg5.acknowledge();

//Try to receive again. This should return null as there is no message available.
Message messageAgain = messageConsumer.receive();
```

### Message types

EDB-JDBC JMS API supports the following message types and can be used in a standard way:

| Message type | JMS type |
|------------------------|-------------------------|
| aq$_jms_message | javax.jms.Message |
| aq$_jms_text_message | javax.jms.TextMessage |
| aq$_jms_bytes_message | javax.jms.BytesMessage |
| aq$_jms_object_message | javax.jms.ObjectMessage |

#### Message properties

#### TextMessage

#### BytesMessage

#### ObjectMessage

### Message

#### Non-standard message

After you create a user-defined type followed by queue table and queue, start the queue. Then, you can enqueue or dequeue a message using EDB-JDBC driver's JMS API.

Expand Down

0 comments on commit 2559801

Please sign in to comment.