1 JMS as XML and Object-Based Messaging Integration Infrastructure Michael Wynholds Founder Carbon Five mike@carbonfive.com.

Post on 27-Mar-2015

215 Views

Category:

Documents

1 Downloads

Preview:

Click to see full reader

Transcript

1

JMS as XML and Object-Based Messaging Integration Infrastructure

Michael WynholdsFounderCarbon Fivemike@carbonfive.com

2

THIS PRESENTATION

• Basics of JMS – 10%• Types of integration – 50%

– Integrate system components– Integrate dependent objects in EJBs

• Message payloads – 20%– Java objects– XML

• Q & A – 20%

3

WHAT IS JMS?

• Java Messaging Service• Java API for enterprise messaging

– Non-Java implementations available• Multiple messaging paradigms

– Point-to-point– Publish/Subscribe

4

REAL WORLD EXAMPLE #1

Major Components

vs.

Sub-Components

5

INTEGRATING SYSTEM COMPONENTS

• Major components– Crucial serial functionality– Affects user experience– Example: shopping basket

• Sub-components– Possibly crucial functionality– Slight delays acceptable– Example: Email notification engine

6

THE WRONG WAYProcesses happening serially:

– User does something in major component– Waits for sub-component to finish before

continuing on through the application

7

THE WRONG WAYTwo things wrong:

– Why should the user wait?– What if we decide later we want to perform other

non-crucial actions at this time?

8

THE RIGHT WAY:ASYNCHRONOUS

9

ASYNCHRONOUS

• Fire and continue• Can still have guaranteed delivery• Sub-components can be moved to other

machines

10

THE RIGHT WAY:LOOSE COUPLING

11

LOOSE COUPLING• Determine significant events• Major components publish• Sub-components subscribe• Addition or modification of sub-component

requires no change to major component

12

EXAMPLE:EMAIL NOTIFICATION

• Pet Store• What are significant events?

– User logs in– User status is changed– User purchases pet– Shipment is delayed (from another publisher)

13

SIGNIFICANT EVENT XML<event type="user-status-change"> <context> <timestamp>2001-03-17 12:42:06 PST</timestamp> <user> <first-name>Guy</first-name> <last-name>Incognito</last-name> <email>guy@coolpets.com</email> <status>ADMINISTRATOR</status> </user> </context>

<user> <first-name>Michael</first-name> <last-name>Wynholds</last-name> <email>mike@carbonfive.com</email> <status>REGULAR</status> </user>

<new-status>PREFERRED</new-status></event>

14

SIGNIFICANT EVENT OBJECTS

15

NOTIFICATION ENGINE CODEprivate void init() throws NamingException, JMSException{ Context ctx = JNDIUtil.getContext(); String selector = new StringBuffer() .append("type = ").append(MessageTypes.CARBONFIVE_EVENT) .toString();

tconFactory = (TopicConnectionFactory) ctx.lookup(JMS_FACTORY); tcon = tconFactory.createTopicConnection(); tsession = tcon.createTopicSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE); try { topic = (Topic) ctx.lookup(TOPIC_NAME); } catch (NamingException ne) { topic = tsession.createTopic(TOPIC_NAME); ctx.bind(TOPIC_NAME, topic); } tsubscriber = tsession.createSubscriber(topic, selector, false); tsubscriber.setMessageListener(this); tcon.start();}

16

public void onMessage(javax.jms.Message msg){ synchronized (this) { int type = msg.getIntProperty("type"); Event event = (Event) ((ObjectMessage) msg).getObject(); switch (msg.getIntProperty("type")) { case MessageTypes.USER_STATUS_CHANGE: Email email = generateEmail((UserStatusChangeEvent) event); email.send(); break;

default: break; } }}

NOTIFICATION ENGINE CODE

17

private Email generateEmail(UserStatusChangeEvent event){ Email email = new Email(); email.setTo(event.getUser().getEmail()); email.setFrom("administrator@carbonfive.com"); email.setSubject("Your status has changed"); email.setBody(getBody()); return email;}

NOTIFICATION ENGINE CODE

18

MESSAGE SENDER CODE

