1 / 34

JMS as XML and Object-Based Messaging Integration Infrastructure

JMS as XML and Object-Based Messaging Integration Infrastructure. Michael Wynholds Founder Carbon Five mike@carbonfive.com. THIS PRESENTATION. Basics of JMS – 10% Types of integration – 50% Integrate system components Integrate dependent objects in EJBs Message payloads – 20%

declan
Download Presentation

JMS as XML and Object-Based Messaging Integration Infrastructure

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. JMS as XML and Object-Based Messaging Integration Infrastructure Michael Wynholds Founder Carbon Five mike@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 WAY Processes happening serially: • User does something in major component • Waits for sub-component to finish before continuing on through the application

  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. 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 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. NOTIFICATION ENGINE CODE 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; } } }

  17. NOTIFICATION ENGINE CODE 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; }

  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. MESSAGE SENDER CODE 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 }

  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. REAL WORLD EXAMPLE #2 Entity EJB persistence optimization

  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. SOLUTION #2 • Don’t use isModified() • Slooooooowwwwwww…. • Every getter hits the database • Something may have changed • But most of the time, nothing has changed

  26. SOLUTION #3 • 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

  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. 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.

More Related