Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 JMS as XML and Object-Based Messaging Integration Infrastructure Michael Wynholds Founder Carbon Five

Similar presentations


Presentation on theme: "1 JMS as XML and Object-Based Messaging Integration Infrastructure Michael Wynholds Founder Carbon Five"— Presentation transcript:

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

2 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 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 4 REAL WORLD EXAMPLE #1 Major Components vs. Sub-Components

5 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 6 THE WRONG WAY Processes happening serially: –User does something in major component –Waits for sub-component to finish before continuing on through the application

7 7 THE WRONG WAY Two things wrong: –Why should the user wait? –What if we decide later we want to perform other non-crucial actions at this time?

8 8 THE RIGHT WAY: ASYNCHRONOUS

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

10 10 THE RIGHT WAY: LOOSE COUPLING

11 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 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 13 SIGNIFICANT EVENT XML 2001-03-17 12:42:06 PST Guy Incognito guy@coolpets.com ADMINISTRATOR Michael Wynholds mike@carbonfive.com REGULAR PREFERRED

14 14 SIGNIFICANT EVENT OBJECTS

15 15 NOTIFICATION ENGINE CODE private 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 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 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 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 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 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 21 Entity EJB persistence optimization REAL WORLD EXAMPLE #2

22 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 whats the problem?

23 23 THE PROBLEM Multiple beans modify same dependent object Bean instance may be on separate machines

24 24 SOLUTION #1 Make dependent object an EJB No longer coarse-grained –EJB overhead takes toll Multiple machine problem not fixed

25 25 Dont use isModified() Slooooooowwwwwww…. Every getter hits the database –Something may have changed –But most of the time, nothing has changed SOLUTION #2

26 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 27 DEPENDENT OBJECT CODE public class Thing { private String name; public void setName(String name) { this.name = name; fireModificationEvent(this.getClass().getName(), this.hashCode()); }

28 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 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 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 dont know.

31 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 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 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 34 REFERENCES http://www.carbonfive.com/oreilly Contains links to this and other Carbon Five presentations.


Download ppt "1 JMS as XML and Object-Based Messaging Integration Infrastructure Michael Wynholds Founder Carbon Five"

Similar presentations


Ads by Google