Summary: Creating JMS messages with the space API; reading/taking JMS messages with the space API; using JMS API with the
MessageConverter to send custom POJOs to the space.
OverviewJMS-space interoperability allows JMS applications to communicate with non-JMS applications using the space, without having to know or deal with the space API. Gigaspaces introduced the ability for JMS applications to write messages to the space by implementing them as Externalizable MetaDataEntries, thus allowing non-JMS applications (usually space API applications) to read these MetaDataEntries using a template. Furthermore, since GigaSpaces, an application using the space API can write JMS messages of any type to the space, using the space API (without knowing JMS). Therefore, it is possible to handle JMS messages the same way as any other Entry type. In GigaSpaces, it is possible for the JMS application to control and decide exactly which type of object is written to the space, as long as the written object is valid for the receiving/reading application. This is done using the new MessageConverter feature. A common use-case is writing a JMS message to the space, where the message is "stripped" on the space side, leaving only the message body, usually a POJO. The space application can then read the POJO using a template that includes only the POJO type. To summarize, the table below shows which operations are supported, allowing interoperability between the JMS and space API.
The following sections will show you how to use the MessageConverter to write objects to the space using the JMS API; and how to write JMS messages and read/take those messages using the space API.
Writing POJOs/Entries to Space using JMS API – MessageConverterThis feature allows clients to define the outcome of JMS writes. By implementing a MessageConverter, you can convert JMS messages to a POJO before they are written to the space. The result of using a converter is that what is written to the space is not necessarily the JMS message (with all the headers, properties etc.), but the result of the message conversion. A basic use-case of this feature might be writing POJOs to the space using standard JMS API, and not the space API. A simple implementation of this conversion is the ObjectMessage2ObjectConverter class. When the MessageConverter is invoked by passing an ObjectMessage to its toObject method, it returns the contained POJO (message's body). When using the MessageConverter to send ObjectMessages, what is actually written to the space is only the JMS message body, which contains the POJO. The ObjectMessage wrapper is not written. You can create a custom implementation of the MessageConverter. The returned object can be an Entry, an object, an array of Entries, or an array of objects. The returned object can be the same JMS message passed as an argument, or a different one. Generally, the possibility of what can be returned from the conversion method are endless, however, the returned objects should be Entries or POJOs, valid for working with the space. IMessageConverter InterfaceThis interface defines an API for message conversion: interface IMessageConverter { Object toObject(javax.jms.Message m); } Implement the IMessageConverter interface to return the object required to be written to the space. Following is the implementation code of ObjectMessage2ObjectConverter: class ObjectMessage2ObjectConverter implements IMessageConverter { Object toObject(javax.jms.Message msg) { if (msg != null && msg instanceof javax.jms.ObjectMessage) { return ((javax.jms.ObjectMessage)msg).getObject(); { return msg; } } When passing an ObjectMessage to this converter, it returns the message body, which is actually the POJO. Setting MessageConverter for ConnectionFactoryYou can configure a ConnectionFactory to use a MessageConverter. Any MessageProducer created under this ConnectionFactory uses the converter automatically when sending messages. Offline ConfigurationYou can configure a ConnectionFactory to use a MessageConverter in the Open Spaces Spring configuration: <bean id="messageConverter" class="com.j_spaces.jms.utils.ObjectMessage2ObjectConverter" /> <os-jms:connection-factory id="connectionFactory" giga-space="gigaSpace" message-converter="messageConverter" /> In this example, a ConnectionFactory is configured, and an instance of ObjectMessage2ObjectConverter is injected into it. Configuring MessageConverters During RuntimeYou can use the GSJMSAdmin helper class to get a ConnectionFactory with a MessageConverter, by using one its methods. For the list of methods, see Javadoc . Passing null as a MessageConverter means that the ConnectionFactory does not use a MessageConverter. The following code uses the ObjectMessage2ObjectConverter to send instances of the MyPOJO class to the space: ObjectMessage2ObjectConverter converter = new ObjectMessage2ObjectConverter(); ConnectionFactory connectionFactory = GSJMSAdmin.getInstance().getConnectionFactory(space, converter); ... ObjectMessage msg = session.createObjectMessage(new MyPOJO()); producer.send(msg); Setting MessageConverter per MessageIt is possible to set a MessageConverter per sent message. This is done by setting the JMS_GSMessageConverter property before calling MessageProducer.send(). For example, to use the ObjectMessage2ObjectConvertor on a specific message: ObjectMessage2ObjectConverter converter = new ObjectMessage2ObjectConverter(); ObjectMessage msg = ... msg.setObjectProperty("JMS_GSMessageConverter", converter); producer.send(msg);
MessageConverter ResolutionIn case a MessageConverter is set for a ConnectionFactory, and another MessageConverter is set in a message, GigaSpaces resolves this in the following order:
Considerations
Writing and Reading JMS Messages using Space APIWriting JMS messages1. Create JMS Message InstanceTo create a JMS message, use the new operator as follows: GSSimpleMessageImpl simpleMessage = new GSSimpleMessageImpl(null); GSTextMessageImpl textMessage = new GSTextMessageImpl (null); GSObjectMessageImpl objectMessage = new GSObjectMessageImpl(null); GSMapMessageImpl mapMessage = new GSMapMessageImpl (null); GSBytesMessageImpl bytesMessage = new GSBytesMessageImpl (null);
2. Set Required HeadersUse the Message API to set the body, the header values, and the properties: // create the message GSTextMessage textMessage = new GSTextMessage(null); // set the message's body textMessage.setText("This is my message."); // set the message's headers textMessage.setJMSMessageID("message1"); // set the message's properties textMessage.setBooleanProperty("processed", false); 3. Write Message to SpaceUse the space API to write the message in an ordinary way: spaceProxy.write(textMessage, null, Lease.Forever);
Reading/Taking JMS MessagesLike with any Entry/POJO type, to receive a JMS message from the space you need to create a template. The template is matched with the objects in the space, and matching objects are retrieved. All public members of the message class participate in the match process, including the properties map. Therefore, if you don't know the exact content of a message properties map, it is better to set it to null in the JMS message template. 1. Create Template Based on JMS Message ClassesGSSimpleMessageImpl simpleMessageTemplate = new GSSimpleMessageImpl(); GSTextMessageImpl textMessageTemplate = new GSTextMessageImpl (); GSObjectMessageImpl objectMessageTemplate = new GSObjectMessageImpl(); GSMapMessageImpl mapMessageTemplate = new GSMapMessageImpl (); GSBytesMessageImpl bytesMessageTemplate = new GSBytesMessageImpl (); To create a generic template for all kinds of JMS messages, create an instance of GSMessageImpl as follows: GSMessageImpl genericMessageTemplate = new GSMessageImpl();
Using the default constructors creates a null template of the JMS message. This means that the properties map is also null. If you do not use the default constructor, you should set the properties map to null by invoking: jsmMessageTemplate.setProperties(null);
2. Read/Take from the SpaceYou can use the template to read or take messages from the space. The following example takes a text message from the space: GSTextMessageImpl msg = (GSTextMessageImpl ) spaceProxy.take(textMessageTemplate, null, 1000L);
|
![]() |
GigaSpaces.com - Legal Notice - 3rd Party Licenses - Site Map - API Docs - Forum - Downloads - Blog - White Papers - Contact Tech Writing - Gen. by Atlassian Confluence |