private void init() throws NamingException, JMSException{ Context ctx = JNDIUtil.getContext();

tconFactory = (TopicConnectionFactory) ctx.lookup(JMS_FACTORY); tcon = tconFactory.createTopicConnection(); tsession = tcon.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); try { topic = (Topic) ctx.lookup(TOPIC_NAME); } catch (NamingException ne) { topic = tsession.createTopic(TOPIC_NAME); ctx.bind(TOPIC_NAME, topic); } tpublisher = tsession.createPublisher(topic);}

19

public void send(Serializable obj, int type) throws JMSException{ if (obj == null) { throw new NullPointerException("obj is null"); } ObjectMessage msg = tsession.createObjectMessage(); msg.setObject(obj); msg.setIntProperty("type", type); tpublisher.publish(msg); msg = null; // gc}

MESSAGE SENDER CODE

20

USER STATUS CHANGE CODE

private void handleStatusChange(ServletRequest request){ HttpSession session = request.getSession(true);

User user = UserManager.getUserById(request.getParameter("user_id")); User me = session.getCurrentUser();

UserStatusChangeEvent event = new UserStatusChangeEvent(); EventContext ctx = new EventContext(); ctx.setUser(me); ctx.setTimestamp(new Date()); event.setContext(ctx); event.setUser(user); event.setNewStatus(request.getParameter("new_status")); MessageSender.send(event, MessageTypes.USER_STATUS_CHANGE_EVENT);

user.setStatus(request.getParameter("new_status"));}

21

Entity EJB persistence optimization

REAL WORLD EXAMPLE #2

22

ENTITY EJB PERSISTENCE• Entity EJB guarantees synchronization

with persistent store• Overhead in EJB container• Coarse-grained Entity Beans are better• isModified() method often used to optimize

• So what’s the problem?

23

THE PROBLEM

• Multiple beans modify same dependent object• Bean instance may be on separate machines

24

SOLUTION #1• Make dependent object an EJB• No longer coarse-grained

– EJB overhead takes toll

• Multiple machine problem not fixed

25

• Don’t use isModified()• Slooooooowwwwwww….• Every getter hits the database

– Something may have changed– But most of the time, nothing has changed

SOLUTION #2

26

• JMS-based isModified()• Dependent object publishes to topic when

a setter is called• Entity Beans subscribe to events

corresponding to their dependent objects• Efficient• Spans multiple machines

SOLUTION #3

27

DEPENDENT OBJECT CODEpublic class Thing{ private String name;

public void setName(String name) { this.name = name; fireModificationEvent(this.getClass().getName(), this.hashCode()); }}

28

EJB isModified()private void init() throws NamingException, JMSException{ Context ctx = JNDIUtil.getContext(); String selector = new StringBuffer() .append(“class = ”) .append(Thing.class.getName()) .toString();

tconFactory = (TopicConnectionFactory) ctx.lookup(JMS_FACTORY); tcon = tconFactory.createTopicConnection(); tsession = tcon.createTopicSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE); try { topic = (Topic) ctx.lookup(TOPIC_NAME); } catch (NamingException ne) { topic = tsession.createTopic(TOPIC_NAME); ctx.bind(TOPIC_NAME, topic); } tsubscriber = tsession.createSubscriber(topic, selector, false); tsubscriber.setMessageListener(this); tcon.start();}

29

EJB isModified()public void onMessage(javax.jms.Message msg){ synchronized (this) { ModEvent event = (ModEvent) ((ObjectMessage) msg).getObject(); if (Thing.class.getName().equals(event.getClassName())) { if (this.thing.hashCode == event.getHashCode()) { this.setModified(true); } } }}

30

ISSUES• Class-based, not object-based events

– May receive many messages when using common objects

• hashCode() method not always unique– Just means you do a database hit

• Must implement hashCode() in objects to work across machines

• Can use hash code in selector– Which is more efficient?– I don’t know.

31

MESSAGE PAYLOADS

• Objects– Rule of thumb: Use objects when you can

use objects.

• XML– Rule of thumb: Use XML when you need to

use XML.

32

OBJECT MESSAGES• Easy to create / use• Little processing overhead• No need for XML tools• Better within same JVM or when JVM is

guaranteed• Full functionality of Java inside message

33

XML MESSAGES• Can be much smaller size

– Better for high-traffic distributed systems

• Potential direct interaction with receiving systems

• Producer or consumer may be non-Java JMS client

• No class sync needed

34

REFERENCES

• http://www.carbonfive.com/oreilly

Contains links to this and other Carbon Five presentations.

top related