Davies j.   the definitive guide to soa. bea aqua logic service bus(2007)(408)
Upcoming SlideShare
Loading in...5

Davies j. the definitive guide to soa. bea aqua logic service bus(2007)(408)



Definitive Guide to SOA. BEA AquaLogic

Definitive Guide to SOA. BEA AquaLogic



Total Views
Slideshare-icon Views on SlideShare
Embed Views



1 Embed 1

http://localhost 1



Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
Post Comment
Edit your comment

    Davies j.   the definitive guide to soa. bea aqua logic service bus(2007)(408) Davies j. the definitive guide to soa. bea aqua logic service bus(2007)(408) Presentation Transcript

    •  CYAN   YELLOW  MAGENTA   BLACK   PANTONE 123 C EMPOWERING PRODUCTIVITY FOR THE SERVICE DEVELOPER The EXPERT’s VOIce ® in SOA Companion eBook Available The Definitive Guide to SOA: BEA AquaLogic Service Bus ® The Definitive Dear Reader, Guide to The Definitive Guide to SOA In the past few years, Service Oriented Architecture (SOA) in general and SOA Enterprise Service Buses (ESBs) specifically have gained a lot of momentum in the software industry. Although a number of excellent books are available on these topics, the book I really wanted to read was one that married the theory to real-world practice. Like many software developers and architects, I learn best from code. I began learning the BEA AquaLogic® Service Bus (ALSB) while it was still in beta form. I found myself struggling with some of the product’s core concepts and supporting technologies. It occurred to me that there are many people like myself in the software industry today: software professionals who know what they need to do, but who find themselves at a loss when moving to new products, technologies, and paradigms. I wanted a book that would allow me to understand the service bus quickly and show me, with living code, how these SOA and ESB theories are BEA AquaLogic Service Bus best put into practice. Sadly, no such book existed. The opportunity was clear. I began to work on this book knowing that my greatest strength was my ignorance. I would ask the experts at BEA every question I had, and then document their answers. I believe that many of your questions will be the same as mine. Of course, some topics require true expertise before you can write about them authoritatively, BEA AquaLogic Service Bus specifically security and the Transport SDK. To address these topics, I asked my coauthors Ashish Krishna and David Schorow to contribute their invaluable ® expertise. As a result, this book is suitable for people who are completely new to ESBs and SOA theory. It is also an invaluable tool for experts in ALSB. Jeff Davies, ® BEA Senior SOA Architect A hands-on guide to SOA with Companion eBook THE APRESS JAVA™ ROADMAP BEA AquaLogic® Service Bus Beginning Java™ EE 5 The Definitive Guide to SOA: See last page for details BEA AquaLogic® Service Bus on $10 eBook version Beginning J2EE™ 1.4 SchorowSOURCE CODE ONLINE Jeff Davies, Krishna, ISBN-13: 978-1-59059-797-2 Davies,www.apress.com ISBN-10: 1-59059-797-4Shelve in 90000 BEA Senior SOA ArchitectJava Programming/Web Services with Ashish Krishna and David Schorow(with other SOA books) Foreword by Jayaram KasiUser level:Intermediate–Advanced 9 781590 597972 Director of Technical Program Management, BEA Systems this print for content only—size & color not accurate 7" x 9-1/4" / CASEBOUND / MALLOY
    • 797-4FM 4/4/07 5:00 PM Page i The Definitive Guide to SOA: BEA AquaLogic ® Service Bus Jeff Davies with Ashish Krishna and David Schorow
    • 797-4FM 4/4/07 5:00 PM Page ii The Definitive Guide to SOA: BEA AquaLogic® Service Bus Copyright © 2007 by BEA Systems, Inc. All rights reserved. No part of this work may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording, or by any information storage or retrieval system, without the prior written permission of the copyright owner and the publisher. ISBN-13: 978-1-59059-797-2 ISBN-10: 1-59059-797-4 Printed and bound in the United States of America 9 8 7 6 5 4 3 2 1 Trademarked names may appear in this book. Rather than use a trademark symbol with every occurrence of a trademarked name, we use the names only in an editorial fashion and to the benefit of the trademark owner, with no intention of infringement of the trademark. AquaLogic® and all other AquaLogic-based marks are trademarks or registered trademarks of BEA Systems, Inc. in the US and in other countries. Apress, Inc. is not affiliated with BEA Systems, Inc. Lead Editor: Steve Anglin Technical Reviewer: Jayaram Kasi Editorial Board: Steve Anglin, Ewan Buckingham, Gary Cornell, Jason Gilmore, Jonathan Gennick, Jonathan Hassell, James Huddleston, Chris Mills, Matthew Moodie, Jeff Pepper, Paul Sarknas, Dominic Shakeshaft, Jim Sumser, Matt Wade Project Manager: Elizabeth Seymour Copy Edit Manager: Nicole Flores Copy Editors: Susannah Davidson Pfalzer and Heather Lang Assistant Production Director: Kari Brooks-Copony Production Editor: Katie Stence Compositor: Dina Quan and Gina Rexrode Proofreader: Liz Welch Indexer: Broccoli Information Management Cover Designer: Kurt Krames Manufacturing Director: Tom Debolski Distributed to the book trade worldwide by Springer-Verlag New York, Inc., 233 Spring Street, 6th Floor, New York, NY 10013. Phone 1-800-SPRINGER, fax 201-348-4505, e-mail orders-ny@springer-sbm.com, or visit http://www.springeronline.com. For information on translations, please contact Apress directly at 2560 Ninth Street, Suite 219, Berkeley, CA 94710. Phone 510-549-5930, fax 510-549-5939, e-mail info@apress.com, or visit http://www.apress.com. The information in this book is distributed on an “as is” basis, without warranty. Although every precau- tion has been taken in the preparation of this work, neither the author(s) nor Apress shall have any liability to any person or entity with respect to any loss or damage caused or alleged to be caused directly or indirectly by the information contained in this work.
    • 797-4FM 4/4/07 5:00 PM Page iii Contents at a Glance Foreword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii About the Authors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv About the Technical Reviewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi ICHAPTER 1 Why Use a Service Bus? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 ICHAPTER 2 Installing and Configuring the Software . . . . . . . . . . . . . . . . . . . . . . . . 11 ICHAPTER 3 Hello World Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 ICHAPTER 4 Message Flow Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 ICHAPTER 5 A Crash Course in WSDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 ICHAPTER 6 Message Flows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 ICHAPTER 7 Advanced Messaging Topics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 ICHAPTER 8 Reporting and Monitoring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173 ICHAPTER 9 Security Models and Service Bus. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195 ICHAPTER 10 Planning Your Service Landscape . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 ICHAPTER 11 Versioning Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233 ICHAPTER 12 Administration, Operations, and Management . . . . . . . . . . . . . . . . . 253 ICHAPTER 13 Custom Transports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 ICHAPTER 14 How Do I . . . ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335 IAPPENDIX AquaLogic Service Bus Actions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355 IINDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369 iii
    • 797-4FM 4/4/07 5:00 PM Page iv
    • 797-4FM 4/4/07 5:00 PM Page v Contents Foreword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii About the Authors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv About the Technical Reviewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi ICHAPTER 1 Why Use a Service Bus? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 The Problems We Face Today . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Point-to-Point Integrations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Tight Coupling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 More Code Than Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 Early ESBs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Modern Solutions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Loose Coupling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Location Transparency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Mediation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Schema Transformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Service Aggregation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Load Balancing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Enforcing Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Monitoring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Configuration vs. Coding. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Enter AquaLogic Service Bus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Loose Coupling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Location Transparency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Mediation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Schema Transformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Service Aggregation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Load Balancing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Enforcing Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 Monitoring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 Configuration vs. Coding. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 Won’t This Lock Me into BEA Technologies? . . . . . . . . . . . . . . . . . . . . . . . . . 9 Why Buy an Enterprise Service Bus? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 v
    • 797-4FM 4/4/07 5:01 PM Page vi vi ICONTENTS ICHAPTER 2 Installing and Configuring the Software . . . . . . . . . . . . . . . . . . 11 Installing the Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 Configuring WebLogic Workshop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 A Quick Tour of Workshop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 Creating the Service Bus Domain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 Configuring Ant in Eclipse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 Configuring Workshop for the AquaLogic Server . . . . . . . . . . . . . . . . . . . . . 16 Importing the Sample Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 ICHAPTER 3 Hello World Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 Creating and Deploying a Web Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 @WebService . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 @SoapBinding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 @WLHttpTransport . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 @WebMethod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 Creating a POJO Test Client. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 Creating the HelloWorld Project in ALSB . . . . . . . . . . . . . . . . . . . . . . . 35 Creating the WSDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 Business Services and Proxy Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 Creating the Business Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 Creating the Proxy Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 A Quick Note on the Configuration Changes Screen . . . . . . . . . . . . . 45 Testing the Proxy Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 ICHAPTER 4 Message Flow Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 Message Flow Overview. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 Pipeline Pairs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 Branch Nodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 Route Nodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 Goodbye World! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 What the Heck Just Happened Here?. . . . . . . . . . . . . . . . . . . . . . . . . . 60 A Hidden Design Flaw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
    • 797-4FM 4/4/07 5:01 PM Page vii ICONTENTS vii ICHAPTER 5 A Crash Course in WSDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 Namespaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 The Default Namespace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 Target Namespace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 <types> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 Native Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 Custom Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 minOccurs and maxOccurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 Importing XML Schemas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 <message> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 <portType> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 <binding> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 <service> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 <port> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 WSDL Best Practices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 Elements vs. Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 The Dependency Trap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 Document-Centric vs. RPC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 Troubleshooting WSDLs and Schemas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 Visualizing Documents from Schemas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 The ElementFormDefault Attribute . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 The attributeFormDefault Attribute . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 ICHAPTER 6 Message Flows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 Scenario 1: User Requests a Product Catalog . . . . . . . . . . . . . . . . . . . . . . . 95 Scenario 2: User Orders a Product . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 ICHAPTER 7 Advanced Messaging Topics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 Synchronous Invocation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 Asynchronous Invocation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 Setting up WebLogic Server. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 Asynchronous Business Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
    • 797-4FM 4/4/07 5:01 PM Page viii viii ICONTENTS Service Types and Transport Protocols . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 SOAP with WSDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 SOAP Without WSDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 XML with WSDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 XML Without WSDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 Messaging Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 Transport Typed Service: EJB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 POJO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164 SOAP with Attachments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 ICHAPTER 8 Reporting and Monitoring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173 Monitoring. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173 The Temperamental Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174 Reporting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188 Viewing Report Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 Purging Report Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191 Reporting Providers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192 Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194 ICHAPTER 9 Security Models and Service Bus . . . . . . . . . . . . . . . . . . . . . . . . . 195 Security Paradigms with SOA Challenges . . . . . . . . . . . . . . . . . . . . . . . . . . 195 Transport-Level Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196 Message-Level Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197 Ad-Hoc, Custom, Token-Based Security . . . . . . . . . . . . . . . . . . . . . . 197 ALSB Security Model. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 Inbound Security in ALSB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 Identity Propagation in ALSB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 SSL Authentication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 Digital Signatures and Encryption . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201 Using ALSB Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201 Recommendations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
    • 797-4FM 4/4/07 5:01 PM Page ix ICONTENTS ix ICHAPTER 10 Planning Your Service Landscape . . . . . . . . . . . . . . . . . . . . . . . . 205 The SOA Coordinate System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 The Software Abstraction Scale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 The Service Domain Scale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210 The Coordinate System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 Mapping Your SOA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213 The Top-Down Approach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213 The Bottom-Up Approach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215 SOA Mapping Test 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 SOA Mapping Test 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217 Service Maps at Scale. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 Service Tooling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219 Architectural Transformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219 Communication Principles and Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . 224 Communication Principle I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225 Communication Principle II . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225 Communication Principle III . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225 Communication Pattern I: Flow of Gravity . . . . . . . . . . . . . . . . . . . . . 225 Communication Pattern II: Direct Use of Enterprise Services . . . . 227 Communication Pattern III: Indirect Use of Enterprise Services . . . 228 Communication Pattern IV: Inter-Application Communications Within a Domain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229 Geared for Performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229 Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231 ICHAPTER 11 Versioning Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233 What Is a Service? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233 Service Orientation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237 What Is Versioning?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238 Do We Version Services or Operations? . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 Versioning Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240 Versioning Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 Constrained by Reality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 If Not Versions, Then What?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 The Future of IT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
    • 797-4FM 4/4/07 5:01 PM Page x x ICONTENTS ICHAPTER 12 Administration, Operations, and Management. . . . . . . . . . . 253 Support for Team Development . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253 The Change Center . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253 Conflict Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253 Undo and Redo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254 How to Resolve Conflicts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254 System Administration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256 Operations Settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256 Access Control Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257 Deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258 Deployment Automation Basics. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260 Advanced Automation Technique . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267 ALSB Clusters. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267 Creating a Cluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270 Introducing the Node Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271 Controlling Managed Servers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273 Deploying to a Cluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274 Location Transparency and ALSB . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274 Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279 ICHAPTER 13 Custom Transports. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 Introduction to Custom Transports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 Why Build a Custom Transport? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282 How Does a Custom Transport Fit into ALSB? . . . . . . . . . . . . . . . . . 283 Components of a Custom Transport . . . . . . . . . . . . . . . . . . . . . . . . . . 285 The Sample Socket Transport . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285 Capabilities of the Socket Transport. . . . . . . . . . . . . . . . . . . . . . . . . . 286 Building and Installing the Sample Transport . . . . . . . . . . . . . . . . . . 286 Using the Sample Socket Transport . . . . . . . . . . . . . . . . . . . . . . . . . . 290 Building a Custom Transport . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294 Overview of the Transport SDK Interfaces. . . . . . . . . . . . . . . . . . . . . 294 Overview of Tasks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296 Transport Provider Configuration XML File . . . . . . . . . . . . . . . . . . . . 297 Transport Provider Schemas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298 Implementing Transport Provider User Interface Classes . . . . . . . . 301 Deploying Service Endpoints Using the Custom Transport . . . . . . . 310 Implementing Transport Provider Runtime Classes . . . . . . . . . . . . . 313 Registering the Transport Provider . . . . . . . . . . . . . . . . . . . . . . . . . . . 332 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
    • 797-4FM 4/4/07 5:01 PM Page xi ICONTENTS xi ICHAPTER 14 How Do I . . . ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335 Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335 Administration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337 Messaging and Protocols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343 XML, XQuery, and XSLT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350 Miscellaneous . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351 Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353 IAPPENDIX AquaLogic Service Bus Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . 355 Communication Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355 Dynamic Publish . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356 Publish . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357 Publish Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357 Routing Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358 Service Callout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359 Transport Headers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359 Flow Control Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359 For Each . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360 If . . . Then . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361 Raise Error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361 Reply . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362 Resume . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362 Skip . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363 Message Processing Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363 Assign . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363 Delete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364 Insert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364 Java Callout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364 MFL Transform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365 Rename . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365 Replace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366 Validate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366 Reporting Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366 Alert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367 Log . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367 Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 368 IINDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369
    • 797-4FM 4/4/07 5:01 PM Page xii
    • 797-4FM 4/4/07 5:01 PM Page xiii Foreword E nterprise Service Bus (ESB) is a hot topic today. Many vendors are either building new products in this category or dressing up their existing products to pitch them as an ESB. How- ever, there is no clearly accepted definition of what an ESB is, or what its architecture or programming paradigm should be. Definitions range from saying that ESB is wholly unneeded to saying it has all the capabilities of a full integration suite with built-in BPM, data aggrega- tion, and WSM capabilities. Architectures range from being embedded in the clients and endpoints to being a central intermediary. Programming paradigms for the ESB range from writing Java to being completely configuration driven and pliable with graphical interfaces. BEA did not dress up one of their existing products and pitch it as an ESB but built an ESB from scratch. First introduced in summer 2005, BEA’s ESB has a razor sharp focus on where it is positioned as a component in an end-to-end SOA architecture. It complements a BPM service or a data aggregation service but serves a different and distinct role. Much of SOA is about componentization, interconnectivity, and reuse, and the ESB component serves as an intermediary with the clear and distinct role of providing loose coupling between clients and services, a routing fabric, connectivity, and a central point of security enforcement that con- tribute to the manageability of your SOA network. It can be a central intermediary or a decentralized network of intermediaries. Also, it is completely configuration based with browser-based graphical interfaces. In this book, Jeff Davies introduces you to ESBs in general and BEA’s AquaLogic Service Bus in particular. He includes many examples and clear, understandable explanations of the product and how it can be leveraged to implement a number of ESB use cases. He takes the very practical and useful approach of picking one of the leading products in the ESB category and doing a “show and tell” instead of delving into a lot of philosophical discussions and argu- ments about various contrasting architectures or definitions for an ESB. The book is very readable and instructive. As one of the architects of the first release of the product, I feel this book is a fine introduction to AquaLogic Service Bus. Jayaram Kasi Director of Technical Program Management AquaLogic Service Bus BEA Systems xiii
    • 797-4FM 4/4/07 5:01 PM Page xiv
    • 797-4FM 4/4/07 5:01 PM Page xv About the Authors IJEFF DAVIES, SOA architect and technical evangelist at BEA, has over 20 years of experience in the software field. Jeff has extensive experience developing retail applications, such as Act! for the Windows and Macintosh platforms, and a number of other commercially available applications, principally in the telecommunications field. His background also includes the development, design, and architecture of enterprise applications. Prior to joining BEA, Jeff was the chief architect at a telecommunications company and responsible for their SOA. Now at BEA, Jeff is focused on the practical application of BEA products to create SOA solutions. IASHISH KRISHNA is part of the product management team for integration and SOA products at BEA Systems; he’s responsible for BEA’s integration product. Prior to this, Ashish worked as an SOA architect and was responsible for enabling SOA and EDA solutions at key customers for BEA. Ashish was also part of core engineering team at BEA responsible for architecture and design of various components for BEA’s ESB. Before BEA, Ashish was a founding engineering staff member of ECtone, a Silicon Valley start-up that was later acquired by BEA. Ashish has a diverse background in enterprise integration and software development, including legacy systems, EDI, and ERP integration technologies. He was a consultant for SAP R/3 and EDI, responsible for numerous implementations at Fortune 500 companies in telecommunications, automotive, and manufacturing industries. Ashish holds a master’s degree in aerospace engineering and a bachelor of engineering degree in mechanical engineering. He is also a PhD candidate in mechanical engineering at Texas A&M University. IDAVID SCHOROW has over 20 years of experience working on enterprise soft- ware. David is the chief architect for BEA AquaLogic Service Bus and has guided its development and evolution. Prior to joining BEA, David was the chief Java architect at the NonStop division of HP overseeing the develop- , ment of a wide variety of Java projects, including the NonStop Java JVM, NonStop SQL JDBC drivers, the port of WebLogic Server to the NonStop platform, and other enterprise Java products. David has extensive experience in high-performance transaction processing systems, the environments used by the most demanding, mission-critical applications, such as airline reservations, health care, and banking. David has a bachelor of science degree from MIT and a PhD from the University of California, Berkeley. xv
    • 797-4FM 4/4/07 5:01 PM Page xvi
    • 797-4FM 4/4/07 5:01 PM Page xvii About the Technical Reviewer IJAY KASI has been an infrastructure architect since 1988, working for Hewlett Packard, Commerce One, and BEA Systems. He has architected the kernel of a relational database management system, system-level high-availability capabilities, a messaging and routing fabric for B2B electronic commerce, and ESBs at both Commerceone and BEA. He has also worked as a distributed OLTP architecture consultant. He was one of the key architects of ALSB and has been with the project since inception. He is now the director of program management for ALSB and is working on a variety of integrations with other products. xvii
    • 797-4FM 4/4/07 5:01 PM Page xviii
    • 797-4FM 4/4/07 5:01 PM Page xix Acknowledgments T here are many people who have helped me to make this book a reality. I want to thank my wife for her love and understanding as I spent hours on my computer mumbling incoherently about “namespaces” and the like. There is no finer wife in the world. Similarly, I’d like to thank my children, Eric and Madeline, for putting up with my highly distracted nature while writing this book. Of course, I’d like to thank my parents and my aunt and uncle for enabling me to get to this point in my life with their constant love and support. I’d like to thank Jay Kasi at BEA for his help and tutelage while writing this book. I have never met a person with such a deep understanding of any software product in my life. Many times when I was stuck on a problem, Jay would quickly look at the code and deliver an exact analysis of the problem within moments. I’d also like to thank the many folks who helped review the book and provided me with technical answers to the more unusual scenarios. Specifically, I want to recognize (in alpha- betical order) Deb Ayers, Stephen Bennett, Naren Chawla, George Gould, David Groves, Dain Hansen, Gregory Haardt, Karl Hoffman, Ashish Krishna, Usha Kuntamukkala, Saify Lanewala, Michael Reiche, Kelly Schwarzhoff, Jeremy Westerman, Mike Wooten, and Bradley Wright. Finally, I’d like to thank the great mentors in my life, Mark Russell and Gerry Millar. They taught me everything from how to tie a neck-tie to how to “listen to what they are feeling.” They both taught me that it’s the people who are important; the software is incidental. That’s a hard but invaluable lesson for a natural-born geek. Thank you. Jeff Davies The BEA AquaLogic Service Bus team is full of innovative people. Their contributions and drive to be the best are reflected in the product. I would like to thank the team for all the hard work. It would not have been possible to write this book without their efforts in producing a world-class product, and I know firsthand, as I was part of the engineering team for the first customer ship (FCS) back in 2005. I would like to thank my wife Sumina, and my daughter, Isheeta, for their support and patience especially in letting me work on this book at late hours, on holidays, and especially during our month-long vacation to India—our first in four years! Ashish Krishna Chapter 13 explains the Transport SDK; this useful extensibility mechanism was designed and implemented by Greg Fichtenholtz, a senior engineer on the ALSB team. It is his design that enables ALSB to be used in new and different environments not addressed in the original implementation. The usefulness of the Transport SDK is because of his good design work. Greg is only one member of a very talented team that created the ALSB product; however, their names are too numerous to mention (and I’d be afraid of leaving someone out). This group, with its engineering prowess and creative energy, works under the management of Ashok Aletty, who fosters a productive, cooperative, and enjoyable atmosphere; these people xix
    • 797-4FM 4/4/07 5:01 PM Page xx xx IACKNOWLEDGMENTS are responsible for making AquaLogic Service Bus such a fantastic product. I consider myself fortunate to have the opportunity to work with such a great team on this exciting product. I’d also like to thank my sister, Stephanie Schorow, for her thorough review of an early draft of the chapter. She is the real writer of the family—Chapter 13 is much more readable because of her efforts. Lastly, I’d like to thank my wife, Mona, and my son, Marcus, for their understanding and support when working on this book required my nights and weekends (and cancelling a ski trip). David Schorow ccee59bc36148c9d24781934e7ce1b10
    • 797-4FM 4/4/07 5:01 PM Page xxi Introduction S ervice-Oriented Architecture (SOA) is rapidly becoming the new standard for today’s enter- prises. A number of books have appeared in bookstores that discuss various aspects of SOA. Most (if not all) are high-level discussions that provide some strategies for you to consider but very little tactical information. As a software engineer, I am able to grasp these abstract con- cepts fairly quickly, as I’m sure you are. However, the devil is always in the details. I know that once I begin to implement a new technology, I will discover a whole new dimension of bugs, design issues, and other problems that are never discussed in those strategic books. SOA is not a technology—it is architecture and a strategy. In order for you to implement your own SOA, you need to learn not a single new technology but a whole series of differing technologies. I thought I knew XML pretty well before I began walking the path to SOA. It didn’t take long for me to figure out that there was a lot more to XML than I had previously thought. I had to learn the details of XML, XML Schema, WSDL, XQuery, and XPath before I could begin to make informed design judgments. While I enjoy reading about new strategies, I enjoy realizing them in code just as much. Code keeps you honest. A lot of things work very well on paper, but once you start flipping bits, the truth will emerge in all of its intolerant glory. What I really wanted to read was a detailed book on SOA development. Since I could not find one, I wrote one. I wrote this book under the assumption that there were thousands of other software developers like myself— people who enjoyed writing code and loved to put theory into practice. This book is a mix of theory and working code samples. One reason there are so few books on writing real code for an SOA is because few SOA platforms exist that the average developer can download and use. Most SOA (specifically ESB) vendors keep their software locked away, demanding that you purchase it before you can use it. This is like purchasing a car you have never seen or driven based solely on the description provided to you by the salesperson. Fortunately, BEA Systems provides an enterprise class ESB that anyone can download for free. This book will walk you through many detailed examples of connecting the ALSB to legacy systems, show common design patterns for web services, and generally increase both your development and architectural expertise in ESB and SOA. What Is AquaLogic? AquaLogic Service Bus is a single product in the AquaLogic product family. The AquaLogic family includes many products with diverse functionalities; see the BEA web site for a com- plete listing (www.bea.com). xxi
    • 797-4FM 4/4/07 5:01 PM Page xxii xxii IINTRODUCTION How This Book Is Organized This book comprises 15 chapters in total. We’ve written most of the chapters so that they may be read individually. However, we do recommend reading Chapters 2 and 3 so that you can set up your development environment and understand the basic principles of an enterprise service bus. Chapter 1, “Why Use a Service Bus?,” describes the functions and benefits of an enterprise service bus. Chapter 2, “Installing and Configuring the Software,” guides you through installing and configuring the AquaLogic Service Bus and a development environment. By installing the software as described in this chapter, you will be able to run all of the sample code con- tained in this book. In Chapter 3, “Hello World Service,” following the grand tradition of programming books, we write a web service, test it, and integrate it with the AquaLogic Service Bus. Along the way, we provide a quick tour of AquaLogic Service Bus Administration console. In Chapter 4, “Message Flow Basics,” you’ll learn what message flows are, how to create them, and how they are used in AquaLogic Service Bus. Chapter 5, “A Crash Course in WSDL,” introduces you to Web Services Description Lan- guage (WSDL), the language of modern web services. Creating (or just reading) WSDL requires a fair bit of skill beyond simple XML. This chapter teaches you the core of what you need to know about WSDLs and leaves out the fluff! In Chapter 6, “Message Flows,” we really put AquaLogic Service Bus through its paces, with sample code for almost every feature available. Chapter 7, “Advanced Messaging Topics,” covers just about every weird integration issue and use of ALSB that you will ever see. Chapter 8, “Reporting and Monitoring,” shows you that there is more to ALSB than just messaging. It can keep you informed about the health of your enterprise and provide automated alerts and sophisticated status reports of services and the servers that host them. Chapter 9, “Security Models and Service Bus,” presents a topic that is often discussed but seldom understood. This chapter will provide you with a solid understanding of how to implement security within your service bus. Chapter 10, “Planning Your Service Landscape,” discusses the considerable planning required to move to SOA. In this chapter, we introduce a methodology that will simplify this planning process and provide you with a taxonomy by which you can quickly classify your services. Chapter 11, “Versioning Services,” is possibly the most controversial chapter in the book! Forget everything you’ve heard about versioning web services and brace yourself for some heresy!
    • 797-4FM 4/4/07 5:01 PM Page xxiii IINTRODUCTION xxiii Chapter 12, “Administration, Operations, and Management,” will teach you some best practices for how to keep your service bus running, because there is more to a service bus than development. Chapter 13, “Custom Transports,” explores the Transport SDK. While AquaLogic Service Bus provides many useful transport protocols out of the box, it also contains an API that allows you to create your own customer transports, so it can integrate with any legacy system. Chapter 14, “How Do I . . . ?,” answers some common questions about using AquaLogic Service Bus in the real world. The Appendix, “AquaLogic Service Bus Actions,” is a quick reference for the actions sup- ported by AquaLogic Service Bus. —Jeff Davies
    • 797-4FM 4/4/07 5:01 PM Page xxiv
    • 7974CH01.qxd 2/20/07 1:10 PM Page 1 CHAPTER 1 Why Use a Service Bus? E nterprise Service Buses (ESBs) are all the rage in modern software development. You can’t pick up a trade magazine these days without some article on ESBs and how they make your life wonderful. If you’re a software development veteran, you’ll recognize the hype immedi- ately. ESBs aren’t going to be the magic answer for our industry any more than were XML, web services, application servers, or even ASCII. Each of the aforementioned technologies started life with a lot of fanfare and unrealistic expectations (the result of the inevitable ignorance we all have with any emerging technology), and each technology ended up becoming a reliable tool to solve a specific set of problems. The same is true for the ESB. Putting the hype aside, let’s focus on a bit of software history so we can better understand the problems that the ESB is designed to address. The Problems We Face Today Software development is a tough business. We expect modern software systems to have expo- nentially more functionality than we expected from them only a few years ago. We often develop these systems with ever-dwindling budgets and sharply reduced timeframes, all in an effort to improve efficiency and productivity. However, we cannot lament these issues. These very issues drive us to deliver software that’s better, faster, and cheaper. As we’ve raced to develop each generation of software system, we’ve added significantly to the complexity of our IT systems. Thirty years ago, an IT shop might have maintained a single significant software system. Today most IT shops are responsible for dozens, and sometimes hundreds, of software systems. The interactions between these systems are increasingly com- plex. By placing a premium on delivering on time, we often sacrifice architecture and design, promising ourselves that we’ll refactor the system some time in the future. We’ve developed technologies that can generate large quantities of code from software models or template code. Some of the side effects of this race into the future are a prevalence of point-to-point integrations between software applications, tight coupling at those integration points, lots of code, and little configuration. 1
    • 7974CH01.qxd 2/20/07 1:10 PM Page 2 2 CHAPTER 1 n WHY USE A SERVICE BUS? Point-to-Point Integrations Software development today is tactical and project oriented. Developers and architects fre- quently think in terms of individual software applications, and therefore their designs and implementations directly reflect this thinking. As a result, individual applications are directly integrated with one another in a point-to-point manner. A point-to-point integration is where one application depends on another specific appli- cation. For example, in Figure 1-1, the CustomerContactManager (CCM) application uses the Billing application interface. You can say that the CCM application “knows” about the billing application. You also hear this kind of relationship referred to as a “dependency,” because one application depends on another application to function correctly. Figure 1-1. Early point-to-point integrations Figure 1-1 illustrates a trivial IT environment, one that has only two applications and two point-to-point integrations. Just to be clear, the first integration allows the CCM system to call the Billing system. The second integration point allows the Billing system to call the CCM system. When your IT department is this small, point-to-point integration is fairly easy to manage. Figure 1-2 expands on the problem a bit. The IT shop is now home to 8 software systems and a total of 11 integration points. This illustrates a common pattern in integration: the num- ber of integration points grows faster than the number of systems you’re integrating! Even Figure 1-2 is, by modern standards, a trivial IT system. A midsized service provider where Jeff once worked had 67 business systems and another 51 network systems. One hun- dred eighteen software systems integrated in a point-to-point manner is unmanageable. We know of telcos that have 12 or more billing systems. Having duplicates of certain software sys- tems (such as billing) or having a large number of software systems in general is quite common; large companies can acquire smaller companies (and therefore acquire the software systems of the smaller companies) faster than most IT shops can integrate the newly acquired systems.
    • 7974CH01.qxd 2/20/07 1:10 PM Page 3 CHAPTER 1 n WHY USE A SERVICE BUS? 3 Figure 1-2. Increasing point-to-point integration Tight Coupling Tight coupling is often a byproduct of point-to-point integrations, but it’s certainly possible to develop tightly coupled applications no matter what your integration environment looks like. There are two types of coupling, tight and loose. Loose coupling is desirable for good software engineering, but tight coupling can be necessary for maximum performance. Coupling is increased when the data exchanged between components becomes larger or more complex. In reality, coupling between systems can rarely be categorized as “tight” or “loose.” There’s a continuum between the two extremes. Most systems use one another’s APIs directly to integrate. For Enterprise JavaBeans (EJB) applications, you commonly create a client JAR file for each EJB application. The client JAR file contains the client stubs necessary for the client applications to call the EJB application. If you make a change to any of the APIs of the EJB application, you need to recompile and deploy the EJB application, recompile the client JAR, and then recompile and redeploy each of the client applications. Figure 1-3 illustrates this set of interdependencies between the software compo- nents and the file artifacts that realize them.
    • 7974CH01.qxd 2/20/07 1:10 PM Page 4 4 CHAPTER 1 n WHY USE A SERVICE BUS? Figure 1-3. EJB coupling model Tight coupling results in cascading changes. If you change the interface upon which other components depend, you must then recompile the client applications, often modifying the client code significantly. It’s a common (and false) belief that you can use interfaces to reduce the coupling between systems. Interfaces are intended to abstract out the behavior of the classes that implement the interfaces. They do provide some loosening of the coupling between the client and the implementation, but their effect is almost negligible in today’s systems. This is not to say that interfaces aren’t useful; they most certainly are. But it’s important to understand the reasons why they’re useful. You still end up tightly coupled to a specific interface. For example: package com.alsb.foo; public interface SampleIF { public int getResult(String arg1); } A client that depends on this interface is tightly coupled. If you change the getResult() method to take another argument, all clients of the interface must be recompiled. It’s precisely this level of intolerance to change that tightly couples the code. The problem isn’t so much in the design of the interface, but with the technology that implements the interface. More Code Than Configuration Every medium-to-large sized enterprise runs a lot of code these days. We have so much code as an industry that we needed to invent tools to manage it all. We have source code control (SCC) systems that provide document management of our code. In the last few years we’ve seen the rise of source code knowledge bases.
    • 7974CH01.qxd 2/20/07 1:10 PM Page 5 CHAPTER 1 n WHY USE A SERVICE BUS? 5 Early ESBs Early ESBs were primarily concerned with making web services available to service con- sumers. Their implementation was clunky (as new technologies usually are) and didn’t embrace many open standards, simply because those standards didn’t exist at the time. Fur- thermore, the developers of early ESBs could only try to predict how web services would affect enterprise computing and IT organizations. The early ESBs were “ESBs” in name only. As the industry has matured, so has our under- standing of the role of an ESB in modern architecture. Today’s ESBs must go far beyond simply “service enabling” functionality. An ESB must also provide robust solutions for today’s IT challenges. Modern Solutions The IT industry is constantly evolving. Our understanding of the issues that surround the management of large IT systems matures on a daily basis. Modern ESBs are simply the latest tools to help us manage our IT problems. They benefit from real-world examples of how Service-Oriented Architecture (SOA) is changing the face of today’s advanced corporations. Although early ESBs could only address a handful of the following issues, modern ESBs need to address them all. Loose Coupling You might have heard that web services provide you with loose coupling between systems. This is only partially true. Web services, by the very nature of Web Services Description Lan- guage (WSDL) and XML Schema Document (XSD), can provide some loose coupling because they formalize a contract between the service consumer and the service provider. This is a “design by contract” model, and it does provide tangible benefits. If you’re careful, you can create a schema that’s platform neutral and highly reusable. However, if you take a look at any WSDL you’ll see that the service endpoints are written into the WSDL, as you can see in Listing 1-1. Listing 1-1. HelloWorld Service Defintion <service name="HelloWorldService"> <port binding="s1:HelloWorldServiceSoapBinding" name="HelloWorldPortSoapPort"> <s2:address location="http://www.bea.com:7001/esb/Hello_World" /> </port> </service> By specifying a specific machine and port (or a set of machines and ports), you’re tightly coupling this service to its physical expression on a specific computer. You can use a Domain Name Server (DNS) to substitute portions of the URL, and therefore direct clients into multi- ple machines in a server farm. However, DNS servers are woefully inadequate for this, due to their inability to understand and manage the status of the services running on these servers.
    • 7974CH01.qxd 2/20/07 1:10 PM Page 6 6 CHAPTER 1 n WHY USE A SERVICE BUS? So, loose coupling isn’t achieved by WSDL or web services alone. A more robust solution is to provide some mediation layer between service clients and service producers. Such a media- tion layer should also be capable of bridging transport and security technologies. For example, a service might be invoked through a traditional HTTP transport mechanism, but it can then invoke lower-level services through Java Message Service (JMS), e-mail, File Transfer Protocol (FTP), and so on. This approach is often effectively used to “wrap” older services and their transports from the newer service clients. Location Transparency Location transparency is a strategy to hide the physical locations of service endpoints from the service clients. Ideally a service client should have to know about a single, logical machine and port name for each service. The client shouldn’t know the actual service endpoints. This allows for greater flexibility when managing your services. You can add and remove service endpoints as needed without fear of having to recompile your service clients. Mediation An enterprise service bus is an intermediary layer, residing between the service client and the service providers. This layer provides a great place for adding value to the architecture. An ESB is a service provider to the service clients. When clients use a service on the service bus, the service bus has the ability to perform multiple operations: it can transform the data or the schema of the messages it sends and receives, and it can intelligently route messages to vari- ous service endpoints, depending on the content of those messages. Schema Transformation The web service published by the service bus might use a different schema from the schema of the business service it represents. This is a vital capability, especially when used in conjunc- tion with a canonical taxonomy or when aggregating or orchestrating other web services. It’s quite common that a service client will need to receive its data using a schema that’s signifi- cantly different from that of the service provider. The ability to transform data from one schema to another is critical for the success of any ESB. Service Aggregation The service bus can act as a façade and make a series of web service calls appear as a single service. Service aggregation follows this pattern, making multiple web service calls on behalf of the proxy service and returning a single result. Service orchestration is similar to service aggregation, but includes some conditional logic that defines which of the lower-level web services are called, and the order in which they’re invoked. Load Balancing Due to their position in any architecture, ESBs are well suited to perform load balancing of service requests across multiple service endpoints. When you register a business web service with AquaLogic Service Bus (ALSB), you can specify the list service endpoints where that business service is running. You can change this list, adding or removing service endpoints without having to restart the ALSB server.
    • 7974CH01.qxd 2/20/07 1:10 PM Page 7 CHAPTER 1 n WHY USE A SERVICE BUS? 7 Enforcing Security You should enforce security in a centralized manner whenever possible. This allows for a greater level of standardization and control of security issues. Furthermore, security is best enforced through a policy-driven framework. Using security policies means that the creation and application of security standards happens outside the creation of the individual web services. Monitoring An ESB plays a vital role in an SOA. As such, you must have a robust way to monitor the status of your ESB, in both proactive and reactive manners. The ability to proactively view the per- formance of the service bus allows you to help performance-tune the service bus for better performance. Tracking the performance over time can help you plan for increasing the capac- ity of your ESB. Reactive monitoring allows you to define alerts for specific conditions. For example, if a specific service doesn’t complete within a given timeframe, the ESB should be able to send an alert so that a technician can investigate the problem. Configuration vs. Coding A modern service bus should be configuration based, not code based. For many engineers the importance of that statement isn’t immediately obvious. It took us some time before we appreciated the configuration-oriented capability of ALSB. Most software systems in use today are code based. J2EE applications are a great example of this. In a J2EE application you write source code, compile it into an EAR or WAR file, copy that EAR or WAR file onto one or more J2EE application servers, then deploy those applications. Sometimes it’s necessary to restart the J2EE server, depending on the nature of your deployment. Configuration-based systems work differently. There’s nothing to compile or deploy. You simply change the configuration and activate those changes. We would argue that your tele- phone is configuration based; you configure the telephone number you want to call, and your call is placed. There’s no need to restart your phone. Similarly, network routers and switches are configuration based. As you make changes to their configuration, those changes take effect. There’s no need for a longer software development life cycle to take place. Configuration and coding are two different strategies. Neither is superior to the other in all situations. There are times when the J2EE approach is the right approach, and times when the configuration-based approach is best. Enter AquaLogic Service Bus BEA released AquaLogic Service Bus in June 2005. ALSB runs on Windows, Linux, and Solaris platforms. ALSB is a fully modern ESB and provides functionality for each of the capabilities expected from today’s enterprises, described in the following sections. Loose Coupling Aside from the loose coupling benefits from WSDL and XSD, ALSB adds the ability to store WSDL, XSD, eXtensible Stylesheet Language Transformation (XSLT), and other information
    • 7974CH01.qxd 2/20/07 1:10 PM Page 8 8 CHAPTER 1 n WHY USE A SERVICE BUS? types within the ALSB server as “resources.” These resources are then made available through- out the ALSB cluster of servers, allowing you to reuse these resources as needed. The benefit of this might not be immediately clear, so we’ll give an example. Many com- panies define and manage enterprise-wide data types using an XML schema. Because ALSB can store an XML schema as a resource in the service bus, that schema can easily be reused by any number of WSDLs or other XSDs. This enables you to create and enforce enterprise-wide standards for your data types and message formats. Location Transparency One of the capabilities of ALSB is to register and manage the locations of various web services within the enterprise. This provides a layer of abstraction between the service client and the service provider, and improves the operational aspect of adding or removing service providers without impact to the service clients. Mediation One of the roles for which ALSB is specifically designed is that of a service mediator. ALSB uses the paradigm of “proxy services” and “business services,” where the proxy service is the serv- ice that ALSB publishes to its service clients, and the business services are external to ALSB. In between the proxy service and the business service is the layer where service mediation takes place. Schemas can be transformed, as can the data carried by those schemas. Intelligent or content-based routing also takes place in this mediation layer. Schema Transformation Schema transformation is a central capability of ALSB. ALSB provides a number of ways to transform schemas, depending on your specific needs. You can use XSLT to transform XML data from one schema to another. Similarly, you can use XQuery and XPath to perform XML schema transformations. Additionally, ALSB supports the use of Machine Format Language (MFL) to format schemas to and from non-XML formats. Service Aggregation ALSB doesn’t match a single proxy service to a single business service. Instead, ALSB allows you to define a many-to-many relationship between proxy services and business services. This approach allows for service aggregation, orchestration, and information enrichment. Load Balancing Because ALSB registers the service endpoints of all business services, it’s ideally situated for operating as a load balancer. This is especially true because ALSB is configuration based, not code based. As a result, you can add or remove service endpoints from a business service and activate those changes without having to restart your service bus.
    • 7974CH01.qxd 2/20/07 1:10 PM Page 9 CHAPTER 1 n WHY USE A SERVICE BUS? 9 Enforcing Security ALSB, as a service mediator, is ideally situated to enforce the security of the web services because it operates on the perimeters of the enterprise. ALSB is designed to enforce security through the use of explicit security policies. Using ALSB, you can propagate identities, medi- ate, and transform between different security technologies, such as Basic Authentication, Secure Sockets Layer (SSL), and Security Assertion Markup Language (SAML). Monitoring ALSB provides a robust set of features around monitoring. The service bus console allows you to look proactively at the state of your entire ESB. For reactive monitoring, ALSB allows you to define alerts for conditions that you define. You can send these alerts via Simple Network Management Protocol (SNMP) traps to third- party monitoring programs, such as Hewlett Packard’s OpenView or AmberPoint’s SOA Management System. Also, alerts can be delivered via e-mail to specified recipients. We’ll discuss monitoring more fully in Chapter 8. Configuration vs. Coding ALSB is a configuration-based service bus. You don’t write Java code for ALSB, although ALSB can recognize and make use of Java code in some circumstances. Instead, you configure ALSB through its web-based console. One handy feature of the ALSB console is the Change Center. Your configuration changes don’t take effect when you make each change. Instead, your configuration changes are grouped together, similarly to a database transaction, and only take effect when you tell ALSB to activate your changes. This is a critical capability, because many times you’ll make multiple changes that are interdependent. Of course, creating these changes by hand can be an error-prone process. As a result, ALSB allows you to make changes in one environment (a development or a test environment) and then export those changes as a JAR file. You can then import that JAR file into your pro- duction environment as a set of configuration changes, and activate them as if you had entered those changes directly into the Change Center by hand. Won’t This Lock Me into BEA Technologies? ALSB is entirely standards based. You configure ALSB through the use of XQuery, XPath, XSLT, and WSDLs. The only aspect of ALSB that might be deemed “proprietary” is the implementa- tion of the message flows (see Chapter 4). However, these message flows are simply graphical constructs for common programming logic, and they’re easy to reproduce in just about any programming language. The real heavy lifting in ALSB is done using the open standards for functionality, and WebLogic Server for reliability and scalability. Because ALSB is standards based, it’s designed to integrate with and operate in a hetero- geneous architecture. Using ALSB as a service bus doesn’t preclude you from using other technologies in any way. ALSB is used to integrate with .NET applications, TIBCO, SAP Oracle, , JBoss, WebSphere, Siebel, and many more. BEA didn’t achieve this level of heterogeneity by accident; it’s all part of its “blended” strategy: using open standards and open source to achieve the maximum amount of interoperability.
    • 7974CH01.qxd 2/20/07 1:10 PM Page 10 10 CHAPTER 1 n WHY USE A SERVICE BUS? Why Buy an Enterprise Service Bus? We come across this question frequently. The truth is that an ESB contains no magic in it at all. It’s possible to build your own ESB from scratch. In fact, one of the authors has done it twice before joining BEA. There’s nothing that the engineers at BEA can write that you cannot write, given enough time, money, and training. This principle holds true for all software. You don’t have to use Microsoft Word to write your documents; you could create your own word proces- sor. The same holds true for your web browser. HTML standards are publicly available, and you could use your engineering time to develop your own browser. Naturally, few of us would ever consider writing our own word processor or web browser. It’s a far better use of our time and money either to buy the software or to use an open source version. This is especially true if your company isn’t a software company. If you work in an IT shop for a company whose primary line of business isn’t software, you’ll recognize the fact that building software from scratch is a difficult sell to your executive staff. There simply is no return on investment for such development efforts. Your time and skills are better spent solv- ing problems specific to your company. There are a number of benefits to purchasing ALSB. First is the fact that it comes from a dyed-in-the-wool software company. BEA has been in business for more than a decade and has a long history of delivering innovative, successful products. Furthermore, BEA supports those products for many years. BEA’s first product was Tuxedo, a product that BEA still sells and supports to this day, though it’s gone through many versions to keep it current with today’s technologies. A number of open source ESBs are available today. Most are in the early stages of develop- ment and functionality. Although we love open source and advocate its use in many areas, we would be hesitant to use an open source ESB. An ESB will become the central nervous system of your enterprise. You should exercise caution and diligence when selecting an ESB. You want one with a proven record of success, from an organization that works hard to keep itself ahead of current market demands. ALSB is built on BEA’s WebLogic Server technology. This gives you enterprise-quality reliability and scalability. On top of this, AquaLogic is built on open standards for maximum interoperability in a heterogeneous environment. It’s an ESB that will carry your company into the future. Summary In this chapter we reviewed the features and functions that a modern ESB should have, and we’ve described each feature’s importance to the organization. ALSB implements all these fea- tures, and possesses many more advanced features that we’ll cover in this book. But we’ve talked enough about ALSB. It’s time to start to demonstrate, in working code, exactly how to use these features to their fullest.
    • 7974CH02.qxd 2/20/07 1:14 PM Page 11 CHAPTER 2 Installing and Configuring the Software T his chapter will walk you through the installation process for ALSB and the process of con- figuring your development environment. By the end of this chapter, you’ll be able to compile and run the sample code that comes with this book. To begin with, you need a computer that runs Java. Specifically, it needs to run Java Devel- opment Kit (JDK ) version 1.5 or later. All the examples are written using JDK 1.5, and ALSB requires that you have JDK 1.5 installed. Fortunately, ALSB ships with two different JDKs that meet this requirement. One is the JRockit JDK, which is intended for use on production systems that run on Intel (or compatible) CPUs. The second is the Sun JDK, which is recom- mended for use with development versions of ALSB, or production versions that aren’t running on Intel-compatible CPUs. Naturally, you need to install the ALSB software. You can download ALSB from http:// dev2dev.bea.com/alservicebus/. It’s also a good idea to download the most recent documen- tation so you can stay informed about recent changes. Of course, you’ll need an editor to edit your sample source code. ALSB ships with WebLogic Workshop, an IDE that’s based on Eclipse (http://www.eclipse.org), and comes with a suite of Eclipse plug-ins that are preconfigured to make your development with ALSB must faster. You’ll often use Ant to build your software, especially the Java web service that will act as your “business service” (more about business services later). You’ll need Ant version 1.6 or later. Like most of the software used by ALSB, Ant is included with the ALSB installer and is preconfigured into the WebLogic Workshop environment. The Ant home page is at http:// ant.apache.org. Finally, you’ll need two software packages for some of your more advanced work with the service bus. The first is an FTP server that you’ll use to demonstrate integrating the service bus with legacy systems via FTP You can use any FTP server that you like. We selected the FileZilla . FTP server, which resides at http://filezilla.sourceforge.net/. Also, you’ll need access to an e-mail server when testing the e-mail integration. Because your company might not appre- ciate you sending test e-mails over its e-mail server, we recommend installing your own e-mail server. We selected Java Mail Server, which is available at http://www.ericdaugherty.com/ java/mailserver. Because both FTP and SMTP are based on well-defined standards, feel free to substitute your own FTP and e-mail servers. However, we do provide a detailed configura- tion walkthrough of both these programs, so if you aren’t accustomed to setting up these types of servers, you’re better off using the same ones we’ve used. 11
    • 7974CH02.qxd 2/20/07 1:14 PM Page 12 12 CHAPTER 2 s INSTALLING AND CONFIGURING THE SOFTWARE You’ll find all the software you need for this book in the Source Code/Download area of the Apress web site at http://www.apress.com. Installing the Software ALSB comes with most of the software you’ll need to compile and deploy the applications you create in this book: Ant, WebLogic Workshop, WebLogic 9.x, and the JDK 1.5. Installing ALSB is a breeze. For the most part, you can safely accept the default values provided by the installa- tion program. However, we do recommend creating a new BEA home directory if you have a previous version of WebLogic 9 installed. On our system we have WebLogic 8.1 installed in the traditional BEA home directory of Cbea. We installed ALSB into C:bea92ALSB to keep the installations separate. Once you have the software installed, you need to do a little configuration to complete the setup. Configuring WebLogic Workshop ALSB ships with a customized version of Eclipse known as the WebLogic Workshop. This customization is achieved by using Eclipse’s plug-in capability to extend Eclipse. Workshop comes entirely preconfigured and ready to run. When you start Workshop for the first time, it will ask you to select a workspace (see Figure 2-1). A workspace is a directory where your Work- shop projects will be created. Workshop allows you to create as many workspaces as you like. For your purposes, we recommend that you name your new workspace alsb_book, and use that workspace as the home for all the projects you’ll create in this book. Figure 2-1. Create a workspace in Eclipse. Once you’re happy with the name of your workspace, click the OK button, and the WebLogic Workshop IDE loads. If you’re familiar with the Eclipse IDE, learning Workshop will be a breeze for you. If you’re moving to WebLogic Workshop 9 from WebLogic Workshop 8, or are otherwise unfamiliar with Workshop 9, we’ll review the major capabilities of the latest ver- sion of Workshop in the following section. Also, you’ll find that the first project in Chapter 3 will walk you through the IDE in detail, making it much easier to learn the Workshop IDE as you go.
    • 7974CH02.qxd 2/20/07 1:14 PM Page 13 CHAPTER 2 s INSTALLING AND CONFIGURING THE SOFTWARE 13 A Quick Tour of Workshop Workshop is a modern IDE for developing modern applications. Much of the functionality of Workshop is directly inherited from Eclipse. Developers using Workshop enjoy the features they’ve come to expect from a modern IDE: code completion, code refactoring, project aware- ness, built-in Ant and JUnit, and much more. Workshop is even aware of a wide variety of application servers, and you can easily configure it to start and stop application servers from within the IDE. A robust debugger is included. When you run Workshop for the first time, it will resemble Figure 2-2. The left side of the IDE is dedicated to project information. The right side shows properties and annotations of the current file. The bottom portion of the IDE provides information on code problems, holds “watched” variables during debugging sessions, and tracks task markers in your code. The center of the IDE is dedicated to editing source code and other file types. Figure 2-2. Workshop’s first run You might have noticed that Workshop makes liberal use of tabs. Every window in the IDE has a tab, allowing you to switch quickly between different views of information. This helps to make the most of your screen real estate. The real star of the show is the icon with each win- dow. Those of you moving to Workshop 9 from Workshop 8 will also love this little icon. Clicking this icon causes the associated window to expand to fill the entire IDE application window. The claustrophobic days of Workshop 8 are now a distant memory!
    • 7974CH02.qxd 2/20/07 1:14 PM Page 14 14 CHAPTER 2 s INSTALLING AND CONFIGURING THE SOFTWARE You also want to configure Workshop to be aware of the specific libraries you’ll need to use, especially for some of your client code that doesn’t execute within a WebLogic container. To this end, you need to create several libraries in Workshop. A library is just a named collec- tion of JAR files that you can add to your projects. Begin by selecting Windows ® Preferences from the main menu bar of Workshop. When the Preferences dialog appears, select the Java ® Build Path ® User Libraries path in the tree. Click the Add button and specify the name of the library (see Figure 2-3). Your first library will be designed for web service test clients, so name the library WebLogic WebService Client. Figure 2-3. Naming the new library Next, click the Add JARs button. You need to navigate into your %WEBLOGIC_HOME% serverlib directory to find the JAR files you need. Select the following JAR files: %WEBLOGIC_HOME%serverlibweblogic.jar %WEBLOGIC_HOME%serverlibwebserviceclient.jar %WEBLOGIC_HOME%commonlibapache_xbean.jar That’s it for our short tour of Workshop. You’ll learn more as you begin to use it in Chapter 3. Creating the Service Bus Domain For the purposes of this book, you’ll create a new WebLogic 9 domain for ALSB. You’ll use the Configuration Wizard. On a Windows box, from the Start menu select BEA Products ® Tools ® Configuration Wizard. Once the wizard is running, perform the following steps: 1. Ensure the “Create a new WebLogic domain” radio button is selected and click the Next button. 2. Ensure the “Generate a domain configured automatically to support the following BEA Products” radio button is selected. Also ensure the ALSB and the Workshop for WebLogic Platform checkboxes are checked. Click the Next button. 3. Set the password to something simple, such as weblogic. Be sure your Caps Lock isn’t set on your keyboard. Click the Next button. 4. Select Development Mode and the BEA-supplied JDK radio buttons. Select the Sun SDK from the associated listbox. The JDK must be version 1.5.0 or later. Click the Next button.
    • 7974CH02.qxd 2/20/07 1:14 PM Page 15 CHAPTER 2 s INSTALLING AND CONFIGURING THE SOFTWARE 15 5. In the Customize Environment and Service Settings page, ensure the No radio button is selected and click the Next button. 6. Set the Domain name to alsb_book and click the Create button. 7. In the Creating Domain page, check the Start Admin Server checkbox, then click the Done button. You have now created and started the alsb_book domain that you’ll use for the rest of this book. Configuring Ant in Eclipse The Ant plug-in in Workshop needs a slight configuration to enable it to recognize the WebLogic-specific Ant tasks you’ll use in this book. Furthermore, some WebLogic Ant tasks simply won’t work unless you tell Ant about the weblogic.jar file. From the main menu in Workshop, select Window ® Preferences. This displays the preferences as shown in Figure 2-4. In the Preferences dialog, navigate to the Ant/Runtime category, then click the Classpath tab. You need to add the weblogic.jar file to the Ant classpath. Click the Ant Home Entries and then click the Add External JARs button. Navigate to your <BEA_HOME>weblogic92serverlib directory and select the weblogic.jar file. Figure 2-4. Configuring the Ant plug-in in Workshop This enables Ant to recognize the WebLogic-specific Ant tasks listed in Table 2-1.
    • 7974CH02.qxd 2/20/07 1:14 PM Page 16 16 CHAPTER 2 s INSTALLING AND CONFIGURING THE SOFTWARE Table 2-1. WebLogic-Specific Ant Tasks Task Description ClientGenTask Web service client generator Ant task JwscTask Java web service compiler Ant task WLDeploy WebLogic deployment Ant task WsdlcTask WSDL compiler Ant task You’ll use these tasks in each of your project Ant files. Configuring Workshop for the AquaLogic Server Next you want to configure Workshop for WebLogic so you can manage your ALSB server from the Workshop interface. Using the Workshop menu, select File ® New ® Server. The New Server dialog appears, and the Server’s host name field should be set to localhost, as shown in Figure 2-5. Click the Next button. Figure 2-5. The first step in creating a new server is to specify the host name and runtime. Your next step is to select the domain that you created earlier in this chapter. Once you’ve selected the alsb_book domain, as shown in Figure 2-6, click the Next button. The last step of configuring a server is to define the projects that are deployed on the server. Because you don’t have any projects defined yet, just click the Finish button, as shown in Figure 2-7.
    • 7974CH02.qxd 2/20/07 1:14 PM Page 17 CHAPTER 2 s INSTALLING AND CONFIGURING THE SOFTWARE 17 Figure 2-6. Selecting the domain home of the server Figure 2-7. Adding and removing projects from the ALSB server
    • 7974CH02.qxd 2/20/07 1:14 PM Page 18 18 CHAPTER 2 s INSTALLING AND CONFIGURING THE SOFTWARE At this point, your new server should appear in the Servers window of the Workshop IDE, as shown in Figure 2-8. Figure 2-8. The Servers tab in the Workshop IDE If you haven’t already started the alsb_book server, you can do so now by right-clicking the server name and selecting Start from the pop-up menu, or by selecting the server from the list (as shown in Figure 2-8), and clicking the start button ( ). If you’ve previously started the server, Workshop automatically detects that the server is running. Importing the Sample Code This book comes with a significant amount of sample code. Your first step is to copy the proj- ects you downloaded from the Source Code/Download area at http://www.apress.com into the workspace that you created when you first started Workshop for WebLogic (see Figure 2-1). Next you need to import those projects into the Workshop IDE. You do this by right-clicking in the Package Explorer window and selecting Import from the pop-up menu. This brings up the Import dialog, shown in Figure 2-9. Select Existing Projects into Workspace from the dialog and click the Next button. The next step in the Import Projects wizard is to select the workspace that contains the projects. Do this by selecting the root directory and browsing to the workspace directory you created earlier in this chapter, as shown in Figure 2-10. Your project list might not match the one shown in Figure 2-10 exactly, but that’s okay. Click the Finish button to import all these projects into Workshop.
    • 7974CH02.qxd 2/20/07 1:14 PM Page 19 CHAPTER 2 s INSTALLING AND CONFIGURING THE SOFTWARE 19 Figure 2-9. Import the existing projects into Workshop. Figure 2-10. The final step in importing the sample projects into Workshop
    • 7974CH02.qxd 2/20/07 1:14 PM Page 20 20 CHAPTER 2 s INSTALLING AND CONFIGURING THE SOFTWARE Summary When these steps are complete, your Workshop for WebLogic IDE will be fully configured to use with the following chapters of this book. The ease with which you can interact with the AquaLogic server will improve your coding experience and productivity. You’re now ready for the fun part. In the next chapter, you’ll get right down to business by creating a Java web service, then using ALSB to exercise the web service.
    • 7974CH03.qxd 3/2/07 10:04 AM Page 21 CHAPTER 3 Hello World Service I n the tradition of computer learning books of the past several decades, in this chapter you’ll write a quick Hello World service to help you get an understanding of the basics of ALSB. During this process, you’ll gain a fundamental understanding of the ALSB interface, how to create a project using the ALSB console, and more. You’ll also see from end to end how to cre- ate and deploy business and proxy services on ALSB, along with how to create test clients to ensure that your services are working as desired. You’ll follow these steps: 1. Use Workshop to create and deploy a web service that implements the business logic. sNote ALSB supports interoperability between heterogeneous systems. It can connect to .NET, Apache Axis, WebSphere, and other web service platforms. However, for ease of development, you’ll develop your web services using WebLogic Server (WLS). 2. Use Workshop to create a client for the web service created in step 1. 3. Create a HelloWorld project in ALSB. 4. Define the WSDL for the web service in ALSB, based on the web service you created in step 1. 5. Create a business service definition in ALSB, based on the WSDL. 6. Create a proxy service in ALSB based on the business service. 7. Create a test client for the proxy service to confirm that everything runs properly, end to end. Before you proceed, be sure that the alsb_book domain is running. Creating and Deploying a Web Service Your first step is to create a web service that implements the business logic. Your requirements for this service are simple. 21
    • 7974CH03.qxd 3/2/07 10:04 AM Page 22 22 CHAPTER 3 s HELLO WORLD SERVICE The service will contain one operation named getGreeting. This operation must take a string argument that’s a name of a person. The service returns a string greeting that includes the name argument. getGreeting(String name) : String You’ll implement this web service using the JDK 1.5 with annotations, using Workshop to create the source files and Ant to build your project. You need to have completed the installa- tion process defined in Chapter 2. You’ll find the complete source code for this exercise in the Source Code/Download area at http://www.apress.com. Begin by starting the Workshop IDE by selecting BEA Products ® Workshop for WebLogic Platform from the Start menu. If it prompts you to select a workspace, select the workspace that you created in Chapter 2. After Workshop loads, right-click in the Package Explorer tab (on the left side of the IDE) and select New ® Project from the pop-up menu. This brings up the New Project dialog, shown in Figure 3-1. Figure 3-1. Workshop’s New Project wizard Select the Web Service Project in the Web Services folder and click the Next button. Name the project “Hello World.” The Target Runtime should default to BEA WebLogic 9.2 if you’re using ALSB version 2.5 or later. Click the Next button. On the Select Project Facets page of the New Project wizard, you need to select the “facets” of your project, as shown in Figure 3-2. For your purposes, the defaults are fine. Click the Next button.
    • 7974CH03.qxd 3/2/07 10:04 AM Page 23 CHAPTER 3 s HELLO WORLD SERVICE 23 Figure 3-2. Hello World project facets The next window allows you to configure the web module (see Figure 3-3). Here you’ll make some changes. Change the Context Root field from “Hello World” to “business/hello.” Context roots must be unique across projects within a server. The “business” prefix of the root allows you to group all your “business” services together, making it easier to navigate the web services later on. Figure 3-3. Specify the Hello World context root.
    • 7974CH03.qxd 3/2/07 10:04 AM Page 24 24 CHAPTER 3 s HELLO WORLD SERVICE Click the Next button. This is the last page of the New Project wizard. Ensure that the Use Shared J2EE Libraries radio button is selected and click the Finish button. The Hello World project appears in the Project Explorer window, and should look identical to the structure shown in Figure 3-4. Figure 3-4. The Hello World project Writing a web service for WLS 9.x is a snap. You’ll write your web service as a POJO (that is, Plain Old Java Object) because that’s the simplest way to create a web service. First, you need to create a Java package for your web service. Right-click the src folder in the Project Explorer and select New ® Package from the pop-up menu. Name the package com.proalsb.business. Now, right-click the newly created package and select New ® WebLogic Web Service from the pop-up menu. Enter HelloWorld for the file name and click the Finish button. Workshop cre- ates a HelloWorld.java file for you and displays it in the source code section of the Workshop IDE. It already bears some annotations, specifically @WebService and @WebMethod. This is just a skeleton web service; you need to put some meat on the bones before it becomes useful. Workshop for WebLogic allows you to work either directly with the source code, or via “property sheets.” One of the great things about property sheets is that they give you a menu of options, making it simple to see what’s available to you. Each of these properties translates directly into an annotation in the source file, so there’s no hidden code. The source files are still the source of “truth,” reflecting all the property and annotation settings. For example, with the HelloWorld.java file selected in Workshop, look at the Annotations window (see Figure 3-5). At the top of this window is a group of properties under the title of WebService (if this group isn’t open, click the plus sign next to the group name to show the child properties). Take a look at the name attribute of the WebService annotation. By default it’s set to [HelloWorld]. The square brackets are an idiom specific to Workshop, and they indicate default values that will be used. Maybe it’s just our nature, but we’ve never trusted default values, so we prefer to set them explicitly. Remove the square brackets around the name property so that the name is now set to HelloWorld. Notice how the @WebService annotation in your source code has been modified to include the name attribute. Now set the serviceName field to HelloWorldService and set the targetNamespace field to http://www.proalsb.com.
    • 7974CH03.qxd 3/2/07 10:04 AM Page 25 CHAPTER 3 s HELLO WORLD SERVICE 25 Figure 3-5. Workshop property sheet for Hello World Next, move to the WLHttpTransport property. This property is worthy of some description. Setting this property defines the transport protocol used by your web service. Every web service needs to have a protocol specified to function. You’ll set the portName field to HelloWorldSoapPort to indicate that you’re using a SOAP binding for the web service port. Next, you need to set the serviceURI field to HelloWorldService. The service URI is appended to the context path for the web service, which brings up an interesting point. When you cre- ated this web service project, the wizard prompted you for a contextRoot, which you set to business/hello. If you set a value in the contextPath attribute of the WLHttpTransport property, it will override the value that you set when you first created the project. Because you don’t need to override that value, leave the contextPath attribute blank. Next you need to modify the WSDL property, at the bottom of the property list window. Set its exposed attribute to true. You want to be able to see the WSDL in a web browser. You also need to set the SOAPBinding property. Set the parameterStyle to WRAPPED, the style to DOCUMENT, and the use to LITERAL. Last, you need to write some code for this web service. Your HelloWorld service needs to have one operation: getGreeting(). This operation takes a string argument that contains a name, and returns a string that contains a customized greeting. See Listing 3-1 for the imple- mentation details of this method. Listing 3-1. The HelloWorld Web Service package com.proalsb.business; import javax.jws.*; import weblogic.jws.WLHttpTransport; import weblogic.jws.WSDL; import javax.jws.soap.SOAPBinding; @WebService(name="HelloWorld", serviceName = "HelloWorldService", targetNamespace = "http://www.proalsb.com") @WLHttpTransport(serviceUri = "HelloWorldService", portName = "HelloWorldSoapPort") @WSDL(exposed=true) @SOAPBinding(parameterStyle=SOAPBinding.ParameterStyle.WRAPPED) public class HelloWorld {
    • 7974CH03.qxd 3/2/07 10:04 AM Page 26 26 CHAPTER 3 s HELLO WORLD SERVICE @WebMethod public String getGreeting(String name) { return("Hello " + name + " from the business service!"); } } In this web service, you use only the fundamental annotations to achieve your goal, so it’s worth your time to better understand these annotations. @WebService This annotation denotes the Java class as defining a web service. This annotation takes at most five arguments, shown in Table 3-1. Table 3-1. @WebService Annotation Attributes Attribute Description Required name The name of the port type of the WSDL that will be No generated for this service. targetNamespace This is the XML namespace that will be used in the No generated WSDL. The default value is specified by the JAX-RPC specification (at http://java.sun.com/xml/ jaxrpc/index.jsp). serviceName The name of the service. This maps to the <wsdl:service> No element of the WSDL file. The default value is the unqualified name of the Java class with the string Service appended. wsdlLocation The relative or absolute URL of a predefined WSDL file No that this web service will implement. If you leave this undefined, a WSDL will be generated for you by the jwsc Ant task. If you do enter a value here, the jwsc Ant task will return errors if the Java class is inconsistent with the port types and bindings specified in the WSDL file. endpointInterface The fully qualified name of an existing service endpoint No interface file. If you specify this value, the jwsc Ant task won’t generate the interface for you, and you’re required to have the interface file in your CLASSPATH. If this value is undefined, the jwsc Ant task will generate the interface for you. In general, we recommend always specifying at least the name and the targetNamespace attributes. To use this annotation you need to import javax.jws.WebMethod in your Java source code. @SoapBinding The @SoapBinding annotation allows you to specify the information that’s contained in the <wsdlsoap:binding> section of a WSDL file (see Table 3-2).
    • 7974CH03.qxd 3/2/07 10:04 AM Page 27 CHAPTER 3 s HELLO WORLD SERVICE 27 Table 3-2. @SoapBinding Annotation Attributes Attribute Description Required style Specifies the encoding style of the SOAP messages. No Valid values are: SOAPBinding.Style.Document SOAPBinding.Style.RPC The default is SOAPBinding.Style.Document use Specifies the formatting style of the SOAP messages. No Valid values are: SOAPBinding.Use.Literal SOAPBinding.Use.Encoded The default value is SOAPBinding.Use.Literal parameterStyle Defines if method parameters represent the entire body of No a message or if they are elements wrapped inside a top-level element named after the operation. Valid values are: SOAPBinding.ParameterStyle.Bare SOAPBinding.ParameterStyle.Wrapped The default value is SOAPBinding.ParameterStyle.Wrapped sNote You should generally avoid using the Encoded SOAP binding. It isn’t WS-I compliant and therefore reduces your ability to reuse encoded web services. In general, we recommend specifying all these attributes explicitly to communicate your intention clearly for how the code will operate. To use this annotation you need to import javax.jws.SOAPBinding in your Java source code. @WLHttpTransport The @WLHttpTransport annotation specifies the URI information for the resulting web service (see Table 3-3). Table 3-3. @WLHttpTransport Annotation Attributes Attribute Description Required contextPath The context root of the web service. Yes serviceURI The web service URI portion of the URL used by the client. Yes WebLogic Workshop IDE will provide a default serviceURI for you if you don’t use this annotation. portName The name of the <wsdl:port> value. If you don’t specify this No value, the jwsc Ant task and the WebLogic Workshop IDE will generate a default port name based on the name of the class that implements the service.
    • 7974CH03.qxd 3/2/07 10:04 AM Page 28 28 CHAPTER 3 s HELLO WORLD SERVICE Just to clarify this a bit more, if you refer to the code in Listing 3-1 you’ll see that the @WLHttpTransport attribute is defined with a contextPath of business and the serviceURI of HelloWorldService. When you run this service on your local ALSB server running on port 7001, the full URL for the web service will be http://localhost:7001/business/HelloWorldService. @WebMethod You use the @WebMethod annotation to identify a Java method as a web service operation (see Table 3-4). Table 3-4. @WebMethod Annotation Attributes Attribute Description Required operationName The name of the operation. This maps to a <wsdl:operation> No tag in the WSDL file. The default value is the name of the Java method. action The action for this operation. For SOAP bindings, the value No of this attribute determines the value of the SOAPAction header in the SOAP messages. This attribute appears in the WSDL file that’s generated for the web service. At this point you need to test the web service. However, web services need to run on a server, so your next task is to define a WebLogic Server within Workshop. At the bottom of the Workshop IDE you’ll see a tab named Servers. Click that tab, right-click in the Servers window, and select New ® Server from the pop-up menu. Set the server name to localhost and set the runtime to BEA WebLogic v9.2. Click the Next button to continue. Browse for the alsb_book domain directory you created in Chapter 2. Click the Next button. Now you can select the HelloWorld project for deployment onto the server by clicking the Add All button. Click the Finish button to complete the creation of this server in Workshop. Now, in the Servers window, you should see the alsb_book server listed (see Figure 3-6). You can also see the status of the server. To make life even more convenient, you can start and stop that server from within the Workshop IDE itself. Figure 3-6. The configured alsb_book server Notice that the state of your server is listed as Republish. This is because the HelloWorld project needs to be published (that is, deployed) to the server. This occurs for two reasons: • You’ve never published the project to that server before. • You’ve made changes to the project and now it’s out of sync with the server.
    • 7974CH03.qxd 3/2/07 10:04 AM Page 29 CHAPTER 3 s HELLO WORLD SERVICE 29 Publishing a project to the server is a simple process. Just right-click the server name (see Figure 3-7) and select Publish from the pop-up menu. If the state of the server changes to Synchronized, then you know the server is running the latest compiled versions of all your projects. You can confirm the deployment of the web service by pointing your web browser to the URL http://localhost:7001/business/hello/HelloWorldService?WSDL. The WSDL that was generated for your HelloWorld POJO is displayed. It should look identical to Listing 3-2. Listing 3-2. WSDL for the HelloWorld Web Service <?xml version=1.0 encoding=UTF-8?> <definitions name="HelloWorldServiceDefinitions" targetNamespace="http://www.proalsb.com" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:s0="http://www.proalsb.com" xmlns:s1="http://schemas.xmlsoap.org/wsdl/soap/"> <types> <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.proalsb.com" xmlns:s0="http://www.proalsb.com" xmlns:s1="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="getGreeting"> <xs:complexType> <xs:sequence> <xs:element name="name" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="getGreetingResponse"> <xs:complexType> <xs:sequence> <xs:element name="return" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> </types> <message name="getGreeting"> <part element="s0:getGreeting" name="parameters"/> </message> <message name="getGreetingResponse"> <part element="s0:getGreetingResponse" name="parameters"/> </message> <portType name="HelloWorld"> <operation name="getGreeting" parameterOrder="parameters">
    • 7974CH03.qxd 3/2/07 10:04 AM Page 30 30 CHAPTER 3 s HELLO WORLD SERVICE <input message="s0:getGreeting"/> <output message="s0:getGreetingResponse"/> </operation> </portType> <binding name="HelloWorldServiceSoapBinding" type="s0:HelloWorld"> <s1:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="getGreeting"> <s1:operation soapAction="" style="document"/> <input> <s1:body parts="parameters" use="literal"/> </input> <output> <s1:body parts="parameters" use="literal"/> </output> </operation> </binding> <service name="HelloWorldService"> <port binding="s0:HelloWorldServiceSoapBinding" name="HelloWorldSoapPort"> <s1:address location=¯ "http://localhost:7001/business/hello/HelloWorldService"/> </port> </service> </definitions> Tip s If you get a “failed to deploy” message from Workshop, open the server by clicking the plus sign next to the ALSB server in the Servers window, right-click the HelloWorld project, and select Remove from the pop-up menu. Then you can republish the project. Figure 3-7. Viewing the deployment state of your projects Once the project is published to the server, you need to test it. There are two ways to test your web services. The first way is to right-click the web service file name in the Project Browser (HelloWorld.java, in this case). This is the fastest and easiest way to test a web service. The second way to test a web service is to create a test client project. This approach is more labor intensive. However, it’s a good exercise for you here because it demonstrates how to create a Java POJO in Workshop that can interface with web services.
    • 7974CH03.qxd 3/2/07 10:04 AM Page 31 CHAPTER 3 s HELLO WORLD SERVICE 31 Creating a POJO Test Client In general, it’s good practice to write test code whenever possible. Your next step is to write a small client program to call your web service directly to ensure that it was coded and deployed properly. Fortunately, using WLS 9 makes this process a snap. The process for writing a web service client is as follows: 1. Create a Java project for the client. 2. Generate the client code for the web service based on the WSDL. 3. Get the port object from the service. 4. Use the port object to interact with the service. Listing 3-3 shows how easy it is to create a web service client. Listing 3-3. The HelloWorld Client Program package com.alsb.client; public class HelloWorldClient { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub String url = "http://localhost:7001/business/hello/HelloWorldService?WSDL"; try { HelloWorldService service = new HelloWorldService_Impl(url); HelloWorld port = service.getHelloWorldSoapPort(); String greeting = port.getGreeting("Bob"); System.out.println(greeting); } catch(Exception ex) { ex.printStackTrace(); } } } Create a new project in the Workshop IDE. Select the Java project in the Java folder of the Select Wizard dialog. Name the service HelloWorldClient, as shown in Figure 3-8. Click the Finish button. We prefer to keep our source code separate from the generated code, so we rec- ommend selecting the “Create separate source and output folders” radio button.
    • 7974CH03.qxd 3/2/07 10:04 AM Page 32 32 CHAPTER 3 s HELLO WORLD SERVICE Figure 3-8. Creating the HelloWorldClient project In the src folder of the HelloWorldClient project, create a new package named com.alsb. client. In this package, create a new Java class called HelloWorldClient. You’ll fill in the code for this class in a moment. You still have a few more housekeeping tasks to perform first. A POJO needs a few libraries to call a web service. Right-click the HelloWorldClient proj- ect in the Project Explorer and select Properties. In the Properties dialog (see Figure 3-9), navigate to the Java Build Path entry and then click the Libraries tab. Click the Add Library button, select the User Library entry, and click the Next button. Finally, check the checkbox next to the WebLogic WebService Client library and click the Finish button. This is the library you created in Chapter 2, and it gives you access to WebLogic-specific Ant tasks and the Apache XML Bean libraries. For your POJO client to access the HelloWorld web service, you need to generate some interface files. BEA ships an Ant task called clientgen (located in the weblogic.jar file) that can generate utility files to make accessing web services a breeze. The clientgen utility will create some source files for you. Because we’re also picky about keeping our generated source code separate from our handwritten source code, we create a second folder for the generated source code called gensrc (hey, we’re picky, not creative). To create a second source code folder, click the Source tab in the Properties dialog. Click the Add Folder button and create a folder named gensrc. Now Workshop knows to look into two folders when looking for source code.
    • 7974CH03.qxd 3/2/07 10:04 AM Page 33 CHAPTER 3 s HELLO WORLD SERVICE 33 Figure 3-9. Add the WebLogic WebService Client library. Click the OK button to close the Properties dialog. You’ll invoke the clientgen utility from an Ant script. Workshop is aware of Ant scripts and provides Ant-specific functionality. In the root directory of the HelloWorldClient project, create a file named build.xml (the traditional Ant script name). The script is rather long (74 lines to be exact), so we recommend copying the contents of the build.xml file from the version available in the Source Code/Download area at http://www.apress.com. If you prefer, you can enter the code as shown in Listing 3-4. Listing 3-4. HelloWorld Client build.xml Ant Script <?xml version="1.0" encoding="ISO-8859-1"?> <project name="HelloWorldClient" default="all" basedir="."> <!-- set global properties for this build --> <property name="weblogic.home" value="d:/bea92/weblogic92" /> <property name="src.dir" value="src"/> <property name="gensrc.dir" value="gensrc"/> <property name="classes.dir" value="./bin" /> <property name="webservice.name" value="HelloWorldService"/> <property name="webservice.wsdl.url" value= ¯ "http://localhost:7001/business/hello/${webservice.name}?WSDL"/> <property name="package.name" value="com.alsb.client" /> <!-- Create a PATH-like version of the package name --> <property name="package.path" value="com/alsb/client" /> <!-- Standard WebLogic Ant tasks --> <taskdef name="clientgen" classname="weblogic.wsee.tools.anttasks.ClientGenTask"/>
    • 7974CH03.qxd 3/2/07 10:04 AM Page 34 34 CHAPTER 3 s HELLO WORLD SERVICE <!-- ======================================== Path Section ======================================== --> <path id="javabuild.class.path"> <pathelement path="${classes.dir}"/> <fileset dir="${weblogic.home}/server/lib"> <include name="webserviceclient.jar"/> </fileset> </path> <path id="clientrun.class.path"> <pathelement path="${classes.dir}"/> <fileset dir="${weblogic.home}/server/lib"> <include name="weblogic.jar"/> <include name="webserviceclient.jar"/> </fileset> </path> <target name="all" depends="build.wsclient" description="Create the web ¯ service client libraries for the HelloWorldClient."/> <target name="build.wsclient" depends="clean" description="==> Build the Hello World Service Client Files. Be sure ¯ the web service is running before you execute this task."> <!-- BEGIN: Generate and compile Web Services client classes --> <clientgen wsdl="${webservice.wsdl.url}" destDir="${gensrc.dir}" packageName="${package.name}" /> <!-- Compile our generated classes --> <javac srcdir="${gensrc.dir}" destdir="${classes.dir}" includes="**/*.java" debug="on" classpathref="javabuild.class.path"/> <!-- Compile our client class --> <javac srcdir="${src.dir}/${package.path}" destdir="${classes.dir}" includes="**/*.java" debug="on" classpathref="javabuild.class.path"/> <!-- END: Generate and compile Web Services client classes --> </target> <target name="clean" description="Removes all generated files"> <delete dir="${classes.dir}" failonerror="false"/> <delete dir="${gensrc.dir}" failonerror="false"/>
    • 7974CH03.qxd 3/2/07 10:04 AM Page 35 CHAPTER 3 s HELLO WORLD SERVICE 35 <mkdir dir="${classes.dir}" /> <mkdir dir="${gensrc.dir}" /> </target> <target name="run.wsclient" description="Run the client to test our business service"> <java fork="yes" classname="${package.name}.Client" failonerror="true"> <classpath refid="clientrun.class.path"/> </java> </target> </project> Be sure to modify the script to match your environment. Specifically, look at the value for the weblogic.home property. If it isn’t set correctly, Ant will give you an error. Also, be sure that your ALSB server is running before you run the Ant script. The clientgen utility in the Ant script interrogates the ALSB server to get the WSDL. It’s usually better to get the WSDL from the source (that is, the server that hosts the web service) rather than copying the WSDL file to a local directory. Once you have this Ant script entered, open the script file in Workshop. You’ll see a win- dow named Outline on the right side of the Workshop IDE. At the top of the outline is a node named HelloWorldClient. Expand that node and look for the all target. To run an Ant target from within Workshop, just right-click the target name and select Run As ® Ant Build from the pop-up menu. Ant runs the script and generates the needed utility files for your HelloWorldClient. Now open the HelloWorldClient.java file. Modify the source code so that it matches the code shown in Listing 3-3. It’s worth noting a few things about the code that clientgen creates for you. There are three main steps in invoking a web service. First, you need to create a serv- ice stub that can connect to the service. You do this by invoking the <service>_Impl class and passing in the URL of the service. The second step is to get the port from the service. The port is the interface to the service. This service interface contains the Java methods you’ll invoke. The third and final step is to invoke the operation(s) on the port. This is the pattern for all web service invocations from a POJO. This test client is intended for a human to execute. You could just as easily have written a unit test using JUnit to perform an automated test on the web service. Creating the HelloWorld Project in ALSB Until now, all your work has taken place in WLS. Nothing about it has been specific to ALSB. Now that you’re certain that your HelloWorld web service is working as intended, it’s time to move into ALSB and learn how to use it. Open your web browser and point it to the service bus console at http://localhost:7001/ sbconsole. When you point your browser to the service bus console, it defaults to the Dash- board view (under the Monitoring section in the left navigation bar). ALSB uses BEA’s portal technology to provide a robust, customizable interface. As you can see from Figure 3-10, the left navigation bar provides you with several different categories of views into the service bus. The Dashboard view gives you a quick status of the service bus servers and services. In later
    • 7974CH03.qxd 3/2/07 10:04 AM Page 36 36 CHAPTER 3 s HELLO WORLD SERVICE chapters, we’ll explore the other categories in the navigation bar in greater detail as we use them to complete our exercises. Let’s get started and create the HelloWorld project. Click the Project Explorer link in the navigation bar to see the currently deployed projects. At this time, the Project Explorer should only show the default project. Figure 3-10. ServiceBus console window All work done in ALSB is done under the context of a change. Think of a change as a trans- action with a transactional database. With a database you create a transaction context, make your changes to the database, then commit those changes if you’re satisfied with them. The changes you make to a database don’t take effect until you commit those changes. The same principle applies here. Also, just as with a transactional database, if you change your mind about making the changes, you can roll back the transaction. In ALSB, you can discard your changes. When you discard your changes, no change is made to ALSB. Usually, the ability to create a change in the Change Center is reserved for the Administra- tor role. Each administrator account can only make one change at a time; however, multiple administrators may make their changes to the system independently of one another. Let’s look at a quick example to help illustrate this. Imagine that you have two administrators on your service bus, users john and jane. Both users (john and jane) log into the system and begin to make their respective changes. If they create changes that conflict with one another, those conflicts will show up in the Change Center and neither user will be able to commit his or her changes until all conflicts are resolved. ALSB does a great job of ensuring the validity of its configuration at all times.
    • 7974CH03.qxd 3/2/07 10:04 AM Page 37 CHAPTER 3 s HELLO WORLD SERVICE 37 One last note on the Change Center: each change is associated with a user session. A user can log in and start a change. If the user logs out or gets disconnected before he commits his changes, the work he has done up to that point is preserved (not lost) by the service bus. The next time that user logs into the system he can resume making changes right where he left off. This preservation of changes holds true even if the server crashes or is restarted. Your first step in creating the new project is to click the Create button in the Change Center (located in the top-left corner of the ALSB console). Notice how the Create button has changed to a green color and now says Activate. Don’t click the Activate button yet; you have some changes to make first. To create your project, type the project name into the Enter New Project Name field and click the Add Project button. The console should now show that you have both the default project and the Hello World project, as shown in Figure 3-11. Figure 3-11. Hello World created Next, click the Hello World link in the Project Explorer. On this page you have the options to add folders and create resources for the project. Folders are used to help organize the vari- ous resources of the project. Even though your Hello World project is going to be trivial in its complexity, it’s still a good idea to start developing professional ALSB habits. You’ll create a folder called WSDL that will contain your WSDL file for this service, and you’ll also create folders named ProxyServices and BusinessServices. We’ll discuss these folders in the section “Business Services and Proxy Services.” Use the Add Folder link to create these new folders. Creating the WSDL Click the WSDL folder to open it. In the WSDL folder, use the Create Resource combo box to select a WSDL entry. Name the WSDL HelloWorld. Enter a brief description for the WSDL file. The description isn’t necessary, but it’s a good practice, especially when you use ALSB in the real world and have to manage many different resources. In the WSDL field, you need to paste in the WSDL for the web service you created earlier in this chapter. The easiest way to do this is to open your browser and navigate to http:// localhost:7001/business/hello/HelloWorldService?WSDL. Once you see the WSDL in the browser, be sure to view the source (View ® Page Source in Firefox, View ® Source in Internet Explorer) for that page to get the raw XML. Copy the raw XML in its entirety and paste it into
    • 7974CH03.qxd 3/2/07 10:04 AM Page 38 38 CHAPTER 3 s HELLO WORLD SERVICE the large text area box in the service bus console. It’s important that you copy this from the browser’s source page, because if you do it directly from the browser window, you’ll get extra- neous characters that corrupt the WSDL. Alternatively, you can enter the file path to the WSDL file in the textbox near the top of the page, next to the Browse button (see Figure 3-12). Figure 3-12. Creating the HelloWorld WSDL resource You can also load a WSDL resource from a URL. The process for this is described in Chapter 14 in the “Administration” section. Click the Save button. If you mistyped anything in the WSDL, then the ALSB console will report an error in red text. If everything went perfectly, you’ll see the new HelloWorld WSDL resource listed in the WSDL folder for the project. WHAT IS A WSDL? WSDL stands for Web Services Description Language. A WSDL defines a contract between the service provider and the consumers of the service. The WSDL you just added to the project defines a single document- style call that takes a string as an argument and returns an XML document that contains the greeting string from the service. The current version of the WSDL specification is 1.1. WSDL version 2.0 is expected to have some signif- icant changes to the specification. You can get more information on the WSDL specifications at http:// www.w3.org/TR/wsdl.
    • 7974CH03.qxd 3/2/07 10:04 AM Page 39 CHAPTER 3 s HELLO WORLD SERVICE 39 Business Services and Proxy Services ALSB divides services into two categories: business services and proxy services. You can think of proxy services as the services published by ALSB. Instead of your service clients calling the services directly, they call ALSB proxy services instead. This might seem odd at first glance, but we promise it will make sense by the time you finish reading this section. Business services are defined in ALSB to represent services that are external to ALSB. For example, the HelloWorld service you created at the beginning of this chapter is external as far as ALSB is concerned. For ALSB to be able to call the HelloWorld service, you have to create a business service in ALSB. We often think of a business service as the client stub that ALSB uses to interact with external services. As for the external services, we refer to them as service providers. So let’s answer the question that we’re sure you’re asking yourself: “Why shouldn’t my service clients just call the services they need?” There are five reasons. First is location trans- parency. One of the features of ALSB is the ability to proxy multiple endpoints for the same service. If you have the same service running on five different machines, ALSB can round- robin or otherwise load balance the calls among those servers. Location transparency allows you to add, remove, and change service endpoints without having to recompile your clients or perform some DNS trickery. The second reason to invoke ALSB instead of the end services is service aggregation. Not every proxy service in ALSB has to represent a single business service. A proxy service can invoke any number of business services, and can apply conditional logic to select the right subset of business services, depending on the needs of the caller. This also abstracts out the routing logic from the client and places it inside the service bus, where it belongs. The third reason to use ALSB is to provide a layer of abstraction between your service clients and your service providers. For example, let’s say you have a customer management system at your company, and you’ve created a number of service providers that provide serv- ices based on a set of XML document schemas that you’ve defined. At some point your company decides to replace your old customer management system with a newer system. This new system has web services built in. The problem is that the new system uses its own set of XML document schemas that are different from yours. What’s a developer to do? Rewrite all your existing service clients? Madness! With ALSB you can simply create transformations that modify the new XML documents into the form expected by your current clients. The fourth reason to use ALSB is that it provides a centralized area for collecting service invocation metrics. It allows you to create your own Service-Level Agreements (SLAs) that help you monitor service performance, display statistics, and provide a reporting platform. ALSB does all this without requiring you to modify or otherwise instrument the services themselves. The fifth reason to use ALSB is that it provides a centralized platform for security policies. Even if the external web service isn’t robust enough to provide security, the fact that ALSB “proxies” those services gives you the ability to apply industry-standard, robust security policies. ALSB is a powerful tool in your enterprise, granting you flexibility where you need it most.
    • 7974CH03.qxd 3/2/07 10:04 AM Page 40 40 CHAPTER 3 s HELLO WORLD SERVICE Creating the Business Service When you create a business service in ALSB, you’re making ALSB aware of an existing, external web service. In this case, you’re creating a business service that represents the web service you created in the first part of this chapter. You begin by navigating to the BusinessServices folder you created earlier, and selecting Business Service from the Create Resource combo box. Set the Service Name field to Hello World Business Service. Enter any description you like. Next, select the WSDL Web Service radio button and click the Browse button. This brings up the WSDL browser window (see Figure 3-13). Figure 3-13. WSDL browser window Click the Hello World name to select it as the WSDL for your business service. In the next window, click the HelloWorldSoapPort and click the Submit button. Back in the main browser window, click the Next button. The next window allows you to specify the transport configuration of the business service (see Figure 3-14). Notice that the correct endpoint for the business service is prepopulated for you in the Existing URIs section. This is because you copied the WSDL of the business service directly. If the same business service existed on multiple endpoints (that is, on multiple machines), you could specify the additional endpoints and the load balancing algorithm, allowing ALSB to balance the calls across multiple servers. Figure 3-14. Business Service - Transport Configuration window
    • 7974CH03.qxd 3/2/07 10:04 AM Page 41 CHAPTER 3 s HELLO WORLD SERVICE 41 For your purposes, the defaults are fine. Click the Next button. The next window is the HTTP Transport Configuration window. Once again, just click the Next button to accept the defaults. The next step in the wizard is the SOAP Binding Configuration page. This page allows you to specify whether or not ALSB should enforce WS-I compliance. For this exercise, leave the checkbox unchecked. This brings you to the final step in the configuration wizard: the summary page (see Figure 3-15). Figure 3-15. Business Service - Summary window Click the Save button to save the business service. At this point, ALSB is aware of the busi- ness service, and it knows how to invoke it. Your next step is to define a proxy service that represents (and provides a layer of abstraction for) this business service. Creating the Proxy Service A proxy service is a web service published by the service bus that represents a “real” service (also known as a service provider) elsewhere. By using a proxy service, you can create a layer of abstraction between the consumers of a service and the service provider. This allows you to move and change the service providers without affecting the consumers. For your HelloWorld service, you need a proxy service to present the service to your consumers.
    • 7974CH03.qxd 3/2/07 10:04 AM Page 42 42 CHAPTER 3 s HELLO WORLD SERVICE You begin by navigating to the ProxyServices folder in the HelloWorld project, using the Project Browser. In the Create Resource combo box, select Proxy Service. Set the Service Name to HelloWorld and provide a brief description of the service. Under Service Type - Create from Existing Service, select the Business Service radio button and click the associated Browse but- ton. This brings up the Service Browser window (see Figure 3-16). Figure 3-16. Service Browser In the Service Browser window, select the radio button for the Hello World Business Ser- vice and click the Submit button. Back in the Edit a Proxy Service - General Configuration window, click the Next button. In the Edit a Proxy Service - Transport Configuration window, set the Endpoint URI to /esb/Hello_World (see Figure 3-17). It’s critical that your end point begins with the “/” charac- ter or you’ll get errors later. Click the Next button. The next window is the Edit a Proxy Service - HTTP Transport Configuration window. You’ll use the default configuration, so just click the Next button. Similarly, in the Edit a Proxy Service - Operation Selection Configuration window, you use the default values. Click the Next button. Figure 3-17. Specify the endpoint URI for the proxy service.
    • 7974CH03.qxd 3/2/07 10:04 AM Page 43 CHAPTER 3 s HELLO WORLD SERVICE 43 The final window is the summary window. Your window should look identical to the one in Figure 3-18. Click the Save button to save this proxy service. Figure 3-18. Edit Proxy Service - Summary window Now let’s make sure that your creation of the proxy service was successful. Click the Acti- vate button to commit your changes to ALSB. ALSB prompts you for a description of the changes you’re activating. Once again, the description isn’t necessary, but it is a best practice. When you’re operating in a production environment, where your changes may affect many servers, and you make a mistake while configuring something, the session activation descrip- tions can be a lifesaver. Get into the habit of entering meaningful descriptions and you won’t regret it. The proxy service you just created is now running. Let’s take a look at the WSDL for your proxy service. Open your browser and navigate to http://localhost:7001/esb/HelloWorld?WSDL. If the WSDL displays, you know the service was also deployed. The WSDL for the proxy service looks similar to the WSDL for the business serv- ice, with the exception of a different service endpoint. However, a little magic happened here, and you need to be aware of it. Back in the ALSB console, navigate to the proxy service you just created. You’re going to make some changes, so you need to click the Create button in the Change Center again. Next, click the Edit Message Flow button of the proxy service, as high- lighted in Figure 3-19.
    • 7974CH03.qxd 3/2/07 10:04 AM Page 44 44 CHAPTER 3 s HELLO WORLD SERVICE Figure 3-19. Proxy Services folder This brings up the message flow for the Hello World proxy service (see Figure 3-20). All proxy services have a message flow. Every message flow has a start node; in this case the start node is called Hello World. It has a pair of green arrows on the icon. These arrows indicate that the service is two way. That is, the service is invoked and returns in a synchronous manner. Figure 3-20. Hello World message flow The bottom node in the flow is a routing node. As its name suggests, it routes a message to another service. The name was generated for you by ALSB and succinctly tells you that it’s routing the message to the Hello World Business Service that you defined earlier in this chapter.
    • 7974CH03.qxd 3/2/07 10:04 AM Page 45 CHAPTER 3 s HELLO WORLD SERVICE 45 Left-click the bottom node and select Edit ® Route Node from the pop-up menu. The Edit Stage Configuration window shows you more detail on how the route node operates (see Fig- ure 3-21). In the combo box, select the getGreeting operation. You’ve just instructed the node to route all requests to the getGreeting operation of the HelloWorld Business Service. Figure 3-21. Edit Stage Configuration window Click the Save button, once for each of the two windows, until you get back to the browser page that shows the proxy service. Now click the Activate button. Your proxy service is now configured to route all requests it receives to the proper business service. Your next step is to test the proxy service to ensure that it’s working as intended. A Quick Note on the Configuration Changes Screen As you can see, after you activate a change in the Change Center, the ALSB console will show you the View Configuration Changes page (see Figure 3-22). Figure 3-22. The View Configuration Changes page This page shows all the changes that have been applied to the domain. Each entry repre- sents a change session where you’ve clicked the Create and Activate buttons, and shows all the changes you made to the system in between those two button clicks. If you click one of the task names, another window will show you a more detailed view of the changes that took place inside the task (see Figure 3-23).
    • 7974CH03.qxd 3/2/07 10:04 AM Page 46 46 CHAPTER 3 s HELLO WORLD SERVICE Figure 3-23. Individual tasks inside a change Testing the Proxy Service ALSB provides a simple-to-use but robust mechanism for testing proxy and business services manually. For automated testing, we recommend that you write test clients that can be invoked from JUnit or use some other testing framework. The test console is designed to let you quickly test any service defined in ALSB. The test console is only available if no changes are active in the Change Center. Now that you’ve saved your changes for the HelloWorld proxy service, you can left-click the Test Console button, as shown in Figure 3-24. Figure 3-24. The Test Console button The test console provides a general-use user interface to any web service. The test console parses the interface of the service and customizes itself to make it easier to enter test informa- tion. For example, if you click the Test Console button for your HelloWorld proxy service, you’ll see the test console as shown in Figure 3-25.
    • 7974CH03.qxd 3/2/07 10:04 AM Page 47 CHAPTER 3 s HELLO WORLD SERVICE 47 Figure 3-25. The HelloWorld proxy service test console There are two important parts of the test console. First is the Available Operations combo box at the top. This is an important control once you begin to develop more sophisticated services that have more than one operation. The second important area is the Request Docu- ment section of the console. See how the SOAP Body text area has been filled with the appro- priate document for invoking the HelloWorld web service? As you go on to develop more complex services and documents, the test console will become a vital tool to help keep you productive by automating the generation of test documents.
    • 7974CH03.qxd 3/2/07 10:04 AM Page 48 48 CHAPTER 3 s HELLO WORLD SERVICE Let’s use the test console to run a quick test. Replace the string entry between the <alsb:name> tags and click the Execute button. The test console invokes the proxy service using the name you’ve supplied and then shows you a result page. The result page shows the request document, the response document (see Figure 3-26), the response metadata, and the invocation trace (see Figure 3-27). Figure 3-26. The request and response documents in the test console If you click the plus signs in the Invocation Trace section of the test console results, you can see the receiving request and routing information. You can drill down into detailed infor- mation: document construction, header information, the creation of user-defined variables, and the list goes on. Figure 3-28 shows the invocation trace for the Hello World proxy service. The Invocation Trace section of the test console is an invaluable tool when it comes to debug- ging both proxy and business services.
    • 7974CH03.qxd 3/2/07 10:04 AM Page 49 CHAPTER 3 s HELLO WORLD SERVICE 49 Figure 3-27. The response metadata and the invocation trace in the test console Figure 3-28. Invocation Trace details
    • 7974CH03.qxd 3/2/07 10:04 AM Page 50 50 CHAPTER 3 s HELLO WORLD SERVICE Summary You did quite a lot quickly in this chapter. Let’s review what you’ve accomplished. • You learned how to create and deploy a web service for WebLogic 9.x. This became your service provider. • You learned the basics of ALSB. ALSB acts as an intermediary between the service provider and the service consumer, providing a layer of abstraction between the two. • You gained a basic understanding of the ALSB interface. • You learned how to create several of the most common resources in any ALSB project: business services, proxy services, and WSDLs. • You learned how to create web service test clients to verify that your code behaves as expected and the deployments were successful. • You learned how to use the test console to quickly test the proxy and business service that you created. In the next chapter, you’ll learn more about the message flows and how to use them effectively.
    • 7974CH04.qxd 3/2/07 10:11 AM Page 51 CHAPTER 4 Message Flow Basics M essaging is at the heart of ALSB. Messages are handled by message flows: a set of instruc- tions on what to do with each message. In Chapter 3 you created your first message flow. It was trivial in nature, yet it shares the same basic set of components that even the most advanced message flows possess. Each message flow is constructed from one or more nodes. There are four basic node types: Start, Pipeline Pair, Route, and Branch. If no nodes are added to a message flow, then ALSB simply echoes the request message back to the caller. Message Flow Overview A proxy service is defined by its message flow. A message flow consists of a set of nodes. There are four types of nodes: Start, Pipeline Pair, Branch, and Route. Each type of node is used for a specific purpose, as noted in Table 4-1. Table 4-1. Message Flow Node Types Node Type Description Start Every message flow begins with a Start node. A Start node cannot be modified. It exists only to mark the entry point of the message flow. Route This is a leaf node that handles the request/response dispatching of the message to a business service. No other nodes can follow a Route node. Branch This node is used to make decisions in the message flow, based on the contents of the message. You can make two types of decisions in a Branch node: operational branches or conditional branches. Pipeline Pair A Pipeline Pair node explicitly represents both the request and the response message paths in the node, making it easier to customize transformations and other operations on either the request or response side of the node. This type of node can be followed by at most one other node type. As you can see from Table 4-1, there are rules concerning each node, specifically about the number of nodes that might follow. (That is, the Pipeline Pair node can have at most one node following it, and so on.) Figure 4-1 is a graphical representation of a sample message flow that helps to demonstrate some of these node rules. The Pipeline Pair nodes are followed by, at most, one other node. The Branch nodes can make decisions to route the message among any number of other nodes. Though the diagram only shows Branch nodes routing to 51
    • 7974CH04.qxd 3/2/07 10:11 AM Page 52 52 CHAPTER 4 s MESSAGE FLOW BASICS at most two nodes, there is, in fact, no limit on the number of nodes that a Branch node can reference. Last, the Route nodes make up the leaves of this message flow tree, because their job is to route messages to external services. Figure 4-1. Sample message flow structure Pipeline Pairs As its name implies, a Pipeline Pair is a pair of pipelines. Each pipeline is a sequence of stages representing a nonbranching, one-way processing path. The left pipeline is the request pipeline. This pipeline is dedicated to request processing only. The right pipeline is the response pipeline, dedicated solely to the handling of the response. Pipeline Pairs are composed of Stages. A Stage is simply a group of Actions (more on Actions later). Figure 4-2 shows this relationship graphically. The Pipeline Pair contains a request pipeline and a response pipeline. Each pipeline contains a chain of Stage nodes. You can create error handlers at the stage level. Additionally, you have the option of adding an error handler to each of the two pipelines. This error handler will catch any errors generated in the pipeline that aren’t already handled by a stage error handler.
    • 7974CH04.qxd 3/2/07 10:11 AM Page 53 CHAPTER 4 s MESSAGE FLOW BASICS 53 Figure 4-2. Pipeline Pair details Using Figure 4-2 as a guide, you can see that the request pipeline has a pipeline error handler attached. By the way, both the Request Pipeline start ( ) and Response Pipeline start ( ) icons are unmodifiable. The only thing you can do with these nodes is to add or remove stages or add a pipeline error handler. Let’s focus on the request pipeline side for a bit. You can see that the request pipeline has an pipeline error handler associated with it. The warning symbol ( ) indicates that there’s an associated error handler. This means that if any of the stages within the pipeline generate an error, the request pipeline will handle the error. However, you also see that the “transform request format” stage has a stage error handler associated with it, so any errors that are gener- ated in that stage will be handled by the stage error handler, not the overall request pipeline error handler. One interesting thing to note: if the stage error handler raises an error, then the pipeline error handler will then handle that error. This nesting of error handlers is reminiscent of Java’s exception handling approach. On the other side of the pipeline, the response pipeline has no error handlers at all. Any errors that arise in this pipeline will be handled by the default system error handler, which for SOAP messages will generate a SOAP fault to the caller.
    • 7974CH04.qxd 3/2/07 10:11 AM Page 54 54 CHAPTER 4 s MESSAGE FLOW BASICS Branch Nodes Branch nodes provide decision-making capability to the message flow. Branches are defined by creating a lookup table of string values. Each Branch node is capable of enforcing a single decision only. If your decision logic requires multiple decisions, you’ll need to use multiple Branch nodes. There are two subtypes of Branch nodes: conditional and operational. A conditional branch node makes decisions based on string matching conditions. For example, Figure 4-3 shows the lookup table for a conditional branch. There are three possible paths the Branch node can take, depending on the contents of the variable name. If the name is Foo, the Foo branch will be taken; if the name is Bar, the Bar branch will be taken. If the name variable doesn’t match either of those string values, the default path will be taken. Figure 4-3. Defining a conditional branch node An operational branch node works similarly, but it uses operations defined in a WSDL, not string values. This is handy if your WSDL defines multiple operations and you need to perform some additional logic based on the operation that’s being invoked, as shown in Figure 4-4. Figure 4-4. Defining an operational branch node
    • 7974CH04.qxd 3/2/07 10:11 AM Page 55 CHAPTER 4 s MESSAGE FLOW BASICS 55 Route Nodes Route nodes are the nodes that handle the request and response communication between the message flow and another service. The other service might be a business service, or it might be another proxy service in the ESB itself. It represents the boundary between the request and response processing for the proxy. Like a Pipeline Pair node, the Route node has an intrinsic understanding of both the request and response values of its messages. Also, like with the Pipeline Pair, you can perform specific request and response functions on the messages. How- ever, unlike the Pipeline Pair, the Route node isn’t divided into stages. From an error handling point of view it’s an all-or-nothing construct. You can add an error handler to the entire Route node, but that’s the limit. No error handling is possible within a Route node. Finally, because the Route node communicates with other services directly, there can be no other nodes in the message flow that follow a Route node. Unlike Pipeline Pairs and Branch nodes, a Route node is comprised of a series of actions that are performed on the request and/or response portions of the message. Actions Each Route node in the message flow or stage in a Pipeline Pair or an error handler pipeline can contain any number of actions. An action is an instruction, similar in nature to a line of code in a traditional programming language. However, unlike traditional programming lan- guages, actions aren’t source code that gets compiled, but configuration information that’s stored in the message bus. Actions aren’t written in Java, C++, or even in a scripting language such as Python or Ruby. Instead, actions are created graphically, with the occasional mix of XQuery, XPath, and/or XSLT. Goodbye World! Let’s put this newfound knowledge to use by creating a variant of your Hello World proxy service. In this exercise, you’ll create a new project and a new proxy service. However, you’ll reuse the existing Hello World business service. The purpose of this project is to take the string response from the Hello World business service and transform its contents to say “Goodbye” instead of “Hello.” Though modest in scope, this simple project will demonstrate the value of data transformation and service reuse. 1. To begin, open up the ALSB console and click the Create button in the Change Center. 2. Create a new project and name it Goodbye World. 3. In the new project, create a folder named Proxy Services. In this folder, create a proxy service resource named GoodbyeWorld. This proxy service is based on the existing Hello World business service. 4. Set the End Point URI for the service to /esb/GoodbyeWorld. Just accept the rest of the default values on the following pages until the proxy service is created. 5. Click the Edit Message Flow icon for the Goodbye_World proxy service. Left-click the RouteTo_Hello World Business Service icon and select Edit Route from the pop-up menu.
    • 7974CH04.qxd 3/2/07 10:11 AM Page 56 56 CHAPTER 4 s MESSAGE FLOW BASICS Now you’ll work some magic. You know that the Hello World business service takes a name argument and returns a greeting result that contains the string Hello <name> from the business service! You need to intercept and transform the response from the business serv- ice and change the “Hello” to a “Goodbye.” Therefore, you need to perform some actions in the response portion of the Route node. You need to perform a minimum of two steps. The first step is to get the greeting string from the response and store it in a local variable. The sec- ond step is to replace the “Hello” portion with “Goodbye” and then put the new string back into the response value. If you followed the preceding steps, you should see the “Edit Stage Configuration: Route Node” page displayed in the ALSB console. Perform the following steps to complete the response processing for this node: 1. Select the getGreeting operation from the combo box. 2. Click the “Add an action” link in the Response Actions table. Select Message Processing ® Assign action from the pop-up menu. 3. Click the Expression link and type in the following XQuery expression to retrieve the string data from the response: replace($body/alsb:getGreetingResponse/alsb:return, Hello, Goodbye) Your expression should appear exactly like the one shown in Figure 4-5. Figure 4-5. Say “Goodbye” to “Hello”! 4. Now click the Validate button to be sure you typed it in correctly. Finally, click the Save button. sNote The XQuery replace() method is case dependent!
    • 7974CH04.qxd 3/2/07 10:11 AM Page 57 CHAPTER 4 s MESSAGE FLOW BASICS 57 A bit of explanation is due here. You just created an XQuery script that calls the XQuery replace() function. It searches through the first string argument, finding all instances of the second string argument (“Hello” in this case) and replaces all those instances with the third argument, “Goodbye.” It then returns the resulting string. Next you’ll assign the result of the replace function to a local variable. This is a simple process of typing the variable name into the associated variable field, as shown in Figure 4-6. Figure 4-6. Assign the string to the goodbyeGreeting variable. sNote You don’t need to declare variables in advance when using the ALSB console. Simply enter the variable name and ALSB takes care of the rest. Now that you have the “Goodbye” string stored in the goodbyeGreeting variable, you need to insert that data back into the message response. To do this you need to create a Replace action to follow your existing Assign action. Left-click the icon of the Assign action you just created (that is, ) and select Add an Action ® Message Processing ® Replace from the pop-up menu). Click the XPath link for the newly created Replace action. You need to tell ALSB what node you’re replacing. In the XPath Expression Editor, enter the following expression: ./alsb:getGreetingResponse/alsb:return As you can see from the expression, you’re just putting your modified string back where you found the original string. Click the Save button to return to the main page for configuring the Route node. For the variable name, enter body. Note that you don’t enter $body when using the con- sole because you aren’t writing direct XQuery, so you only enter the name of the variable itself, without the $. Now click the Expression link for the Replace action and enter the following XQuery expression: string($goodbyeGreeting)
    • 7974CH04.qxd 3/2/07 10:11 AM Page 58 58 CHAPTER 4 s MESSAGE FLOW BASICS sCaution You cannot just enter the variable ($goodbyeGreeting) here. You must cast it to a string data type or you’ll get an error. Click the Save button. Back at the Route Node Configuration window, be sure to select the “Replace node contents” radio button, because you just want to replace the node contents. If you were to replace the entire node with this string, you’d corrupt the message format. This last step is optional. When you call this proxy service it operates as a black box. You can’t see what’s going on inside easily. We like to add some logging functions, to make it easier for us to see that our proxy services are working as expected, especially in the early stages of development. Tip s Using logging actions can make it easier to debug proxy services. Left-click the Replace action icon ( ) and select Add an Action ® Log to create your Log action. Click the Expression link for the Log action and enter the following XQuery expression: concat(Goodbye data: , string($goodbyeGreeting)) Click the Save button. Be sure to set the “at severity level” combo box to Error. This will display the log entry onto the ALSB system console (not the user interface, but the console window that shows the System.out messages for your operating system). You can leave the “with Annotation” field blank. Your Route node configuration should now look like Figure 4-7. Click the Save button twice, then click the Activate button in the Change Center. Once you’ve activated that session, it’s time to test your new proxy service. Once you’ve activated your new Goodbye World project, navigate to the Proxy Services folder of the project and click the little insect icon to the right of the proxy service name ( ). Notice that the XML document in the test console looks exactly like the one from your Hello World project, as shown in Figure 4-8. Just enter a name in the “name” field and click the Execute button. In a moment, the results appear in the test console. What we love about the test console is the incredibly rich detail that it provides. You don’t just get the response string, you get so much more! The test console provides you with the following details: • The request document • The response document • The response metadata • A detailed invocation tree You’ll quickly come to love and rely on the test console. It lays open to you all the infor- mation to make your life as a service developer or service composer as easy as possible.
    • 7974CH04.qxd 3/2/07 10:11 AM Page 59 CHAPTER 4 s MESSAGE FLOW BASICS 59 Figure 4-7. The final version of the GoodbyeWorld Route node Figure 4-8. The Goodbye World test console
    • 7974CH04.qxd 3/2/07 10:11 AM Page 60 60 CHAPTER 4 s MESSAGE FLOW BASICS What the Heck Just Happened Here? Did you find the Goodbye World exercise a little confusing? Does it seem like you’ve stepped into an alien world where nothing makes sense? Good; that’s normal, unless you have a strong background in XML and XQuery. We felt the same way when we got started with ALSB. We thought we had a good under- standing of XML, but it turns out that our knowledge only scratched the surface. ALSB does a great job of making much of the work quick and easy. However, there’s no masking XML or XQuery. These are important technologies that will be with us for a long time to come. The dif- ficulty is that if you come from a traditional programming background, XML and XQuery often seem like alien languages; they just don’t map well to procedural or object-oriented program- ming models. The good news is that with a little practice, and a little bit of explanation, this will become clear and simple. We’ll walk you through the XQuery you just entered and do our best to explain some of the basics so that this becomes a simple process when you’re working on your own projects. On top of what we’ll cover here, Chapter 5 is all about WSDL; that will also help to give you some clarity. Let’s begin with the replace statement you used in the Goodbye World project. The replace function is an XQuery function. If you look carefully at Figure 4-5 you’ll see a list of available XQuery functions on the left-hand side of the ALSB console. The replace function itself is easy to understand if you have a background in software engineering. The part of the statement you’re probably confused by is the first argument in that function: $body/ alsb:getGreetingResponse/alsb:return. How did we know what the first argument should be? More importantly, how will you know which argument to use when you’re using this in the real world? To begin, it’s important to understand that ALSB breaks all request and response mes- sages down into several components and makes these components available to you through the use of XQuery variables. The $body variable is a prime example of this. The $body variable holds the main payload (also known as the body) of the message. You’ll find that most of your message processing and transformations involve the $body of the message. The other standard XQuery variables of a message are $attachments, $header, $inbound, $operation, and $outbound. sNote ALSB uses SOAP as the canonical message format. Whenever non-SOAP messages are used, ALSB will transform the messages into SOAP format. The $body variable contains the <soap:body> element, and the $header variable contains the <soap:header> element. The $body is comprised of XML. To know the format of that XML, you have to know the type of message you’re dealing with. In this case, you know that you’re dealing with a response message from the HelloWorld business service. In ALSB, navigate to the HelloWorld WSDL that you created in Chapter 3. Start by looking for the operation declaration. You know you’re deal- ing with the getGreeting operation. For convenience’s sake, we’ve included this declaration in Listing 4-1.
    • 7974CH04.qxd 3/2/07 10:11 AM Page 61 CHAPTER 4 s MESSAGE FLOW BASICS 61 Listing 4-1. The getGreeting Operation Definition <operation name="getGreeting" parameterOrder="parameters"> <input message="s0:getGreeting"/> <output message="s0:getGreetingResponse"/> </operation> As you can see in Listing 4-1, the operation takes an input message and returns an output message. Because you’re modifying the greeting that’s returned by the business service, you know that you need to know the structure of the response message. From Listing 4-1 you can determine that the message you need to modify is named getGreetingResponse (ignore the s0: namespace prefix for now). You next step is to find the getGreetingResponse message dec- laration in the WSDL file (see Listing 4-2). Listing 4-2. The getGreetingResponse Message Definition <message name="getGreetingResponse"> <part element="s0:getGreetingResponse" name="parameters"/> </message> Not a lot to see here. The format of this message is defined by the getGreetingResponse element. Your next step is to find that element definition, which is conveniently located in Listing 4-3. Listing 4-3. The getGreetingResponse Element Definition <xs:element name="getGreetingResponse"> <xs:complexType> <xs:sequence> <xs:element name="return" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> Finally, you’ve discovered the structure of the return message. You now know that the $body variable in the return message will contain the structure in Listing 4-4 (namespaces omitted for now). Listing 4-4. The getGreetingResponse Return <getGreetingResponse> <return>greeting goes here</return> </getGreetingResponse> Now that you know the structure of the return document, you can create an XPath expres- sion to represent it: $body/alsb:getGreetingResponse/alsb:return
    • 7974CH04.qxd 3/2/07 10:11 AM Page 62 62 CHAPTER 4 s MESSAGE FLOW BASICS Here we’ve inserted the namespaces again for completeness. This XPath expression instructs ALSB to get the contents of the alsb:return node. Now, if you return to Figure 4-5, the entire XQuery function call should make sense to you. The real benefit here is that you’ve learned how to determine the contents of the $body variable for any message you process. s Caution Namespaces are as fundamental to modern XML communications as package names are in Java. Once you’re comfortable with XQuery and XPath, the most common reason for your XQuery and XPath code not to work correctly will be due to using the wrong namespace. One last note about namespaces: like all programming paradigms, they’re brutally intol- erant of errors. In Java, if you omit the package name of a class (and don’t explicitly import the class), most modern IDEs will detect this and prompt you at design time either to import the class, import the entire package, or specify a fully qualified class name when you use it. Due to its interpretative nature, ALSB doesn’t validate namespace usage at this level of detail. The best it will do is tell you if you’ve used a namespace prefix that hasn’t been defined. If you omit the namespace when you should have included it, ALSB won’t detect a problem until runtime. Even at runtime, errors are rarely recognized and reported. Usually your expressions are sim- ply evaluated to null and no value is returned at all. For example, Listing 4-5 shows three (invalid) variations of the proper XPath expression from Listing 4-4. Listing 4-5. Three Invalid Expressions $body/alsb:getGreetingResponse/return $body/getGreetingResponse/alsb:return $body/getGreetingResponse/return As you can see, it would be easy to omit a namespace inadvertently, and difficult to spot the problem when looking at the code. If your expressions are coming back null or empty, look at the namespace usage first. A Hidden Design Flaw Your Goodbye World project runs like a rocket, but did you notice the subtle design flaw? The flaw isn’t in the service itself, but in how you assembled it. Remember that reuse is a core con- cept of any ESB and is central to SOA. Your proxy service is certainly reusable, but you missed the opportunity to reuse something within the proxy service itself: the XQuery function that changes “Hello” to “Goodbye.” ALSB has the ability to store XQuery, WSDL, XML Schema, XSLT, WS-Policy files, and more as reusable resources. The ability to store these resources (sometimes referred to as “assets or “artifacts”) along with proxy services makes ALSB a lightweight service repository. It’s certainly a best practice to reuse these resources whenever possible.
    • 7974CH04.qxd 3/2/07 10:11 AM Page 63 CHAPTER 4 s MESSAGE FLOW BASICS 63 Let’s take a moment to see how you can make XQuery a reusable resource in your ESB. For this exercise, you’ll create a new proxy service inside your Goodbye World project. You’ll name this new proxy service GoodbyeWorldXF (the XF indicates it uses an XQuery function). You won’t overwrite your GoodbyeWorld service because it will be handy to compare the two when you’re done. You should be familiar with the process of creating a proxy service by now, so we’ll skip over the boring details. The process is essentially the same as the one you followed when you created the GoodbyeWorld proxy. However, before you create the actions in the Route node for your new GoodbyeWorldXF, you need to create your XQuery resource. Creating the XQuery process is similar to creating a proxy service. You first navigate to the project and folder where you’d like to create the resource. Then select XQuery from the “Create resource” combo box. Name the resource Hello_to_Goodbye and provide a short description: “Change the word ‘Hello’ in a given string to ‘Goodbye’.” Next you write your XQuery into the large text area box. Listing 4-6 shows the content of the XQuery resource you’re creating. Listing 4-6. Sample XQuery Function Performing a String Replacement xquery version "1.0"; declare namespace xf = "http://tempuri.org/util/"; declare function xf:helloToGoodbye($hello as xs:string) as xs:string { let $goodbye := replace($hello, Hello, Goodbye) return $goodbye }; declare variable $greeting as xs:string external; xf:helloToGoodbye($greeting) Let’s look at this XQuery script resource in more detail. It’s a good guide for other XQuery resources that you might create. The first line is a declaration of the type of data contained in this resource. It’s optional in ALSB to include this line. We like to include it for completeness, and because there are other, external tools that require the line to exist, so including it makes it easier to copy and paste the script between tools. The second line of text is your namespace declaration. This places your function in a spe- cific namespace, which helps to avoid naming collisions. Immediately after the namespace declaration, you declare your XQuery function. Note that you prefix the function name by the namespace. This function take a single xs:string argument named $hello and returns an xs:string. The body of the function is pretty straightforward. You can see how the call to the replace function is stored in a local variable named $goodbye, which is returned by the function. The next line of code is interesting. Here you formally declare a variable, which you’ve never had to do before. You must explicitly define a variable because you’re using an external XQuery variable. Later, when you use this script resource, ALSB will prompt you to provide a value for this external variable. Declaring external variables is the mechanism for passing data from ALSB to the XQuery script.
    • 7974CH04.qxd 3/2/07 10:11 AM Page 64 64 CHAPTER 4 s MESSAGE FLOW BASICS The last line of code in this script calls the function you’ve defined, passing in the external variable as the argument. This last line is necessary to “hook up” the caller to the script. With- out this line, the XQuery script would still run, but the method would never be invoked. The caller of this script has no knowledge of the xf:helloToGoodbye function. It only knows about the XQuery script resource itself. When ALSB invokes the script, it runs the entire script; it doesn’t invoke a method. This is similar in nature to how other scripting languages are invoked. Okay, back to defining your proxy service. Click the Save button to save your XQuery script. If you made a typo, the ALSB console will give you a warning and let you correct the problem before it saves the script. In fact, the console won’t let you save the script resource unless it’s syntactically valid. Now it’s time to edit the Route node for your GoodbyeWorldXF proxy service. In the Response Actions section, create a new Assign action. When editing the Assign expression, be sure to click the XQuery Resources link, as shown in Figure 4-9. You can then use the Browse button to search for the XQuery expression you want to invoke. In this case, you’ll select Goodbye World/Hello_to_Goodbye. In the Bind Variables section of this page, set the greeting field to string($body/alsb:getGreetingResponse/alsb:return). This tells ALSB to set the XQuery script’s external variable to the value you need to modify. Figure 4-9. Invoking an XQuery resource Click the Save button to save this portion of the Assign action. Set the variable name for the Assign action to greeting. Next you add a Replace action. Set the XPath to ./alsb:getGreetingResponse/alsb:return and set the variable field to body. Finally, set the Expression to string($greeting) and select the “Replace node contents” radio button. Your Route node should now look like Figure 4-10.
    • 7974CH04.qxd 3/2/07 10:11 AM Page 65 CHAPTER 4 s MESSAGE FLOW BASICS 65 Figure 4-10. Your final Route node for GoodbyeWorldXF Save everything and activate your changes. Test the new service to be sure that it performs correctly. One interesting thing to note: as you can see from Figure 4-11, you can also test your XQuery script. Figure 4-11. You can test XQuery resources too! When you test the Hello_To_Goodbye script, remember to include the word “Hello” on the test string. Summary In this chapter you were introduced to the basics of message flows. You also reused one of your existing services from Chapter 3. Reuse is one of the core concepts of ESBs and SOA, and here we’ve demonstrated the power of that concept. You also saw an example of data transfor- mation, where you intercepted data in flight and modified it to suit your needs. You learned how to create, use, and store XQuery scripts as reusable resources within ALSB, again promot- ing the reusability of your ESB. You also gained familiarity with a powerful tool in ALSB: the test console. Your skills are rapidly growing and you’re now ready to tackle more advanced topics.
    • 7974CH04.qxd 3/2/07 10:11 AM Page 66
    • 7974CH05.qxd 3/12/07 12:33 PM Page 67 CHAPTER 5 A Crash Course in WSDL I n this chapter, you’ll learn the “bare bones” of creating a WSDL by hand. Our goal in this chapter is to provide you with some best practices and quickly get you up to speed with the language. If you’re already comfortable with the WSDL language, you can safely skip this chap- ter. If you’re a WSDL/XML Schema purist, then reading this chapter will only upset you: we won’t take the time to cover the esoteric capabilities of the language here. In Chapter 3 you learned how to use the Java annotations to have WLS generate a WSDL for you. This is a handy feature, especially when learning how to write web services in Java. WLS also provides the ability to generate code in the other direction: to generate Java code from a WSDL. You should be aware of the subtle differences in these approaches. They both have their strengths and their weaknesses. We’ve heard it proposed that if you’re a Java-centric shop, you should just use the WSDL generation feature and not worry about the details of WSDL creation and syntax. This is patent nonsense. We remember the days when the C language was introduced to the personal computing world. At the time, BASIC was the dominant language. Some vendors created BASIC-to-C lan- guage converters, making the claim that you didn’t need to waste time learning C; you could continue to write your BASIC programs and then push a button to convert the programs into C. These programs did work, especially for very small projects, but they weren’t viable in the long run. By using this code generation approach, you rob yourself of the ability to use more powerful, language-specific capabilities. As a result, you guarantee that you’ll write mediocre software at best. The one saving grace of these BASIC-to-C converters was that they did work as a learning tool to help BASIC programmers understand how to write C programs. We live in an increasingly web service–oriented world. WSDL is the language of web serv- ices, and it will serve you well to become conversant in WSDL, especially if you’re striving to create excellent systems. You can fall into a subtle mental trap when you generate WSDL from your Java code: you might find yourself generating Java API–oriented web services. If you look at the world through Java-colored glasses, the work you produce will be similarly colored, whereas if you look at the world through the prism of web services, your work will naturally become more service oriented. It’s vital to adopt the new mindset as soon as possible. WSDL is a nontrivial language. To express the depth and breadth of the language fully is beyond the scope of this book. In this chapter, we’ll focus on a WSDL format that’s most amenable to creating highly interoperable web services: document-centric, unencoded (also known as bare or literal encoding). Don’t worry if these terms are meaningless to you now. By the end of this chapter they’ll make perfect sense. 67
    • 7974CH05.qxd 3/12/07 12:33 PM Page 68 68 CHAPTER 5 s A CRASH COURSE IN WSDL A WSDL is comprised of six sections contained by the <definitions> root element: • types: You define the data types used by your WSDL here. Data types in a WSDL are expressed as XML Schema elements. • portType: This is the abstract interface definition of your web service. It’s similar to an interface definition in Java or C#. If you want a quick understanding of the functionality provided by a web service, this is the section of the WSDL to read. • message: This section defines the format of the messages (think documents) that the web service uses. • Binding: Describes how the portType is mapped into a concrete expression of data formats and protocols. • port: Describes the deployment of the service endpoint. In plain English, it describes the URL where the service can be found. • service: A collection of port elements. This allows you to specify the fact that a web service might live on multiple end points. Listing 5-1 shows a sample WSDL file for a simple web service that returns customer information based on the ID of the customer. Even though it describes a simple service, the sample WSDL includes all the necessary principles that you need to understand. We’ll use this listing as a reference throughout the rest of our discussion on WSDL basics. Listing 5-1. A Basic WSDL File <?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.alsb.com/Sample/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="Sample" targetNamespace="http://www.alsb.com/Sample/"> <wsdl:types> <xsd:schema targetNamespace="http://www.alsb.com/Sample/"> <xsd:complexType name="Customer"> <xsd:sequence> <xsd:element name="customerID" type="xsd:int" minOccurs="1"/> <xsd:element name="firstName" type="xsd:string" minOccurs="1"/> <xsd:element name="lastName" type="xsd:string" minOccurs="1"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="CustomerQuery"> <xsd:sequence> <xsd:element name="customerID" type="xsd:int" minOccurs="1"/> </xsd:sequence> </xsd:complexType>
    • 7974CH05.qxd 3/12/07 12:33 PM Page 69 CHAPTER 5 s A CRASH COURSE IN WSDL 69 <!-- Map our types into elements --> <xsd:element name="getCustomer" type="tns:CustomerQuery"/> <xsd:element name="getCustomerResponse" type="tns:Customer"/> </xsd:schema> </wsdl:types> <wsdl:message name="GetCustomerRequest"> <wsdl:part element="tns:GetCustomer" name="customerQuery" /> </wsdl:message> <wsdl:message name="GetCustomerResponse"> <wsdl:part element="tns:getCustomerResponse" name="customer"/> </wsdl:message> <wsdl:portType name="Sample"> <wsdl:operation name="getCustomer"> <wsdl:input message="tns:GetCustomerRequest" /> <wsdl:output message="tns:GetCustomerResponse" /> </wsdl:operation> </wsdl:portType> <wsdl:binding name="SampleSOAP" type="tns:Sample"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> <wsdl:operation name="getCustomer"> <soap:operation soapAction="http://www.alsb.com/Sample/Customer" /> <wsdl:input> <soap:body parts="GetCustomerRequest" use="literal" /> </wsdl:input> <wsdl:output> <soap:body parts="GetCustomerResponse" use="literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="Sample"> <wsdl:port binding="tns:SampleSOAP" name="SampleSOAP"> <soap:address location="http://www.alsb.com/" /> </wsdl:port> </wsdl:service> </wsdl:definitions>
    • 7974CH05.qxd 3/12/07 12:33 PM Page 70 70 CHAPTER 5 s A CRASH COURSE IN WSDL Namespaces Before we get too far into our discussion of WSDL, we’ll take a moment to discuss XML name- spaces. The namespace concept is used extensively both by WSDL and XML Schema. Namespaces can make reading a WSDL file difficult unless you understand what a namespace is and how it affects the document. A namespace is a way to categorize or group element, data type, and attribute names within an XML document. This is especially handy when combining multiple XML vocabular- ies into a single document. An XML namespace is analogous to a Java package or a C# namespace keyword. Namespaces help to protect against naming collisions. Let’s examine a concrete example of a naming collision and learn how XML namespaces help. Examine both Listing 5-2 and Listing 5-3 and notice the difference in how the Address data types are defined. Listing 5-2. Shipping.xsd Snippet <xsd:complexType name="Address"> <xsd:sequence> <xsd:element name="street" type="xsd:string" minOccurs="1"/> <xsd:element name="city" type="xsd:string" minOccurs="1" maxOccurs="1"/> <xsd:element name="state" type="xsd:string" minOccurs="1" maxOccurs="1"/> <xsd:element name="zipCode" type="xsd:string" minOccurs="1" maxOccurs="1"/> </xsd:sequence> </xsd:complexType> Listing 5-3. Customer.xsd Snippet <xsd:complexType name="Address"> <xsd:sequence> <xsd:element name="street1" type="xsd:string" minOccurs="1" maxOccurs="1"/> <xsd:element name="street2" type="xsd:string" minOccurs="1" maxOccurs="1"/> <xsd:element name="street3" type="xsd:string" minOccurs="1" maxOccurs="1"/> <xsd:element name="city" type="xsd:string" minOccurs="1" maxOccurs="1"/> <xsd:element name="state" type="xsd:string" minOccurs="1" maxOccurs="1"/> <xsd:element name="zipCode" type="xsd:string" minOccurs="1" maxOccurs="1"/> </xsd:sequence> </xsd:complexType> Both Address types are valid, but their structure varies significantly. If you try to use both these schemas in an Order web service, there will be a naming conflict because they share the same name. To correct this problem, you’d declare two namespaces—one for each of the schemas that you want to use. The following XML snippet shows you how to declare a name- space: xmlns:shp="http://www.alsb.com/shipping" In this case, the namespace you declare is http://www.alsb.com/shipping. This name- space uses the prefix of shp to represent the namespace. A namespace is defined by a URI string, not the prefix. You can think of the prefix as a variable that holds the namespace “value.” Alternatively, you can think of a namespace prefix as a pointer that represents a
    • 7974CH05.qxd 3/12/07 12:33 PM Page 71 CHAPTER 5 s A CRASH COURSE IN WSDL 71 namespace. For example, Listing 5-4 shows what might appear to be two namespace declara- tions. In reality, it is a single namespace that two different namespace prefixes refer to. The string is the namespace, not the prefix. Listing 5-4. Two Prefixes Can Represent the Same Namespace xmlns:shp="http://www.alsb.com/shipping" xmlns:foo="http://www.alsb.com/shipping" Note that the URI doesn’t have to point to anything in particular or even be a URL. It’s simply a string within the document. The xmlns: that appears before the prefix is simply the notation that tells the XML parser that an XML namespace is about to be declared. Listing 5-5 shows how namespaces allow you to use two different data types with the same name (Address, in this case) in the same WSDL. The <CustomerAddress> element takes the form of the <Address> type that you defined in Listing 5-3, while the <ShippingAddress> takes the form of the <Address> type you defined in Listing 5-2. Listing 5-5. The Order.wsdl Snippet <?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.alsb.com/Sample/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="Sample" xmlns:shp="http://www.alsb.com/shipping" xmlns:customer="http://www.alsb.com/customer" targetNamespace="http://www.alsb.com/order/"> <xsd:import namespace="http://www.alsb.com/customer" <wsdl:types> <xsd:schema targetNamespace="http://www.alsb.com/customer/"> <xsd:element name="CustomerAddress" type="customer:Address> <xsd:element name="ShippingAddress" type="shp:Address> ... </xsd:schema> </wsdl:types> </wsdl:definitions> If you’ve been paying close attention, you might be wondering how these namespaces map to the data types; how does the computer know that a customer:Address has the defini- tion that you provided in Listing 5-3? The answer is that it doesn’t. You have to provide that mapping in a separate XML import statement when you import the Customer.xsd schema. You’ll find that namespaces are used frequently in XML Schema and WSDL documents. Knowing how to use them is critical for understanding these documents. The Default Namespace Every element in an XML document or XSD belongs to a namespace. The default namespace is the namespace applied to all nodes in the document that don’t have an explicit namespace associated. Defining a default namespace is similar to defining a namespace with a prefix; you
    • 7974CH05.qxd 3/12/07 12:33 PM Page 72 72 CHAPTER 5 s A CRASH COURSE IN WSDL just don’t define a prefix. There can only be one default namespace for each element. There’s a fair bit of subtle detail to that last sentence, so let’s explore it further. Listing 5-6 shows how to define a default namespace for an entire WSDL file. Namespaces are inherited by each sub-element in an XML document. Because this is a WSDL document, it’s a common practice to define the WSDL namespace as the default namespace. As a result, the WSDL-specific elements don’t have to have a namespace prefix. You can see this in action in Listing 5-6. The <types> element has no namespace prefix defined for it, so the XML parser uses the default namespace, whereas the <schema> elements all have the xsd: prefix explicitly defined, because the <schema> element isn’t part of the WSDL namespace. Listing 5-6. Defining and Using a Default Namespace <?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions name="Sample" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.alsb.com/order/"> <types> <xsd:schema targetNamespace="http://www.alsb.com/customer/"> <xsd:element name="CustomerAddress" type="customer:Address> <xsd:element name="ShippingAddress" type="shipping:Address> ... </xsd:schema> </types> You can override default namespaces in sub-elements. This allows you to simplify your documents (at least for human readers) by providing a new default namespace in a section of the document where that new namespace is commonly used. You see an example of this in Listing 5-7. The elements <definitions> and <types> are both part of the WSDL namespace. Because <definitions> declares the WSDL namespace as its default namespace, it doesn’t need to specify a namespace prefix. Furthermore, the child <types> element inherits the default namespace of its parent <definitions> element. However, the <schema> and <element> tags are part of the XML Schema namespace, yet they don’t have a namespace prefix in their tags. This is because the default namespace is overridden by the <schema> element: it declares its own default namespace, and this new default namespace is inherited by its child <element> tags. Listing 5-7. Overriding the Default Namespace <definitions name="DefaultNamespaceSample" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="foo" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="foo">
    • 7974CH05.qxd 3/12/07 12:33 PM Page 73 CHAPTER 5 s A CRASH COURSE IN WSDL 73 <types> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="foo"> <element name="Response" type="xsd:string"/> <element name="Request" type="xsd:string"/> </schema> </types> Some people feel this makes the resulting XML easier to read. Other folks argue that it makes it harder to read, especially if you don’t know which tag belongs in which namespace. You’ll have to decide for yourself how you want to use namespaces in your XML. Just like the old arguments about where to place the curly braces in your C, C++, and Java code, it’s a mat- ter of style and personal preference. Target Namespace Aside from a default namespace, you can define a target namespace. Initially, we found this confusing. Like all things technical, it becomes simple once you understand its usage. In your WSDL and XML Schema files, you’re often creating new data types. These new types ought to belong to a namespace. Technically, you can define new elements that don’t belong to a name- space, but remember that you’re concerned with real-world usage here, not every fringe usage. You should always define a target namespace. Listing 5-7 shows the targetNamespace attribute in action. The <schema> element defines a targetNamespace with the value "foo". Nested inside the <schema> element are two element definitions: Request and Response. These new elements are created as members of the "foo" namespace. For example, the proper way to use the Request element in an XML document is as follows: <Response xmlns="foo">Some string here</Response> Alternatively, you could do the following: <ParentElement xmlns:tns="foo" <tns:Response>Some string here</tns:Response> </ParentElement > Just like the default namespace, child elements can also override targetNamespaces. sCaution Earlier we mentioned that XML namespaces are analogous to Java and C# package names. It’s true that they’re similar in many ways, but it’s important to know where they’re different. When you create a package name in a Java application, you’re creating a namespace that affects the organization of software within the scope of that application. When you’re defining an XML namespace, you’re creating a namespace that will affect the organization of data types and services throughout your entire organization! As a result, it’s important to consider carefully how you’ll organize and manage namespaces as a company.
    • 7974CH05.qxd 3/12/07 12:33 PM Page 74 74 CHAPTER 5 s A CRASH COURSE IN WSDL <types> WSDLs use XML Schema to define data types. Therefore, learning some basics of XML Schema will be our first topic. XML Schema is a large topic. To facilitate things, we’ll assume that you have a basic understanding of object-oriented principles. With that background in mind, we’ll focus on how to map object-oriented concepts into XML Schema data types. Traditionally, XML Schema files use the XSD file extension. Native Data Types XML Schema provides for a fair number of native data types (also known as primitives) that you can use in your schemas—data types such as strings, integers, dates, times, and so on. You’d expect these things from any modern language. Using a native data type is pretty simple. For example, declaring an object of type string looks like the following: <element name="MyString" type="string" /> You can find a complete list of these native data types at http://www.w3.org/TR/ xmlschema-2/#built-in-datatypes. Custom Data Types Let’s move to the next level and create some data types that are much more useful. For this example, you’ll create a Customer data type. Your customer has the attributes first name, last name, and customer ID. Listing 5-8 shows how you would define the customer object. Listing 5-8. The Customer Type Definition <complexType name="Customer"> <sequence> <element name="customerID" type="int" minOccurs="1" /> <element name="firstName" type="string" minOccurs="1" /> <element name="lastName" type="string" minOccurs="1" /> </sequence> </complexType> As you can see, you define the Customer object as a complexType. This is roughly equivalent to defining a customer class in Java or C++/C#. You name the complex type using the name attribute. s Best Practice It’s possible to define data types as being anonymous within a named element. This isn’t a good practice within the XSD file itself. This type of design pattern is okay within the WSDL file, though. Name your complex types in your XSD files and then refer to them via <element> tags within your WSDL.
    • 7974CH05.qxd 3/12/07 12:33 PM Page 75 CHAPTER 5 s A CRASH COURSE IN WSDL 75 Next you add properties to your Customer data type. In XML Schema, add the properties using the <sequence> tag. The <sequence> tag means that a series of elements or types will fol- low, in a specific sequence. In this example, you have three properties in this sequence: customerID, firstName, and lastName. Although you use the <sequence> tag to define a sequence of object attributes, you can use two other tags here, depending on your needs. Those are the <choice> and <all> tags. You use those tags when defining more complicated data types, and they’re beyond the scope of this chapter. For our purposes, a <complexType> will always contain a <sequence> of attributes. Notice that each of the attributes in your Customer data type is defined as an element. You use the <element> tag when referring to an existing data type. In the case of our attributes, the existing data types are of type string and int. Inside the Customer data type, you can also ref- erence other custom data types. For example, you can create an Address data type and then use it within your Customer data type, as shown in Listing 5-9. Listing 5-9. Nesting Complex Data Types <complexType name="Customer"> <sequence> <element name="customerID" type="int" minOccurs="1" /> <element name="firstName" type="string" minOccurs="1" /> <element name="lastName" type="string" minOccurs="1" /> <element name="homeAddress" type="Address"/> </sequence> </complexType> <complexType name="Address"> <sequence> <element name="street" type="string" minOccurs="1" /> <element name="city" type="string" minOccurs="1" /> <element name="state" type="string" minOccurs="1" /> <element name="postalCode" type="string" minOccurs="1" /> </sequence> </complexType> minOccurs and maxOccurs You might have noticed in all the listings so far, you use the minOccurs attribute in your ele- ment definitions. This specifies the minimum number of times the element can occur within the sequence. By setting the minOccurs value to 1, you’re specifying that the element must occur at least once in the sequence. If you set the value to 0, then you’re specifying that the element is optional. The complement to minOccurs is the maxOccurs attribute. It specifies the maximum num- ber of times the element can occur in the sequence. The maxOccurs value must be a positive integer, or might be the term “unbounded” (to indicate that there’s no limit on the number of times it might occur). These attributes are often used in conjunction. For example, the combi- nation of minOccurs="1" and maxOccurs="1" specifies that the element must appear only once. The default values of minOccurs and maxOccurs are both "1".
    • 7974CH05.qxd 3/12/07 12:33 PM Page 76 76 CHAPTER 5 s A CRASH COURSE IN WSDL Importing XML Schemas As mentioned previously, you can import existing schemas into your XML schema or WSDL documents. This is an excellent way to reuse these assets, allowing you to make broad changes to your enterprise definitions in a centralized manner. Importing a schema into your WSDL is done within the <types> section. The general format of an import statement is as follows: <import namespace="[the URI to the namespace]" schemaLocation= ¯ "[file path or URI to your .XSD file]" /> For example, in your WSDL, if you wanted to use the customer.xsd and the shipping.xsd schemas, you’d use the following import statements: <xs:import namespace="http://www.alsb.com/customer" schemaLocation="customer.xsd" /> <xs:import namespace="http://www.alsb.com/shipping" schemaLocation="shipping.xsd" /> Notice that the URI for the namespace matches exactly the URIs you used in Listing 5-5 when you defined the namespaces. Now, when you declare an element to be of type customer:Address or shp:Address, the web service is able to determine exactly which Address definition to use. <message> A message describes the abstract form of the input, output, or fault messages. Messages are composed of one or more <part> elements. The <part> elements describe the composition of the <message>. Because you’re using the document-centric style of WSDL, the <part> elements of the <message> must refer to data structures using the element attribute (see Listing 5-10). Listing 5-10. Sample Document-Style Message Definition <wsdl:message name="GetCustomerResponse"> <wsdl:part element="tns:getCustomerResponse" name="customer"/> </wsdl:message> For document-centric WSDL, its common practice to use the operation name as the name of the request message and to append the text “Response” to the operation name and use that as the name of the response message. Listing 5-10 demonstrates this naming approach with the GetCustomerResponse message. <portType> The portType section of the WSDL describes the abstract interface of the web service. Listing 5-11 provides an example of a simple portType definition. This section of the WSDL is often compared to an abstract Java interface because it defines, at a high level, how the operations of the service work (that is, what arguments are expected and what results are returned). The <portType> element is made up of <operation> elements. The <operation> elements, in turn, are comprised of <input> and <output> elements that map directly to the <message>
    • 7974CH05.qxd 3/12/07 12:33 PM Page 77 CHAPTER 5 s A CRASH COURSE IN WSDL 77 elements. The <operation> elements might also contain <fault> elements to indicate the SOAP faults that the operation might throw. However, for the purposes of our crash course, you’ll ignore the <fault> element. Listing 5-11. An Example of the <portType> <wsdl:portType name="CustomerPortType"> <wsdl:operation name="findCustomer"> <wsdl:input message="tns:findCustomer" /> <wsdl:output message="tns:findCustomerResponse" /> </wsdl:operation> </wsdl:portType> <binding> The <binding> is used to define how the <portType> (that is, the abstract interface of the web service) is bound to a transport protocol and an encoding scheme. A single portType may be bound to many transports and encoding scheme combinations. The most commonly used encoding scheme and transport protocol combination these days is SOAP over HTTP. The most common bindings other than HTTP/SOAP are HTTP/POST and HTTP/GET, especially when dealing with web services that were developed before HTTP/SOAP gained popularity. As you can see from Listing 5-12, the <binding> is mapped to a <portType>. Each opera- tion of the <portType> is defined in the binding, including the mapping of the operation’s input and outputs to specific message types. Listing 5-12. An Example of the HTTP/SOAP Binding <wsdl:binding name="CustomerServiceSOAP" type="tns:CustomerPortType"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> <wsdl:operation name="findCustomer"> <soap:operation soapAction="" style="document" /> <wsdl:input> <soap:body parts="findCustomer" use="literal" /> </wsdl:input> <wsdl:output> <soap:body parts="findCustomerResponse" use="literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding> <service> A service is simply a collection of <port> elements. A WSDL might contain multiple <service> definitions, one for every distinct binding type that’s supported by the web service.
    • 7974CH05.qxd 3/12/07 12:33 PM Page 78 78 CHAPTER 5 s A CRASH COURSE IN WSDL <port> A <port> describes the physical locations of a binding. Listing 5-13 shows a sample web service that exists on two different end points. The term “end point” is commonly used when dis- cussing web services. An end point is simply a URI that points to a physical location where a service exists. Listing 5-13. Sample <service> and <port> Tags <wsdl:service name="CustomerService"> <wsdl:port binding="tns:CustomerServiceSOAP" name="CustomerServiceSOAP"> <soap:address location="http://server1:7001/customer/CustomerService" /> <soap:address location="http://server2:7001/customer/CustomerService" /> </wsdl:port> </wsdl:service> That’s it for the basics of WSDL. Like many technical topics, it’s conceptually simple. Also, like many technical topics, “the devil is in the details.” Fortunately, this technology has existed long enough for some best practices to emerge. We’ll go over two of those best practices in the next section. WSDL Best Practices Once you begin creating your own services, the flexibility of WSDL can cause some confusion and even arguments among service designers. Everyone wants to write services “the right way,” especially when they’re brand new to services and don’t have any experience to draw on. At BEA, we have the advantage of speaking with numerous members of our Professional Ser- vices Group who help customers design not only individual services, but entire SOAs on a daily basis. This provides us with a great source of real-world experience. In this section, we’ll share the best practices that we use to help simplify designs and ensure success. Elements vs. Types In some of the sample WSDLs you’ve seen so far, you used several different mechanisms to create your data types. The first is to use <elements> to wrap anonymous data types. Listing 5-14 shows how this is done. Listing 5-14. Using an <element> to Wrap a <complexType> <xs:element name="findProduct"> <xs:complexType> <xs:sequence> <xs:element name="id" type="xs:int"/> <xs:element name="name" type="xs:string"/> <xs:element name="family" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element>
    • 7974CH05.qxd 3/12/07 12:34 PM Page 79 CHAPTER 5 s A CRASH COURSE IN WSDL 79 This approach provides considerable flexibility, allowing the service designer to define any data type needed by the service. A second, but closely related, approach is to define separate, named <complexType> types and then create <elements> of the required type. Listing 5-15 provides a concise example of defining a complexType and then using an element to refer to it. Listing 5-15. Using Named Types and Elements <xs:complexType name="ProductRequestType"> <xs:sequence> <xs:element name="id" type="xs:int"/> <xs:element name="name" type="xs:string"/> <xs:element name="family" type="xs:string"/> </xs:sequence> </xs:complexType> <xs:element name="findProduct" type="ProductRequestType"/> This approach is an improvement over the first approach. It gives the service designer the same level of flexibility as the first approach, but now the service designer has the ability to reuse the named complexType. In large, real-world services, documents (defined by data struc- tures) become increasingly complex and the ability to reuse data types becomes increasingly important. This reuse also eases maintenance of the service, because if a complexType needs to change, having a separate definition of that type will make the change simpler to perform. Also, you can be sure that all the elements of that type will automatically inherit the change. By defining a complexType by name, you gain the ability to reuse it in your document. However, this principle also operates at a higher level: the enterprise. Many data types are the property of the enterprise. If you define these data types as externally available resources, you gain the ability not only to reuse them across multiple WSDLs, but also to provide enterprise- wide standards and a control point for your SOA governance group. Listing 5-16 shows how this is done. You create your complexTypes in one or more external XML schema files and then import them into your WSDLs for use. This approach sacrifices some flexibility for the sake of reuse, standardization, and control. Listing 5-16. Define Enterprise Data Types Outside Your WSDLs <xs:import namespace="http://www.alsb.com/product" schemaLocation="product.xsd" /> <xs:element name="findProductRequest" type="ProductRequestType"/> Ideally, you’d store and publish your XML Schema documents in an enterprise service repository. However, because service repositories are relatively new, you can also simply pub- lish the XSDs on a set of web servers to achieve some of the same benefit. The one benefit that a service repository provides over a simple web server is that a repository can cross-check any changes that you make to your XSDs with any services that import those schemas. ALSB provides you with some repository behavior out of the box. When you create a WSDL or a service that uses a specific XSD, ALSB keeps track of the resulting dependencies. In fact, ALSB will go so far as to prohibit you from removing a resource that’s used by existing services and resources.
    • 7974CH05.qxd 3/12/07 12:34 PM Page 80 80 CHAPTER 5 s A CRASH COURSE IN WSDL sBest Practice Define your types in separate and distinct XML Schema files and reference those types from within your WSDLs. One thing to note, however: you must exercise moderation when importing various schemas into each other lest you fall into the dependency trap. The Dependency Trap When you import a schema, you’re creating a fairly tight coupling between the imported schema and the WSDL or XSD that imports it. You can create an enterprise-wide set of schemas that are all interdependent, allowing you to more easily “inherit” changes made in lower-level schemas. However, this becomes difficult to manage at scale. It’s better to create clusters of related schemas and WSDLs and then use a tool such as ALSB to loosely couple them via transformation. If you examine Figure 5-1, you can see how the dependency trap can manifest itself. In the lower-right section of the figure is a legacy EJB application called Contract Manager. This application was developed in house several years ago to handle the contract management needs of the company. The IT department has service-enabled the Contract Manager applica- tion by creating the ContractManagerAppService, a web service wrapper. The ContractManagerAppService is invoked via an HTTP over SOAP protocol, and is defined by the ContractManagerApp WSDL, which imports the ContractManagerAppTypes XML Schema. To the left of the legacy Contract Manager application is the Scorecard application. This application is newer, and therefore comes with a prebuilt web service interface. The Scorecard web service also follows the best practice of having the WSDL import its XML Schema types from a separate XML Schema file. So far, everything seems to be fairly standard. There are no problems yet simply because we’re only looking at standalone web service implementations. At this point, the IT department has matured its SOA thinking beyond mere service enablement, and it has begun to realize the value of service aggregation. It decides to create a CustomerService component that will act as a façade for all customer-centric information. This service uses the CustomerServices WSDL as its contract, which in turn imports the CustomerTypes XML Schema file. The CustomerTypes schema also imports a UtilityTypes schema, because the architects and developers have begun to identify some utility types used across the entire organization, namely the PostalAddress type. Also, the architects have embraced the concept of reuse, so they design the CustomerService WSDL to import the XML Schemas used by the Contract Manager and the Scorecard applica- tions. The CustomerServices web service is then coded and placed into production. Everything seems fine on the surface, but the dependency trap is now fully set and is about to be sprung! The trap is unknowingly sprung by the business leaders of the company when they decide that their home-grown contract management application no longer meets their increasing needs. The business purchases a Commercial, Off The Shelf (COTS) application and asks the IT department to install this new application while the company decommissions the Contract Manager application. The business sees this as a simple operation: unplug the old application and plug in the new one—what could be hard about that?
    • 7974CH05.qxd 3/12/07 12:34 PM Page 81 CHAPTER 5 s A CRASH COURSE IN WSDL 81 Figure 5-1. The dependency trap in action Of course, the architects and developers can now see why this change of applications won’t be easy. The new COTS contract management application is already web service enabled. That means that it comes with its own WSDL and one or more XSDs that define the types specific to itself. Because the CustomerService WSDL imported the older ContractManagerAppTypes directly, it needs to be updated. Furthermore, you can bet that we exposed those types directly to the consumers of the CustomerService web service, and now they might all have to be recompiled. In its simplest form, the dependency trap occurs when you allow low-level implementa- tion details, such as application-specific schemas, to bubble up through your services by directly importing them. The way you defeat this trap is through architecture: by defining spe- cific layers of abstraction and then breaking the direct dependencies between each layer. We’ll talk about layers of architecture in Chapter 10, when we introduce the concept of a “service landscape.” For now, let’s see how we’d use ALSB to defeat the dependency trap and give us the agility we need. Figure 5-2 shows the proper usage of ALSB to defeat the dependency trap and provide an opportunity to stop the ripple effect of changing the contract application from affecting the service clients. ALSB acts as a layer of abstraction between the ContractManagerAppService and the CustomerServices. Inside the service bus, you create a project that defines a proxy service, with its own WSDL and XSD. This helps to decouple the proxy service from the
    • 7974CH05.qxd 3/12/07 12:34 PM Page 82 82 CHAPTER 5 s A CRASH COURSE IN WSDL physical service implementation. There has also been another slight change, due to the intro- duction of ALSB. The business service in the ALSB project is dependent on the WSDL of the ContractManagerAppService, and now only indirectly dependent on the schema objects that the ContractManagerAppService defines. So how does this help us achieve the flexible, change-absorbing architecture we desire? Let’s go back to our scenario and see how this affects the architects and developers that are tasked with replacing the legacy ContractManager application. First, they’d need to update the business service definition in ALSB to match that of the new COTS application. Second, they would change the message flow of the proxy service, mapping the new message and schema formats into the existing logical formats defined within the proxy service itself. There would be no need to change the CustomerServices component at all. Figure 5-2. Using ALSB to disarm the dependency trap
    • 7974CH05.qxd 3/12/07 12:34 PM Page 83 CHAPTER 5 s A CRASH COURSE IN WSDL 83 Of course, in the real world it might be that the changes between the legacy application and the new application are so significant that the message flow of the proxy service won’t be sufficient to encapsulate the entire change. However, this approach will give your systems the resilience they need to absorb the majority of system changes without affecting the service clients. When you couple this simple example with the methodology described in Chapter 10, you’ll see how you can use multiple layers of abstraction to control the effects of changes within your SOA. Figure 5-2 only shows the solution for the contract management system. A similar approach would be used to insulate the Scorecard application from its service consumers. In fact, even the CustomerServices component should be abstracted from its service consumers using this same approach. You might wonder why this approach is needed, given the fact that we’re only dealing with three systems; imagine the levels of coupling when you consider an entire enterprise with hundreds of software components! Document-Centric vs. RPC Although WSDL allows considerable flexibility when designing web services, there are emerging standards that promote greater interoperability between different web service implementations. The two main approaches are often referred to as document-centric and Remote Procedure Call (RPC). Within each of these major approaches is the use of encoded or unencoded (also known as “literal”) data. RPC History and Issues RPC style was the first style in use by web service designers. In the early days of SOAP there , was a strong desire to use RPC as a vehicle for invoking remote procedures. The common thinking at that time in the evolution of our industry was to treat a network of computers as if it were one giant, virtual computer. Because the programming paradigm at the time was to make procedure calls, this thinking was carried over into the realm of distributed computing. As a direct result of this thinking, RPC-style web services usually take multiple arguments. For example, a web service that allowed the caller to create a simple customer record and returned the ID of the new customer record might look like this: createCustomer(String firstName, String lastName) : int ID At first glance, this seems simple enough and completely harmless. However, problems began to arise as service developers increased the level of abstraction employed in their web services. As the abstraction level increased, the associated data payload also increased. Imag- ine a service that accepts an order on behalf of a customer, such as many shopping cart implementations on modern web sites. A typical order carries a lot of information: customer name, billing information, lists of products and their costs, customer address information, and possible tax implications. Using an RPC approach to such a service might look like the following: submitOrder(Customer customer, Address shipAddr, Address billAddr, Product[] ¯ products) : int As you can see, as services became more abstract and broader in scope, by necessity they had to deal with more information. That additional information added arguments to each
    • 7974CH05.qxd 3/12/07 12:34 PM Page 84 84 CHAPTER 5 s A CRASH COURSE IN WSDL service. In extreme cases, a dozen or more arguments would appear in the operational signa- ture of a web service. This demanded that the service consumer understand the ordering of the arguments and whether or not it was acceptable to use null values for some arguments. Furthermore, if the service provider changed the service’s operational signature to ask for an additional argument, all existing service consumers were immediately obsolete. RPC was simply too brittle an approach at the enterprise level. The advantage that RPC has over the document-centric style is that the RPC WSDLs are generally easier to read. This is because there’s less “wrapper” code around the arguments for each operation. Document-Centric Style Emerges The document-centric design approach for web services was created to address some of the problems evident in the RPC approach. The primary difference between the RPC and document- centric styles is that the document-centric approach always uses a single argument in its operational signatures; for example: submitOrder(OrderDocument orderDoc) : int This change in design might seem trivial, but it has a number of beneficial side effects that we’ll point out. First and foremost, it makes your designs more message oriented. Because you’re passing a single argument that contains all the necessary information for the service to perform its duties, the service designer will naturally begin to think more in terms of the document (read: message) that he’s passing around, and less about individual service operations. A byproduct of this change in thinking is that more thought is given to the inter- face and less to the functional composition of the service. In turn, services become less “chatty.” We hasten to point out that creating document-centric services doesn’t immunize you from bad design. It’s still possible to create document-oriented services that are chatty, fine grained, and so on. However, this design style encourages good design habits, whereas RPC style does not. Encoded vs. Literal Whether you use RPC or document-centric services, you have another design decision to make: whether or not to encode the data of the service calls (that is, the operational argu- ments) or to leave them in their literal form. sNote Using the Literal or Encoded styles only applies to SOAP services. Here, the decision is easy. The WS-I organization was created to clarify issues regarding the various web service specifications in an effort to improve the interoperability of different web service implementations (commonly referred to as web service stacks). WS-I compliance clearly states that encoding is never to be used. Therefore, you’re left with using the literal style in your SOAP messages.
    • 7974CH05.qxd 3/12/07 12:34 PM Page 85 CHAPTER 5 s A CRASH COURSE IN WSDL 85 Wrapping At this point, it’s obvious that you’re going to use the document-centric, literal style in your SOAP bindings. In the past, this design style wasn’t sufficient to ensure maximum interoper- ability. An additional step was taken in the design of WSDLs called wrapping. Wrapping is the process of naming operations and their request and return values. As an example, an opera- tion named getCustomer would accept a message, also named getCustomer, and it would return a response document named getCustomerResponse. For a while in web services history this was an accepted way of improving web service interoperability, especially in the Java community. However, with the advent of the WS-I man- date that the root element of the document must be unique across all operations defined in the WSDL, the use of wrapping is fading into history. sBest Practice Use document, literal web services whenever possible. Troubleshooting WSDLs and Schemas Inevitably, as you create WSDL and XML Schema documents, you’ll make mistakes. Some- times the tools you use, such as Workshop and ALSB, will catch those mistakes and highlight them for you. However, if you’re new to XML documents, you might not understand the error messages when you first see them. Here’s a primer to help you troubleshoot these problems. Open up Workshop and then open the WSDL Samples project. In the WSDL folder, open the simple.wsdl file. It looks like Listing 5-17. The listing contains a number of errors. However, Workshop only detects two when you open this file, and the first error is really a byproduct of the second error: the missing closing quote on the bold-faced line in Listing 5-17. If you add the closing quote, then save the file, Workshop won’t report any errors. Listing 5-17. The Simple.wsdl File <?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.bea.com/simple/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="simple" targetNamespace="http://www.bea.com/simple"> <wsdl:types> <xsd:schema targetNamespace="http://www.bea.com/simple/simple" elementFormDefault="qualified"> <xsd:element name="FindCustomerResponse"> <xsd:complexType> <xsd:sequence> <xsd:element name="customer" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
    • 7974CH05.qxd 3/12/07 12:34 PM Page 86 86 CHAPTER 5 s A CRASH COURSE IN WSDL </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="FindCustomer" type="string /> </xsd:schema> </wsdl:types> <!-- Messages --> <wsdl:message name="FindCustomerResponse"> <wsdl:part element="FindCustomerResponse" name="FindCustomerResponse" /> </wsdl:message> <wsdl:message name="FindCustomer"> <wsdl:part element="tns:FindCustomer" name="FindCustomer" /> </wsdl:message> <!-- PortType --> <wsdl:portType name="SimplePort"> <wsdl:operation name="FindCustomer"> <wsdl:input message="tns:FindCustomer" /> <wsdl:output message="tns:FindCustomerResponse" /> </wsdl:operation> </wsdl:portType> <!-- SOAP Binding --> <wsdl:binding name="SimpleSOAP" type="SimplePort"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> <wsdl:operation name="FindCustomer"> <soap:operation soapAction="http://www.bea.com/FindCustomer" /> <wsdl:input> <soap:body parts="FindCustomer" use="literal" /> </wsdl:input> <wsdl:output> <soap:body parts="FindCustomerResponse" use="literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="SimpleService"> <wsdl:port binding="tns:SimpleSOAP" name="SimpleSOAPService"> <soap:address location="http://www.bea.com/simple" /> </wsdl:port> </wsdl:service> </wsdl:definitions>
    • 7974CH05.qxd 3/12/07 12:34 PM Page 87 CHAPTER 5 s A CRASH COURSE IN WSDL 87 However, there are still plenty of errors in the simple.wsdl file. One simple way to validate the WSDL is to create a WSDL resource in an ALSB project. Copy the contents of the simple.wsdl file into ALSB and click the Save button. ALSB reports the following error: An error occurred creating the resource: The WSDL is not semantically valid: error: src-resolve.a: Could not find type string. Do you mean to refer to the type named string@http://schemas.xmlsoap.org/soap/encoding/?. ALSB quickly identified that the definition of the FindCustomer element in the <schema> section of the WSDL is defined with a type of string. Looking at the line, you should quickly realize that the type should really be xsd:string. ALSB tries to help by asking you if you really meant to use a different type of string. Add the xsd: prefix to the type and click the Save but- ton again. Now ALSB reports another error: portType not found SimplePort. Whenever you get any sort of not found error, that’s your clue to start to look for missing or improperly defined namespaces. You might be tempted to look at the <portType> definition first, but the real cul- prit is in the <binding> tag, which references the <portType>. Once again, the namespace is missing from the type attribute. Take a look at the following line: <wsdl:binding name="SimpleSOAP" type="SimplePort"> You should change it to this: <wsdl:binding name="SimpleSOAP" type="tns:SimplePort"> Now let’s try to save this file again. Oops! Another error: portType not found {http://www.bea.com/simple/}SimplePort This error is very subtle, and one that we’ve come across on more than one occasion. As usual, ALSB is deadly accurate in its error reporting. It’s telling you that there’s no such type as SimplePort in the namespace http://www.bea.com/simple/. If you examine the namespace definition for the tns prefix you’ll see that it’s correct. The real problem lies in the fact that the targetNamespace in the <wsdl:definitions> tag is missing the trailing / character. Add the trailing slash character and save the WSDL again. The next error is as follows: The WSDL is not semantically valid: The element or type specified for partFindCustomerResponse in message {http://www.bea.com/simple/}FindCustomerResponse cannot be found in any schemas referenced by this wsdl. Again, this message is accurate once you understand it. It says that the type FindCustomerResponse defined in the <part> tag cannot be found.
    • 7974CH05.qxd 3/12/07 12:34 PM Page 88 88 CHAPTER 5 s A CRASH COURSE IN WSDL <wsdl:message name="FindCustomerResponse"> <wsdl:part element="FindCustomerResponse" name="FindCustomerResponse" /> </wsdl:message> You could (and should) use the tns: prefix with the element name. However, that isn’t the true problem. The real problem lies in the fact that the <schema> element declares its own targetNamespace, and this targetNamespace is also missing the trailing slash. We bring this par- ticular issue up because it’s quite common to overlook the fact the targetNamespace might be defined in multiple sections of a WSDL, and those targetNamespaces might not always agree with one another. sBest Practice Minimize the number of targetNamespace attributes in your WSDL and XSD files to the absolute minimum necessary. We’ve seen some WSDL generation tools that define a targetNamespace in several sections where you might not be accustomed to seeing them. The best fix for this problem is to remove the targetNamespace attribute from the <schema> tag completely. Visualizing Documents from Schemas At this point, you’re ready to put all this information to good use. It’s one thing to know how to define document structures using WSDL and XML Schema. However, it’s a different skill to then visualize how instances of these XML documents will appear in the real world. Being able to look at a document definition and then know, unambiguously, how that definition will be realized as a document instance is a critical skill for your success with web services and ALSB. In this section, you’ll learn by doing. We’ll show you a number of WSDLs and XML Schemas and then ask you to choose the right XML document instance from a choice of several sample documents. In our experience, most of the trouble in accurately visualizing document instances is centered around XML namespaces. Namespace errors can be subtle (as we just saw), but they fall into a small number of specific problems. We’ll examine the most common namespace problems here. Also, because we’re concerned with document instances, when we show the WSDLs that define the structures of the documents, we’ll skip over the port and binding information because it isn’t important for this discussion. The ElementFormDefault Attribute Visualizing a document is complicated by the use of the elementFormDefault attribute in the <schema> tag. This attribute is optional and has two possible values, qualified or unqualified. This attribute specifies whether or not the elements in the document must have their name- spaces explicitly specified or not. The default value for this attribute is unqualified. At this point in time, we’re not willing to declare a best practice around the use of this attribute. Certainly, using fully qualified elements leads to more precise WSDLs and XSDs. On the other hand, unqualified elements give you a far more forgiving environment. It doesn’t
    • 7974CH05.qxd 3/12/07 12:34 PM Page 89 CHAPTER 5 s A CRASH COURSE IN WSDL 89 take a lot of skill to create document instances for unqualified elements. Therefore, we’ll focus on qualified element form documents. Our first exercise uses the schema defined in Listing 5-18 and the WSDL shown in Listing 5-19. The WSDL imports the schema. Listing 5-18. The common.xsd File <?xml version="1.0" encoding="UTF-8"?> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.bea.com/RefArch/common/" xmlns:tns="http://www.bea.com/RefArch/common/ elementFormDefault="qualified"> <complexType name="PostalAddressType"> <sequence> <!-- Unique ID for this address --> <element name="id" type="int" /> <element name="streetAddress" type="string" maxOccurs="unbounded"/> <element name="city" type="string" /> <element name="state" type="string" /> <element name="postalCode" type="string" /> </sequence> </complexType> </schema> Listing 5-19. The SimpleImport1.wsdl File (snippet) <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.bea.com/simple/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:cmn="http://www.bea.com/simple/common/" name="simple" targetNamespace="http://www.bea.com/simple/"> <wsdl:types> <xsd:schema targetNamespace="http://www.bea.com/simple/" elementFormDefault="qualified"> <xsd:import namespace="http://www.bea.com/simple/common/" ¯ schemaLocation="common.xsd" /> <xsd:element name="FindAddressResponse"> <xsd:complexType> <xsd:sequence> <xsd:element name="address" type="cmn:PostalAddressType" ¯ minOccurs="0" maxOccurs="unbounded" /> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="FindAddress" type="xsd:string" />
    • 7974CH05.qxd 3/12/07 12:34 PM Page 90 90 CHAPTER 5 s A CRASH COURSE IN WSDL </xsd:schema> </wsdl:types> <!-- Messages --> <wsdl:message name="FindAddressResponse"> <wsdl:part element="tns:FindAddressResponse" name="FindAddressResponse" /> </wsdl:message> <wsdl:message name="FindAddress"> <wsdl:part element="tns:FindAddress" name="FindAddress" /> </wsdl:message> Each <message> in a WSDL is an XML document. Take a look at the FindAddress message in the WSDL (see Listing 5-19). Which of the following XML documents conforms to the mes- sage format defined by the WSDL? <sim:FindAddress xmlns:sim="http://www.bea.com/simple/">Harold</sim:FindAddress> or <FindAddress>Lucy</FindAddress> or <FindAddress><String>Lucy</String></FindAddress> The answer is the first example. It defines and uses the same namespace that’s defined in the WSDL file. The namespace prefix is changed to sim, but that’s just a prefix and is perfectly acceptable. As you learned earlier in this chapter, the namespace is defined by the literal string, not by the prefix name. The second example could be correct, if the following line appeared near the top of the document: xmlns="http://www.bea.com/simple/" The preceding code line, of course, defines the default namespace to be the same name- space needed by the <FindAddress> element. Lets try a slightly more ambitious example. Looking at Listings 5-18 and 5-19 again, select the correct instance of the FindAddressResponse document. <sim:FindAddressResponse xmlns:sim="http://www.bea.com/simple/"> <cmn:address xmlns:cmn="http://www.bea.com/simple/common/"> <cmn:id>279</cmn:id> <cmn:streetAddress>100 Main Street</cmn:streetAddress> <cmn:city>San Jose</cmn:city> <cmn:state>CA</cmn:state> <cmn:postalCode>95131</cmn:postalCode> </cmn:address> </sim:FindAddressResponse> or
    • 7974CH05.qxd 3/12/07 12:34 PM Page 91 CHAPTER 5 s A CRASH COURSE IN WSDL 91 <sim:FindAddressResponse xmlns:sim="http://www.bea.com/simple/"> <sim:address xmlns:cmn="http://www.bea.com/simple/common/"> <cmn:id>279</cmn:id> <cmn:streetAddress>100 Main Street</cmn:streetAddress> <cmn:city>San Jose</cmn:city> <cmn:state>CA</cmn:state> <cmn:postalCode>95131</cmn:postalCode> </sim:address> </sim:FindAddressResponse> or <sim:FindAddressResponse xmlns:sim="http://www.bea.com/simple/"> <sim:address xmlns:cmn="http://www.bea.com/simple/common/"> <sim:id>279</ sim:id> < sim:streetAddress>100 Main Street</ sim:streetAddress> < sim:city>San Jose</ sim:city> < sim:state>CA</ sim:state> < sim:postalCode>95131</ sim:postalCode> </sim:address> </sim:FindAddressResponse> The correct example is the second one. The point of confusion usually centers on the <address> element. The <address> element is defined in the WSDL under the targetNamespace http://www.bea.com/simple/. However, it represents the PostalAddressType defined in the XML Schema file under the http://www.bea.com/simple/common/ namespace. The rule is to always use the namespace in which the element is defined, not the type. Therefore, your <address> element must use the http://www.bea.com/simple/ namespace. Tip s You always use the namespace in which the <element> was defined. The second common area of confusion has to do with the elements defined in the PostalAddressType. By applying the rule defined in the preceding Tip, you can easily deter- mine that the <id>, <streetAddress>, and other elements in the PostalAddressType were defined in the http://www.bea.com/simple/common/ namespace. Therefore, you must declare those elements to be in that same namespace when used in a document instance. If you examine the WSDL, you’ll see that the <address> type is defined as an element in the WSDL under the targetNamespace http://www.bea.com/simple/. However, the elements contained by the PostalAddressType are defined under the http://www.bea.com/simple/ common/ namespace in the common.xsd file. As a result, all the elements that appear inside the <address> element must have the cmn: namespace prefix.
    • 7974CH05.qxd 3/12/07 12:34 PM Page 92 92 CHAPTER 5 s A CRASH COURSE IN WSDL Just for completeness, we’ve included a version of the FindAddressResponse document (see Listing 5-20), which uses unqualified elements. Listing 5-20. Sample Unqualified Document Instance <sim:FindAddressResponse xmlns:sim="http://www.bea.com/simple/"> <address xmlns:cmn="http://www.bea.com/simple/common/"> <id>279</id> <streetAddress>100 Main Street</streetAddress> <city>San Jose</city> <state>CA</state> <postalCode>95131</postalCode> </address> </sim:FindAddressResponse> Notice that only the first element in the document has a namespace declared. The remaining elements are simply “understood” by the parser. The real choice between the quali- fied and unqualified approaches is, “Do I want strongly typed documents or loosely typed?” That’s a question you’ll have to answer for yourself. The attributeFormDefault Attribute Attributes, like elements, also exist within namespaces. The attributeFormDefault attribute is defined in the <schema> tag and can have a value of "qualified" or "unqualified". The default value for the attributeFormDefault is "unqualified". This attribute value is not overridden when its schema is included into a new schema. Listing 5-21 shows a schema that defines the InnerType complex type using a qualified attribute namespace. The important lines of the XML Schema have been highlighted in bold. Listing 5-21. XML Schema That Defines an Attribute in a Namespace <?xml version="1.0" encoding="UTF-8"?> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/inner/" xmlns:tns="http://www.example.org/inner/" attributeFormDefault="qualified"> <complexType name="InnerType" mixed="false"> <sequence> <element name="quantity" type="int" /> </sequence> <attribute name="foo" type="string" /> </complexType> </schema>
    • 7974CH05.qxd 3/12/07 12:34 PM Page 93 CHAPTER 5 s A CRASH COURSE IN WSDL 93 Listing 5-22 shows a portion of a WSDL that imports the schema object and uses it in an element. Note that the attributeFormDefault in the <schema> section of the WSDL is set to unqualified. Listing 5-22. A Snippet of a WSDL That Imports the XML Schema <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.bea.com/inner/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="inner" xmlns:inner="http://www.example.org/inner/" targetNamespace="http://www.bea.com/inner/"> <wsdl:types> <xsd:schema attributeFormDefault="unqualified" targetNamespace="http://www.bea.com/inner/"> <xsd:import namespace="http://www.example.org/inner/" ¯ schemaLocation="inner.xsd" /> <xsd:element name="GetInner" type="inner:InnerType" /> <xsd:element name="GetInnerResponse" type="inner:InnerType" /> </xsd:schema> </wsdl:types> In Listing 5-23 you can see a sample XML document that uses the WSDL from Listing 5-22. Even though the WSDL states that the attributeFormDefault is set to unqualified, it doesn’t override the "qualified" declaration in the XML Schema file. Therefore, any reference to the attribute must be qualified by a namespace. Listing 5-23. An Example XML Document Showing the Use of a Qualified Attribute <inn1:GetInner inn:foo="string" xmlns:inn="http://www.example.org/inner/" ¯ xmlns:inn1="http://www.bea.com/inner/"> <quantity>3</quantity> </inn1:GetInner> The elementFormDefault and attributeFormDefault attributes give you a lot of control over when and where namespaces are used. Once again, we aren’t prepared to define any best practices around the use of the attributeFormDefault attribute. However, declaring all your attributes to be qualified can certainly complicate your XML documents. This additional com- plexity then increases the complexity of the XML document transformations in your message flows. As a result, we discourage the use of qualified attribute names unless you see a clear benefit in your specific project or enterprise.
    • 7974CH05.qxd 3/12/07 12:34 PM Page 94 94 CHAPTER 5 s A CRASH COURSE IN WSDL Summary In this chapter, we haven’t gone into detail with samples of document-centric, literal WSDLs, simply because that’s the only style used in this book. Instead, we focused on why this is the best approach for creating modern, highly interoperable web services. We also examined the details of a WSDL file, and provided you with a number of best practices on how to create your own WSDLs. The section on “Troubleshooting WSDLs and Schemas” should save you many hours of frustration. Perhaps most importantly, we’ve also shown you how to take a WSDL and visualize exactly how the various messages of that WSDL would appear in the form of XML documents. Now that you’ve completed this chapter, the WSDLs and XML Schemas that you’ll see in the rest of the book should make perfect sense to you. The way is now cleared for you to gain a real expertise in AquaLogic Service Bus.
    • 7974CH06.qxd 3/21/07 4:28 PM Page 95 CHAPTER 6 Message Flows I n this chapter, you’ll do a couple fun and interesting projects to help you get accustomed to creating more advanced message flows. Before long, you’ll intuitively understand when to use each type of message flow node and exactly how get the maximum benefit. To begin, you’ll create two use-case scenarios. The first use case will return a product cat- alog to the caller. The contents of the product catalog will contain only products for which the customer is qualified to buy, based on the customer’s credit rating. The second use case allows the customer to submit an order, filled with products. You’ll build a submitOrder service that verifies that the products ordered don’t exceed the customer’s credit rating. If the value of the order does exceed the customer’s credit rating, you’ll return a fault message. If the order is otherwise valid, you’ll then invoke the processOrder service. The processOrder service is asynchronous in nature, because order processing and fulfillment often occur at human speeds instead of computer speeds. s Best Practice Although you’ve generated your web service (and its WSDL) from Java code in the past, this is not a best practice. When dealing with web services, or even SOA, the contract (that is, the WSDL) is of highest importance. The code that implements the contract defined in the WSDL is incidental. By defining the WSDL first, you can plan your architecture up front, without having to wait for the code to be created. It allows your company to focus on what’s most important (the contract), and defer the details (the code) until implementation time. Scenario 1: User Requests a Product Catalog In the first scenario, the user wants to contact a service and get a customized product catalog. The service first gets the credit score for the customer, then builds a catalog of products that are appropriate for the customer’s credit score. For this scenario, you need two new opera- tions. The first is getCreditRating(). This operation takes the customer’s first name and last name and returns the credit score. Obviously, credit scores aren’t determined this simplisti- cally in the real world, but the implementation isn’t important here, so we’ll keep things as simple as possible. The second operation you need to create for your business service is getProductCatalog(). This operation takes a credit rating as the argument and returns a list of products that the cus- tomer can order. Both these service implementations are shown in Listing 6-1. 95
    • 7974CH06.qxd 3/21/07 4:28 PM Page 96 96 CHAPTER 6 s MESSAGE FLOWS You can find this code in the MessageFlow project, which is included in the Source Code/ Download area at http://www.apress.com. Compile this code and deploy it to your WebLogic Server by building the project in Workshop. Be sure to assign the MessageFlow project to the service bus server that you created. Alternatively, if you learn like we do, by doing the work, then follow along and we’ll walk you through the process. 1. Create the MessageFlow project. In Workshop, create a new Web Service project (located in the Web Service folder of Workshop’s New Project wizard). 2. In the src folder of the project, create a package called com.alsb.messageflow. 3. Create a folder in the project and name the folder WSDL. In this folder, you can either copy in the MessageFlow.wsdl file from the sample MessageFlow project that accompa- nies this book, or you can undergo the painstaking process of creating the WSDL from scratch. If you do opt to create the WSDL yourself (using Listing 6-1 as your guide), we recommend that you try and do most of the work using the WSDL editor that comes with Workshop. It allows you to view the WSDL in a graphical format and a text format, depending on your needs. Listing 6-1. The MessageFlow.wsdl for Your MessageFlow Project <?xml version=1.0 encoding=UTF-8?> <definitions name="MessageFlowServiceDefinitions" targetNamespace="http://www.alsb.com" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:alsb="http://www.alsb.com" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"> <types> <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.alsb.com" xmlns:alsb="http://www.alsb.com" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:complexType name="Product"> <xs:sequence> <xs:element minOccurs="1" name="CreditNeeded" nillable="true" type="xs:int" /> <xs:element minOccurs="1" name="Name" nillable="true" type="xs:string" /> </xs:sequence> </xs:complexType> <xs:complexType name="LineItem"> <xs:sequence> <xs:element minOccurs="1" name="Product" type="alsb:Product" /> <xs:element minOccurs="1" name="Quantity" type="xs:int" /> </xs:sequence>
    • 7974CH06.qxd 3/21/07 4:28 PM Page 97 CHAPTER 6 s MESSAGE FLOWS 97 </xs:complexType> <xs:complexType name="Order"> <xs:sequence> <xs:element minOccurs="1" name="FirstName" nillable="true" type="xs:string" /> <xs:element minOccurs="1" name="LastName" nillable="true" type="xs:string" /> <xs:element maxOccurs="unbounded" minOccurs="0" name="LineItem" type="alsb:LineItem" /> </xs:sequence> </xs:complexType> <xs:complexType name="ProductList"> <xs:sequence> <xs:element maxOccurs="unbounded" minOccurs="0" name="Product" type="alsb:Product" /> </xs:sequence> </xs:complexType> <!-- TIP: Start your element names off lower case. This will more closely match the Java naming conventions when you generate the code --> <xs:complexType name="processPreferredOrder"> <xs:sequence> <xs:element name="order" type="alsb:Order" /> </xs:sequence> </xs:complexType> <xs:complexType name="getCreditRating"> <xs:sequence> <xs:element name="firstName" type="xs:string" /> <xs:element name="lastName" type="xs:string" /> </xs:sequence> </xs:complexType> <xs:complexType name="getCreditRatingResponse"> <xs:sequence> <xs:element name="return" type="xs:int" /> </xs:sequence> </xs:complexType> <xs:complexType name="getProductCatalog"> <xs:sequence> <xs:element name="creditRating" type="xs:int" /> </xs:sequence> </xs:complexType> <xs:complexType name="getProductCatalogResponse"> <xs:sequence> <xs:element name="productList" type="alsb:ProductList" /> </xs:sequence> </xs:complexType>
    • 7974CH06.qxd 3/21/07 4:28 PM Page 98 98 CHAPTER 6 s MESSAGE FLOWS <xs:complexType name="processOrder"> <xs:sequence> <xs:element name="order" type="alsb:Order" /> </xs:sequence> </xs:complexType> </xs:schema> </types> <message name="processPreferredOrder"> <part type="alsb:processPreferredOrder" name="processPreferredOrder" /> </message> <message name="getCreditRating"> <part type="alsb:getCreditRating" name="getCreditRating" /> </message> <message name="getCreditRatingResponse"> <part type="alsb:getCreditRatingResponse" name="getCreditRatingResponse" /> </message> <message name="getProductCatalog"> <part type="alsb:getProductCatalog" name="getProductCatalog" /> </message> <message name="getProductCatalogResponse"> <part type="alsb:getProductCatalogResponse" name="parameters" /> </message> <message name="processOrder"> <part type="alsb:processOrder" name="processOrder" /> </message> <portType name="MessageFlowPort"> <operation name="processPreferredOrder" parameterOrder="processPreferredOrder"> <input message="alsb:processPreferredOrder" /> </operation> <operation name="getCreditRating" parameterOrder="getCreditRating"> <input message="alsb:getCreditRating" /> <output message="alsb:getCreditRatingResponse" /> </operation> <operation name="getProductCatalog" parameterOrder="getProductCatalog"> <input message="alsb:getProductCatalog" /> <output message="alsb:getProductCatalogResponse" /> </operation> <operation name="processOrder" parameterOrder="processOrder"> <input message="alsb:processOrder" /> </operation> </portType>
    • 7974CH06.qxd 3/21/07 4:28 PM Page 99 CHAPTER 6 s MESSAGE FLOWS 99 <binding name="MessageFlowServiceSoapBinding" type="alsb:MessageFlowPort"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> <operation name="processPreferredOrder"> <soap:operation soapAction="" style="document" /> <input> <soap:body parts="parameters" use="literal" /> </input> </operation> <operation name="getCreditRating"> <soap:operation soapAction="" style="document" /> <input> <soap:body parts="parameters" use="literal" /> </input> <output> <soap:body parts="parameters" use="literal" /> </output> </operation> <operation name="getProductCatalog"> <soap:operation soapAction="" style="document" /> <input> <soap:body parts="parameters" use="literal" /> </input> <output> <soap:body parts="parameters" use="literal" /> </output> </operation> <operation name="processOrder"> <soap:operation soapAction="" style="document" /> <input> <soap:body parts="parameters" use="literal" /> </input> </operation> </binding> <service name="MessageFlowService"> <port binding="alsb:MessageFlowServiceSoapBinding" name="MessageFlowSoapPort"> <soap:address location="http://localhost:7001/messageflow/MessageFlowService" /> </port> </service> </definitions>
    • 7974CH06.qxd 3/21/07 4:28 PM Page 100 100 CHAPTER 6 s MESSAGE FLOWS 4. Right-click the MessageFlow.wsdl file in the WSDL folder and select WebServices ® Generate Web Service from the pop-up menu. The “Source folder” field should default to MessageFlow/src. For the Package field, enter (or browse) to the value com.alsb. messageflow. At the end of the wizard, a file named MessageFlowPortImpl.java is generated in the com.alsb.messageflow package in the src folder. Because your WSDL is document oriented, your generated source code is also document oriented. Instead of passing multiple arguments into each method, only a single argument appears in each method signature. Listing 6-2 illustrates what we mean by “document- oriented source code.” Listing 6-2. The Complete Version of the MessageFlowPortImpl Class File package com.alsb.messageflow; import java.util.Vector; import javax.jws.WebService; import com.alsb.Product; import weblogic.jws.*; /** * MessageFlowPortImpl class implements web service endpoint interface * MessageFlowPort */ @WebService(serviceName = "MessageFlowService", targetNamespace = "http://www.alsb.com", endpointInterface = "com.alsb.messageflow.MessageFlowPort") @WLHttpTransport(contextPath = "messageflow", serviceUri = "MessageFlowService", portName = "MessageFlowSoapPort") public class MessageFlowPortImpl implements MessageFlowPort { private static Product[] productCatalog = { new Product(), new Product(), new Product(), new Product() }; public MessageFlowPortImpl() { productCatalog[0].setName("Television"); productCatalog[0].setCreditNeeded(610); productCatalog[1].setName("Microwave"); productCatalog[1].setCreditNeeded(500); productCatalog[2].setName("Automobile"); productCatalog[2].setCreditNeeded(710); productCatalog[3].setName("Paper Hat"); productCatalog[3].setCreditNeeded(440); }
    • 7974CH06.qxd 3/21/07 4:28 PM Page 101 CHAPTER 6 s MESSAGE FLOWS 101 public void processPreferredOrder( com.alsb.ProcessPreferredOrder processPreferredOrder) { com.alsb.Order order = processPreferredOrder.getOrder(); System.out.println("Received a PREFERRED order from " + order.getFirstName() + " " + order.getLastName() + " for product " + order.getLineItem()[0].getProduct().getName() + " in quantity of " + order.getLineItem()[0].getQuantity()); return; } public com.alsb.GetCreditRatingResponse getCreditRating( com.alsb.GetCreditRating getCreditRating) { String lastName = getCreditRating.getLastName(); String firstName = getCreditRating.getFirstName(); com.alsb.GetCreditRatingResponse response = new ¯ com.alsb.GetCreditRatingResponse(); int rating; if (lastName.compareToIgnoreCase("X") > 0) { // If the last name starts with an X or later in the alphabet // the person has a bad credit rating. rating = 200; } else if (lastName.compareToIgnoreCase("S") > 0) { // Names starting with S or later have a poor credit rating rating = 600; } else { // Everyone else has a great credit rating rating = 750; } System.out.println("Business: The credit rating for " + firstName + " " + lastName + " is " + rating); response.setReturn(rating); return response; } public com.alsb.GetProductCatalogResponse getProductCatalog( com.alsb.GetProductCatalog getProductCatalog) { // Iterate over the product catalog and return the products that the // customer can purchase com.alsb.ProductList productList = new com.alsb.ProductList(); Vector<Product> customerCatalog = new Vector<Product>(); int creditRating = getProductCatalog.getCreditRating(); com.alsb.GetProductCatalogResponse response = new ¯ com.alsb.GetProductCatalogResponse();
    • 7974CH06.qxd 3/21/07 4:28 PM Page 102 102 CHAPTER 6 s MESSAGE FLOWS for (int x = 0; x < productCatalog.length; x++) { if (productCatalog[x].getCreditNeeded() <= creditRating) { // Add this product to the list because the customer can buy it customerCatalog.add(productCatalog[x]); } } Product[] customerProducts = new Product[customerCatalog.size()]; customerCatalog.copyInto(customerProducts); productList.setProduct(customerProducts); response.setProductList(productList); return response; } public void processOrder(com.alsb.ProcessOrder processOrder) { com.alsb.Order order = processOrder.getOrder(); System.out.println("Received a regular order from " + order.getFirstName() + " " + order.getLastName() + " for product " + order.getLineItem()[0].getProduct().getName() + " in quantity of " + order.getLineItem()[0].getQuantity()); return; } } Of course, the generated source file won’t contain any method implementations. You need to add those yourself. Compile and deploy the Message Flow web service to WLS. You’ve successfully created your business service. Now we get to the heart of the matter. You need to create a new proxy service in ALSB that uses the two business services you just created. Your new service will aggregate the two busi- ness functions, hiding them from the user. This pattern of hiding underlying complexity is called the Façade pattern. In SOA, it’s more commonly known as service mediation: using one service to hide the complexity and interrelationships of lower-level services. Let’s get started creating our proxy service. First, create a new project in ALSB. Name the new project MessageFlow. Next, create a new folder in the project called WSDL. sBest Practice This exercise demonstrates the best practice for separating the data types used by a WSDL into an XML Schema document. This enhances the ability to reuse fundamental data types. If you were to define these types (such as the Order type) within the WSDL itself, you’d be forced to redefine these types if you ever needed to use them in a different WSDL. This is akin to copying and pasting code, and should be shunned whenever possible.
    • 7974CH06.qxd 3/21/07 4:28 PM Page 103 CHAPTER 6 s MESSAGE FLOWS 103 Now move to the WSDL folder in the ALSB console for your current project. In this folder, you need to create a new WSDL resource for the business service that you’ll use. The easiest way to get the WSDL contents is directly from its URL (assuming the WSDL is published online). In the Create Resource combo box, in the Bulk category, select Resources from URL. Then follow the Resource Creation wizard, supplying the URL for the WSDL and a name for the WSDL resource you’re creating. The URL for the Message Flow web service is http:// localhost:7001/MessageFlow/MessageFlowService?WSDL. Notice that when you import the WSDL, ASLB detects the import of the order.xsd schema. ALSB will generate a new file name for the order.xsd file when it imports it. You can rename it later, using the service bus console if you like. sNote Be aware that when you import WSDLs and other resources that ALSB makes a local copy of that file. It doesn’t maintain a live link to the file you import. As a result, if you change the business service WSDL, you’ll need to re-import the WSDL into ALSB. However, there might not always be a WSDL published online. In those situations, you need to copy and paste a WSDL directly into the console. Begin by selecting WSDL from the Create Resource combo box. Follow the steps of the wizard to paste in your WSDL. Navigate to the root directory of your MessageFlow project. Create a business service called MessageFlow Business. Set its type to WSDL Web Service and browse to select the Message Flow WSDL. Click the Next button and examine the End Point URI of the service (see Figure 6-1). If you see that the URI includes a specific IP address, you might wish to change the URI to use the alias localhost instead of the physical IP address. This is especially important if your com- puter is occasionally connected to a Virtual Private Network (VPN), because that might change your physical IP address and make your web service unavailable. Figure 6-1. It’s best to replace literal IP addresses with DNS names or “localhost” when working with the exercises in this book.
    • 7974CH06.qxd 3/21/07 4:28 PM Page 104 104 CHAPTER 6 s MESSAGE FLOWS Now click the Last button to accept the default values for your business service. Click the Save button to save the definition of the business service. Activate your changes by clicking the Activate button in the Change Center. Now let’s test our business service to ensure that it’s working as intended. Click the test console icon, next to the Message Flow Business resource in the service bus console (the little bug icon, under the Actions heading). The test console should default to the getCreditRating operation. Change the SOAP body so that the firstName and lastName fields are something other than “string.” Only the last name is important for this operation. Setting the lastName to a value of Smith should return a credit rating of 600. Check the source code for the web service to see the credit rating logic to confirm that your results are correct as you try different names. Now we get to the new and fun part of the exercise. You’ll create a proxy service that will take a customer name and return a list of products that the customer can purchase. Previ- ously, your proxy services simply published the WSDL of the business service it represented (à la Hello World in Chapter 3). However, in this case you have no such luxury. You need a new WSDL that represents your aggregate service. Now, we find that creating a WSDL by hand is about as much fun as hand-coding EJB deployment descriptors (that is to say, no fun at all). Fortunately for us, we can quickly put a WSDL together based on the two operations we’re aggregating (getCreditRating and getProductCatalog). Fortunately for you, you can just use the WSDL that you created by hand in the WSDL/ folder of the MessageFlow project. It’s named Message Flow Proxy WSDL. Your next step: in the ALSB console, navigate to the WSDL folder in your ALSB project. Create a WSDL resource here named Message Flow Proxy WSDL. Because this WSDL isn’t pub- lished by any web servers yet, you need to copy the text from the WSDL file in the Eclipse project and paste it into the large WSDL textarea control in the service bus console. Click the Save button. Next, in the service bus console, navigate to the root directory of your project. In this folder, you’ll create a new proxy service resource named getProducts, and you’ll base the serv- ice type on the Message Flow Proxy WSDL resource that you just created. Click the Next button and specify the Endpoint URI as /esb/getProducts. Click the Last button and then the Save button to save the new proxy service. So far, so good. You have created a proxy service that uses the WSDL you need for the service. Your next step is to “hook up” the proxy service so that it calls the supporting business services. Click the Edit Message Flow icon ( ). Your current message flow for your proxy service contains only a Start node. You want to use a Pipeline Pair for this message flow. The reason we chose to use a Pipeline Pair is that it naturally breaks its work processing down into a series of stages. You’ll use a stage for the call to the getCreditRating() business service and a second stage for the getProductCatalog() business service. Now you could do all this work in a single Route node, but that would be a poor design decision, similar in nature to taking multiple methods in you Java code and making them just one big method. You can do it, but it’s not very modular. Modularity of design is important, even within a message flow. Later on, when we take a closer look at fault handling, you’ll see how your use of stages in a Pipeline Pair helps to make fault handling much simpler and more precise.
    • 7974CH06.qxd 3/21/07 4:28 PM Page 105 CHAPTER 6 s MESSAGE FLOWS 105 To add a Pipeline Pair to your message flow, left-click the Ordering Proxy Start node and select Add Pipeline Pair from the pop-up menu. When the Pipeline Pair is added, your mes- sage flow should look like the one in Figure 6-2. Figure 6-2. An empty Pipeline Pair Let’s add our first stage to the request pipeline (the icon on the left with the green arrow pointing down). Left-click the request pipeline and select Add Stage. Left-click the newly cre- ated stage and select Edit ® Name and Description from the pop-up menu. Set the name of the node to assign variables and click the Save button. Tip s Give your stages meaningful names. It will help when you need to make changes in the future! Your next step is to edit the stage to the request pipeline to retrieve the firstName and lastName parameters that were passed into your proxy service and store them into local vari- ables. You do this because later on, when you use the service callout actions, those actions cannot use XPath expressions; instead, the service callout action expects to see local vari- ables only. Left-click the assign variables stage and select Edit ® Stage. You need to add two Assign actions to this stage. You’re assigning the values of the first name and last name of the incom- ing message to your local variables firstName and lastName. It’s easy to enter the wrong text or a typo here, so we strongly recommend that you make good use of the Variable Structures browser to ensure that only valid data is entered. When editing your XQuery, click the Variable Structures heading at the bottom of the left navigation pane, as shown in Figure 6-3. Select body in the combo box, because the data you’re looking for is carried in the body of the SOAP message. Then drill down through the contents of the body variable and click the firstName element. You’ll see the XPath for that element in the Property Inspector, near the bottom of the page. To use the value that’s displayed in the Property Inspector, just click once inside the textarea control and then click the Copy Property link (to the right of the Property Inspector). Because you only need the actual text from the firstName node, you append the /text() command to the end of the XPath.
    • 7974CH06.qxd 3/21/07 4:28 PM Page 106 106 CHAPTER 6 s MESSAGE FLOWS Figure 6-3. Using the Variable Structures browser Using this technique will save you hours of headaches trying to figure out why your service isn’t working as expected. Use this technique to assign the firstName and lastName variables. Be sure to append the /text() method to the Assign action for the lastName variable also. Ensure that your assign variables stage matches the information that appears in Table 6-1. Click the Save button. Table 6-1. The Expressions to Use in the Assign Variables Stage Expression Local Variable Name $body/alsb:CustomerName/alsb:firstName/text() firstName $body/alsb:CustomerName/alsb:lastName/text() lastName Left-click the assign variables stage and select Add ® Stage from the pop-up menu. Set the name of the node to get credit rating and click the Save button. Now it’s time to hook up this stage to make the call to the getCreditRating() operation of the business service. Left- click the get credit rating stage and select Edit ® Stage from the pop-up menu. This brings you to an empty Action page. Left-click the “Add an action” link and select Message Processing ® Assign. You need to create the SOAP Body structure that you’ll pass into the business serv- ice. Assign the expression from Listing 6-3 to a variable named soapBodyRequest.
    • 7974CH06.qxd 3/21/07 4:28 PM Page 107 CHAPTER 6 s MESSAGE FLOWS 107 Listing 6-3. Creating the SOAP Body for the getCreditRating Request <soap:Body xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <alsb:getCreditRating xmlns:alsb="http://www.alsb.com"> <alsb:firstName>{$firstName}</alsb:firstName> <alsb:lastName>{$lastName}</alsb:lastName> </alsb:getCreditRating> </soap:Body> Now you add the service callout action. Left-click the existing Assign action and select Communication ® Service Callout from the pop-up menu. The service callout action allows you to make a call to an existing service. Left-click the Service link, select the Message Flow Business service, and click the Submit button. Next, select the getCreditRating() operation from the combo box. Select the Configure Soap Body radio button and enter the value soapRequestBody for the SOAP Request Body field. Similarly, enter the value of soapResponseBody into the SOAP Response Body field. Your Service action should look like Figure 6-4. Figure 6-4. Calling the getCreditRating service After the Service Callout action, you need to create an Assign action that retrieves the customer’s credit rating. In the Assign action, assign the expression $soapResponseBody/ getCreditRatingResponse/alsb:return/text() to the variable creditRating. Click the Save button to save your changes to the stage. Now, as you discovered in Chapter 4, a Pipeline Pair can have at most one node following it. What we didn’t point out is that if the Pipeline Pair doesn’t have a node following it, then ALSB will create an “echo” response for you. This response will just echo the SOAP request back to the caller, which is definitely not what you want here. For this reason, you must add a Route node after the Pipeline Pair. It’s in the Route node that you’ll make your call to the getProductCatalog business service.
    • 7974CH06.qxd 3/21/07 4:28 PM Page 108 108 CHAPTER 6 s MESSAGE FLOWS To add a Route node, left-click the Pipeline Pair node (near the top of the node, not down in the area that shows the stages) and select Add ® Add Route. Rename the Route node to get product catalog. Save the new name and edit the Route node itself. Click the Add Action link and select Communication ® Routing. This will create the Route action. Click the Service link of the Route action and select the Message Flow Business service. Select getProductCatalog from the combo box. Now things get a little murky here, so we’ll take a moment to shed some light onto what is happening. By default, all a Route node does is route the request message to a service. In this case, the body of the request message is what the node will route to the getProductCatalog service. However, the body of the original request message to your proxy service isn’t what the service is expecting to see, as shown in Figure 6-5. Figure 6-5. The request $body of the proxy service You know that the getProductCatalog service couldn’t care less about receiving the firstName and lastName arguments. It demands that you send it the customer’s credit rating. As a result, you must transform the request to match the format expected by the getProductCatalog service. To perform this transformation, you’ll use the Replace action. You need to replace the contents of the getProductCatalog element (that is, the firstName and lastName nodes) with the credit rating. You need to transform the contents of the request message from this: <alsb:getProducts xmlns:alsb="http://www.alsb.com"> <alsb:firstName>John</alsb:firstName> <alsb:lastName>Doe</alsb:lastName> </alsb:getProducts> to this: <alsb:getProductCatalog xmlns:alsb="http://www.alsb.com"> <alsb:creditRating>600</alsb:creditRating> </alsb:getProductCatalog> Click the <XPath> link. Enter the XPath expression ./*. This XPath notation means “all children relative to the current node.” You need to replace everything in the SOAP Body ele- ment, represented by the $body variable. Click the Expression link to enter the expression that will replace the contents of the $body variable. The expression you’ll use is in Listing 6-4. As you can see, you manually construct the XML structure that you want to send to the business service. Most of this is static XML. The curly braces are escape characters, used to denote the section in which dynamic XQuery can be found.
    • 7974CH06.qxd 3/21/07 4:28 PM Page 109 CHAPTER 6 s MESSAGE FLOWS 109 Listing 6-4. The Expression for the Replace Action in the Route Node <alsb:getProductCatalog xmlns:alsb="http://www.alsb.com"> <alsb:creditRating>{$creditRating}</alsb:creditRating> </alsb:getProductCatalog> Save your XPath expression and fill out the rest of the Route node so that it matches Figure 6-6. Figure 6-6. Defining the stage for retrieving the product list Because the return message format of the getProductCatalog service matches exactly the format of your proxy service, you allow the return message from the Route node to flow through the Pipeline Pair node without any transformation. Or, to put it more plainly, you’re done with this message flow; no more work is necessary. Your message flow should now look like Figure 6-7. That completes the creation of the proxy service. Save all your changes and click the Activate button in the Change Center to activate all your work. Let’s test our handiwork to ensure that everything is running as expected. Using the ALSB console, navigate to the proxy service in the Message Flow project and click the testing icon ( ). Enter the name Bob Aaron and click the Execute button. You should see the name you entered in the request document section, and you should see a list of four products in the response document section of the page. Try it again with the name Tom Zanka, and you should see only one product show up in the response document. The getCreditRating service returns the credit rating based on the last name of the customer (our apologies to those of you with last names in the second half of the alphabet), then the getProductCatalog business serv- ice makes a decision about which products the customer can order. What if you wanted to make a decision in your proxy service instead of in a business serv- ice? For example, when the customer orders from you, you want to send a confirmation of the order to the customer. If the customer has a high credit rating, you’d like to send an additional “up-sell” e-mail, encouraging the customer to purchase additional products from your com- pany. You’d also like to place this decision logic in your proxy service so that you might be able to change it quickly if necessary. This brings us to our second scenario.
    • 7974CH06.qxd 3/21/07 4:28 PM Page 110 110 CHAPTER 6 s MESSAGE FLOWS Figure 6-7. Message flow after stage 2 Scenario 2: User Orders a Product In this scenario, the customer submits an order to your submitOrder proxy service. The proxy service invokes the getCreditRating business service. It then checks the credit rating of the customer, and if the customer’s credit rating is high enough, it will route the order to the processPreferredOrder business service. Otherwise, the order will be routed to the processOrder business service. This routing decision is performed in a Branch node. The bulk of the infrastructure that you need for this exercise has already been created in Scenario 1. Let’s begin by creating the submitOrder proxy service in the proxy directory of your Message Flow project. You’ll base this proxy on the WSDL port of the Message Flow Proxy WSDL. Tip s Place business decisions into proxy services instead of compiled code. Doing so allows you to change business logic without recompiling any code. This increases your IT and business agility. Edit the message flow of your submitOrder proxy service. You first need to add a Pipeline Pair to the Start node. Like our previous scenario, you need to have two stages in this Pipeline Pair. However, we’re going to share a time-saving trick here, so don’t race off and create both stages yet. Simply create the first stage and name it get customer name. Edit this stage, create two Assign actions, and configure them according to Table 6-2. If you use the Variable Struc- tures browser, be sure to browse the body of the submitOrder operation, not the getProducts operation.
    • 7974CH06.qxd 3/21/07 4:28 PM Page 111 CHAPTER 6 s MESSAGE FLOWS 111 Table 6-2. Retrieving the Customer’s Name from the Order Expression Variable Name $body/alsb:Order/FirstName/text() firstName $body/alsb:Order/LastName/text() lastName Now here’s the time-saving trick. You need a service callout to the getCreditRating opera- tion of the business service. If you were to create this stage by hand, it would look exactly like the same stage you defined earlier in Scenario 1 of this chapter. Fortunately, ALSB allows you to copy and paste stages, and that’s what you’re going to do. Navigate to the message flow of the getProducts proxy service. Left-click the get credit rating stage, and the pop-up menu gives you the option to copy the stage. Copy the stage and then navigate back to the message flow of the submitOrder proxy service. Left-click the get customer name stage and select Paste from the pop-up menu. Voilà! Just like copy and paste in a document, this process can help to speed up your editing process and reduce typos at the same time. Next, you add a conditional branch node after the Pipeline Pair node. Name this new node decide order processing type. You go through two phases when editing a Branch node. The first phase involves creating the various branches, as shown in Figure 6-8. The second phase involves adding stages to each branch. Your Branch node is simple: customers with a credit rating greater than 700 are preferred customers, and their orders will be processed by your preferred order processor. Everyone else is a regular customer who will have their orders processed by the normal order processor. You need to create a single, additional branch in your Branch node (there’s always a default branch). Click the Branch node icon and select Edit Branch from the pop-up menu. Edit the Branch Definitions window so that it looks like Figure 6-8. Figure 6-8. Branch Definitions window Click the Save button after you’ve added your branch. Take a look at the Map of Message Flow portion of the console on the left-hand side of the page. It shows you the entire message flow, including the Branch node and the branches that you just created. You can use this message flow map to navigate quickly through your message flow. You’ll use this control to navigate directly to the preferred customer branch of your Branch node. Click the “preferred customer” link in the Map of Message Flow control (shown in Figure 6-9) now.
    • 7974CH06.qxd 3/21/07 4:28 PM Page 112 112 CHAPTER 6 s MESSAGE FLOWS Figure 6-9. Map of Message Flow control You’re now looking at the page that allows you to define the message flow for the pre- ferred customer branch condition. Notice that the start icon ( ) at the top of the message flow is different from the other Start node icon you’re used to seeing. This is a visual cue that you’re editing a Branch node and not a full message flow. Click the Start node, and add a Route node, and name it route to preferred order processing. Edit the Route node, selecting Message Flow Business as the service and selecting processPreferredOrder as the operation. Now you need to do some additional work here, because the submitOrder proxy service takes one message format while the processPreferredOrder and processOrder operations on the business service each require a different format. You’ll find this to be a common occurrence when working with XML docu- ments and web services. This can be confusing unless you take your time and understand the structure of each document. There’s a simple way to know unambiguously which document format is used and where: the test console feature of ALSB, which is an invaluable tool. Open the test console for the submitOrder service and then select the submitOrder operation from the combo box. You’ll see a sample payload that should look exactly like that in Listing 6-5. Listing 6-5. The Document Format of the submitOrder Proxy Service <alsb:Order xmlns:alsb="http://www.alsb.com"> <FirstName>string</FirstName> <LastName>string</LastName> <!--Zero or more repetitions:--> <LineItem> <Product> <CreditNeeded>3</CreditNeeded> <Name>string</Name> </Product> <Quantity>3</Quantity> </LineItem> </alsb:Order>
    • 7974CH06.qxd 3/21/07 4:28 PM Page 113 CHAPTER 6 s MESSAGE FLOWS 113 Listing 6-5 tells you what the $body variable will contain when the submitOrder operation is invoked. Your next step is to figure out what the exact document format of the processPreferredOrder business service operation is. You accomplish this task also by using the test console. Listing 6-6 shows the document format for the processPreferredOrder operation. Listing 6-6. The Document Structure for the processPreferredOrder Business Service Operation <processPreferredOrder xmlns="http://www.alsb.com"> <alsb:order xmlns:alsb="http://www.alsb.com"> <FirstName>string</FirstName> <LastName>string</LastName> <!--Zero or more repetitions:--> <LineItem> <Product> <CreditNeeded>3</CreditNeeded> <Name>string</Name> </Product> <Quantity>3</Quantity> </LineItem> </alsb:order> </processPreferredOrder> Within the Request actions of the Route node, you need to change the value of $body from its original structure defined in Listing 6-5 to the processPreferredOrder structure in Listing 6-6. Now that you know exactly what you have to do, the work itself becomes almost trivial: 1. You need to change the <alsb:Order> tag to become an <alsb:order> tag. 2. You need to wrap the new <alsb:order> tag with a <processPreferredOrder> tag. Other than that, the structures are identical. Here are the logical steps you’ll take to trans- form the message: 1. Copy the contents of the $body variable into a local variable called order. You do this by using the Assign action to assign the expression $body/alsb:Order to the variable order. 2. Use a Rename action to rename the value of the XPath expression /alsb:Order in the order variable to use the local name of order and the namespace of http://www. alsb.com. 3. You use a Replace action to replace the XPath expression ./* in the variable body with the expression shown in Listing 6-7. Be sure to select the “Replace entire node” radio button.
    • 7974CH06.qxd 3/21/07 4:28 PM Page 114 114 CHAPTER 6 s MESSAGE FLOWS Listing 6-7. The Expression to Wrap the $order Variable <processPreferredOrder xmlns="http://www.alsb.com"> {$order} </processPreferredOrder> That completes the preferred order branch. The Route node should now look like Figure 6-10. Next, you need to do the same thing in the default branch, but change the XML tag shown in Listing 6-7 to <processOrder xmlns="http://www.alsb.com">. Figure 6-10. The Route node for the preferred order branch That’s it for this message flow. Save all your work and activate your changes. It’s time to test the changes. Navigate to the submitOrder proxy service and click the test console button to test this service. Click the submitOrder link at the top of the test console. The test console page should look like Figure 6-11.
    • 7974CH06.qxd 3/21/07 4:28 PM Page 115 CHAPTER 6 s MESSAGE FLOWS 115 Figure 6-11. Test console for the submitOrder proxy service Notice the field where you can enter your order. You know from your schema that an Order is a complex object, containing the customer’s first name, last name, and an array of line items. The test console window knows the format of the document and provides you with a simple version that contains sample data. You can leave the sample data in place, or replace it with more specific data, as needed.
    • 7974CH06.qxd 3/21/07 4:28 PM Page 116 116 CHAPTER 6 s MESSAGE FLOWS To ensure that the service is working as intended, set the last name to “Donaldson” to get a customer with a high credit score and click the Execute button. Because submitOrder is a one-way call, there’s no meaningful response from the web service. However, the test console will show you the invocation trace of the web service. Scroll down to the bottom of the test console and ensure that the route to preferred order processing node was executed, as shown in Figure 6-12. Figure 6-12. Invocation trace for preferred orders Now click the Back button and try the test again, but this time change the name to “Zim- merman.” The invocation trace for that call should be routed to the “normal order processing” node via the default branch. You can also examine the console output of the ALSB server to see the debugging messages from the processOrder and processPreferredOrder Java methods to confirm that everything is working correctly. Summary That’s it for the three processing node types. They might appear a little confusing at first, but now that you’ve used them, their purposes should be much more evident. Route nodes are used to transfer the processing to the primary web services. Pipeline Pairs are used to provide you, the service composer, with an additional level of detail and control over the service proxy, especially in the area of error handling. Last, you use the Branch nodes to make runtime deci- sions within your proxy services. You can assemble these three node types to meet the needs of any proxy service.
    • 7974CH07.qxd 3/21/07 4:44 PM Page 117 CHAPTER 7 Advanced Messaging Topics M essages are at the heart of an ESB, and ALSB is no exception. Therefore, it’s worth your while to ensure you have a solid understanding of the principles of messages and invocation models. Much of this chapter is more specific to WLS than it is to ALSB. It’s important to know both sides of the “services equation,” and creating WebLogic web services will figure promi- nently in your ALSB work. Synchronous Invocation Synchronous messaging is by far the most common messaging model in use today. A synchro- nous call is one where the caller waits for the called operation to complete before the caller can take another action. Synchronous calls are often the norm because they’re easier to understand and easier to perform (from a developer’s point of view). At times, you might hear people disparage synchronous calls, mistakenly believing that asynchronous calls are somehow “better.” Such zealotry should be avoided. Synchronous calls are just another tool in your tool chest and are often the appropriate choice. For example, if a customer logs onto your web site and requests to see his billing details for the last month, you would most likely implement this function synchronously; your customer is waiting for a response, and you don’t want to keep the customer waiting for an indeterminate amount of time. You’ve already used synchronous messaging in the HelloWorld project in Chapter 3. You’ll implement another synchronous service here to help illustrate the benefit of using asynchro- nous services (which we’ll cover shortly). Your synchronous service will accept an order for processing. Order processing (also known as fulfillment) often takes an extended amount of time. For our purposes, the process will take 30 seconds to complete, though real-world implementation often requires days to complete, depending on the nature of the products and services ordered. As in the previous chapter, we begin our service definition with a WSDL file and then generate code from this service contract. You can find the source code for this chapter in the AdvancedMessaging project in Eclipse (download the source code from the Source Code/Download area at http://www.apress.com). The business service (see Listing 7-1) is quite simple, in order to illustrate clearly what’s important to us in this chapter: the mechanics of synchronous and asynchronous messages, and how to best employ them using ALSB. 117
    • 7974CH07.qxd 3/21/07 4:44 PM Page 118 118 CHAPTER 7 s ADVANCED MESSAGING TOPICS Listing 7-1. A Synchronous Business Service package com.alsb.advmessage.syncbusiness; import javax.jws.WebService; import weblogic.jws.*; /** * SyncBusinessImpl class implements web service endpoint interface SyncBusiness */ @WebService( serviceName="SyncBusiness", targetNamespace="http://www.alsb.com/SyncBusiness/", endpointInterface="com.alsb.advmessage.syncbusiness.SyncBusiness") @WLHttpTransport(contextPath="advmessage",serviceUri="SyncBusiness", portName="SyncBusinessSOAP") public class SyncBusinessImpl implements SyncBusiness { private static long thirtySeconds = 30000; private static long timeDelay = thirtySeconds; private static int orderID = 100; public SyncBusinessImpl() { } public com.alsb.order.Order submitOrder(com.alsb.order.Order submitOrder) { // Assign an order ID to the order submitOrder.setId(orderID++); System.out.println("Starting to process the SYNC order id " + submitOrder.getId()); com.alsb.order.Order result = new com.alsb.order.Order(); result.setFirstName(submitOrder.getFirstName()); result.setId(submitOrder.getId()); result.setLastName(submitOrder.getLastName()); result.setLineItem(submitOrder.getLineItem()); if (result.getId() % 2 == 0) { // Even numbered order succeed result.setOrderStatus(com.alsb.order.OrderStatus.completed); } else { // Odd numbered orders fail result.setOrderStatus(com.alsb.order.OrderStatus.error); } try { Thread.sleep(timeDelay); } catch (InterruptedException ex) { ex.printStackTrace(); } finally {
    • 7974CH07.qxd 3/21/07 4:44 PM Page 119 CHAPTER 7 s ADVANCED MESSAGING TOPICS 119 System.out.println("Completed processing the SYNC order id " + submitOrder.getId()); } return result; } } If you examine the business service source code, you’ll see where we put in a Thread.sleep(timeDelay) call to force the call to take 30 seconds to complete. This is to simu- late a long-running process. Certainly, asking your user to wait for 30 seconds or more is unreasonable by today’s standards. Such a length of time should make you either think of a way to optimize this process so that it runs faster, or to implement the process asynchro- nously. In the next section, you’ll see how you can take this synchronous process and wrap it in an asynchronous wrapper. Asynchronous Invocation A strong component of all loosely coupled systems is asynchrony: the ability for a caller to start a process (work) without having to wait for that process to complete before the caller moves on to its next task. For example, a web site may gather up the details of an order for a cus- tomer. When the customer is through shopping, he or she clicks the Submit Order button and the web site then submits the order to the back-end order processing system for fulfillment. The order fulfillment process might take days to complete. It isn’t reasonable to ask the client to wait for that order to be fully processed before the client can do anything else. You don’t want to tie up the execution threads of your web server waiting for back-end systems to com- plete long-running processes. In fact, such a situation demands asynchronous processing. The client just wants to sub- mit the order and get on with his life. The client wants to tell the back-end system to “do this unit of work and don’t bother me again.” That’s an asynchronous call. In missile terminology, this is referred to as “fire and forget.” Lock the missile onto the target, click the fire button, and the missile does the rest. You can think of asynchronous calls as “fire and forget” technology. However, there are some subtleties here that you must think about when you begin to design asynchronous services. First, a web service may be asynchronous; second, a proxy service in the service bus may be asynchronous. Furthermore, not all asynchronous services are “fire and forget.” A better analogy for this second type of asynchronous service would be to think of asking your teenage son to mow the lawn, and then to let you know when he has com- pleted the mowing (usually so you can ask him to do the next chore). These are known as Asynchronous Request-Response services. Bear in mind that asynchronous services are a bit harder to use than synchronous serv- ices. Don’t go crazy and start designing all your services as asynchronous. It adds some overhead to the caller (especially in the Request-Response model) and is often not appropri- ate for the problem you need to solve. For example, many queries need to be synchronous. If a customer logs into your web site and navigates to the page that shows him his bill, he’s waiting for an immediate response. Making the bill retrieval service asynchronous in this instance might not be useful.
    • 7974CH07.qxd 3/21/07 4:44 PM Page 120 120 CHAPTER 7 s ADVANCED MESSAGING TOPICS Setting up WebLogic Server In this experiment, you’ll create an asynchronous “business” web service. To do this, you need to create a web service that is both “one way” (that is, the operation returns a void) and “buffered” (messages are stored in a JMS queue until the web service can handle them). Creating a JMS server and a message queue in WebLogic 9 is considerably simpler than in past versions. Using the WLS console, first, navigate to Services ® Messaging ® JMS Servers. Click the Lock and Edit button and then the New button to create a new JMS Server. Name the server WebServiceJMS and set the Persistent Store field to File Store. Click the Next button. Target the new JMS server to your AdminServer. Click the Finish button. Next, you’ll create the JMS queue that will be used to deliver the buffered requests to the web service. Navigate to Services ® Messaging ® JMS Modules and click the New button. Set the Name field to WebServiceQueue. Leave the Descriptor File Name and the Location in Domain fields blank. Click the Next button. Select the AdminServer as the target and click the Next button. Now you need to add some resources to your JMS module. Click the “Would you like to add resources” checkbox and click the Finish button. Next you need to create your single resource: the message queue. Click the New button under the Summary of Resource label. Select Queue as the Type of resource and click the Next button. Set the Name to WebServiceQueue, set the JNDI Name to alsb.WebServiceQueue, and set the Template field to None. Click the Next button. Now you need to create a subdeployment. Click the Create a New Subdeployment button. Name the subdeployment WSSubDeployment and click the OK button. Now target the subdeployment to the WebServiceJMS server and click the Finish button. Your last step is to create a Store And Forward (SAF) agent. In the navigation bar on the left side of the WebLogic console, select Services ® Messaging ® Store-and-Forward-Agents. Click the New button to create a new agent. Name the agent WebService SAF Agent, select the FileStore as the persistent store, and set the Agent Type to Both so that it can enable both sending and receiving agents. Click the Next button, target the agent to the AdminServer, and click the Finish button. Finally, click the Activate Changes button to activate your newly created JMS server and its message queue. Now that the WLS is configured with a JMS queue for handling asynchro- nous messages, let’s take a quick look at the business service that provides the functionality. Asynchronous Business Service Creating an asynchronous web service is a straightforward process. The asynchronous service you’re going to create is modeled in Figure 7-1. You need to keep in mind a couple “rules” when creating an asynchronous web service: • Asynchronous operations return a void data type. • Asynchronous operations have the @Oneway() attribute. • Asynchronous operations can specify message delivery retries using the @MessageBuffer() attribute. • Asynchronous services use the @BufferQueue() attribute to specify the JMS queue to which they listen.
    • 7974CH07.qxd 3/21/07 4:44 PM Page 121 CHAPTER 7 s ADVANCED MESSAGING TOPICS 121 Figure 7-1. Asynchronous web service Your asynchronous business service is simple. Let’s take a quick look at the WSDL for the asynchronous service (see Listing 7-2). It’s almost identical to the synchronous business serv- ice WSDL from Listing 7-1. The main difference in this WSDL file is that there is no return message. It has only a single operation called submitAsyncOrder that takes an Order message. Listing 7-2. The AsycBusiness WSDL <?xml version="1.0" encoding="UTF-8"?> <definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.alsb.com/AsyncBusiness/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="AsyncBusiness" targetNamespace="http://www.alsb.com/AsyncBusiness/"> <types> <xsd:schema targetNamespace="http://www.alsb.com/AsyncBusiness/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:order="http://www.alsb.com/order"> <xs:import namespace="http://www.alsb.com/order" schemaLocation="./order.xsd" /> <xsd:element name="submitOrder" type="order:Order" /> </xsd:schema> </types> <message name="submitOrder"> <part element="tns:submitOrder" name="submitOrder" /> </message> <portType name="AsyncBusiness"> <operation name="submitOrder"> <input message="tns:submitOrder" /> </operation> </portType> <binding name="AsyncBusinessSOAP" type="tns:AsyncBusiness"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> <operation name="submitOrder"> <soap:operation soapAction="http://www.alsb.com/AsyncBusiness/submitOrder" />
    • 7974CH07.qxd 3/21/07 4:44 PM Page 122 122 CHAPTER 7 s ADVANCED MESSAGING TOPICS <input> <soap:body parts="submitOrder" use="literal" /> </input> </operation> </binding> <service name="AsyncBusiness"> <port binding="tns:AsyncBusinessSOAP" name="AsyncBusinessSOAP"> <soap:address location="http://localhost:7001/advmessage/AsyncBusiness" /> </port> </service> </definitions> If you examine the source code for the AsyncBusinessImpl.java file in Listing 7-3, two annotations are of specific interest in this situation. The first is the @BufferQueue annotation. It’s used to specify the JMS queue to which the web service will listen. You supply the Java Naming Directory Interface (JNDI) name of the queue in the name attribute of the annotation. The second annotation of interest is @MessageBuffer, where you specify the retryCount and the retryDelay attributes. As the attribute names imply, these allow you to specify the retry count and delay values that will be used when listening to the JMS queue. Listing 7-3. The AsyncBusinessImpl.java File package com.alsb.advmessage.syncbusiness; import javax.jws.WebService; import weblogic.jws.*; /** * AsyncBusinessImpl class implements web service endpoint interface * AsyncBusiness */ @WebService( serviceName="AsyncBusiness", targetNamespace="http://www.alsb.com/AsyncBusiness/", endpointInterface="com.alsb.advmessage.syncbusiness.AsyncBusiness") // Use the following JMS queue to get buffered JMS messages @BufferQueue(name="alsb.WebServiceQueue") @WLHttpTransport(contextPath="advmessage",serviceUri="AsyncBusiness", portName="AsyncBusinessSOAP") public class AsyncBusinessImpl implements AsyncBusiness { private static long fiveMinutes = 300000; private static long thirtySeconds = 30000; private static long timeDelay = thirtySeconds; public AsyncBusinessImpl() { }
    • 7974CH07.qxd 3/21/07 4:44 PM Page 123 CHAPTER 7 s ADVANCED MESSAGING TOPICS 123 @MessageBuffer(retryCount=5, retryDelay = "10 seconds") public void submitAsyncOrder(com.alsb.order.Order submitOrder) { Date now = new Date(); System.out.println("Starting to process the async order id " + submitOrder.getId() + " at " + now.toLocaleString()); try { Thread.sleep(timeDelay); } catch (InterruptedException ex) { ex.printStackTrace(); } finally { now = new Date(); System.out.println("Completed processing the async order id " + submitOrder.getId()+ " at " + now.toLocaleString()); } } Just to make things interesting, you’re going to create a proxy service that works synchronously, but calls the asynchronous business service. This is a technique for taking asynchronous services and presenting them in a synchronous manner to the service clients. To do this, you make a copy of the AsyncBusiness.wsdl file, name it AsyncProxy.wsdl, and make a few minor adjustments to it so that the proxy service will behave synchronously. You can find the WSDL files in the Advanced Messaging project at srccom.alsb.wsdl. We’ve included a excerpt of the file in Listing 7-4 that highlights the important changes. Listing 7-4. The AsyncProxy.wsdl file <?xml version="1.0" encoding="UTF-8"?> ... <message name="submitOrder"> <part element="tns:submitOrder" name="submitOrder" /> </message> <message name="submitOrderResponse"> <part element="tns:submitOrder" name="submitOrder" /> </message> <portType name="AsyncProxy"> <operation name="submitAsyncOrder"> <input message="tns:submitOrder" /> <output message="tns:submitOrder" /> </operation> </portType> <binding name="AsyncProxySOAP" type="tns:AsyncProxy"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> <operation name="submitAsyncOrder">
    • 7974CH07.qxd 3/21/07 4:44 PM Page 124 124 CHAPTER 7 s ADVANCED MESSAGING TOPICS <soap:operation soapAction="http://www.alsb.com/AsyncProxy/submitOrder" /> <input> <soap:body parts="submitOrder" use="literal" /> </input> <output> <soap:body parts="submitOrder" use="literal" /> </output> </operation> </binding> ... </definitions> You can use the test console to test the proxy service and see how it behaves synchro- nously while the business service labors asynchronously in the background. Run several tests using the test console as quickly as you can, then monitor the text console of the WLS to see the output from the business service. If it weren’t for the operation name of submitAsyncOrder(), the programmer who wrote the client would have no way of knowing if this was an asynchronous operation, or merely an operation with no return value. However, the behavior of the client demonstrates a clear dif- ference. This client will execute much faster, with per-call times around the 60ms mark on our test machine, as opposed to the synchronous version that takes a full 30-plus seconds for each method invocation. sNote The first time you run the client, you’ll notice a delay as the test console makes each of the parallel service invocations. That is because the WLS is creating the process threads to handle each test console’s requests. The second time you run the client, you’ll see it execute at full speed, because the WLS will have the threads pooled and ready to go. There’s a drawback to writing asynchronous web services though, and that is the use of JMS. If your client cannot “speak” JMS, then this approach will become especially important because it allows you to wrap a synchronous HTTP service around an asynchronous JMS serv- ice. This is a prime example of the importance of service mediation and the flexibility that service mediation provides. Service Types and Transport Protocols So far we’ve taken an in-depth look at the invocation models used by our messages. Now it’s time we take a look at the service types and transport protocols. A “service type” represents a message format type. For example, ALSB supports the following service types: SOAP or XML defined by a WSDL, SOAP without a WSDL, and XML without a WSDL and a Messaging Type (Binary, Text, MFL, or XML). A transport protocol is a protocol that’s used to transport messages from sender to receiver. JMS, HTTP and HTTPS are all transport protocols. ,
    • 7974CH07.qxd 3/21/07 4:44 PM Page 125 CHAPTER 7 s ADVANCED MESSAGING TOPICS 125 You start creating a service by first determining the service type that you’ll need to use. Most commonly, this is a SOAP with WSDL service type. However, you might opt to use a dif- ferent service type, depending on your specific needs. For example, if you’re providing a service to clients that can’t speak SOAP or WSDL, you might opt to implement an XML service type instead. If your service clients can only communicate in some proprietary binary format, you’d choose the Binary Messaging Type, and so on. Once you know the service type you’ll use, you then select the transport protocol. Not all transport protocols are available to every service type (see Table 7-1). Table 7-1. Service Types and Transport Protocols Service Type Transport Protocol SOAP or XML with WSDL JMS, HTTP, HTTPS SOAP (no WSDL) JMS, HTTP, HTTPS XML (no WSDL) JMS, HTTP, HTTPS, Email, File, FTP Messaging Type (Binary, Text, MFL, or XML) JMS, HTTP, HTTPS, Email, File, FTP sNote All service types can send and receive attachments using Multipurpose Internet Mail Extensions (MIME). The rest of this chapter is devoted to examining various combinations of service type and transport protocols. SOAP with WSDL Certainly, SOAP with WSDL is one of the most popular message types, especially in the web service world. Originally SOAP was an acronym for Simple Object Access Protocol. Today, SOAP is generally recognized as a name only, as the old acronym no longer applies. Today, SOAP is an XML protocol for encoding and transmitting data. A SOAP message is comprised of an envelope, which in turn is made up of a header section and a body section. Listing 7-5 shows a sample SOAP message sent to the AsyncProxyService you created earlier. Listing 7-5. Sample SOAP Envelope <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Header xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> </soap:Header> <soapenv:Body> <asy:submitOrder xmlns:asy="http://www.alsb.com/AsyncProxy/"> <FirstName>string</FirstName> <LastName>string</LastName> <!--Zero or more repetitions:--> <LineItem>
    • 7974CH07.qxd 3/21/07 4:44 PM Page 126 126 CHAPTER 7 s ADVANCED MESSAGING TOPICS <Product> <CreditNeeded>3</CreditNeeded> <Name>string</Name> </Product> <Quantity>3</Quantity> </LineItem> </asy:submitOrder> </soapenv:Body> </soapenv:Envelope> We won’t take the time to provide a SOAP example here because all the samples in this book, other than some of those defined in this chapter, are examples of using the SOAP protocol. SOAP Without WSDL At first glance, SOAP without WSDL might seem like an odd combination. Why would you ever want to use SOAP without a WSDL to define its structure? You’ll most likely need this sort of a service type when dealing with legacy SOAP clients that were written without using a WSDL. Another use for this approach is when you want to have a single SOAP port exposed for all messages. All message received by this single SOAP port can then be examined and routed to the appropriate web services. Creating this type of service is simple. You need to create a proxy service using Any SOAP Service as the service type (see Figure 7-2). For this example, just select the default for the rest of the Proxy Service creation wizard. Figure 7-2. Creating a SOAP proxy service that doesn’t use a WSDL
    • 7974CH07.qxd 3/21/07 4:44 PM Page 127 CHAPTER 7 s ADVANCED MESSAGING TOPICS 127 Next, you need to create a simple message flow for the service. Add a Pipeline Pair node to the message flow that has a single stage in the request pipeline. In that stage, you’ll add two actions. The first action will be to Assign the contents of the $body variable into a local variable named soapMsg. The second action will be a Log action using the following expression: concat(Received the following SOAP Any message: , $soapMsg). Be sure to set the Severity level to Error so that it shows up in the ALSB console and sys- tem log. Save all your changes and activate them in the Change Center. Testing the service is straightforward. Bring up the test console, and you’ll see that the service expects a document. Notice that the test console doesn’t provide you with a default document format, with good reason: because the service will accept any SOAP document, the test console has no way of knowing what document you want to send. To simplify testing, you’ll find a sample SOAP document located in the WSDL directory of the SOAPAttachmentsClient project in the Eclipse workspace. The document is named SOAPnoWSDL.soap and is the same SOAP document that’s sent to the AsyncBusinessService you created earlier. Take the liberty of changing the structure of the document to see how any valid SOAP document is accepted. The response of the proxy service is to echo whatever docu- ment was submitted. In a nutshell, this type of service will accept any SOAP document you throw at it. You do need to exercise caution when using this service type. Your proxy service might end up being responsible for parsing every possible type of content for a service of this type. This structure is akin to a Java method (pre-1.5) that takes a Collection as an argument and returns a Collection: it’s flexible because it can mean anything, and it’s complex for the same reason. XML with WSDL Although SOAP is increasingly popular, it’s not the only way to send a message. You can also use a pure XML file, and you can enforce the structure of the XML message by mapping it to a WSDL. The key here is to create a WSDL that doesn’t rely on the SOAP protocol. Instead, it will use the HTTP POST/GET protocols. Our sample will use the HTTP POST protocol. A WSDL that doesn’t use SOAP is pretty uncommon, so it’s worth taking a closer look at one to understand how it’s put together. You can find the source file for Listing 7-6 in the WSDL directory of the SOAPAttachmentsClient Eclipse project. Listing 7-6. A WSDL for an XML Service That Does Not Use SOAP <?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:alsb="http://www.alsb.com" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="XMLWSDLDefinitions" xmlns="http://www.alsb.com" targetNamespace="http://www.alsb.com"> <wsdl:message name="getGreetingRequest"> <wsdl:part name="name" type="xsd:string" /> </wsdl:message>
    • 7974CH07.qxd 3/21/07 4:44 PM Page 128 128 CHAPTER 7 s ADVANCED MESSAGING TOPICS <wsdl:message name="getGreetingResponse"> <wsdl:part name="response" type="xsd:string" /> </wsdl:message> <wsdl:portType name="XMLWSDLPortType" xmlns="http://www.alsb.com"> <wsdl:operation name="getGreeting"> <wsdl:input message="alsb:getGreetingRequest" /> <wsdl:output message="alsb:getGreetingResponse" /> </wsdl:operation> </wsdl:portType> <wsdl:binding name="XMLWSDLHTTP" type="alsb:XMLWSDLPortType"> <http:binding verb="POST" /> <wsdl:operation name="getGreeting"> <http:operation location="/GetGreeting" /> <wsdl:input> <mime:content type="application/x-www-form-urlencoded" /> </wsdl:input> <wsdl:output> <mime:content type="text/xml" /> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="XMLWSDLService"> <wsdl:port binding="alsb:XMLWSDLHTTP" name="XMLWSDLHTTP"> <http:address location="http://localhost:7001/xmlwsdl/XMLWSDLService" /> </wsdl:port> </wsdl:service> </wsdl:definitions> You can see from the listing that the SOAP binding has been replaced by an HTTP binding that uses the verb POST. The getGreeting operation exists at /GetGreeting (the fully qualified location is http://localhost:7001/xmlwsdl/XMLWSDLService/GetGreeting), and it takes an input argument that is encoded in the manner used by HTTP POST. The operation returns an XML document. Create a new proxy service with the name XMLWSDLService, and base it on the WSDL from Listing 7-6. Be sure to set the Endpoint URI to /XMLWSDLService. Select the defaults for the rest of the proxy service creation wizard. Next, you’ll create a simple message flow that gets the name from the XML document that was submitted, and returns an XML document that con- tains the response. Figure 7-3 shows the message flow graphically. First, you need to create the get name stage in the request pipeline. This stage contains a single Assign action that assigns the expression $body/name/text() to the local variable name. Next, you create the create greeting stage in the response pipeline. This stage has two actions. The first action is an Assign action that assigns the value of the expression concat(Hello , $name) to the local variable greeting. The second action is a Replace that replaces the contents of the SOAP Body element, represented by the variable $body, with the value of the expression <response>{$greeting}</response>, as shown in Figure 7-4.
    • 7974CH07.qxd 3/21/07 4:44 PM Page 129 CHAPTER 7 s ADVANCED MESSAGING TOPICS 129 Figure 7-3. The XMLWSDLService message flow Figure 7-4. The “create greeting” stage definition Be sure to save all your changes, then activate them in the Change Center. You can use the test console to test your XMLWSDLService to ensure that it’s working. Just for fun, let’s write a Java client to demonstrate how you’d use such a service programmatically (see Listing 7-7). Listing 7-7. Java Client for the XMLWSDLService public static void main(String[] args) { // Construct the XML document that we will POST String doc = "<?xml version=1.0?><name>John</name>"; String hostname = "localhost"; int port = 7001; try { InetAddress addr = InetAddress.getByName(hostname); Socket sock = new Socket(addr, port);
    • 7974CH07.qxd 3/21/07 4:44 PM Page 130 130 CHAPTER 7 s ADVANCED MESSAGING TOPICS //Send the header String path = "/XMLWSDLService/GetGreeting"; BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream(),"UTF-8")); wr.write("POST " + path + " HTTP/1.0rn"); wr.write("Host: " + hostname + "rn"); wr.write("Content-Length: " + doc.length() + "rn"); wr.write("Content-Type: text/xml; charset="utf-8"rn"); wr.write("rn"); //Send the document wr.write(doc); wr.flush(); // Read the response BufferedReader rd = new BufferedReader( new InputStreamReader(sock.getInputStream())); String line; while((line = rd.readLine()) != null) System.out.println(line); } catch(UnknownHostException ex) { ex.printStackTrace(); } catch(IOException ex) { ex.printStackTrace(); } } As you can see from Listing 7-7, writing the Java client requires a fair bit of knowledge about the HTTP protocol, but it’s not that difficult if you have an example to work with. When you run this client, you’ll see the following (raw HTTP) output as the XMLWSDLService provides its response (see Listing 7-8). Listing 7-8. HTTP Response from the XMLWSDDLService HTTP/1.1 200 OK Connection: close Date: Thu, 27 Apr 2006 20:07:41 GMT Content-Type: text/xml; charset=utf-8 X-Powered-By: Servlet/2.4 JSP/2.0 <?xml version="1.0" encoding="utf-8"?> <response>Hello John</response>
    • 7974CH07.qxd 3/21/07 4:44 PM Page 131 CHAPTER 7 s ADVANCED MESSAGING TOPICS 131 XML Without WSDL The next service type is an XML service that doesn’t use WSDL. It’s similar to the SOAP without WSDL service that you defined earlier. Create a new proxy service and set its name to XMLnoWSDLService. Select the Service Type as Any XML Service. Set the Endpoint URI for this sample to /XMLnoWSDLService and accept the rest of the default values in the Proxy Service wizard. To keep things simple, our message flow for this service will consist of a Pipeline Pair with a single stage in the request pipeline. That stage will have a single action: an Assign action that will take the value of the $body variable and assign it to the input local variable. Save all your work and activate your changes in the Change Center. Now use the test console to test the XMLnoWSDLService. Simply enter any valid XML document into the test console and you’ll see that the service accepts it just fine. It isn’t necessary to enter the <?xml version="1.0" encoding="UTF-8"?> directive at the top of the request document to test your XML. The XML without WSDL service type suffers from the same malady as the SOAP without WSDL service type: it’s simply too flexible to be useful at scale. It’s tempting to believe that such a service will simplify your life. Proponents might argue that “I only have one service to maintain, so it must be simpler.” However, that is misleading. Although it’s true that they’d have only one service interface to maintain, who knows how many services would be imple- mented underneath the “cover” of this broadly defined service? To make matters worse, you have no way to control service proliferation, nor do you have any visible mechanism for han- dling version changes. Finally, the service contract is so broad as to be useless. The only way for a service consumer to know how to make use of this service is to contact the service provider and ask for the secret XML format to use in order to get his or her work done. Although technically this is a service, it isn’t service oriented in any way. Messaging Types This service type permits one form of message as the request and (possibly) a different mes- sage format as the response. For example, you might need a service that accepts an XML request, but returns a binary file. Proxy services based on the Message Type service type can give you a lot of flexibility when integrating directly with legacy systems. sNote The Message Type service type also supports File, FTP, and Email transport protocols. However, there is one caveat here. The File, FTP, and Email transport protocols are all “one-way” protocols, not “request-response.” Therefore, if you wish to use File, FTP, or Email, you need to define the response mes- sage type as None. If you specify a return type, ALSB will only let you specify HTTP, HTTPS, or JMS as the transport protocols.
    • 7974CH07.qxd 3/21/07 4:44 PM Page 132 132 CHAPTER 7 s ADVANCED MESSAGING TOPICS Message Type: Binary As the name implies, this message type allows you to send binary messages. You can use a service such as this to communicate legacy or other proprietary data across the service bus. Your sample binary service will binary “message” and send it to a message-driven bean over JMS for processing. To accomplish this, you need to take the following steps: 1. Create the JMS assets on the WLS. You need a JMS Server, a JMS topic named binaryFile, and a connection factory named alsbConnectionFactory. 2. Create a Message-Driven EJB (also known as an MDB) that listens to the binaryFileTopic topic. The bean will take the binary message and write it out to a temporary file. 3. Define a business service named BinaryBusinessService that knows how to route the binary message payload to the JMS topic. 4. Define a proxy service named BinaryService that accepts a binary formatted message and routes the message to the business service. Creating the JMS Assets To create the JMS assets, you must log into the WebLogic console by opening your web browser at the address http://localhost:7001/console. Log into the console and click the Lock & Edit button in the Change Center so you can make some changes to your system. First, navigate to Services ® Messaging ® JMS Servers. Click the New button to create a new JMS server. Name the service alsbJMSServer and set the persistent store to “(none),” as shown in Figure 7-5. Figure 7-5. Creating a JMS server
    • 7974CH07.qxd 3/21/07 4:44 PM Page 133 CHAPTER 7 s ADVANCED MESSAGING TOPICS 133 Click the Next button to move to the window that allows you to target the server. Select AdminServer from the combo box (it should be the only server listed) and click the Finish but- ton. At this point, your JMS server has been created, but you need to create a connection factory and a topic for the server before it is useful to you. JMS connection factories and topics are categorized as types of JMS Module Resources in WebLogic 9. So, your next step is to create a JMS module for your newly created JMS server. Navigate to the Services ® Messaging ® JMS Modules section in the WLS console. Click the New button to create a new JMS module. In the Create JMS System Module window, fill in the Name field with alsbJMSResources and leave the other two fields blank. Click the Next button to continue. Target the AdminServer and click the Next button. The next window asks you if you would like to add resources to the JMS system module. Check the checkbox and click the Finish button. The console now pre- sents you with the window that shows the summary of resources for the alsbJMSResources module, as shown in Figure 7-6. Figure 7-6. The alsbJMSResources—Summary of Resources window Click the New button. The next window prompts you for the type of resource to create (see Figure 7-7). Select the Connection Factory radio button and click the Next button. Name the connection factory alsbConnectionFactory and set the JNDI Name to the same.
    • 7974CH07.qxd 3/21/07 4:44 PM Page 134 134 CHAPTER 7 s ADVANCED MESSAGING TOPICS Figure 7-7. Selecting the type of JMS resource Tip s Keep your names simple and as self-explanatory as possible. This includes the JNDI names. If you have the need to create JNDI names in a hierarchy, be sure to define naming standards to make it easy for your developers, quality assurance, and production services folks to find whatever they’re looking for. Using “cute” names such as “Calvin” and “Hobbes” will only cause confusion, especially as the scale of your work grows. Click the Next button once you’ve defined the names for the connection factory. Select the AdminServer as the target for the connection factory and click the Finish button. Your con- nection factory is now defined. You’ll follow a similar process to create your JMS topic. Back in the Summary of Resources page, click the New button and select the Topic radio button. Click the Next button to continue.
    • 7974CH07.qxd 3/21/07 4:45 PM Page 135 CHAPTER 7 s ADVANCED MESSAGING TOPICS 135 Now in the JMS Destination Properties page of the wizard, set the name to binaryFileTopic and set the JNDI Name to the same value. You aren’t using a JMS template, so leave that field as None. On the next window, click the Create a New Subdeployment button and accept the default value of binaryFileTopic (subdeployments default to the name of the first resource they con- tain). Click the OK button to continue. The last step is to target the alsbJMSServer, as shown in Figure 7-8. Click the Finish but- ton. Your work with regard to creating the JMS resources for the WLS is complete. Figure 7-8. Targeting the topic Activate the changes you’ve made via the Change Center. Creating the Message-Driven Bean Your next step is to create a message-driven bean that will listen to the binaryFileTopic JMS topic for binary messages. It will then save those binary messages to the local file system. You can find the source code for the MDB in the ServiceTypes project in Eclipse. You can find the important details of the MDB in Listing 7-9. If you examine the @MessageDriven annotation, you can see that the JMS topic JNDI name to which the bean will listen is defined in the destinationJNDIName attribute.
    • 7974CH07.qxd 3/21/07 4:45 PM Page 136 136 CHAPTER 7 s ADVANCED MESSAGING TOPICS Listing 7-9. BinaryMDB.java package com.alsb.business; import ... @MessageDriven(maxBeansInFreePool = "200", destinationType = "javax.jms.Topic", initialBeansInFreePool = "20", transTimeoutSeconds = "0", defaultTransaction = MessageDriven.DefaultTransaction.REQUIRED, durable = Constants.Bool.FALSE, ejbName = "binaryMDB", destinationJndiName = "binaryFileTopic") public class BinaryMDB implements MessageDrivenBean, MessageListener { public final static long serialVersionUID = 1L; private static final boolean VERBOSE = true; private MessageDrivenContext m_context; /** * Retrieve the BytesMessage and save that data as a file */ public void onMessage(Message msg) { BytesMessage bm = (BytesMessage) msg; try { long length = bm.getBodyLength(); byte[] binaryData = new byte[(int)length]; int numRead = bm.readBytes(binaryData); // Create a temporary file on the local file system. File outputFile = File.createTempFile("mdb_", "xxx"); log("Created the file: " + outputFile.getAbsolutePath() + " with a file size of " + numRead + " bytes"); FileOutputStream fos = new FileOutputStream(outputFile); fos.write(binaryData); fos.close(); } catch(IOException ex) { ex.printStackTrace(); } catch(JMSException ex) { System.err.println("An exception occurred: "+ex.getMessage()); } } ... } The onMessage method is the entry point of every MDB. This method shows how to accept a binary message from ALSB. You start by converting the input message into a BytesMessage. You then find the length of the binary message and create a byte array to hold the message contents. After you read the bytes into the array, you create a temporary file and write the bytes out to the file. You send a System.out.println to the console so that it’s easy to see where the file was created. This will be handy later on when you’re testing the system end to end.
    • 7974CH07.qxd 3/21/07 4:45 PM Page 137 CHAPTER 7 s ADVANCED MESSAGING TOPICS 137 To compile and deploy the MDB, open the associated build.xml file in Eclipse and run the binary.mdb task. Once this task has completed successfully, you’re ready to move to the next step: defining the business service. Defining the Business Service Next you need to define a business service that represents the BinaryMDB you just created. This business service needs to route messages to the correct JMS topic. In the ServiceTypes project in the ALSB console, create a folder named Business Services. In the new folder, create a busi- ness service named BinaryBusinessService and select as the Service Type a Messaging Service. Click the Next button. Set the Request Message Type to Binary and the Response Message Type to None, as shown in Figure 7-9. Click the Next button to continue. Figure 7-9. Defining the BinaryBusinessService request and response types You need to communicate with your MDB over a JMS topic, so your Protocol must be set to jms. The Endpoint URI is composed of the JNDI name of your connection factory and the JMS topic name. Because you’re connecting to a JMS server on your local machine, you can set the Endpoint URI to the following: jms://localhost:7001/alsbConnectionFactory/binaryFileTopic Click the Next button. Use the default values on the JMS Transport Configuration window. Click the Next button and then the Save button. Your BinaryBusinessService is now defined and ready to be called from your proxy service. Creating the Proxy Service Creating a binary proxy service follows the same pattern we have used throughout this book. Name the proxy BinaryService and select Messaging Service as the service type. Click the Next button. The second window in the wizard allows you to define the request and response message types. For this exercise, you’ll set the request message type to Binary. Because we’re demon- strating the use of the File transport protocol (which is a one-way protocol), you must set the response to None.
    • 7974CH07.qxd 3/21/07 4:45 PM Page 138 138 CHAPTER 7 s ADVANCED MESSAGING TOPICS Select the File protocol and set the Endpoint URI to the following: file:///{drive ID}/filedir Be sure to substitute the correct drive ID for your system. The next step in the wizard is to define the details of the File transport protocol. The fields with red asterisks next to them are required fields. The File Mask field is pretty straightforward. You’ll leave it with the default value of *.* so that you can send any type of file to the service. The Polling Interval specifies the number of seconds between each polling event. When the polling event occurs, ALSB will examine the directory (specified by the Endpoint URI) to see if any files match the file mask. The read limit specifies the maximum number of files to process during each polling event. The default value is 10. If you set this value to zero, all files that match the file mask at the time of the polling event will be processed. The Sort By Arrival checkbox forces the selection of files from the directory based on their create date. The Scan SubDirectories checkbox instructs ALSB to look for files recursively in any existing subdirectories. The Pass By Reference checkbox tells ALSB to copy the file to the Archive Directory and pass a reference to the file in the message itself. The Post Read Action tells ALSB either to delete the file or to copy it to the Archive Directory after the message has been processed. The Stage Directory specifies where the files should be stored while they’re being processed. The Archive Directory defines a directory in the file system that will store the files after they’ve been processed. Of course, this only has significance if the Post Read Action is set to Archive. The Error Directory specifies where messages and attachments are posted if there is a problem. The “Request encoding” checkbox specifies the character encoding scheme used for File requests. The default is utf-8. Be sure your configuration matches the one in Figure 7-10. Figure 7-10. Defining the details of the File transport protocol
    • 7974CH07.qxd 3/21/07 4:45 PM Page 139 CHAPTER 7 s ADVANCED MESSAGING TOPICS 139 Tip s Be careful when defining your Stage, Archive, and Error directories. Give them absolute paths so you can be sure of their location. This is especially true if you have the Scan SubDirectories checkbox checked and you inadvertently place your archive directory within the directory specified by the Endpoint URI; this can cause an infinite loop. Click the Finish button to save your proxy service. Your next step is to route requests from the proxy service to the business service. Routing the Proxy to the Business Service We’re going to keep it simple here. Edit the message flow for your proxy service and add a Route node. Route the message to the BinaryBusinessService, as shown in Figure 7-11. No further actions are needed. Save all your work so far and activate your changes in the Change Center. It’s testing time! Figure 7-11. The message flow and Route node for the BinaryService End-to-End Testing To test a binary service, we prefer to use image files. If an image is corrupted, it’s much easier to notice the corruption in an image, video, or sound file than it is to look through a text file, especially if the files are significant in size. Image files are a good compromise because they can be fairly large. Start by selecting the file you wish to use for the test. Copy the test file into the directory defined by the Endpoint URI for the proxy service. If your system is set up like mine, that means you need to copy the file into the D:filedir directory on your local hard drive. Once that’s done, it might take up to a minute before the proxy service polls the directory and picks up the file for processing. You’ll know when the file has been processed by watching the out- put console for the WLS that’s hosting ALSB. You should see output similar to the following: Created the file: D:TEMPmdb_6801xxx with a file size of 171366 bytes
    • 7974CH07.qxd 3/21/07 4:45 PM Page 140 140 CHAPTER 7 s ADVANCED MESSAGING TOPICS When you see this message, navigate to the file that the MDB just created and give it the correct file extension so that it matches the file extension of the source file (usually a JPG or PNG). When the file is appropriately renamed, open it up to ensure that it appears in good condition. Message Type: Text Text messages are useful when you need to exchange non-XML text information. Sample uses of this service type include exchanging plain text files or comma-separated values. In this sample, you’ll create a Text service that uses FTP as its transport protocol. To make use of the FTP transport protocol, you’ll need access to an FTP server. We used the FileZilla FTP server, available from SourceForge at http://sourceforge.net/projects/filezilla/. Of course, you can opt to use any FTP server you like, but we’ll walk you through some details of setting up the FTP server for use by a specific account, so you might have some translation to do to meet the specifics of your FTP server. The installation program for FileZilla is easy to run. Once you install the FTP server and start it, you’ll need to create a user account. Your proxy service will log into the FTP server using this account. We selected this scenario for two reasons. First, it seems more realistic that the FTP server would apply some level of security when communicating business information to external entities. Second, it give you a chance to see how you create and use Service Accounts in ALSB. To create a user account in FileZilla, click the icon. This brings up the Users dialog box. Click the Add button underneath the Users listbox, and a new dialog appears where you can enter the username for the account you’re creating. Name the account tester and click the OK button. Now that the account is created, you need to set some properties for the account. Back in the Users dialog, be sure the “Enable account” and Password checkboxes are checked. Set the Password field to password (see Figure 7-12). Figure 7-12. Setting the user password
    • 7974CH07.qxd 3/21/07 4:45 PM Page 141 CHAPTER 7 s ADVANCED MESSAGING TOPICS 141 Next, you need to define a home directory for this user account. Click the “Shared folders” entry in the Page listbox on the left side of the dialog. Next, click the Add button in the “Shared folders” portion of the dialog box. A new dialog appears that allows you to select a directory on your computer. We chose to create an ftproot directory, but you can select any directory you wish. Click the OK button to close the Users dialog in FileZilla. FileZilla is now properly config- ured for your needs. Your next step is to create a Service Account in ALSB. A Service Account allows you to create account names and passwords so that ALSB can log into external services and systems. In your case, you need to create a Service Account so that you can log into the FileZilla FTP server using the account tester/password. To create a Service Account, be sure to start a new change in the Change Center. Then navigate to the Message Type project in the Project Explorer. In the root directory of the proj- ect, create a Service Type resource. Name the resource FTP Account and provide a meaningful description, as shown in Figure 7-13. Figure 7-13. Creating a Service Account Be sure to set the Resource Type to Static. This allows you to define a static username and password. Click the Next button. Enter the username as tester and set the password to password. Click the Last button, then the Save button, and then activate the change in the Change Center. Prior to version 2.5 of ALSB, you would define the important aspects of the Service Account outside the Change Center, in the Security Configuration section of the ALSB console. With the release of ALSB 2.5, this has been changed. Service Accounts are now part of a project and no longer a part of the overall ALSB system configuration. Next, you need to create the proxy service itself. Start by creating a new proxy service in the ServiceTypes project. Name the service TextFTP and be sure to select the Service Type as Messaging Service. Click the Next button. Set the protocol to “ftp” and then provide the URI of the FTP service. The URI to use is ftp://localhost:21/ftp_in. s Caution The Endpoint URI of an FTP transport protocol is pretty darned picky. If the URI contains a direc- tory name, then the URI must not end with a /. If the URI does not refer to a directory, then the URL must end with a /.
    • 7974CH07.qxd 3/21/07 4:45 PM Page 142 142 CHAPTER 7 s ADVANCED MESSAGING TOPICS Click the Next button to get to the FTP Transport Configuration window, shown in Figure 7-14. Here is where you get to make use of the Service Account you created earlier. Select the “external user” radio button for the User Authentication. The Service Account field appears. Click the Browse button and select the FTP Account from the list of Service Accounts. Figure 7-14. Defining the FTP transport protocol details Most of these setting are self-explanatory, especially if you read the previous section on the BinaryService. Click the Next button and then click Save to save the definition of this proxy service. Next, you’ll create a simple message flow for this proxy service. Add a Pipeline Pair to the Start node and then add a stage to the request pipeline. Name the stage show text info.
    • 7974CH07.qxd 3/21/07 4:45 PM Page 143 CHAPTER 7 s ADVANCED MESSAGING TOPICS 143 In the show text info stage, we’ll create two new variables to demonstrate where to get the most pertinent information. The contents of the text file are held in the $body variable. You can extract just the text by using the expression $body/text(). Create an Assign action to save this data to the local variable textContents. Add a Log action to display the contents of the file. You can find the name of the file that the proxy server is using by using the following expression: $inbound/ctx:transport/ctx:request/tp:headers/ftp:fileName Create an Assign action and a matching Log action to retrieve this data and send it to the log, as shown in Figure 7-15. Figure 7-15. TextFTP stage definition Testing this service can take several forms: • You can use the test console. • You can use an FTP client, connect to the FileZilla server, and put a text file onto the FTP server. • You can just make a local copy of a text file into the D:ftproot directory. We prefer the second approach because it more closely simulates how this service will operate in the real world. To run the test, first create a new directory where you’ll hold your sample files. For this example, name the temporary directory /ftptemp. Navigate into FTP temp and create a couple short text files. We created files named a.txt and b.txt with just a few words in each file. Open up a command prompt and navigate to the /ftptemp directory. Enter the command ftp. This starts the FTP client program on most Windows machines. Next, you need to connect to the FTP server on your local machine with the following command: open
    • 7974CH07.qxd 3/21/07 4:45 PM Page 144 144 CHAPTER 7 s ADVANCED MESSAGING TOPICS You will be prompted for a username and password, in turn. Enter tester for the user- name and password for the password. After you receive the “Logged on” message, type in the FTP command mput *.txt (mput stands for multi-put, which allows you to send multiple files to the FTP server). The FTP client then prompts you to confirm each file (a.txt and b.txt, if you followed the earlier instructions). Press the “y” key to confirm each file. After the files are sent, you can type the commands close and quit to close the FTP connection and quit the FTP client. In the ALSB output console, you should see the results of the Log action that you defined for your proxy service. The output should look similar to the following: <May 7, 2006 10:11:29 AM PDT> <Error> <ALSB Logging> <000000> < [PipelinePairNode1, PipelinePairNode1_request, stage1, REQUEST] Text contents = Sample text file named b.txt> <May 7, 2006 10:11:29 AM PDT> <Error> <ALSB Logging> <000000> < [PipelinePairNode1, PipelinePairNode1_request, stage1, REQUEST] TextFTP proxy received a file named: ftp_in/b.txt2325484791769069271-214ec371. 10b0f56dcbd.-7dd4.Stage> <May 7, 2006 10:11:29 AM PDT> <Error> <ALSB Logging> <000000> < [PipelinePairNode1, PipelinePairNode1_request, stage1, REQUEST] Text contents = Sample text file named a.txt> <May 7, 2006 10:11:29 AM PDT> <Error> <ALSB Logging> <000000> < [PipelinePairNode1, PipelinePairNode1_request, stage1, REQUEST] TextFTP proxy received a file named: ftp_in/a.txt2325484791769069271-214ec371. 10b0f56dcbd.-7dd5.Stage> Notice that the name of the file, as far as the proxy service is concerned, is greatly “deco- rated,” and the file type is set to .Stage. You’ll need to account for this if the name of the file is important to your processing requirements. We won’t bother to write a business service for this proxy service. The usage of the text data should be a trivial exercise for you by now. Message Type: XML There’s no difference between an XML with no WSDL and this message type. There are two reasons you might use this message type. The first reason is if XML was needed in the request or response, but not both. The second reason for using this message type is if you want to declare the schema of the XML message. If XML is needed in both the request and response, then you should use the XML without WSDL service type, described earlier. MFL stands for Message Format Language. You can use MFL any time you need to process data that is formatted in some method other than XML. MFL allows you to define data format types, and then apply those types to messages that are sent and received from ALSB. In this exercise, you’ll create a proxy service that’s invoked by an e-mail message. The e-mail message will contain a formatted text message. The proxy service will read the e-mail and convert the formatted text message from its original format into a different text format that’s expected by the business service. You’ll also create a matching business service that will be invoked via FTP building on some of the work you did in a previous section. ,
    • 7974CH07.qxd 3/21/07 4:45 PM Page 145 CHAPTER 7 s ADVANCED MESSAGING TOPICS 145 There are a lot of moving parts in this exercise, so it will help if you keep an overview in mind of the various artifacts that you need to create and the steps you need to perform to make this exercise complete. Use the following list as a mental guide for the rest of this section: 1. Install an e-mail server on your machine and create an e-mail account named proxy@mydomain.com. 2. Create a Service Account to the e-mail server. 3. Create a user account on the FTP server named customerftp. Assign the root directory of this user to D:ftproot or C:ftproot, whichever is appropriate for your environment. Be sure you manually create the ftproot/customerftp directory or FileZilla might com- plain later about not being able to create the file. 4. Create a Service Account to the FTP server. 5. Create an MFL file that defines the data format that will be e-mailed to your proxy server. 6. Create an MFL file that defines the format of the file the business service will send to the FTP server. 7. Create an XQuery Transformation file that converts Email MFL format into the FTP format. 8. Add both MFL files and the XQuery to the ServiceTypes project. 9. Create a proxy service based on the CustomerEmailFormat MFL resource and tell the proxy to poll the e-mail account for messages. 10. Create a business service based on the CustomerFTPFormat MFL resource and tell it to send the data as a file to the FTP server. 11. Write a message flow for the proxy service that uses the XQuery transformation and invokes the business service. 12. Test the whole thing, end to end. Simple, isn’t it? Let’s get started. You’ll need an e-mail address that the proxy service can use when it checks to see if it has received an e-mail. Because it’s unlikely that your system administrator will want you mon- keying around with your company’s real e-mail server, you’ll set up your own e-mail server. For this you’ll use the Java EMail Server, an open source project from SourceForge. You can download this file yourself at the following URL: http://prdownloads.sourceforge.net/javaemailserver/jes-1.4.zip?download Alternatively, you can use the version included with this book’s downloadable code in the Source Code/Download area at http://www.apress.com.
    • 7974CH07.qxd 3/21/07 4:45 PM Page 146 146 CHAPTER 7 s ADVANCED MESSAGING TOPICS To install the e-mail server, just open the ZIP file and extract the contents (preserving the directory structure) into a new directory. Once the files are in place, navigate into the directory where you extracted the files and edit the user.conf file. In this file, add the following lines at the end: user.proxy@mydomain.com=password userprop.proxy@mydomain.com.forwardAddresses= user.mailclient@mydomain.com=password userprop.mailclient@mydomain.com.forwardAddresses= This creates a new e-mail user named proxy with a password of password. Accept the default values in the mail.conf file. If you should have trouble running the e-mail server, you should check the mail.conf file first. However, the defaults are fine for most developer machines. Next, you need an e-mail client so that you can send e-mails to proxy@mydomain.com to invoke the service. You’ll write a simple e-mail client that will send e-mails to your proxy serv- ice. You can find the code in the ServiceTypes project in the Eclipse workspace. As mentioned earlier, your service will accept a formatted text message. If you take a look at the e-mail client that sends the formatted text message, you’ll see in the body of the e-mail that the message has the following format: [first name]t[last name]t[middle initial]t[customer id]r The t represents a tab. This is simply a tab-delimited message format. You could just as easily have used commas or another text character instead of the tab character. The important point is to understand how the body of the e-mail is formatted. MFL is a notation that allows you to define arbitrary message formats, such as the tab- delimited format you’ll use in this exercise. Your next step is to create an MFL file that defines this message format. Once you have the MFL file, you’ll add that file as an MFL resource to your ServiceTypes project so you can make use of it in your proxy service. ALSB ships with a tool that makes the creation and editing of MFL files simple. It’s called the Format Builder, and you can start it from within Eclipse by right-clicking the MFL direc- tory in the ServiceTypes project in Eclipse and selecting New ® Other. Next, from the “Select a wizard” dialog box in Eclipse, select the Message Format File file type from the AquaLogic Service Bus folder. You’ll first build an MFL file that matches the tab-delimited format that will be e-mailed to your proxy service. You’ll then build a second MFL file that represents the data format that will be sent to the FTP business service. In the Format Builder application, select File ® New from the menu bar. You see the inter- face change and you have the opportunity to name the new message format. Change the message format name to CustomerEmailFormat and click the Apply button. Now you define the message format in detail. Right-click the envelope icon in the left nav- igation bar of the Format Builder and select Insert Field. Name the field firstName and be sure the Optional checkbox is unchecked. The field type is a String value. This field will occur only once. The field is terminated by the t delimiter and the code page is UTF-8. Repeat this process for the lastName and MI fields. The last field you’ll create is the CustomerID field. It’s similar to the other fields in all respects, save one: the delimiter value is set to r. Your window should look similar to that
    • 7974CH07.qxd 3/21/07 4:45 PM Page 147 CHAPTER 7 s ADVANCED MESSAGING TOPICS 147 shown in Figure 7-16. Please note that the order of the fields is critical. If your order is different, simply click and drag on the fields in the left navigation bar to put them into the correct order. Figure 7-16. Defining the String data fields Save the CustomerEmailFormat.mfl file in the ServiceTypes/MFL directory of the Eclipse project. Next you’ll create the CustomerFTPFormat.mfl file that defines the file format expected by the FTP server. This format has the following structure: [ID]t[Name]r As you can see, the format required by the FTP server is significantly different from the format you receive in the e-mail. A little transformation is in order to make this communica- tion work. To further complicate matters, the FTP format requires that the ID field be a numeric field, while the Email format defines it as a String field. The game is afoot! To define the CustomerFTPFormat.mfl file, you’ll need to create a new file in the Format Builder. Name the new file CustomerFTPFormat.mfl. Create the ID and Name fields, following the same processes you just performed for the CustomerEmailFormat.mfl file. The only differ- ence is that the ID field must be defined as Numeric. Be sure the ID field is terminated with the t character, while the Name field is terminated with the r. Your file should look like Figure 7-17.
    • 7974CH07.qxd 3/21/07 4:45 PM Page 148 148 CHAPTER 7 s ADVANCED MESSAGING TOPICS Figure 7-17. Defining the CustomerFTPFormat.mfl file Save this file in the ServiceTypes/MFL directory in the Eclipse project workspace. Well done so far. You have defined your input and output formats. Now you need to define an XQuery resource that will perform the transformation of the data from the input format (CustomerEmailFormat.mfl) into the output format (CustomerFTPFormat.mfl). Fortunately, you have a tool in Eclipse that makes this process significantly less tedious: the XQuery Mapper. You begin in Eclipse. Left-click the ServiceTypes/MFL directory and press the F5 key to update the folder so that Eclipse knows about the two MFL files you created there. Right-click the ServiceTypes/MFL directory and select New ® Other from the pop-up menu in Eclipse. This brings up the “Select a wizard” dialog box in Eclipse. Navigate to the AquaLogic Service Bus folder and select XQuery Transformation. Click the Next button to start the XQuery Trans- formation wizard. The first step in the wizard is to define the file name. Set the file name to customerMFLTransform. Be sure the parent folder is set to /ServiceTypes/MFL and click the Next button. Now you can specify the source of the XQuery transformation. Because MFL is a non- XML format, select the Non-XML radio button above the listbox on the left side of the dialog box, as shown in Figure 7-18. Expand the node named MFL/CustomerEmailFormat.mfl, select the CustomerEmailFormat object, and click the Add button.
    • 7974CH07.qxd 3/21/07 4:45 PM Page 149 CHAPTER 7 s ADVANCED MESSAGING TOPICS 149 Figure 7-18. Selecting the XQuery source type Click the Next button to select the target type. Once again, select the Non-XML radio but- ton, then expand the MFL/CustomerFTPFormat.mfl node so that you can select and then add the CustomerFTPFormat object. Click the Finish button. You’ll now see the customerMFLTransform.xq file in Eclipse. By default, you should see the design view, as shown in Figure 7-19. Figure 7-19. XQuery Transform design view The design view of the XQuery Transformation editor is a powerful tool that allows you to work graphically and generate XQuery scripts. You have two things to do in this transforma- tion. First, you’ll map both the last name and then the first name from the source format to the Name field of the target format. Along the way, you’ll ensure that the Name field of the target
    • 7974CH07.qxd 3/21/07 4:45 PM Page 150 150 CHAPTER 7 s ADVANCED MESSAGING TOPICS format ends up as [lastName], [firstName]. Adding the comma will help for human readabil- ity. Second, you’ll map the CustomerID from the source to the ID field of the target, converting it from a String to a Numeric along the way. Let’s get started with the first and last names. Click the lastName and drag it onto the tar- get’s Name field, then release the mouse button. A green arrow will show up, visually linking the two fields. Next, click and drag the firstName field from the source onto the Name field of the target and release the mouse. Your XQuery Transformation should look like Figure 7-20. Figure 7-20. Mapping the name fields to the target However, you need to do a little extra formatting in the Name field of the target format. Click the Source view of the XQuery Transformation to see the raw XQuery text that has been generated so far. There is a single XQuery function declaration. In that function, look for the text between the <Name></Name> tags. That text should be as follows: <Name>{ concat($customerEmailFormat/lastName, $customerEmailFormat/firstName) }</Name> You want to add a comma and a white space between the last name and the first name, so you modify this line of code as follows: <Name>{ concat($customerEmailFormat/lastName, , $customerEmailFormat/firstName) }</Name> Switch back to the design view. Now you want to map the CustomerID source field into the ID field of the target format. If you click and drag, as you did before, you’ll get the following error message:
    • 7974CH07.qxd 3/21/07 4:45 PM Page 151 CHAPTER 7 s ADVANCED MESSAGING TOPICS 151 That’s because you can’t map a String into a Numeric. The XQuery Transformation tool isn’t able to make a judgment call on this kind of transformation, but you know that the String version of the CustomerID field will always be a numeric value, so you need to create this map- ping yourself. Go back into the Source view of the transformation and add the following line of code just below the CustomerFTPFormat tag: <ID>{ $customerEmailFormat/CustomerID/text() }</ID> Switch back to the design view and it should look like Figure 7-21. Note the little “f” on the icons next to the ID and Name attributes of the target. They indicate that the mapping uses one or more XQuery functions and is not a straight copy of the data in the fields. Figure 7-21. The complete XQuery transformation Save the XQuery transformation file. Then, in the ALSB console, navigate to the ServiceTypes project. Create an XQuery folder in the project, and in that folder add the XQuery transformation file as an XQuery resource. Name the new resource CustomerEmailToFTP. You’ll find the XQuery by clicking the Browse button and navigating to ServiceTypesMFL customerMFLTransform.xq. Navigate into the MFL folder of the ServiceTypes project and create an MFL resource for the CustomerEmailFormat.mfl and the CustomerFTPFormat.mfl files. Use the file names for the resource names (omitting the MFL file extension). Next, you need a Service Account to log into the e-mail server to retrieve the e-mail. In the ServiceTypes project in ALSB, create a new Service Account as shown in Figure 7-22. Be sure to select Static as the Resource Type. Click the Next button and set the username to proxy@mydomain.com and the password to password. Click the Save button to save this Service Account.
    • 7974CH07.qxd 3/21/07 4:45 PM Page 152 152 CHAPTER 7 s ADVANCED MESSAGING TOPICS Figure 7-22. Creating a Service Account for the MFLEmail2FTP proxy The Service Account for the e-mail account is now defined and active. Next, you must define a new Service Account to connect to your FTP server using a different login name. Fol- low the same process as you just did for creating the e-mail Service Account, but with the following changes: 1. In the ServiceTypes project folder (in the ALSB console), create a new Service Account named customerftp. Be sure to select the Resource Type as Static again. 2. Click the Next button, set the username to customerftp, and set the password to password. Those are all the Service Accounts you need for this exercise. You’re now ready to create your proxy service. In the ServiceTypes project, create a new proxy service resource. Name the proxy MFLEmail2FTP. You can optionally provide a description of the service (remember, this is a best practice when doing this in the real world), and select the Messaging Service as the Ser- vice Type. Click the Next button. Configure the message type. Select the Request Message Type as MFL and select the CustomerEmailFormat. For the response message type, select None. Click the Next button. Select the “email” protocol (see Figure 7-23). Be sure to set the Endpoint URI to use the POP3 port, not the SMTP port, because you’re reading e-mail via POP3 in this exercise. Figure 7-23. Configuring the “email” protocol On the next page of the wizard (see Figure 7-24), you need to select the e-mail Service Account, so that your proxy service will be able to log into the e-mail server to retrieve the emails. The Polling Interval defines, in seconds, how often the proxy service will connect to
    • 7974CH07.qxd 3/21/07 4:45 PM Page 153 CHAPTER 7 s ADVANCED MESSAGING TOPICS 153 the e-mail server to check for new e-mails. The Read Limit specifies the maximum number of e-mail messages to process each time the proxy service connects to the e-mail server. The Post Read action of “delete” specifies that the e-mails that are read will then be deleted. Set the Attachments combo box to “ignore,” because you aren’t interested in any e-mail attachments. Figure 7-24. Configuring the e-mail transport details The IMAP Folder is the directory used when processing. The IMAP Move Folder is only used if the Post Read Action is set to “move.” The Download Directory specifies the directory into which the e-mail messages are downloaded when they are about to be processed. The Archive Directory specifies the directory where the e-mail messages are archived if the Post Read Action is set to Archive. The Error Directory is where the e-mail messages are stored if there is an error processing them. Last, the Request Encoding specifies the encoding scheme used to encode the e-mail messages. This is used to ensure that the proxy server parses the e-mail messages using the correct character encoding scheme. Click the Next button and then click the Save button on the following window. The basics of the proxy service are now defined. You must now create a business service that will accept a text message using the CustomerFTPFormat. Name the business service MFLBusiness and select Messaging Service as the service type. Set the request message type to MFL and select the CustomerFTPFormat MFL resource. Be sure that the response message type is set to None; otherwise you won’t be able to use the FTP transport protocol.
    • 7974CH07.qxd 3/21/07 4:45 PM Page 154 154 CHAPTER 7 s ADVANCED MESSAGING TOPICS Next, you define the transport protocol. Select FTP as the protocol and leave the load balancing algorithm at the default value of round-robin. Add an Endpoint URI of ftp:// localhost:21/customerftp. Accept the remaining default values and click the Next button. On the next window (see Figure 7-25), set the user authentication to “external user,” then select the customerftp Service Account. Set the prefix field to customer and the suffix field to text. You should set the transfer mode to binary, simply because it allows a greater variety of character encodings to be transferred. Last, use the default request encoding of utf-8. Figure 7-25. Setting the transport configuration Save all your work and activate the change in the Change Center. Next, you define the message flow for your proxy service. Create a new change in the Change Center and edit the message flow for the MFLEmail2FTP proxy service. Add a Pipeline Pair node to the message flow. In the request pipeline, add a stage and name it get Email Info. This stage is not necessary to the function of the proxy service, but we wanted to demon- strate where you find some of the important information about the e-mail message. Edit the get Email Info stage and create some Assign actions. First, you’ll create Assign actions to get the firstName, lastName, and CustomerID from the e-mail message. Click the <Expression> link for the Assign statement, then select the Variable Structures link in the left navigation pane. Open the $body (request) node and the nested CustomerEmailFormat node, and voilà! You can see the structure of the MFL file represented in the format to which you should now be accustomed (see Figure 7-26). No parsing is necessary from you; ALSB takes care of all those boring details.
    • 7974CH07.qxd 3/21/07 4:45 PM Page 155 CHAPTER 7 s ADVANCED MESSAGING TOPICS 155 Figure 7-26. Accessing MFL data is easy within the body variable. Click the firstName node and paste it into the expression edit box. Assign the value of that expression to a variable named firstName. Do the same for the lastName and CustomerID fields, assigning them to local variables. The To and From fields of the e-mail are accessed through the $inbound structure. Figure 7-27 shows the exact location of this information. If you need to know the date of the e-mail or if you make service routing decisions based upon who sent the e-mail, the $inbound variable is a rich source of that information. Figure 7-27. The $inbound structure holds the rest of the commonly needed e-mail information.
    • 7974CH07.qxd 3/21/07 4:45 PM Page 156 156 CHAPTER 7 s ADVANCED MESSAGING TOPICS Just for completeness, create two new local variables and assign their values based on the From and Date fields of the $inbound structure. Add a few log statements that output this infor- mation at the Error severity level so you can see the debug information on the ALSB console as you run your tests. Next, you need to add a Route node to the Pipeline Pair to route the request to the MFLBusiness service. Edit the Route node and add a Replace action to the Request Actions section. Define the XPath as “.” in the variable body. Click the <Expression> link and in the XQuery Expression Editor, click the XQuery Resources link on the page. Click the Browse button to select the specific XQuery resource you wish to use. In this case, the resource is the CustomerEmailToFTP resource you defined earlier. In the Bind Variables section, the console is asking you to bind the customerEmailFormat variable (this is an external variable defined in the customerEmailToFTP file you created .xq earlier) to the local variable that contains that data. That information happens to be at $body/CustomerEmailFormat, so enter that as the binding. You want to replace the node contents, not the entire body node (see Figure 7-28). With this step complete, save everything and activate the change in the Change Center. It’s time to test your service. Figure 7-28. The Route node to the MFLBusiness service To make life a little simpler, a MailClient program in the Eclipse ServiceTypes project will send a properly formatted e-mail to the proxy@domain.com e-mail account. Open the source file for the MailClient.java program in Eclipse and right-click in the source code. Select Run As ® Java Application from the pop-up menu and the client will send an e-mail. You might have to wait up to two minutes to see the proxy service receive the e-mail and the MFLBusiness service fire off the FTP event, but you should see the following output on your WLS console: <May 11, 2006 6:26:07 PM PDT> <Error> <ALSB Logging> <000000> < [PipelinePairNode1, PipelinePairNode1_request, get email, REQUEST] first name: John, Last Name:Doe, Customer ID: 75> <May 11, 2006 6:26:07 PM PDT> <Error> <ALSB Logging> <000000> < [PipelinePairNode1, PipelinePairNode1_request, get email, REQUEST] From: mailclient@mydomain.com> <May 11, 2006 6:26:07 PM PDT> <Error> <ALSB Logging> <000000> < [PipelinePairNode1, PipelinePairNode1_request, get email, REQUEST] Subject: Order>
    • 7974CH07.qxd 3/21/07 4:45 PM Page 157 CHAPTER 7 s ADVANCED MESSAGING TOPICS 157 Next, check the file that was sent to the FTP server and open it up. You should see a file with a highly decorated name, similar to the following: c486083985906103420-53cbe67b.10b25da1470.-7e4e.txt. Open the file to ensure that it’s a properly encoded, tab-delimited file whose content looks like the following: 75 Doe,John What this exercise impresses on us is the amount of coding and complexity that was involved in getting it to work. There are a lot of moving parts in this exercise. It’s pretty cool to see this beast run. However, this level of complexity runs completely counter to good SOA practices. There’s a reason why e-mail and FTP are considered legacy connection mechanisms. Although it’s good to know you have this level of flexibility with ALSB, you should never con- nect a system of this complexity directly to your main ESB. Instead, you can use specific instances of ALSB to act as an adapter to these legacy systems, converting these file formats into proper XML Schema objects and exchanging the data via web services. Transport Typed Service: EJB In the past, you could use a JWS to wrap an EJB and publish it as a service. ALSB now allows you to define EJBs as business services and call them directly from a business service. Our example will show a SOAP proxy service invoke a stateless session bean (the only kind of EJB you can invoke from ALSB) to calculate the amount of tax on a given price. This exercise requires the following steps: 1. Create and deploy the EJBBusiness stateless session bean to the WLS. 2. Create a business service that knows how to invoke the EJB. 3. Create a proxy service that returns the tax for any amount given to it. 4. Create the message flow that routes the proxy message to the EJB, then returns the calculated tax amount via the proxy service. Creating the EJBBusiness Bean In the EJBCallout project in Workshop, you can build and deploy the EJBBusiness bean by selecting the project in the Workshop Package Explorer pane and then selecting Project ® Build Project from the menu bar. You also need to add the project to the WLS (named alsb_book) so that you can deploy the EJB onto the server. Once you have successfully built and deployed the EJB, your final step is to create a client JAR file. You create a client JAR file for an EJB by right-clicking the project name in the Package Explorer window and then selecting Export from the pop-up menu. This brings up Workshop’s Export dialog (see Figure 7-29). Select “EJB JAR file” from the list of export destinations. Select the EJBCallout in the EJB module combo box. For the Destination field, browse to the EJBCallout project directory where your EJBCallout Workshop project resides on your hard drive. This creates a JAR file that contains both the implementation files and the client files for the EJB.
    • 7974CH07.qxd 3/21/07 4:45 PM Page 158 158 CHAPTER 7 s ADVANCED MESSAGING TOPICS Figure 7-29. Exporting a client JAR file for the EJBCallout project Let’s take a quick look at the code for this EJB (see Listing 7-10). If you’re an experienced EJB developer, you’ll quickly appreciate the value that annotation brings to EJB development. Listing 7-10. The EJBBusiness Bean package com.alsb.ejb; import javax.ejb.SessionBean; import weblogic.ejb.GenericSessionBean; import weblogic.ejbgen.Session; import weblogic.ejbgen.JndiName; import weblogic.ejbgen.FileGeneration; import weblogic.ejbgen.Constants; import weblogic.ejbgen.RemoteMethod; /** * <code>GenericSessionBean</code> subclass automatically generated by Workshop. * * Please flush out the {@link #ejbCreate()} method; add all desired * business methods; and review the Session, JndiName, and FileGeneration * annotations to ensure the settings match your intended use. */ @Session(ejbName = "EJBBusiness") @JndiName(remote = "ejb.EJBBusinessRemoteHome") @FileGeneration(remoteClass = Constants.Bool.TRUE, remoteHome = Constants.Bool.TRUE, localClass = Constants.Bool.FALSE, localHome = Constants.Bool.FALSE) public class EJBBusiness extends GenericSessionBean implements SessionBean { private static final long serialVersionUID = 1L;
    • 7974CH07.qxd 3/21/07 4:45 PM Page 159 CHAPTER 7 s ADVANCED MESSAGING TOPICS 159 /* (non-Javadoc) * @see weblogic.ejb.GenericSessionBean#ejbCreate() */ public void ejbCreate() { // IMPORTANT: Add your code here } // IMPORTANT: Add business methods @RemoteMethod(transactionAttribute=Constants.TransactionAttribute.SUPPORTS) public double calculateTax(double taxableAmount) { return taxableAmount * 0.08d; } } The majority of the file is annotation. This greatly simplifies EJB development because you can now generate the boilerplate EJB code from the annotations in the implementation file. As you can see in the source code, the tax rate is defined at 8 percent. The method returns 8 percent of the taxableAmount argument. No effort is made to qualify the taxable amount (that is, it will calculate negative numbers also) simply because this is demo code. With your EJB built and deployed, let’s move on to building the business service. Creating the Business Service ALSB 2.5 introduced a new resource type: the JAR file. JAR files were introduced specifically to support calling EJBs. Just like any other EJB client, ALSB needs a client JAR to access an EJB. Your first step will be to add the client JAR as a resource so that your business service will be able to reference it. In the ServiceTypes project in the ALSB console, create a new folder named JARs. This folder will hold the client JAR file that you need to access the EJBBusiness EJB. In the new JARs folder, add a JAR resource. Fill in the fields as shown in Figure 7-30. Figure 7-30. Defining an EJB client JAR resource Click the Save button. Next, in the Business Services folder, create a new business service with the name EJBBusiness. EJBs are categorized at Transport Typed Services, so select the appropriate radio button. Click the Next button to continue.
    • 7974CH07.qxd 3/21/07 4:45 PM Page 160 160 CHAPTER 7 s ADVANCED MESSAGING TOPICS Select the ejb protocol. For the Endpoint URI use the following: ejb::EJBBusinessHome You have the luxury of leaving the <provider> field blank because you’re calling an EJB on the local machine. If you need to invoke a remote EJB, then read the following section, about creating a JNDI provider and using it in the URI. Click the Next button to continue. We’ve always felt that the next page in the wizard was cool (see Figure 7-31). ALSB interro- gates the JAR file resource to discover the important aspects of the EJB. Click the Browse button for the Client Jar field and select the JAR file you added as a resource earlier in this exercise. Like magic, the metadata defined in the JAR file is populated into the appropriate fields in the window. Figure 7-31. Defining the EJB invocation details By default, the Style is set to Document Wrapped and the Encoding is set to Literal. These options provide the greatest level of interoperability. Change the name of the parameter to taxableAmount. Click the Next button and then the Save button to save your business service. You can see the WSDL that was generated for the business service by clicking the Export WSDL icon .
    • 7974CH07.qxd 3/21/07 4:45 PM Page 161 CHAPTER 7 s ADVANCED MESSAGING TOPICS 161 Creating a JNDI Provider In our simple example, we left the provider blank because the EJB is deployed onto the same servers as the service bus. However, in real-world deployments, you’ll often have to create a JNDI provider. In fact, you’ll create a JNDI provider to your local machine, just to get a feel for the process. First, navigate to the System Administration ® JNDI Providers window. Click the Add but- ton and then fill in the window as shown in Figure 7-32. Figure 7-32. Defining a JNDI provider Note the use of the t3 protocol in the provider URL. Only t3 is supported here. Set the User Name and Password fields appropriately (set both to weblogic if you followed the instructions in Chapter 2 for creating your ALSB domain) and save the JNDI provider. Now you can edit the EJB protocol for the same business service that you defined in this exercise and use the localProvider that you just created. The behavior will be the same. The proper Endpoint URI is as follows: ejb:localProvider:ejb.EJBBusinessRemoteHome Creating the Proxy Service To create the proxy service, you begin by creating a WSDL folder in the ServiceTypes project. In this new folder, create a WSDL resource. Name the resource EJBTaxProxy, then browse to the TaxProxy.wsdl file located in the WSDL directory of the EJBCallout Workshop project on your hard drive. Next, you’ll create the proxy service in the Proxy Services folder. Name the proxy service EJBTaxProxy and set the Service Type as a WSDL Web Service. Click the Browse button to browse for the WSDL resource that you just added. Once you’ve selected the WSDL, click the Next button. Select the protocol to be HTTP Set the Endpoint URI to /EJBTaxProxy. Click the Next but- . ton. Accept the default values in the next two windows and then click the Save button to save your proxy service.
    • 7974CH07.qxd 3/21/07 4:45 PM Page 162 162 CHAPTER 7 s ADVANCED MESSAGING TOPICS Creating the Message Flow The last item you need to create is the message flow that routes the data from the proxy serv- ice to the business service. Open the message flow for the proxy service, and create a Route node. Edit the Route node and set it to route to the EJBBusiness service, invoking the calculateTax operation, as shown in Figure 7-33. Figure 7-33. Route node for the EJBBusiness message flow You need an Assign action to assign the value of the expression: $body/alsb:calculateTaxRequest/alsb:taxableAmount/text() Set the value to a local variable named amount. Next, you need a Replace action to replace the contents of the entire SOAP Body element contained in the $body variable with the follow- ing expression: <open:calculateTax> <open:taxableAmount>{$amount}</open:taxableAmount> </open:calculateTax> Notice that the business service uses the namespace label open. For the preceding expres- sion to be valid, you need to define the open namespace in the ALSB console. To define the namespace, click the Add Namespace link in the expression editor. This link is highlighted in Figure 7-34. Remember that namespaces are defined by their text value, not by their labels. Therefore, it’s critical that you get the string values correct. We spent 20 minutes debugging this simple transformation simply because we had originally omitted the trailing slash and defined the namespace as http://www.openuri.org instead of http://www.openuri.org/! After you complete the Route node, including the creation of the user-defined open name- space, save all your work and then activate the change. Test the service by placing different amounts into the test browser to see the responses.
    • 7974CH07.qxd 3/21/07 4:45 PM Page 163 CHAPTER 7 s ADVANCED MESSAGING TOPICS 163 Figure 7-34. Adding a user-defined namespace Why Use EJBs? There are a lot of EJBs in the world. Odds are pretty good that if your company uses J2EE, then you have legacy EJBs that implement business logic. It might make sense for you to wrap these EJBs in web services to make them more easily accessible to your enterprise. ALSB allows you to connect to these assets without recompiling them or otherwise having to modify them, thereby reducing the level of effort to publish the functionality of these EJBs. However, there’s a downside to this strategy, or at least a subtle and insidious danger. EJBs are usually not written with services in mind. Entity EJBs usually contain little abstraction from the data source and primarily function as a mechanism to mediate between data con- sumers and the database. Even stateless session beans, implementing the Façade pattern to hide the complexity of underlying EJB interdependencies, are rarely written to service- oriented standards. Publishing them directly as services might well reduce the level of abstrac- tion and loose coupling in your ESB. Low-level implementation details contained in common EJB interfaces can have a dire effect on an enterprise-level service bus. Although it’s possible to write service-oriented EJBs, it’s rare that an EJB is written to that level. By their very nature, EJBs are designed to implement IT and business concepts close to the physical level. Usually you’ll find it necessary to create proxy services at a greater level of abstraction. These proxy services act more as an adapter for the EJBs. It’s these low-level proxy services that can then participate in the overall SOA.
    • 7974CH07.qxd 3/21/07 4:45 PM Page 164 164 CHAPTER 7 s ADVANCED MESSAGING TOPICS POJO Another new feature of ALSB, introduced in version 2.5, is the ability for a Service Callout action to invoke Java code directly. Colloquially known as POJOs (an acronym for Plain Old Java Objects), they are simple Java classes without the overhead associated with EJBs and Java Web Services. The benefit of POJOs is that they are technically simple to create and have little overhead, at least compared to an EJB. The drawbacks of the POJO are the same as the benefits. Because they have little overhead, there’s no thread management (as you would have in a J2EE con- tainer), and their very simplicity means that without some sort of IT governance, anyone who can write even the simplest Java code can create resources for your service bus. Use POJOs with caution. There’s an important restriction to using a POJO in ALSB: only static methods are recog- nized by the service bus. However, there’s nothing to stop you from instantiating Java objects or threads from within the POJO itself. This is similar to EJBs where the J2EE specification states that you may not create threads within an EJB, but it’s still possible to do it. Similarly, BEA strongly discourages the creation of threads and object instantiation within a POJO. Okay, with all the legal disclaimers aside, let’s hammer out a POJO to see just how easy it is. Listing 7-11 shows the source code for a simple POJO that, like the previous EJB exercise, calculates the 8 percent tax of any amount that you give it. Now this is easy code! Listing 7-11. A Sample POJO package com.alsb.pojo; public class Pojo { /** * ALSB can only call static methods in a POJO. * @param taxableAmount * @return The additional tax to be paid */ public static double calculateTax(double taxableAmount) { double taxRate = 0.08; return taxableAmount * taxRate; } } You can find this code in the ServiceTypes project in Workshop. If you wish to create your own POJO project, simply follow these steps: 1. Create a new Java project in Workshop. Name it POJO. 2. Add a source code folder to the project. Traditionally, this is named src. 3. Create a package in the source code folder called com.alsb.pojo. 4. Create a new Java class in the com.alsb.pojo package. Name the class Pojo and use the code in Listing 7-11 to define the class. 5. To build the project, right-click the POJO project in Workshop and select Build Project from the pop-up menu.
    • 7974CH07.qxd 3/21/07 4:45 PM Page 165 CHAPTER 7 s ADVANCED MESSAGING TOPICS 165 6. After the project is built, you need to create a JAR file for the Pojo project. Right-click the Pojo project and select Export from the pop-up menu. 7. In the Export dialog, select “JAR file” from the list of file types you can export. Click the Next button. 8. Select the file name and the destination of your JAR file. We prefer to put them in the root directory of our projects, as shown in Figure 7-35. 9. Click the Finish button. Figure 7-35. Specifying the location of the JAR file This builds the JAR file for the POJO project. Next, you need to import it into ALSB for use in an ALSB project. Back in the ALSB console, navigate to the JARs directory in the ServiceTypes project. Add a new JAR resource, name the resource Pojo, and select the pojo.jar file that you just compiled. Next, navigate to the Proxy Services directory in your ServiceTypes ALSB project and cre- ate a new proxy service called PojoProxy. Select the Message Type radio button under Service Type and click the Next button. Select Text for both the request message and the response message (we’re more concerned with demonstrating the invocation model of a POJO in this exercise than we are with rehashing our previous integration demonstrations), and click the Next button.
    • 7974CH07.qxd 3/21/07 4:45 PM Page 166 166 CHAPTER 7 s ADVANCED MESSAGING TOPICS Set the protocol to HTTP and the Endpoint URI to /PojoProxy. Accept the default values for the rest of the Proxy Service wizard and save the proxy service. Next, you need to create a message flow for the proxy. Add a Pipeline Pair to the message flow. In the request pipeline, create a calculate tax stage. Create a return tax due stage in the response pipeline. Edit the calculate tax stage. In the calculate tax stage (shown in Figure 7-36), add an Assign action that assigns the value of the $body/text() expression to the taxableAmount local variable. Figure 7-36. The “calculate tax” stage definition Next, add a Java Callout action. Click the Method link, then click the Pojo link in the Select a JAR window. This brings up the Select a Class and Method window, as shown in Figure 7-37. Figure 7-37. Selecting a class and method Click the plus sign next to the com.alsb.business.Pojo line to expose the methods avail- able. Click the radio button for the calculateTax() method and click the Submit button. Fill in the fields of the Java Callout so that it matches those shown in Figure 7-37. Save this stage.
    • 7974CH07.qxd 3/21/07 4:45 PM Page 167 CHAPTER 7 s ADVANCED MESSAGING TOPICS 167 Next, edit the return tax due stage in the response pipeline. Because you didn’t route to a service, the Pipeline Pair simply echoes the request document back to you, but you can place a Log action in this stage so that you can see the results of the Pojo invocation. Use the follow- ing expression in the Log action: concat(Tax due is , $taxDue) Save all your work and activate the change in the Change Center. When you test the serv- ice you just enter a number in the large text area. There is no XML involved in this invocation. Look in the WebLogic console to see the log output and verify that the POJO executed prop- erly. In the real world you probably wouldn’t use a POJO to calculate a tax. In the United States, tax rates vary at the federal, state, and local levels, depending on the product. Most countries have similarly complex rules and calculations for their taxes. However, there are some applica- tions where a POJO makes sense. If you have logic that’s better expressed in Java code than it is in a database or an XQuery, POJOs are a perfect match. SOAP with Attachments It’s possible to send a SOAP message with one or more attachments. This is similar to attach- ing a file to an e-mail. ALSB supported SOAP with Attachments starting in version 2.0. SOAP with Attachments supports any arbitrary MIME type. Typically, attachments are defined in the WSDL, as you will do in this exercise. However, no special considerations are required when defining the WSDL for the proxy service, because attachments can be considered orthogonal to the message content and data types. sBest Practice Declare all expected or optional attachments to operations in the WSDL. Your business service is located in the SOAPwithAttachment project in Workshop. This service has one operation that takes a message that contains a String file name and a MIME attachment as the arguments. The operation then returns the name of the newly created local file. You’ll use this to send the name of a ZIP file, plus the file itself, to the business service. The business service will then save the attachment to the local file system (in the root directory of the C: drive). Listing 7-12 shows the WSDL for the business service. The important parts of the WSDL are in bold to highlight them. To define attachments in your WSDL, you need to change the message that will carry the attachment and the soap:operation that handles the message. In this case, only the <input> message of the operation is concerned with the attachment. How- ever, you can also have an operation return (that is, <output>) a message with an attachment.
    • 7974CH07.qxd 3/21/07 4:45 PM Page 168 168 CHAPTER 7 s ADVANCED MESSAGING TOPICS Listing 7-12. The WSDL for the SOAPwithAttachment Business Service <?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.alsb.com/SOAPwithAttachment/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" name="SOAPwithAttachment" targetNamespace="http://www.alsb.com/SOAPwithAttachment/"> <wsdl:types> <xsd:schema targetNamespace="http://www.alsb.com/SOAPwithAttachment/"> <xsd:element name="submitAttachmentResponse" type="xsd:string" /> <xsd:element name="fileName" type="xsd:string" /> </xsd:schema> </wsdl:types> <wsdl:message name="submitAttachmentResponse"> <wsdl:part element="tns:submitAttachmentResponse" name="submitAttachmentResponse" /> </wsdl:message> <wsdl:message name="submitAttachment"> <wsdl:part element="tns:fileName" name="fileName" /> <wsdl:part name="file" type="xsd:base64Binary" /> </wsdl:message> <wsdl:portType name="SOAPwithAttachmentPort"> <wsdl:operation name="submitAttachment"> <wsdl:input message="tns:submitAttachment" /> <wsdl:output message="tns:submitAttachmentResponse" /> </wsdl:operation> </wsdl:portType> <wsdl:binding name="SOAPwithAttachmentSOAP" type="tns:SOAPwithAttachmentPort"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> <wsdl:operation name="submitAttachment"> <soap:operation soapAction="http://www.example.org/SOAPwithAttachment/¯ submitAttachment" /> <wsdl:input> <mime:multipartRelated> <mime:part> <soap:body parts="fileName" use="literal" />
    • 7974CH07.qxd 3/21/07 4:45 PM Page 169 CHAPTER 7 s ADVANCED MESSAGING TOPICS 169 </mime:part> <mime:part> <mime:content part="file" type="application/zip" /> </mime:part> </mime:multipartRelated> </wsdl:input> <wsdl:output> <soap:body parts="submitAttachmentResponse" use="literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="SOAPwithAttachment"> <wsdl:port binding="tns:SOAPwithAttachmentSOAP" name="SOAPwithAttachmentSOAP"> <soap:address location="http://localhost:7001/SOAPwithAttachment" /> </wsdl:port> </wsdl:service> </wsdl:definitions> First, you’ll create a new WSDL resource in the WSDL folder for your business service. Use the Resources from URL option to import the WSDL from its URL. This ensures that the busi- ness web service has been compiled and deployed properly onto your server. The following URL points to the WSDL on your server: http://localhost:7001/SOAPwithAttachments/SOAPwithAttachment?WSDL Name the WSDL SOAPwithAttachment and complete the import process. Next, move into the Business Service folder of the ServiceTypes project and create a new business service named SOAPwithAttachmentBusinessService. Base this business service on the WSDL that you just imported. Click the Last button to skip the other pages of the wizard. Then click the Save button to save this business service. Next, create a proxy service named SOAPwithAttachmentProxy in the Proxy Services folder. You’ll base this proxy service directly on the SOAPwithAttachmentBusinessService. Accept all default values for the proxy service and then save it. The test console is insufficient for testing services with attachments. As a result, you need to create a client for your proxy service in Java code. You’ll use this client to test your service and ensure that the attachment is passed through the proxy service to the business service and ultimately saved as a file on the local hard drive. The client code relies on the existence of a test.zip file in the root directory of the C: drive. You can create any ZIP file and simply save it as C:test.zip to meet the needs of your client. We like using ZIP files for attachments for two reasons: • They are commonly used as attachments in the real world. • You can easily tell if a ZIP file is corrupted because it won’t open. Your client project is located in the Workshop project named SOAPwithAttachmentClient. You use the build.xml file for building and running the client. Open the build.xml file in Work- shop and be sure that the Outline window is open also. The Outline window shows you the Ant
    • 7974CH07.qxd 3/21/07 4:45 PM Page 170 170 CHAPTER 7 s ADVANCED MESSAGING TOPICS tasks that you can run. Begin by running the generate task, followed by the build task, and finally execute the run task. Assuming that everything went properly, you should now find a testX.zip file in the root directory of your C: drive. Open this file and confirm that the contents match the contents of the original test.zip file. Now that you have a proxy service that can accept attachments, it’s time to explore what you can do with these attachments in the proxy service. The possibilities are almost limitless, but we’ll confine ourselves to some of the more basic tasks that demonstrate how you interact with attachments in a proxy service. In the ALSB console, create a new change in the Change Center and then open up the message flow for the SOAPwithAttachmentProxy service. The message flow should only contain two nodes: a Start node and the Route. Click the Start node and add a Pipeline Pair. In the request pipeline, add a new stage and name it examine attachment. Next, edit the examine attachment stage. You’re going to add a few logging statements so you can see the type of metadata that’s associated with attachments. Start by adding an Assign statement that assigns the expression fn:count($attachments/attachment) to a variable named numAttachments. The $attachments structure contains all the attachments that are associated with a message. Each child attach- ment has a specific structure. The structure and the meaning of the fields are shown in Table 7-2. Table 7-2. Attachment Metadata Field Description Content-ID The MIME type ID for the content. This is reported to be a globally unique value, but we find it tends to be the part name from the <mime:content part="" .../> section of the <soap:operation> declaration in the WSDL file. If you run this example, you’ll see that the Content-ID value is file. Content-Type The MIME type for the content. This is represented as major type or subtype. In your WSDL you declared the attachment to be an application/zip. Your debugging statement will show it as an application/octet-stream. Content-Transfer-Encoding Specifies how the attachment is encoded. This is sometimes empty. Content-Description A text description of the content. This is sometimes empty. Content-Location A locally unique URI that identifies the attachment. This is sometimes empty. Content-Disposition Declares how the attachment is to be handled. This is sometimes empty. body Holds the attachment data. Figure 7-38 shows a set of actions in the examine attachments stage that loop through all the attachments of a message.
    • 7974CH07.qxd 3/21/07 4:45 PM Page 171 CHAPTER 7 s ADVANCED MESSAGING TOPICS 171 Figure 7-38. An example of looping through the attachments of a message The Log action nested in the For Each action contains a single statement that sends all the attachment information to the test console of ALSB where you can read it. This rather com- plex statement follows: concat(Attachment , string($index), of , string($totalAttachments), fn:codepoints-to-string(10), Content-ID: , $attach/ctx:Content-ID, fn:codepoints-to-string(10), Content-Type: , $attach/ctx:Content-Type, fn:codepoints-to-string(10), Content-Transfer-Encoding: , $attach/ctx:Content-Transfer-Encoding, fn:codepoints-to-string(10), Content-Description: , $attach/ctx:Content-Description, fn:codepoints-to-string(10), Content-Location: , $attach/ctx:Content-Location, fn:codepoints-to-string(10), Content-Disposition: , $attach/ctx:Content-Disposition, fn:codepoints-to-string(10), body: , $attach/ctx:body, fn:codepoints-to-string(10)) By the way, you use the fn:codepoints-to-string(10) function to print a newline charac- ter to the console to make the text output more legible.
    • 7974CH07.qxd 3/21/07 4:45 PM Page 172 172 CHAPTER 7 s ADVANCED MESSAGING TOPICS Summary You might have noticed that this is one of the longest chapters in the book, and for good rea- son: ALSB provides you with myriad ways of connecting to and communicating with external systems. It provides an excellent mechanism for performing intelligent routing and data trans- formation. We’ve gone into great detail here and exercised almost every major capability of the service bus. At this point you should have a solid understanding of the primary capabilities of ALSB, and therefore a good idea of where you could use ALSB within your architecture.
    • 7974CH08.qxd 3/28/07 12:43 PM Page 173 CHAPTER 8 Reporting and Monitoring A lthough reporting and monitoring are discrete capabilities of the service bus, they’re closely related. Monitoring is the ability to collect runtime information, while reporting is focused on delivering message data and alerts. There’s also some overlap between monitoring and reporting. For example, you can monitor the number of alerts that have been reported. Monitoring is focused on operational information: the general health of the service bus, how many alerts have been generated and of what type, the status of Service Level Agreements (SLAs), and the gathering of related statistics. A simple way to differentiate between monitor- ing and reporting is this: monitoring is strategic, reporting is tactical. Monitoring Figure 8-1 shows the operational health of your ESB. This is the default view of the service bus console. You can see this on your service bus by pointing your browser at http:// localhost:7001/sbconsole. The Service Summary portlet shows the number and severity of all alerts thrown into the alert log within the last 30 minutes. Because you have no alerts defined yet, your Service Summary should show no alerts at this time. The Server Summary portlet on the right shows the overall health of the servers in your cluster. Because your domain contains only a single server, the entire pie chart represents this single server and should be colored all green to indicate that your single server is running just fine. If you were running a cluster of service bus servers, the pie chart would be divided among the different servers. However, to run a cluster of servers, you must have a cluster license from BEA, and cluster licenses are not freely downloadable. Both the Service Summary and Server Summary portlets show, in addition to their respective pie charts, up to ten of the top alerts and most critical servers. You can click the information in these summaries and drill down into greater detail. This information is pro- vided by the WebLogic Diagnostic Framework. At the bottom of the page is the Alert Summary portlet that shows all the alerts over the interval used by the Service Summary portlet. You can customize this portlet by selecting only the fields you want displayed. By default, all fields are displayed (that is, severity, time stamp, service, and Alert Rule name). We’ll cover alert creation later, in the “Reporting” section. Typically, an operator looks at this window and is aware of a problem when an alert is generated. The window automatically refreshes after every minute, but the interval is config- urable. When an alert is generated, the operator will drill down into details for the service, including detailed performance reporting windows. 173
    • 7974CH08.qxd 3/28/07 12:43 PM Page 174 174 CHAPTER 8 s REPORTING AND MONITORING Figure 8-1. The Dashboard The Temperamental Service As long as all your services are working as expected, the Monitoring portlet is quite boring. To jazz things up a bit, you need to create a web service whose performance you can control pro- grammatically. You also need to create some SLAs so that your web service can violate those agreements, and you need to throw some alerts into the monitoring portlet. To achieve this, you’ll create two web services that contain various operations. These web services will contain a built-in delay mechanism. You need to be able to set the delay value from your client so you can be sure to violate your SLAs at will. Finally, you’ll create a client program that can invoke your web services to help you test various scenarios and to illustrate the monitoring capabili- ties of the service bus. Creating the Business Services Listing 8-1 shows the source code from the business service. The service provides three different operations. Each operation will respond back to the caller within a semi-random timeframe. The time delays are contained in the behaviors array. Compile and deploy this web service before moving to the next step, in the section “Creating the ALSB Project.”
    • 7974CH08.qxd 3/28/07 12:43 PM Page 175 CHAPTER 8 s REPORTING AND MONITORING 175 Listing 8-1. The TemperamentalCreditService package business; import javax.jws.*; import javax.jws.soap.SOAPBinding; import weblogic.jws.WLHttpTransport; import weblogic.jws.WSDL; @WebService(targetNamespace="http://www.alsb.com", serviceName="TemperamentalCreditBS", name="TCrBS") @WLHttpTransport(serviceUri="business/credit", portName="TCrBSSoapPort") @WSDL(exposed=true) @SOAPBinding(parameterStyle=SOAPBinding.ParameterStyle.WRAPPED) public class TemperamentalCredit { /** The amount of time (in seconds) the web service will delay */ private static int DELAYINSECONDS = 0; @WebMethod public String variableCreditCheck(String arg0) { delay(); return arg0 + DELAYINSECONDS; } @WebMethod public String variableOpA(String arg0) { delay(); return arg0 + DELAYINSECONDS; } @WebMethod public String variableOpB(String arg0) { delay(); return arg0 + DELAYINSECONDS; } @WebMethod public String variableOpC(String arg0) { delay(); return arg0 + DELAYINSECONDS; } @WebMethod public String rapidCreditCheck(String arg0) { return arg0; }
    • 7974CH08.qxd 3/28/07 12:43 PM Page 176 176 CHAPTER 8 s REPORTING AND MONITORING @WebMethod public int setDelay(int delayInSeconds) { DELAYINSECONDS = delayInSeconds; return DELAYINSECONDS; } private void delay() { try { Thread.sleep(DELAYINSECONDS * 1000); } catch(InterruptedException ex) { ex.printStackTrace(); } } } The code itself is straightforward. Near the end of the listing is the setDelay() operation. This operation allows the service test client to set the delay (in seconds) that it wants each of the other operations to use. The other operation call the delay() operation, which sleeps the thread for the specified number of seconds. The methods variableCreditCheck(), variableOpA(), variableOpB(), and variableOpC() all delay for whatever amount of time is specified. Only the rapidCreditCheck() operation ignores the delay and returns immediately. We’ll use this operation later to show how you can fail over between services. The second web service is the TemperamentalCustomerService. However, because its implementation is remarkably similar to that of the TemperamentalCreditService, we won’t bother to list it in the text. Creating the ALSB Project Your next step is to create a project named Temperamental in the ALSB console. In this project you need to create WSDL resources, based on the WSDLs of the business services. If you suc- cessfully compiled and deployed the business services in the previous step, you can get the WSDLs of the services at http://localhost:7001/TemperamentalService/business/credit?WSDL and http://localhost:7001/TemperamentalService/business/customer?WSDL Once you have the WSDL resource created, create the business service for the WSDL. Name the business services TemperamentalCreditBS and TemperamentalCustomerBS, respec- tively. Next, create proxy services named TemperamentalCredit and TemperamentalCustomer and set the URLs for the proxy services to /esb/TemperamentalCredit and /esb/ TemperamentalCustomer. Once you create the proxies, you need to edit the Route nodes of
    • 7974CH08.qxd 3/28/07 12:43 PM Page 177 CHAPTER 8 s REPORTING AND MONITORING 177 each message flow. Your proxy services only need to pass the message from the service client through to the business service. Figure 8-2 shows how simple this is. Just check the “Use inbound operation for outbound” checkbox. This allows your proxy to route to the correct operation on the business service, based on the name of the inbound service operation. Figure 8-2. Creating a simple “pass-through” Route node Defining the Service Level Agreements Creating an SLA is almost an art form. Often, you’ll hear people talk about setting SLAs to detect failures. This is certainly a good idea, but if you only create SLAs to detect failures, you’re doing your customers a disservice! We believe it’s even more important to create SLAs that show successful service calls that are approaching their performance limit. For example, if your service must be able to respond to a service request in less than 2 seconds, and nor- mally responds to these requests in 0.8 seconds, you should consider using multiple SLAs: one for the failure condition (that is, > 2 seconds) and others to help alert your operations team when the service time begins to exceed its normal time (that is, > 1 second and possibly > 1.8 seconds). The purpose of the SLA is not only to notify you of a failure, but to act as a tool to help you prevent failures in the first place! SLAs are based on alerts. Alerts are comprised of an Alert Destination and one or more Alert Rules. To help you understand the capabilities of ALSB monitoring, and following the true nature of this book, let’s dive right in and create a few SLAs for our TemperamentalProxy service. Be sure you’ve started a change in the Change Center. Your first action is to create a new resource in your Temperamental project: a Notification type of resource called an Alert Destination. Name this Alert Destination “Console Alert” and fill in the rest of the parameters as shown in Figure 8-3.
    • 7974CH08.qxd 3/28/07 12:43 PM Page 178 178 CHAPTER 8 s REPORTING AND MONITORING Figure 8-3. Creating an Alert Destination As you can see from the Alert Destination creation window, alerts can be sent to the monitoring console, an SNMP trap, a report, an e-mail address, JMS queues, or a combination of any of the aforementioned tools. For our purposes, we need to create a destination that reports solely to the console for now. Click the Save button. With our Alert Destination cre- ated, let’s create some rules for our Temperamental services. Click the Monitoring icon for the proxy service, as shown in Figure 8-4. Figure 8-4. The location of the Monitoring icon
    • 7974CH08.qxd 3/28/07 12:43 PM Page 179 CHAPTER 8 s REPORTING AND MONITORING 179 This brings up the Monitoring Configuration window, as shown in Figure 8-5. Be sure that the checkboxes to Enable Service and Enable Monitoring are checked. For this exercise, go ahead and set the Aggregation Interval to ten minutes and click the Update button. This enables the Add New button at the bottom of the page. The aggregation interval is the moving window of time over which the statistics for the service are aggregated. The window moves forward every minute. Figure 8-5. Enabling monitoring of a service Let’s create an alert. Click the Add New button. Your first alert will be to report on failures of the variableCreditCheck() maximum response time. For this operation, a failure occurs if the maximum response time exceeds 20 seconds. Name the new rule Credit Check Failure and fill in the remainder of the page as shown in Figure 8-6. A few fields here are worthy of special mention. First are the Start Time, End Time, and Rule Expiration Date fields. These fields allow you to specify when you want the rule to apply. For example, you might set the rule to apply from midnight to one minute before mid- night each day until Jan 1, 2100 (effectively forever). You might want to monitor performance for only part of each day as part of your SLA. This would allow you to be concerned with the performance during working hours, or hours that are important to the consumers of your services. Similarly, providing an end date for the monitoring might make sense if your service consumer is only concerned about the performance for a limited number of days (that is, during a sales promotion, or similar promotional activity).
    • 7974CH08.qxd 3/28/07 12:43 PM Page 180 180 CHAPTER 8 s REPORTING AND MONITORING Figure 8-6. Creating an Alert Rule The Rule Enabled field allows you simply to turn the rule on or off, as needed. Because monitoring does consume extra clock cycles on the servers, some customers run with the monitoring turned off for maximum efficiency. Some companies only monitor services when they are first introduced into production. After those new services have run without any prob- lems for a week or so, these companies relax or eliminate their monitoring. There is no right way to monitor your services. It all depends on your specific needs. The Alert Severity field allows you to specify the severity level of the alert. You may choose from Normal, Warning, Minor, Major, Critical, and Fatal. The Alert Frequency field allows you to define when the alert is fired, either Every Time or “Once when Condition is True.” The last field on this window is Stop Processing More Rules. Select Yes if the alert is so bad that you want all further rule processing to stop. Normally you leave this field set to the No position. Tip s Name your alerts carefully. If your alert is specific to an operation in the web service, then we recom- mend that you put the operation name into the name of the alert. However, if the alert applies to the entire service, there’s no need to include the service name in the alert, simply because the table of alerts in the monitoring console will show the name of the service. Click the Next button, and a new window appears that allows you to define the conditions that trigger the alert. These rules are completely customizable. Before you configure your con- ditions, let’s take a walk through the types of conditions you can detect in ALSB (see Table 8-1).
    • 7974CH08.qxd 3/28/07 12:43 PM Page 181 CHAPTER 8 s REPORTING AND MONITORING 181 Table 8-1. Alert Expressions Type Subtype Description Count Success Ratio (%) Test against the percentage of successful service calls and operations. Count Failure Ratio (%) Test against the percentage of failed service calls and operations. Count Message Count Test against the number of messages sent across services and operations. Count Error Count Test against the number of messages that have errors. Count Validation Error Count Test against the number of messages that have validation. Count Operation.<operation name>.Message Count Test against the number of messages routed to a specific operation. Count Operation.<operation name>.Error Count Test against the number of errors generated from a specific operation. Count <flow element>.Message Count Test against the number of messages sent to a specific flow element. Count <flow element>.Error Count Test against the number of errors generated from a specific flow element. Count WSS Error Count Test against the number of Web Service Security–related errors. Minimum Response Time Test against the minimum response. Minimum <flow element>.Response Time Test against the minimum response time for all invocations of this flow element. Minimum Operation.<operation name>.Response Time Test against the minimum response time to a specific operation. Maximum Response Time Test against the maximum response. Maximum <flow element>.Response Time Test against the maximum response time across all invocations of the specified service. Maximum Operation.<operation name>.Response Time Test against the maximum response time to a specific operation. Average Response Time Test against the average response. Continued
    • 7974CH08.qxd 3/28/07 12:43 PM Page 182 182 CHAPTER 8 s REPORTING AND MONITORING Table 8-1. Continued Type Subtype Description Average RouteTo_<service name>.Response Time Test against the average response time of all operations within a specific service. Average RouteTo_<operation name>.Response Time Test against the average response time of a specific operation. Tip s Name your alerts carefully. If your alert is specific to an operation in the web service, then we recom- mend that you put the operation name into the name of the alert. However, if the alert applies to the entire service, there’s no need to include the service name in the alert, simply because the table of alerts in the monitoring console will show the name of the service. A <flow element> is one of the following: • A request pipeline in a Pipeline Pair • A response pipeline in a Pipeline Pair • A Route node As an example, if you’re looking at the Count type for a service that contains a Pipeline Pair named Pipeline1, you would see the following subtypes in the combo box: Pipeline1.request.Error Count Pipeline1.response.Error Count As you can see from Table 8-1, there are a considerable number of conditions against which you can test. Knowing what to test and how to test is simply something that cannot be learned from a book. It’s highly specific to your services and the SLAs that your company wants to meet. Let’s create an Alert Rule. For your first rule, you want to select Maximum from the combo box on the left. In the next combo box, select Operation.variableCreditCheck.Response Time. In the third checkbox, select the “>” (greater than) comparator. Finally, in the textbox, enter 20000 to represent 20 seconds. Your window should look like Figure 8-7. When all this informa- tion is correct, click the Add button to create the simple expression.
    • 7974CH08.qxd 3/28/07 12:43 PM Page 183 CHAPTER 8 s REPORTING AND MONITORING 183 Figure 8-7. Defining conditions for an alert Click the Finish button to tell the service bus that you’re done with that expression. Then click the Save button to save your changes. Congratulations; you’ve just created your first alert. Tip s It’s important to remember that this time, values are all specified in milliseconds. Jeff here—I can’t tell you how many times I’ve had to debug a rule because I did something silly. For example, I’ve accidentally created rules such as Operation.foo.Response Time > 2000 and Operation.foo.Response Time < 3. Obviously, the rule itself is invalid. If you find that some of your alerts aren’t firing off as expected, take a closer look at the time values you’ve specified for each rule. At this point, you have a single alert that will fire upon a fatal condition becoming true. If this happens, your whole pie chart will turn black (the color of a fatal alert). To make things more interesting, you need more alert types to be fired, and that means you need more alerts defined in the system. Your next alert will be to create a warning if the maximum response time is greater than two seconds but less than three seconds. This requires you to create a complex statement. Fortunately, the process for creating a complex statement is simple. Navigate back into the Monitoring Configuration window for the TemperamentalCredit proxy service. Click the Add New button to create a new alert. Name the alert OpA Warn to indi- cate that the nature of the alert is a warning on the OpA operation performance. Be sure to set the severity field to Warning and click the Next button. Now you’re ready to create your complex expression. Complex expressions are merely two or more simple expressions linked together via a conjunction (and/or). Begin by creating two simple expressions. The first expression is to test for the maximum response time of OpA to be > 2000. Click the Add button and then create the second simple expression: max OpA response time < 3001. Click the Add button again so that both simple expressions are now listed in the Complex Expression section of the window, as shown in Figure 8-8.
    • 7974CH08.qxd 3/28/07 12:43 PM Page 184 184 CHAPTER 8 s REPORTING AND MONITORING Figure 8-8. Creating a complex expression for an alert Notice at this point that the Finish button at the bottom of the window is grayed out. That’s because you have two simple expressions defined, but you haven’t connected them with an And or Or conjunction to create a single complex expression. Click the checkboxes next to each expression and then click the And button. Voilà! You’ve created a complex expression. If you look carefully at the complex expression in Figure 8-9, you’ll notice there are paren- theses around the newly created expression. It should also be obvious that you can now add more simple expressions and combine them into complex expressions. You can also combine multiple complex expressions into expressions of even greater complexity. There’s no limit to the complexity of the expressions you can create here. Of course, evaluating expressions takes time, so it’s best to keep your expressions as simple as possible. Figure 8-9. A fully formed complex expression You have several more rules to create. Table 8-2 provides a summary of the rules. You’ve already created the first two rules in the table; you’ll need to add the rest of the rules to keep your monitoring display in sync with the rest of this text.
    • 7974CH08.qxd 3/28/07 12:43 PM Page 185 CHAPTER 8 s REPORTING AND MONITORING 185 Table 8-2. TemperamentalCredit Alert Rules Name Expression Credit Check Failure Maximum Operation.variableCreditCheck.Response Time > 20000 OpA Warn Maximum Operation.OpA.Response Time > 2000 and < 3001 OpB Minor Maximum Operation.OpB.Response Time > 3000 and < 5001 OpC Major Maximum Operation.OpC.Response Time > 5000 and < 10001 Additionally, you need to create two rules for the TemperamentalCustomer service, as shown in Table 8-3. Table 8-3. TemperamentalCustomer Alert Rules Name Expression getVariableCustomer Critical Maximum Operation.getVariableCustomer.Response Time > 10000 and < 20001 OpA Fatal Maximum Operation.OpA.Response Time > 20000 Save all your work so far. It’s time to create your service client to invoke these services and cause your newly created alerts to fire! Coding the Proxy Client Your proxy client (see Listing 8-2) works like most of the POJO clients you’ve created so far. In WebLogic Workshop, open up the TemperamentalServiceClient project. Within the project, open the build.xml Ant script and execute the all target. When that target completes, execute the run.wsclient target to run the LoadTestClient against the proxy services. Listing 8-2. LoadTestClient.java package proxy; import proxy.TemperamentalCustomerBS; public class LoadTestClient { private static final String customerUrl = "http://localhost:7001/esb/TemperamentalCustomer?WSDL"; private static final String creditUrl = "http://localhost:7001/esb/TemperamentalCredit?WSDL"; private static TCrBS creditPort = null; private static TCBS customerPort = null; public static void main(String[] args) { runMonitoringTest(); // Uncomment the following line to run the // failover test in chapter 9 //runServiceFailoverTest(); }
    • 7974CH08.qxd 3/28/07 12:43 PM Page 186 186 CHAPTER 8 s REPORTING AND MONITORING /** * Perform the necessary housekeeping to connect to the * proxy services */ private static void loadServiceReferences() { try { System.out.println("Opening the credit service as " + creditUrl); TemperamentalCreditBS creditService = new TemperamentalCreditBS_Impl(creditUrl); creditPort = creditService.getTCrBSSoapPort(); System.out.println("Opening the customer service as " + customerUrl); TemperamentalCustomerBS customerService = new TemperamentalCustomerBS_Impl(customerUrl); customerPort = customerService.getTCBSSoapPort(); } catch(Exception ex) { ex.printStackTrace(); } } private static void runMonitoringTest() { try { loadServiceReferences(); System.out.println("Invoking the methods..."); // Generate a warning on Op A creditPort.setDelay(2); creditPort.variableOpA("foo"); // Generate a minor alert on Op B creditPort.setDelay(3); creditPort.variableOpB("foo"); // Generate a major alert on Op C creditPort.setDelay(6); creditPort.variableOpC("foo"); // Generates a fatal alert creditPort.setDelay(25); creditPort.variableCreditCheck("William Smith"); // Generate a critical customer alert customerPort.setDelay(12); customerPort.getVariableCustomer(2); // Generate a fatal customer alert customerPort.setDelay(25); customerPort.getVariableCustomer(2); } catch(Exception ex) { ex.printStackTrace(); } }
    • 7974CH08.qxd 3/28/07 12:43 PM Page 187 CHAPTER 8 s REPORTING AND MONITORING 187 private static void runServiceFailoverTest() { try { loadServiceReferences(); // Generate a critical customer alert creditPort.setDelay(60); String creditRating = creditPort.variableCreditCheck("timeout"); System.out.println("Credit rating is: " + creditRating); } catch(Exception ex) { ex.printStackTrace(); } } } The code is simple. The runMonitoringTest() method simply calls each of the proxy serv- ices that you’re monitoring, after setting the appropriate delay value. After you’ve run the LoadTestClient, there will be a number of alerts visible in the Dashboard view of ALSB (see Figure 8-10). Figure 8-10. The Dashboard after running the TemperamentalService tests
    • 7974CH08.qxd 3/28/07 12:43 PM Page 188 188 CHAPTER 8 s REPORTING AND MONITORING Reporting Reporting is a subset of the monitoring function of ALSB. Monitoring is based on the near real-time collection of SLA and Pipeline alerts. Reporting is based on the recording of parts of a message into a database. You can then either view these report entries from the ALSB con- sole or you can access them from an external reporting tool. You can use a Report action in the message flow of any proxy service. You can also embed Report actions in the error handlers associated with pipelines and Route nodes. Both the SLA and Pipeline alert information are aggregated in a database. ALSB provides a reporting user interface to allow you to gather the information you need easily. s Note You can create Report actions based on alerts. However, the default report provider that ships with ALSB ignores these alerts. If you want to use customized reporting alerts, you must create your own report- ing provider. Furthermore, you’ll also need to configure ALSB to use your customized provider. The reporting provider API is a public API supported by BEA. In the Monitoring and Reporting project supplied with this book, there’s a Report Proxy proxy service that illustrates how you use the Report action. There are two main sections of a Report action. The first is the body of the report, which contains the message data that you wish to record. The second section is for the keys by which you wish to search for the report record in the database. You can define as many keys as you would like for the message. As a best practice, we recommend that you store the entire message as the <Expression> of the report. That way you’ll have all the information that was originally available when the Report action was triggered. However, if your message is very large, and all the data is stored elsewhere in your enterprise, you might wish to store only the ID in the <Expression> field. For example, if you’re referring to a customer order, it’s likely that you’ll have the entire order stored in an order database somewhere in your enterprise. In such a case, we would recom- mend storing only the order ID in the Report action to save space in the reporting database. Tip s Creating more than one key within the Report action might not be obvious to you. To create addi- tional keys, simply left-click the key icon, then select Add a Key from the pop-up menu. The report keys are used to search for report expressions. The keys are treated as simple text, so storing a date won’t allow you to search by a date range. However, each report event is automatically assigned a date and time stamp, so you can search based on the time of the report event. Most often, you’ll create key values based on the content of the message you’re reporting. In your ReportProxy service, the Report action records both the id and name values of the <bar> section of the message, as shown in Figure 8-11.
    • 7974CH08.qxd 3/28/07 12:43 PM Page 189 CHAPTER 8 s REPORTING AND MONITORING 189 Figure 8-11. An example of the Report action We recommend that you try the ReportProxy service with the XML in Listing 8-3. Try vary- ing the data values within the XML and using the test console to generate your own reporting data. That way you’ll have some data to view when you get to the next section of this chapter. Listing 8-3. Sample XML File for Generating Report Events <foo> <bar> <id>2</id> <name>name2</name> <id>3</id> <name>name3</name> </bar> </foo> Viewing Report Information You view report information from the Operations portion of the ALSB console. Within the Reporting heading, click the Message Reports link to see the table of the most recent reports. You can quickly sort the information on this table by clicking the table headers. Clicking the same header multiple times toggles the sort order between ascending and descending. If you’re working with a large number of reporting events, simply sorting the records won’t be sufficient. You can also select specific report records by clicking the Filter link near the top right side of the Summary of Message Reports window (see Figure 8-12). You can use the Filter to select report records based on their database timestamp, either by a specific date range, or by selecting the most recent records within a timeframe that you can specify. Additionally, you can search for reports based on the name of the inbound service. The inbound service name is the combination of the project name and the proxy service name, separated by a slash (“/”) character. The Error Code is automatically assigned to the reporting event (if the Report action was created in an error handler), inside the pipeline. You don’t need to take any explicit action to see this value. The Report Index field allows you to search the keys that you’ve created with your Report actions. This provides a simple text-based search within the key data. There are no compari- son operators for the Report Index expression. The text you enter is treated as if it had wild cards on both sides. For example, using Figure 8-12 as a reference, if you entered a value of name for the report index, all six records would be returned as matches. The search function is case sensitive, so a search for myid would return zero matches, whereas a search for myID would return four matches.
    • 7974CH08.qxd 3/28/07 12:43 PM Page 190 190 CHAPTER 8 s REPORTING AND MONITORING Figure 8-12. The report filter If you click the link for the report in the Report Index field, it will bring up the View Message Detail window (see Figure 8-13). This window is rich in detail, allowing you to see at a glance most of the information you might be interested in. At the bottom of this window is a Detail link. Clicking this link brings up another browser window that contains the <Expression> of the Report action. Most of Figure 8-13 is self-explanatory. We want to add a little detail here for the fields that are blank in the current figure. The Outbound Service section is only filled with data if the Report action is contained within a Route node. It’s similar in structure to the Inbound Service section above it. The Fault section is only filled with data if the Report action is included inside an error handler, whether it is a pipeline error handler or a Route node error handler. This is often a better approach to debugging errors than using the Log action, especially if you’re looking for problems at runtime when the proxy service is in a production environment.
    • 7974CH08.qxd 3/28/07 12:43 PM Page 191 CHAPTER 8 s REPORTING AND MONITORING 191 Figure 8-13. The View Message Detail window for a report event Purging Report Information Information is like fruit—it ages quickly. The Purge Messages link in the Operations ® Reporting section of the ALSB console provides a simple user interface for purging messages. You can either purge all messages in the reporting database or you can purge messages within a spe- cific date and time range, as shown in Figure 8-14.
    • 7974CH08.qxd 3/28/07 12:43 PM Page 192 192 CHAPTER 8 s REPORTING AND MONITORING Figure 8-14. The interface for purging report messages Purging messages occasionally helps to keep your reporting data store performing at an optimal speed. It also makes managing the report records much more manageable. Reporting Providers A reporting provider provides both transport and storage for reporting events. If you deploy ALSB in a cluster, then all the managed servers within the domain will use the reporting provider to aggregate the reporting data. By default, ALSB comes preconfigured with a JMS reporting provider. The JMS reporting provider is used because it first queues the reporting record, and then dequeues and writes the records to the database. This asynchronous design improves the performance of the reporting modules within ALSB. The name of the JMS server is wlsbJMSServer, and the name of the data store is wlsbjmsrpDataStore. You can find both these artifacts using the traditional WLS console. You can change the data store associated with the JMS reporting provider. In a production environment, you’ll probably want the report messages stored in a production-quality data- base, such as Oracle, Microsoft SQL Server, or MySQL. To do this, you can use the database scripts stored in the <%BEA_HOME%>weblogic92integrationdbscripts[database] direc- tory. There’s no script for MySQL, PostgreSQL, or some of the other unsupported open source databases, but if you examine the scripts for the supported databases, creating a script spe- cific for the database you wish to use should be fairly simple. Listing 8-4 shows the basic table structures used for ALSB reporting. The MSG_GUID field is the primary key for the WLI_QS_REPORT_ATTRIBUTE table and is the foreign key for the WLI_QS_REPORT_DATA table. With this knowledge, you can create custom reports in external reporting tools such as Crystal Reports, or execute your own SQL statements directly against the reporting tables. Listing 8-4. The Table Definitions for the Reporting Events CREATE TABLE WLI_QS_REPORT_ATTRIBUTE ( MSG_GUID VARCHAR(64) NOT NULL, DB_TIMESTAMP DATETIME DEFAULT CURRENT_¯ TIMESTAMP NOT NULL,
    • 7974CH08.qxd 3/28/07 12:43 PM Page 193 CHAPTER 8 s REPORTING AND MONITORING 193 LOCALHOST_TIMESTAMP DATETIME NOT NULL, HOST_NAME VARCHAR(50) NOT NULL, STATE VARCHAR(8) NOT NULL, NODE VARCHAR(128) NULL, PIPELINE_NAME VARCHAR(128) NULL, STAGE_NAME VARCHAR(128) NULL, INBOUND_SERVICE_NAME VARCHAR(256) NOT NULL, INBOUND_SERVICE_URI VARCHAR(128) NOT NULL, INBOUND_OPERATION VARCHAR(64) NULL, OUTBOUND_SERVICE_NAME VARCHAR(256) NULL, OUTBOUND_SERVICE_URI VARCHAR(256) NULL, OUTBOUND_OPERATION VARCHAR(64) NULL, MSG_LABELS VARCHAR(512) NULL, ERROR_CODE VARCHAR(64) NULL, ERROR_REASON VARCHAR(1024) NULL, ERROR_DETAILS VARCHAR(2048) NULL, CONSTRAINT PK_WLI_QS_REPORT_ATTRIBUTE PRIMARY KEY(MSG_GUID) ) -- WLI_QS_REPORT_DATA CREATE TABLE WLI_QS_REPORT_DATA( MSG_GUID VARCHAR(64) NOT NULL, DATA_TYPE SMALLINT NULL, ENCODING VARCHAR(24) NULL, DATA_VALUE IMAGE NULL, CONSTRAINT FK_WLI_QS_REPORT_DATA FOREIGN KEY(MSG_GUID) REFERENCES WLI_QS_REPORT_ATTRIBUTE(MSG_GUID) ON DELETE CASCADE ) Finally, it’s possible to run ALSB without a reporting provider of any kind. You can still use the Report action in your message flows, but no data will be written. The only real reason to stop and/or remove a reporting provider is to remove the only database dependency com- monly used by ALSB. For most customers, this database dependency is not an issue, but if you want to run ALSB without any database connections, you’ll need to stop the reporting provider and possibly remove it entirely from the supporting WLS configuration. To stop a reporting provider, you use the WebLogic console. Click the Deployments link in the left navigation bar of the console. Navigate through the list of deployed applications until you come to the JMS Reporting Provider (or the specific reporting provider you’re using, if you aren’t using the default JMS Reporting Provider). Click the checkbox next to the JMS Reporting Provider, then click the Stop button. Similarly, if you wish to undeploy the JMS Reporting Provider, simply click the Lock & Edit button on the console’s Change Center, click the check- box next to the JMS Reporting Provider, and then click the Delete button to remove it completely from the server or cluster.
    • 7974CH08.qxd 3/28/07 12:43 PM Page 194 194 CHAPTER 8 s REPORTING AND MONITORING Summary In this chapter, you learned how to create alerts in support of SLAs. You learned how to create complex rules to fire those alerts and how to use the Dashboard to monitor the alerts and gather information about the state of your ALSB deployments. Additionally, you learned how to use the built-in reporting tool to record events within a message flow, and even how you can access that raw reporting data from an external tool. What strikes us most about this chapter is the simplicity of the interfaces, especially when juxtaposed against the power of the monitoring and reporting tools. These tools really “open up” the service bus in a way that makes it a valuable tool for your operation support personnel and developers alike.
    • 7974CH09.qxd 3/29/07 1:04 PM Page 195 CHAPTER 9 Security Models and Service Bus U sing SOA-enabling applications and creating fine-grained services significantly increases the number of services for you to manage. Composite applications and services consume these additional services, which are distributed across the enterprise for orchestration or to provide high-level services or functionality to meet IT and business needs. The permissions to access to these services must conform to the security policies of the enterprise. If services are not secure, discerning legitimate requests from rogue access attempts is a daunting task. Unauthorized access to a service may result in degraded service performance or even in unavailability. Many factors drive security requirements in the SOA world. Regulatory compliance needs force policies on businesses and IT departments. Internal policies that describe how to access services and what data should be protected are quite common within enterprise environ- ments. Another important issue driving security requirements is the ability to securely interoperate with other systems and services. New standards, such as Web Services Security, promote secure interoperability among disparate and distributed service implementations. Business needs, such as single sign-on, further underscore the need for policy-driven interop- erable security in SOA-enabled enterprise systems. This chapter is intended for architects, developers, administrators, and SOA analysts who are interested in using a service bus as an intermediary to secure a service provider, enforce security policies, and provide a single security model to the service consumers while orches- trating services with multiple security models. Security Paradigms with SOA Challenges As an intermediary, ALSB is ideally suited for defining, configuring, and enforcing security policies and thus securing existing enterprise services without having to rewrite them when business requirements change. The service bus can secure access to a backend application or services and provide interoperability and security brokering capabilities that are truly configu- ration driven. Table 9-1 shows some common security scenarios in enterprise systems and the chal- lenges associated with adopting SOA within those scenarios. We will discuss these scenarios in greater detail in the remainder of this chapter. 195
    • 7974CH09.qxd 3/29/07 1:04 PM Page 196 196 CHAPTER 9 s SECURITY MODELS AND SERVICE BUS Table 9-1. Scenarios and Challenges with Security in Adopting SOA Scenario Challenge Identity management How can you access a secured resource, such as a database or file system, or a legacy backend application that requires a simple username/password to allow access? Privacy protection of messages How can you ensure that only the right service provider can and their payloads access the message? Authenticity How can you know that the message is authentic and has not been issued by someone not authorized to access the service provider? Integrity How can you know that the message and its payload have not been tampered with during transmission? Security enforcement How can you ensure, or apply and enforce, security rules and policies to restrict access to a resource, application, or service that is not secure? Security interoperability How can you enforce single security standards like Web Service Security, SAML, SSL, digital signatures, encryption, and so forth? In a metadata-driven architecture, ALSB can be implemented to dynamically evaluate and enforce security policies without coding, allowing you to evolve and customize your secu- rity enforcement runtimes and architectures. The following sections explain the most common types of security schemes or policies that can be applied by an SOA architect who’s defining an SOA solution and architecture. Transport-Level Security Transport-level security refers to securing transports used during communication between a client and an application or through an intermediary such as ALSB. This includes the ability to define policies, such as requiring clients to use SSL for privacy and authentication purposes when communicating over HTTP Other transports may specify different methods of securing . communications, such as use of SFTP a secure-shell-based (SSH-based) FTP protocol that is , quite popular in SOA and has significant advantages over the relatively insecure username- and password-based FTP . Figure 9-1 shows ALSB acting as an active or passive intermediary to support the enforce- ment of security at the transport level. Let’s take a look at a typical example for securing inbound communications to a proxy service. A proxy service can be configured to use HTTPS as transport for communication and would enforce authentication of clients against a set of users, groups, or roles configured as a part of Access Control List (ACL) policy for the proxy service by simply including it as part of the security configuration in ALSB. As for the backend application, when the business service is created, ALSB will automatically honor the security settings and take appropriate action while communicating with the backend at runtime.
    • 7974CH09.qxd 3/29/07 1:04 PM Page 197 CHAPTER 9 s SECURITY MODELS AND SERVICE BUS 197 ACTIVE VS. PASSIVE INTERMEDIARIES We commonly use the terms active intermediary and passive intermediary when discussing security scenar- ios using ALSB. An active intermediary refers to the situation where ALSB enforces the web service security policy. ALSB acts as a passive intermediary whenever it does not enforce the web service security policy, and instead, the security policy is enforced by the service endpoint to which ALSB routes the message. Figure 9-1. ALSB as an active or passive security intermediary Message-Level Security Message-level security refers to the efforts to secure the payload of a message itself. This is a particularly attractive option if you want to define confidentiality and integrity policies in a manner that is neutral to transports. By removing the dependency on transports for security, you can make security policy and its implementation easier and more portable. This approach is useful in SOA, since it facilitates interoperability and reuse of services that require those policies. Web Service Security specifications define the types of message-level security options that are available currently for an SOA architect. Ad-Hoc, Custom, Token-Based Security Ad-hoc, custom, token-based security refers to the capability in the bus to recognize and assert identity based on a field in the transport header (HTTP/HTTPS), SOAP header (Web Services), or an XML payload (XML) that contains a user-defined custom token. There is also an option to declare and configure arbitrary fields in the SOAP header or an XML payload as a username/password pair. Such capability makes ALSB interoperate with a broad range of legacy integration applications and services that are not capable of Web Service Security. Figure 9-2 shows support in ALSB for Web Service Security profiles for an active interme- diary case. For example, a proxy service can be enabled to enforce a WS-Policy statement such as to use a Web Service Security Username Token profile when clients connect to the proxy service. At the time of proxy configuration, ALSB will automatically recognize the supported WS-Policies shown in Figure 9-2 when referenced in the WSDL for the proxy, thereby automat- ing the process of enabling message-level security and making it extremely simple for the designer. The ALSB runtime engine will expect a valid security header with a username and password that belong to an ACL policy configured for this proxy service.
    • 7974CH09.qxd 3/29/07 1:04 PM Page 198 198 CHAPTER 9 s SECURITY MODELS AND SERVICE BUS Figure 9-2. Using ALSB as an active intermediary ALSB Security Model In this section, we will elaborate on the security model for ALSB. All security in ALSB is config- urable and policy driven. Proxy service security can be configured independently of the business service endpoints. At runtime, the bus automatically mediates and enforces security as prescribed by the policy attached to the proxy service (inbound) and the business service being accessed by the proxy at runtime (outbound).This makes it particularly attractive for use as a security intermediary that can operate in either Active or Passive (pass-through) mode with built-in configuration-driven options for overriding default security settings dynamically. The declarative nature of security in ALSB makes implementing and modifying various security set ups a breeze. Several general rules to use when configuring and enabling security in ALSB follow: • Define a policy for securing the proxy. The various security schemes are combinations of transport- and message-level security. • Configure the security providers that will be used for enforcing security policies attached to the proxy service. • Set up the bus to propagate identity to the business service. Since the outbound invocations from the bus automatically conform to the security requirements of the business service endpoints, let’s focus on security strategies for inbound cases and the options for propagation of identity to bridge inbound/outbound security paradigms. Inbound Security in ALSB The default setting in ALSB is such that any client can access the proxy service. To restrict access to the proxy, there are authentication and authorization policies that must be config- ured. The access to a proxy service can be secured by the following methods: • Basic authentication at the transport level provides the simplest authentication and authorization mechanism—a client is required to pass credentials as part of the transport headers as defined by the protocol for the transport.
    • 7974CH09.qxd 3/29/07 1:04 PM Page 199 CHAPTER 9 s SECURITY MODELS AND SERVICE BUS 199 • Basic authentication at the message level, also known as Web Services Security User- name Token Profile authentication, requires a client to send the credentials as SOAP headers rather than in transport headers. The obvious advantages of such message- level security are that it is standards based and agnostic to the underlying transport protocol. • Public Key Infrastructure (PKI) authentication at the transport or message level is another way to secure access to a service by using a certificate for establishing authen- ticity. PKI-based authentication at the transport level uses SSL authentication. At the message level, it uses the Web Service X.509 profile. • Web Services Security authentication is available using the Security Assertion Markup Language (SAML) profile for end-to-end web-services–based orchestrations among clients, ALSB, and web-services–based business services. • ALSB supports access to proxy services from nonstandard legacy clients, generic HTTP clients, or XML clients. In these cases, the ad hoc custom token or user/password pair can be declared in the proxy service configuration. The token or credential will be extracted by the bus and used for authentication, authorization, and identity propagation. As we mentioned earlier, ALSB has a declarative security model that extends to creden- tials and certificates mapped through references to a credential provider. There are two types of credential providers: • Proxy Service Provider: This credential provider is an artifact that refers to a set of cre- dentials that can be used while enforcing security policies on the proxy, for example, looking up a certificate from the proxy provider to be used for Web Service Security decryption. • Service Account: This credential provider is an artifact that holds reference to credentials for an outbound service that is used by a proxy service at runtime, such as a username/ password pair for accessing a data service. Credential Mapping will be needed to prop- agate the right credential when a proxy invokes a business service (Credential Mapping refers to the situation where the client of the proxy service is mapped to a user ID/ password to be used to invoke the business service that the proxy service is routing to). The types of credentials that can be mapped for a business service follow: • Fixed: A static credential is mapped to the service account and used when invoking the business service to which it is attached. This option works well for global serv- ices such as accessing a file system or a database for lookup. • Pass-through: A username/password pair from inbound headers is directly passed to business service as headers. This option works well when the ALSB is being used as a pass through to loosely couple a backend service. This is a one-to-one map- ping that uses HTTP basic authentication headers or SOAP headers when using a Web Service Security Username Token profile. • Mapped: A mapping is configured in the service account that returns an appropri- ate username/password pair based on the client of the proxy service that is employed by the proxy service for authenticating to the business service.
    • 7974CH09.qxd 3/29/07 1:04 PM Page 200 200 CHAPTER 9 s SECURITY MODELS AND SERVICE BUS Identity Propagation in ALSB Security mediation in ALSB from inbound request to outbound request requires identity to be propagated from the service consumer to the proxy to the backend business services. ALSB can automatically propagate the identity to the business service depending on the security policy for that service. The identity scheme to be propagated can be declared while configur- ing the proxy and business services. The identity propagation options are as follows: • Propagate the username/password pair using credential mapping for transport and message-level security on the outbound message. The inbound security could be any type listed in the “Inbound Security in ALSB” section of this chapter. • Propagate the username/password pair to the outbound request using pass-through credential mapping when inbound security is configured to be transport-level or message-level for legacy cases. The ALSB may or may not handle authentication. • When the business service requires an SAML security token, ALSB can act as an active intermediary to propagate identity by generating a SAML token based on any inbound authentication security policy. • Propagation of message payload and identity to outbound request can also be accom- plished by using a Web Service Security policy on the inbound request but configuring ALSB as a passive or pass-through intermediary. The intermediary does not authenti- cate the client. • When inbound proxy service is secured by authentication policy at both transport level and message level, the identity propagated to the outbound service is the message-level identity. SSL Authentication Using only basic authentication at the transport level is weak security. Typically, it is backed by SSL encryption or even replaced by SSL-based authentication as a strategy to provide secure access to an ALSB proxy. There are two types of authentication mechanisms using SSL certifi- cates: one-way and two-way SSL authentication. One-way SSL authentication refers to a mechanism where the server (ALSB) is required to present a digital certificate to the client to prove its identity. The client performs checks like the following ones to validate the digital certificate: • Is the certificate is trusted and issued by the client’s trusted certificate authority? • Is the validity certificate expired? • Does the certificate subject’s common name (CN) value match the hostname to which it is connecting? Two-way SSL authentication refers to an authentication mechanism where both the client and the server must present digital certificates before the SSL connection is established. In this case, the web server itself will validate the client’s digital certificate in addition to the client’s validation in the one-way case. This is a very useful scheme when one would like to restrict the access to a proxy to only trusted clients.
    • 7974CH09.qxd 3/29/07 1:04 PM Page 201 CHAPTER 9 s SECURITY MODELS AND SERVICE BUS 201 How do these SSL options affect the ALSB proxy security configuration? Well, first, there is a single web server in case of ALSB. Therefore, only one SSL certificate is available, and it’s shared by all proxies. Another way the configuration is affected is in the need to use proxy service providers to store the client certificate used to invoke a business service. An underlying application server feature called Certificate Lookup and Validation (CLV) is also used to validate X.509 digital certificate chains for inbound two-way SSL, outbound SSL, and Web Services Security profiles. Digital Signatures and Encryption So far, we have discussed mechanisms for securing access to the proxy service in ALSB. In addition to that, you can secure the payload itself to prevent tampering with a message pay- load while data is in transit. Encryption provides privacy protection on the messages and communication. At the transport level, SSL will encrypt every piece of data that is transmitted between a client and ALSB proxy. At message-level, using Web Services Security standards, one can provide an encryption policy to securely encrypt the message payload in part of or the whole SOAP envelope. Using a digital signature provides capability to enforce nonrepudiation of both the origin and receipt of messages. This is a message-level security policy and can be applied to part of the payload or the entire SOAP envelope. ALSB provides the following web service policies out of the box: • Auth.xml: Contains the default authentication policy to be used by web service clients to connect to an ALSB proxy service that is enabled using this policy • Encrypt.xml: Contains the default policy to be used by web service clients to encrypt the SOAP body using 3DES-CBC when connecting to an ALSB proxy service that is enabled using this policy • Sign.xml: Contains the default policy to be used by web service clients to sign the SOAP body using RSA-SHA-1 when connecting to an ALSB proxy service that is enabled using this policy sNote RSA is an encryption and authentication system that uses an algorithm created in 1977. The RSA is an abbreviation of the last names of the authors of the algorithm: Ron Rivest, Adi Shamir, and Leonard Adleman. The SHA in SHA-1 stands for “Secure Hash Algorithm.” Using ALSB Security In the previous section, we described the security model for ALSB and explained the basic security functionality in ALSB with a brief overview of how it allows policy-based security to be enforced on inbound clients and outbound services. We also outlined various typical iden- tity propagation scenarios that are supported by ALSB.
    • 7974CH09.qxd 3/29/07 1:04 PM Page 202 202 CHAPTER 9 s SECURITY MODELS AND SERVICE BUS In this section, we will explain how to configure ALSB to enable end-to-end security. There are certain combinations of inbound and outbound services that occur commonly. We will provide a recipe to configure ALSB for such scenarios. You might very well consider these scenarios as patterns or best practices in ALSB. Let’s look at an example scenario that involves a web service username token authentica- tion in ALSB. In this case, message-level security is being used. Listing 9-1 shows a snippet of the Web Service Policy representing the web service username token authentication. Listing 9-1. A Sample WS-Policy for Web Service Username Token Authentication <wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wssp="http://www.bea.com/wls90/security/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-¯ wssecurity-utility-1.0.xsd" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-¯ wssecurity-secext-1.0.xsd" xmlns:m="http://example.org" wsu:Id="encrypt-custom-body-element-and-username-token"> <!-- Require messages to provide a user name and password token for authentication --> <wssp:Identity> <wssp:SupportedTokens> <wssp:SecurityToken IncludeInMessage="true" TokenType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-¯ wss-username-token-profile-1.0#UsernameToken"> <wssp:UsePassword Type="http://docs.oasis-open.org/wss/¯ 2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"/> </wssp:SecurityToken> </wssp:SupportedTokens> </wssp:Identity> </wsp:Policy> Figure 9-3 shows a service consumer invoking a proxy that is secured by a Web Service Security username token authentication policy while the backend application uses a basic authentication policy. Figure 9-3. An example of using username token authentication
    • 7974CH09.qxd 3/29/07 1:04 PM Page 203 CHAPTER 9 s SECURITY MODELS AND SERVICE BUS 203 The steps in invoking the proxy shown in Figure 9-3 follow: 1. A client sends a request to a proxy service. The request contains the username and password credentials. Clients can send other types of tokens for authentication, such as X.509 certificates. If a client sends a certificate token, you must configure an identity assertion provider to map the identity in the token to an ALSB security context. 2. The proxy service asks the domain’s authentication provider if the user exists in its provider store. If the user exists, the proxy service asks the domain’s authorization provider to evaluate the access control policy that you have configured for the proxy service. 3. If the proxy service’s access control policy allows the user access, the proxy service processes the message. As part of generating its outbound request to a business serv- ice, the proxy service asks the business service to supply the username and password that the business service requires. 4. The business service asks its service account for the credentials. Depending on how the service account is configured, it does one of the following: a. Requires the proxy service to encode a specific (static) username and password b. Requires the proxy service to pass along the username and password that the client supplied c. Maps the username that was returned from the authentication provider to some other (remote) username, and requires the proxy service to encode the remote username 5. The proxy service sends its outbound request with the username and password that were returned from the service account. Now that you’ve seen how the flow of Web Service Security authentication works in ALSB, let’s look at other recommendations. Recommendations The challenge with securing an SOA is that most services and applications aren’t stand-alone; they are already connected—with or without security. The challenge is to introduce SOA or service-enable service endpoints without having to write extensive code, incur additional maintenance costs, or leave loopholes that compromise sensitive data. Some services and applications provide their own preferred security protocol. Leveraging these in an SOA is a challenge. For example, one application’s security protocol may differ from the security protocol of the application with which it is communicating. ALSB is one of the simplest interoperable, easy-to-use, configuration-based products to help address security concerns at all levels. Policy-based enforcement allows access to services, and ALSB can act as an intermediary and a single point of enforcement for policies that can be centrally governed. The mainte- nance of security policies becomes much more manageable as a result.
    • 7974CH09.qxd 3/29/07 1:04 PM Page 204 204 CHAPTER 9 s SECURITY MODELS AND SERVICE BUS ALSB provides a configuration-driven approach that bridges multiple security protocols with minimal coding. It also provide flexible authentication for transports, including username/ password basic authentication in transport headers and certificate-based authentication. Message-level encryption can also be added, including the use of security credentials in SOAP headers. SSL or HTTP can provide encryption for confidentiality. Creating secure service-enabled processes for integration using ALSB as a central security bridge makes it easy to secure new and existing services and to manage those services on an ongoing basis. Summary Security is a broad topic and demands a formal strategy for proper implementation. The com- mon patterns for using ALSB as a security intermediary are using ALSB for proxy inbound security enforcement and propagating user identity to the business service endpoint. In this chapter, we covered the basics of security as they apply to ALSB to help you understand how to plan and implement ALSB security as part of your overall security strategy.
    • 7974CH10.qxd 4/2/07 9:53 PM Page 205 CHAPTER 10 Planning Your Service Landscape D esigning an enterprise SOA is a huge task. Although tools that help make creating and managing your SOA easier are advancing at a rapid pace, these tools cannot provide a substi- tute for the amount of human effort required to design the SOA itself. Many of the customers we meet are eager to start designing their SOA but almost immediately get “lost” in the details. Determining where to start can be a daunting task in itself. To help with this, we have developed a service “GPS” (Global Positioning System) to help architects, service designers, and developers to get their bearings quickly within their SOA for those moments when they start to get the feeling of being lost in the details. What follows in this chapter is a set of principles and a methodology for successfully designing your SOA. In the real world, a GPS shows your location by providing you with latitude and longitude coordinates. If you understand the latitude and longitude system, and have a map that includes the surface of the earth that incorporates the coordinates, you get a pretty good idea of your location. The more exact the coordinate and the more detailed your map, then the greater the accuracy of your understanding of your position. The problem with designing your SOA is that you have neither a map nor a coordinate system, making an SOA GPS impossible. In this chapter, we’ll create a coordinate system, and we’ll then teach you how to map your enterprise services. With some effort, you’ll be able to populate your map fully, and using the SOA Coordinate System, you’ll never feel “lost” again. Let’s begin by creating the coordinate system. The SOA Coordinate System Coordinates are just a union of one-dimensional scales. For GPS systems, coordinates use the latitude scale (how far to the north or south you are) and the longitude scale (how far to the east or west you are) to determine your position on the surface of the earth. You need to create a set of scales. Once you have your scales, you can join them together to create your SOA Coordinate System. From there, you’ll create your Enterprise Service Map. The Software Abstraction Scale The first scale is that of abstraction. Architects and developers know that abstraction is a use- ful tool, and we don’t dispute that. However, not everything needs to be highly abstract. Some 205
    • 7974CH10.qxd 4/2/07 9:53 PM Page 206 206 CHAPTER 10 I PLANNING YOUR SERVICE LANDSCAPE things must be literal and concrete for there to be any possibility of higher-level abstractions. We work with a natural scale of abstraction as software developers every day. The Software Abstraction Scale (see Figure 10-1) begins at the bottom with artifacts that have very little abstraction. For example, a database implementation is about as concrete or “physical” as things get in the software world. We don’t mean to imply that there’s no room for abstraction and good design within a database schema; certainly database design is vitally important. The point we make is that in the grand view of enterprise software development, databases are the least abstract elements. Similarly, physical devices, such as routers, modems, and switches are also at the bottom of this scale. Figure 10-1. Software Abstraction Scale Moving up a level on our Abstraction Scale are low-level software components, such as device drivers and database drivers. These components provide a layer of abstraction above the devices they represent. This is an expression of the Façade design pattern, where the com- plexity and interdependencies of lower-level components are hidden. This is the fundamental pattern of abstraction, and we’ll see it repeated in each successive layer. Next we see object-relational mapping tools and frameworks. This includes software packages such as Hibernate (http://www.hibernate.org), Kodo (http://www.bea.com/kodo), and Cayenne (http://incubator.apache.org/cayenne). These tools make it easy to persist the object data within an object-oriented application. Software applications, in turn, provide a greater level of abstraction, and are often the lowest level of interaction where a non-software developer becomes involved. For most of the history of software, applications represented the apex of abstraction.
    • 7974CH10.qxd 4/2/07 9:53 PM Page 207 CHAPTER 10 I PLANNING YOUR SERVICE LANDSCAPE 207 Service orientation began quietly, many years ago, under the name of “application inte- gration.” As enterprises became more adept at creating software applications to automate their processes, there arose a need to have these applications share information with one another. Application developers began to create public Application Programming Interfaces (APIs) to provide a controlled way to allow other applications to make use of their functionality. Looking back, we can see that these APIs were really the first step toward service orientation. Today we create these APIs as web services; hence the name “Application Services” in the figure. In modern IT shops, the number of applications range from the dozens to many hun- dreds. Although each application might have distinctive features and capabilities, there always emerges a natural “clustering” of applications, based on their business function. An order management application is often tightly integrated with other applications that play supporting roles in the order fulfillment process. These clusters of applications represent the functionality required by the “business domain” they inhabit. We’ll talk more about business domains later on in this chapter. For now, think of a business domain as a higher level of abstraction above application services. Finally, the highest level of abstraction is the Enterprise Service Layer (ESL). We think of this layer as the API for the entire enterprise. Services at this level of abstraction don’t recog- nize the arbitrary boundaries of databases, applications, or business domains. These services can go anywhere and do anything (by making use of lower levels of abstraction). However, services at the top level of the Abstraction Scale must not know the implementation details of the hundreds of components that live further down the Abstraction Scale. Enterprise services “paint with a broad brush,” issuing commands to the enterprise and expecting timely results. Now you know what the first dimension of our SOA GPS is. You must understand several principles to make use of this scale. The first principle is that of knowledge dependency; each layer on the scale “knows” about the layer beneath it. A JDBC driver “knows” (that is, is config- ured to talk to) about an instance of a database. Databases do not “know” about JDBC drivers. The dependency is directional. The second principle is that of diminishing detail. As you travel up the scale of dependency, the amount of technical implementation detail contained in each higher layer must be less than the layers below it. This doesn’t imply that there’s less information at the higher levels of abstraction. It simply means that the amount of “low-level” technical information decreases rapidly. Components at the bottom of the scale contain a tremendous amount of technical and implementation detail because they’re doing the real work. Components at the bottom know exactly what to do to make their little piece of the enterprise function correctly. Components at the top of the scale know what to do (that is, process an order), but have no detailed knowledge of how that work gets done. A byproduct of these principles is the location and density of the resulting services in your SOA. Figure 10-2 represents this graphically. At the lower levels of abstraction, you’ll find that you’re creating exponentially more services than you are near the top of the Abstraction Scale. This is as it should be. If your ESL publishes 100 services while the sum total of all your appli- cation services is also 100, then you have provided no abstraction at all! However, if your ESL publishes one to ten services for every hundred services in your Application Service Layer (ASL), then you’re likely providing a good amount of abstraction. These numbers aren’t hard and fast, but are representative of the orders of magnitude that naturally occur with SOA.
    • 7974CH10.qxd 4/2/07 9:53 PM Page 208 208 CHAPTER 10 I PLANNING YOUR SERVICE LANDSCAPE Figure 10-2. Service population If you don’t respect (and by respect we mean design and code) with these two principles in mind, you’ll effectively destroy your software Abstraction Scale and your SOA. We won’t ask you to accept these numbers blindly. Let’s double-check these assumptions against current, successful models to see how well they match up. Let’s begin with a technol- ogy we all know and love: television (see Figure 10-3). There’s a tremendous amount of complexity and detail in any television set. The vast majority of the details involved in presenting you—the TV viewer—with the images and sounds on your set are hidden from you. You use a remote to send commands to your TV. You can perform three basic functions with your television: change the channel, adjust the vol- ume, and turn the TV set on and off. That’s really it. If you examine all those buttons on your remote, those are the services that your remote provides. Those services, in turn, are handled through a motherboard on your TV set. The mother- board aggregates circuit boards (many of them integrated so they physically appear as part of the motherboard) that perform finer-grained functions. Those circuit boards are comprised of hundreds of integrated circuits, each of which is comprised of millions of individual transis- tors. This is abstraction at its best. Abstraction isn’t a technology-specific concept. We see it in human organizations also. Even the largest companies on the planet are organized into hierarchies (see Figure 10-4).
    • 7974CH10.qxd 4/2/07 9:53 PM Page 209 CHAPTER 10 I PLANNING YOUR SERVICE LANDSCAPE 209 Figure 10-3. Television abstraction model Figure 10-4. Organizational abstraction model
    • 7974CH10.qxd 4/2/07 9:53 PM Page 210 210 CHAPTER 10 I PLANNING YOUR SERVICE LANDSCAPE Again, we see abstraction in our daily lives. The CEO cannot possibly know the details that each worker must know for that worker to be effective at his job. In fact, even the worker’s manager cannot know all the details that the worker performs on a daily basis. The important thing to remember here is that this is a good thing (though you might question that on your next annual review). As you move down the Abstraction Scale, the level of detail and the amount of work increases dramatically. This is a natural organizational principle. As archi- tects, service designers, and service developers, we must embrace this principle to design and manage our enterprise architecture successfully. The Service Domain Scale Our second scale is that of service domains (see Figure 10-5). This scale categorizes the vari- ous functions that every enterprise must have in order to succeed. Service domains are directly related to business domains. We use the phrases “service domain” and “business domain” interchangeably because they’re so closely related. A domain is simply an area of logically related knowledge or expertise. Most companies are divided into domains. We com- monly see companies divided into departments such as sales, marketing, human resources, IT, and so on. Service domains are an important concept in enterprise architecture; they pro- vide us with a logical demarcation between applications. This demarcation allows us to make better decisions about how to integrate individual applications. Figure 10-5. Service domain scale Each company may modify its list of service domains. For example, the Service Manage- ment domain only applies to companies that provide services, as opposed to products, to their customers—for example, telephone companies, utilities, and the like. If your company sells products, then there isn’t need for a Service Management domain. Table 10-1 lists the service domains and provides a description for each. It’s important to think of each service domain as a co-equal peer in the enterprise architecture. Human
    • 7974CH10.qxd 4/2/07 9:53 PM Page 211 CHAPTER 10 I PLANNING YOUR SERVICE LANDSCAPE 211 resources might not have the same priority within your organization as does Customer Rela- tionship Management (CRM) or billing, but it plays an important role in keeping your enterprise in compliance with government rules regarding employment, and also helps to keep your employees happy, which in turn benefits the enterprise. Table 10-1. Service Domain Descriptions Service Domain Description Customer Customer Relationship Management. This domain is responsible for maintaining accurate customer information. CRMs are commonly found in this domain, as are other customer/lead tracking types of software. HR Human resources. PeopleSoft and related software products are often found here. For example, in pharmaceutical companies, you would find employee training records for using respirators, CPR training, and so on. Product Products are a marketing concept. Marketing defines and promotes products, and this domain contains the software tools to allow the marketing department to do its job. Inventory Inventory is a count of physical items that are either sold to customers, or in the case of service providers, are physical elements that allow the company to provide service to its customers (for example, telephone switches, line cards, and so on). Services This domain is used exclusively by service providers. If a company sells services (such as communication service, electrical service, natural gas, and so on), this is where those services are defined and maintained. Order Order management. Here orders are collected and processed/fulfilled. Asset Every organization has assets. As asset is an item used by the company or by its employees and contractors. For example, a building owned by the company is an asset, the computers used by the employees are assets, as is the furniture, vehicles, and so on. Accounting Accounts receivable/accounts payable. Commonly referred to as billing. This domain contains the majority of the accounting systems used by the company. Partner Partner relationship management. This domain is responsible for keeping records of the various partners of the company. Supply Supply chain management. This domain contains information about suppliers. With your two scales in hand, you’re ready to create your coordinate system. The Coordinate System When you put these two scales together, you get a coordinate system for your services in your SOA. Figure 10-6 shows the coordinate system that applies to every enterprise. This will become a useful tool when you begin to map your SOA.
    • 7974CH10.qxd 4/2/07 9:53 PM Page 212 212 CHAPTER 10 I PLANNING YOUR SERVICE LANDSCAPE Figure 10-6. The SOA Coordinate System However, before you start the mapping process, there’s one more concept to introduce with regard to the coordinate system that isn’t well represented by a grid. As we mentioned earlier in this chapter, there’s a natural clustering of applications in any IT department. Upon careful examination, you’ll usually find that this clustering falls along the lines of the service domains. You need to formalize this clustering of applications to create your service landscape. To do this, you must begin to think of your architecture in terms of trees, not just simple stacks or layers. Using a tree as a conceptual model will simplify your ability to navigate through the enterprise. Figure 10-7 points out (and overcomes) one of the shortcomings of the grid approach: the Enterprise Services layer is not divided into domains. The whole point of the Enterprise Ser- vices layer is that it’s designed to integrate the different service domains below it. Similarly, an individual domain in the Domain Services layer contains multiple application services. Figure 10-7. Enterprise architecture sample tree Keep in mind that this map is a logical map. It breaks down functionality into logical groups. In practice, you’ll find that some of your applications will cross domain boundaries. This is especially true of large, packaged applications such as Siebel and SAP. You’ll most likely find the same issue with the software that you have developed in house. This is common and doesn’t present a problem for the architecture. Remember, we’re modeling application services, not applications. Application services are still divided into their respective domains, no matter where the applications are physically deployed. For example, imagine that your company uses Siebel for its CRM and order management capabilities. Furthermore, some of the customer information resides in a customer database that came to your IT shop through the acquisition of another enterprise a year ago.
    • 7974CH10.qxd 4/2/07 9:53 PM Page 213 CHAPTER 10 I PLANNING YOUR SERVICE LANDSCAPE 213 As you can see in Figure 10-8, Siebel is a single application that hosts two services that logically belong in different domains. Siebel’s Customer Service is mapped into the Applica- tion Services layer beneath the CRM Domain, while Siebel’s Order Service is mapped into the Application Services layer beneath the Order Management Domain. Applications routinely cross domain boundaries. Always keep in mind that the logical view is what’s important in enterprise architecture. When we lose sight of this logical view (our SOA “map”), that’s when we become lost in the details again. Figure 10-8. Physical application deployment doesn’t impact the logical map. Mapping Your SOA Now that you have a coordinate system, it’s time to create your Enterprise Service Map. Although the SOA Coordinate System remains relatively unchanged from one enterprise to the next, the service map is always highly specific to each enterprise. Therefore, we cannot provide you with a map of your enterprise here. Instead, we’ll provide you with the methodol- ogy for creating your own Enterprise Service Map. Using this methodology provides considerable benefit for you and your organization. First, it helps to provide a high-level taxonomy for categorizing your services. This in turn makes it easier to find—and thereby reuse—existing services. Second, it helps architects and developers to determine quickly which services need to be created and where they must exist in the SOA Coordinate System. This methodology will help to eliminate much of the confusion that naturally occurs when first moving to an SOA. There are two approaches to defining and discovering services: top-down and bottom-up. We’re often asked which approach is “best.” The top-down approach means that you start from a high-level business need and then create the services that are required to fulfill that need. The bottom-up approach is where you look for existing business functionality that you believe will be useful in the future, and service-enable that existing functionality. Both approaches have their place in enterprise architecture, and this mapping methodology fits both approaches nicely. The Top-Down Approach Our first mapping example will use the top-down approach. This approach is generally initi- ated by a line-of-business leader who has a specific business need. These needs tend to be expressed in general terms with little or no technical detail. For our first example, the business need is expressed as, “We need to allow our customers to view their bills online.”
    • 7974CH10.qxd 4/2/07 9:53 PM Page 214 214 CHAPTER 10 I PLANNING YOUR SERVICE LANDSCAPE Figure 10-9 shows a service map that can fulfill the business need. Right from the start, we know that we need a service in the ESL because the service needs to access information from two distinct domains (the Customer and the Accounts Receivable/Accounts Payable domains specifically). This brings us to our first rule of service mapping: Enterprise Service Mapping Rule 1: If the service must cross domain boundaries to do its job, it must exist in the Enterprise Service Layer. Service 1 must aggregate information from the two service domains that are logically responsible for the customer and billing information, so the service in the ESL invokes the two services in the Domain Service Layer (DSL). As Enterprise Service Mapping (ESM) Rule 1 declares, the service in the ESL absolutely cannot skip over the DSL and get the information directly from the various application services. Doing so violates the fundamental principle of abstraction and will quickly render the coordinate system (and therefore your ESM) com- pletely useless. It would be akin to putting a button on your TV remote control to change a single transistor state on a microchip in the TV. Figure 10-9. Mapping your first service If the ESL could skip the DSL, you would lose a fundamental layer of abstraction, and the ESL would then have to know about the physical deployment details of the applications in the Application Service Layer (ASL). This not only increases the amount of maintenance that needs to happen each time a change is made to a physical application deployment (a server is added or deleted), but also eliminates a key layer of transformation. This forces the ESL to “speak” the same language as the application, therefore reducing the possibility of ever achieving a canonical service model at the ESL. This leads us to ESM Rule 2: Enterprise Service Mapping Rule 2: The Enterprise Service Layer cannot “skip” the Domain Service Layer.
    • 7974CH10.qxd 4/2/07 9:53 PM Page 215 CHAPTER 10 I PLANNING YOUR SERVICE LANDSCAPE 215 Each respective domain service then makes use of any number of application services and Relational Database Management System (RDBMS) services to fulfill its service contract. In this case, we see that the Customer DSL can skip the application layer and access the RDBMS Service Layer (RSL) directly. That is because a data service and an application service are components of the domain itself. Domain services must understand the physical deploy- ment nature of their applications, databases, and services, so it’s completely acceptable for a DSL-level service to invoke any service within its domain directly. In the case of the AR/AP domain service, the Customer DSL simply uses an application service. This is often the case with packaged applications, where they either don’t publish their supporting database struc- ture, or they prohibit you from making calls to the application database directly. Each higher-level service may be dependent on lower-level services. The SOA Coordinate System makes the direction of these dependencies implicit. The ESL calls the DSL. The DSL in turn, calls the ASL or the RSL. The ASL may also call the RSL. We’ll cover this later in the chapter in the section “Communication Principles and Patterns.” The Bottom-Up Approach The IT department generally initiates the bottom-up approach. The members of the IT department have a detailed understanding of the daily operations and interactions of the software systems they manage. This detailed knowledge is used to predict which technical functions are likely candidates to become reusable services. For our second example of service mapping, a software developer makes this recommen- dation to the IT department: “We do a lot of sales where credit cards are used as the method of payment, and we use several different credit card payment companies to charge credit cards, depending on which application is taking the order. Furthermore, if one processing agency is responding too slowly, we have logic written in each sales application to fail over to a different credit card processing agency. We should create a single service for credit card processing and encapsulate the fail-over logic so it’s reusable.” See the difference in the level of technical detail? The bottom-up approach is applied when the details are well known. The IT department is fixing an important issue, but one that is so low level that most line-of-businesspeople aren’t aware of it. As you can see in Figure 10-10, the service map is simple. The decision-making process to determine the map should be straightforward after our first exercise. First, you need an appli- cation service that encapsulates both the fail-over logic and the agency-specific connection information. If you need to add or remove a credit card processing agency, then that function will need to happen at the ASL level, and the changes shouldn’t affect any of the service consumers. Next, you know that this credit card service will be invoked by your sales applications; therefore, you must have an ESL-level service (because you’re crossing domains). Last, because the ESL cannot communicate directly with the ASL, you must create a DSL service to route the service request to the appropriate application service. We deliberately left the Order domain in Figure 10-10 to show that even though the appli- cations in the Order domain need to use the credit card service, the Order domain is merely a consumer of the credit card service, and therefore isn’t a part of the service map.
    • 7974CH10.qxd 4/2/07 9:53 PM Page 216 216 CHAPTER 10 I PLANNING YOUR SERVICE LANDSCAPE Figure 10-10. A bottom-up approach for our second service map SOA Mapping Test 1 As you can see, the methodology is simple. To help ensure that you understand the process, let’s try a test. We’ll describe the scenario, and you use the methodology to create a service map on a piece of scrap paper. Also, make a note of whether you’re using a top-down or bottom-up approach, based on the scenario description. Scenario: “Our suppliers need to interrogate our systems and check our current inven- tory levels. Based on our inventory levels, they will ship additional products to us. We need a way to allow our suppliers to see our current inventory levels. However, each of our suppliers has a proprietary format for the inventory data they’ll receive from us, so we need to adapt our inventory information into their data format.” See Figure 10-11 to see the service map and the approach used. Despite the fact that the scenario sounds so complex, the service map is pretty straight- forward. In the Supply domain, you’ll create your supplier-specific adapters (each supplier expects its own data format to be returned to it). Whether you create an application for each adapter or have a single application that’s used by each supplier-specific adapter is a design choice you need to make. However, from the point of view of the service map, it’s not impor- tant. The direct result of this is that we have an application in the Supply domain/ASL. Next, you know that the application in the Supply domain needs information from the Inventory domain. Because you’re crossing domain boundaries, you must have an enterprise- level service. To get to the application service that holds the inventory information, the ESL must make a call through the DSL, so you create a service in the Inventory domain’s DSL also.
    • 7974CH10.qxd 4/2/07 9:53 PM Page 217 CHAPTER 10 I PLANNING YOUR SERVICE LANDSCAPE 217 Figure 10-11. Our service map for Test 1 One thing to note: if a supplier was able to use the data format provided by your enterprise- level service, then that could be an entry point into your enterprise. It’s an architectural decision as to whether or not to publish enterprise-level services directly to your suppliers. Our personal preference is to isolate partner and supplier integration within their respective domains, and keep the ESL as a resource solely for the use of the enterprise itself. Last, we took a top-down approach to this. We worked from the business need, not from a technical improvement. SOA Mapping Test 2 This will be our last test for mapping services. Just to make sure you really understand the process, we’ll make this test a whopper. Let’s dive right in. Scenario: Your manager says, “I need a 360-degree view of the customer. I want to be able to know at a glance the customer contact information, the products they’ve pur- chased, and when they purchased them. I also want to know how they paid for those products so I can target a promotional campaign based on past purchases and payment methods.” Furthermore, your lead developer says, “Getting the product and order data would be a lot faster if we got it directly from our data warehouse, rather than from our online databases.” This sounds a lot harder than it turns out to be. Figure 10-12 shows the service map for the “Customer 360° View” service. To begin with, there’s no question that you’re crossing domains with this map, so you know you need a service in the ESL. Also, you know that you’ll need a service in each of the DSLs that participate in this overall service.
    • 7974CH10.qxd 4/2/07 9:53 PM Page 218 218 CHAPTER 10 I PLANNING YOUR SERVICE LANDSCAPE Figure 10-12. Our service map for Test 2 We threw a bit of a monkey wrench into this test with the engineer’s comment on using the data warehouse. A data warehouse with order information would contain product infor- mation by default. Obviously, this is an RDBMS-layer service, but in which domain: Order or Product? The answer is up to you. In our opinion, this service is centered more on the order than the products, but that’s a personal call. You’d be just a correct to place such an RDBMS service in the Product domain. Data warehouses are like applications in that they almost always cross domain bound- aries. Just like applications, it’s up to you to decide which domain best fits the RDBMS service you’re creating. There’s no right or wrong answer here, just as long as you document your deci- sions and provide a mechanism to allow your development teams to find and reuse these services easily. Service Maps at Scale So far, we’ve drawn service maps for individual services. Let’s create a single service map that contains all the mapping information we’ve created so far. Figure 10-13 shows the map of all our services so far. As you can see, it’s already cluttered. Imagine the service map for a real enterprise with hundreds of services; the map would be unintelligible due to the amount of data on it. It might be visually impressive, but other than that, it would be completely useless. Tip I Do not store service maps that show multiple services. In practice, we find the ESM so straight- forward that we usually do not store service maps at all.
    • 7974CH10.qxd 4/2/07 9:53 PM Page 219 CHAPTER 10 I PLANNING YOUR SERVICE LANDSCAPE 219 Figure 10-13. Mapping multiple services Service mapping isn’t designed to be visually stunning. It’s a simple methodology for defining a high-level view of which services need to exist, and where they need to exist. It also provides guidance on the level of abstraction of those services. It reduces confusion and argu- ment about what services need to be created (or reused), and where and how those services should be deployed. Service Tooling However, as the number of your services grows, the ability to find existing services becomes increasingly difficult. Furthermore, mapping the interdependencies of each service also becomes exponentially more difficult. Making a change to your service landscape, at enterprise-level as complex a task as making a change in a point-to-point architecture. Fortunately, new tools are emerging to help you manage this ocean of data. Service reg- istries operate like a phone book for services, allowing you to look up the locations of the services quickly and retrieve their runtime design information (Service Level Agreements and other metadata). Service repositories are great tools for tracking design-time metadata about services, such as their interdependencies. As your SOA grows, your need for professional service management tools will grow also. BEA is the only company, at the time of this writing, that provides a complete suite of SOA tools, including an enterprise-quality service registry and a service repository. Architectural Transformation Odds are that your current enterprise architecture doesn’t formally recognize service domains. If your company is like the vast majority of companies, then your current enterprise architec- ture will resemble that shown in Figure 10-14.
    • 7974CH10.qxd 4/2/07 9:53 PM Page 220 220 CHAPTER 10 I PLANNING YOUR SERVICE LANDSCAPE Figure 10-14. Point-to-point integration This is commonly referred to as a point-to-point (P2P) integration strategy. We’ve also heard people refer to it as a “rat’s nest” of integrations. The illustration shows 28 circles. Each circle represents an application in the enterprise. The arrows show the dependencies between the applications. Although the figure shows only a modest number of applications (most medium-sized enterprises have well over a hundred software applications running at any time), it represents sufficient complexity for our purposes. The big question is, “How do I transform my architecture from this rat’s nest to use service domains and the SOA Coordinate System?” First, it’s important to recognize that your enterprise didn’t implement this rat’s nest overnight. It took years—even decades—to build that point-to-point architecture, and you won’t correct it overnight. However, we have an approach that will simplify this process, allow- ing you to implement enterprise-wide SOA without having to rewrite your entire enterprise. As we write this, SOA is at a high point in its “hype cycle.” SOA advocates earnestly prom- ise that SOA will cure all your ills and make you more attractive to the opposite sex. These promoters will promise that everything you ever learned about software engineering and run- ning an IT shop is now outdated. SOA makes it all so easy a trained monkey can do it! If you’ve spent any amount of time in the software industry, you recognize this hype cycle pretty quickly. You know that the old “80/20” rule applies: about 80 percent of the hype will turn out to be exaggerations or outright lies, while the other 20 percent is the really useful stuff that you need to learn and apply immediately. The difficulty is in knowing which statements belong in the “hype” bucket and which statements are true. Let us debunk a commonly held belief in our industry: “Point-to-point integrations are evil.” In fact, there are advantages to using a P2P integration strategy. First, P2P is usually fairly quick to implement. Once you know how to communicate to the foreign software system, it’s just a matter of doing the work to make the various API calls. Second, P2P is fairly easy. You don’t have to be a software design expert: the foreign software system is written and there’s usually nothing you can do to improve it. Just write the code and go home. Third, P2P is usually fast from an execution time point of view. Not a lot of translation happens in a P2P integration, thereby eliminating any translation or transformation overhead.
    • 7974CH10.qxd 4/2/07 9:53 PM Page 221 CHAPTER 10 I PLANNING YOUR SERVICE LANDSCAPE 221 Of course, P2P also has some serious drawbacks. P2P systems are difficult to maintain over time, and there tends to be little abstraction in the interfaces of some of these software systems, so making any changes to them tends to affect every client that’s integrated with the system. Because every little change requires significant engineering effort, a greater percent- age of the IT budget goes to maintaining existing systems, and less money is spent on creating new systems or improving existing ones. This phenomenon leads directly to IT (and therefore the business itself ) becoming lethargic and resistant to change. As you can see, P2P has strengths and weaknesses, like every other software strategy. P2P isn’t evil, nor is it “blessed.” It’s simply an integration strategy that makes sense to use in cer- tain situations. The simple fact is that P2P is already present and pervasive in your enterprise. You cannot ignore it; you must deal with it. If your enterprise is like most, you have neither the time nor the money to fix it, so there’s only one thing left to do: embrace it. The approach we suggest here is simply to accept that you’re going to live with large pockets of P2P for some years to come. The trick is to know where P2P is acceptable in the short term, and where you really have to buckle down and fix it. Now that we have an SOA Coordinate System and an SOA map, we can tell you where you need to fix P2P and where you can safely ignore it for the time being. It all comes back to service domains. Applications within a service domain are already implemented using P2P Because the work they do is so . closely related anyway, it’s perfectly acceptable to allow them to remain that way. However, you must break this P2P model when it comes to operations that cross service domains. Your first step is to take an inventory of all your applications and begin to categorize them into the appropriate service domains. Once that’s done, you can begin a series of engineering projects to refactor the various applications so that they’re appropriately represented by the service domains. Figure 10-15 shows this process in principle. Figure 10-15. Isolate applications and services that belong in the same service domain.
    • 7974CH10.qxd 4/2/07 9:53 PM Page 222 222 CHAPTER 10 I PLANNING YOUR SERVICE LANDSCAPE When you’re identifying applications and services, it’s important that you understand the dependencies between the applications in sufficient detail to make a good decision. Each dependency has a direction associated with it, and you must understand the direction of each dependency. With this knowledge, you’re able to begin to move applications and appli- cation services into a logical domain layer. Figure 10-16 shows how this is done. Only one application (A) needs to be modified to call the new Domain Service Layer, instead of calling the application directly. Figure 10-16. Create a DSL. Notice how application B is still directly dependent on application C. For the time being, this is acceptable. Because application C is not yet in a defined Domain or Application Service Layer, the outgoing call from B to C in unavoidable. Our next step is to repeat the process. Once again we isolate applications and services that belong in the same logical domain, playing close attention to their dependencies. We cre- ate a second service domain and ASL. At this stage, we break the direct dependency between application B and C and refactor application B to call the newly created DSL.
    • 7974CH10.qxd 4/2/07 9:53 PM Page 223 CHAPTER 10 I PLANNING YOUR SERVICE LANDSCAPE 223 Figure 10-17. Repeat the process for each domain. There is no hard-and-fast rule about when to introduce an ESB, but we recommend that you introduce it as the second project (immediately after you create your first service domain) or as the third project (after the second service domain is complete). It’s important to introduce the ESB fairly early in the process of creating domains to reduce the amount of refactoring that must be performed for each application that invokes services in other domains. For example, if you examine Figure 10-17 you’ll notice that application B is now dependent on Domain Service Layer 2, while application A is dependent on Domain Service Layer 1. Yet a quick examination of Figure 10-18 shows that applications A and B are now dependent on the ESL. This implies a double refactoring of those applications (from the DSL to the ESL). Obvi- ously, each of these refactoring efforts takes time and money to complete, so you want to minimize the number of such projects. Of course, you might ask, “Why not start by creating the ESL and completely avoid the double refactoring effect?” That sounds good in principle, but we find that creating at least one DSL helps the architects and developers to get their minds wrapped around new tech- nologies and new design patterns required by SOA. We find that this helps to diffuse the attendant fears of experiencing so much change, which in turn increases the success rates of these early projects.
    • 7974CH10.qxd 4/2/07 9:53 PM Page 224 224 CHAPTER 10 I PLANNING YOUR SERVICE LANDSCAPE Figure 10-18. Introduce the ESB early in the process. There are two main advantages of the service domain methodology. First, it leverages your existing P2P architecture, minimizing the amount of change. Fewer changes means less development time and less cost. Second, it provides you with a defined process that’s easily explainable to technologists and businesspeople alike. Trying to get your projects funded under the banner of “SOA” is a difficult proposition. However, once you clearly explain how you can achieve your SOA goals and can break the process down into discrete projects, you’ll increase your odds of success. People rarely fear what they understand. Last, organizing IT assets into a series of service domains that make sense to most business people will increase the level of alignment between your IT shop and your business leaders. Communication Principles and Patterns We’d now like to explain three communication principles and four basic communication patterns in this architectural approach. These principles and patterns should be clearly understood by each architect, service developer, and software engineer involved with realizing this architecture. Fortunately, they’re simple and easy to understand.
    • 7974CH10.qxd 4/2/07 9:53 PM Page 225 CHAPTER 10 I PLANNING YOUR SERVICE LANDSCAPE 225 Communication Principle I Each service layer knows about the layer below it, but not the layer above it. Each service layer acts as a façade for the layer below it. Clients of the ESL should have no knowledge of the various service domains below it. Similarly, the ESL has no knowledge of the ASL beneath the DSL. Communication Principle II Every service layer can know about the Enterprise Service Layer. The ESL is the public API for the enterprise. As a result, it must be available as a resource for any component in the enterprise. This is the only time when it’s permissible for a component in a layer to know about a layer above it. Communication Principle III Web services are used between the service layers. By using web services to communicate between the service layers, you create the ability to have a rationalized monitoring strategy for your enterprise. This approach also promotes reuse of services at each layer by providing a standard service format and the ability to use Universal Discovery, Description, and Integration (UDDI) as a tool for discovering services. Last, it provides an enterprise standard for integration. There are many different ways to inte- grate disparate systems; settling on a standard will reduce your training and maintenance costs and enhance your operational efficiency. Communication Pattern I: Flow of Gravity This is the model that immediately springs to mind for most people when they imagine messages flowing through their enterprise. As shown with the large arrows in Figure 10-19, messages flow from the top downwards. As the message passes through each layer, there’s an opportunity for the message to be transformed and enriched. This demonstrates Communica- tion Principle I and shows how a single message invocation from an enterprise service client can span service domains and multiple application services in a manner completely transpar- ent to the client.
    • 7974CH10.qxd 4/2/07 9:53 PM Page 226 226 CHAPTER 10 I PLANNING YOUR SERVICE LANDSCAPE Figure 10-19. The Flow of Gravity pattern
    • 7974CH10.qxd 4/2/07 9:53 PM Page 227 CHAPTER 10 I PLANNING YOUR SERVICE LANDSCAPE 227 Communication Pattern II: Direct Use of Enterprise Services This pattern demonstrates the use of Communication Principle II. As shown in Figure 10-20, the ESL is being invoked by a DSL and an individual application service. Many modern appli- cations are now capable of invoking external web services (that is, web services that are implemented outside of the invoking application). We expect this trend to continue, making this pattern increasingly common. Figure 10-20. Direct use of the ESL
    • 7974CH10.qxd 4/2/07 9:53 PM Page 228 228 CHAPTER 10 I PLANNING YOUR SERVICE LANDSCAPE Communication Pattern III: Indirect Use of Enterprise Services The third pattern, illustrated in Figure 10-21, is really a minor variation of pattern II. Older software systems that aren’t capable of using web services to integrate with other systems can still participate fully in the ASL. The key is to create an adapter that can translate between the application-specific data formats and the enterprise message formats. This pattern only applies to the ASL because the DSL is fully web service enabled (Communication Principle III). Figure 10-21. Indirect use of the ESL I Caution One thing to beware of with Communication Patterns II and III is the possibility of putting your entire enterprise into an infinite loop. It has always been possible to do this, even with a P2P architecture. However, an SOA makes it much easier to create infinite loops inadvertently. This is one area where your SOA Governance group earns its keep. The Governance groups are commonly charged with understanding the interrelationships between enterprise, domain, and application services.
    • 7974CH10.qxd 4/2/07 9:53 PM Page 229 CHAPTER 10 I PLANNING YOUR SERVICE LANDSCAPE 229 Communication Pattern IV: Inter-Application Communications Within a Domain The fourth and final pattern covers communication and integration within the ASL. Figure 10-22 shows how this pattern allows you to leverage your existing tightly coupled systems in a posi- tive way. The number of system interactions (and therefore the number of messages or procedure invocations) at this level of abstraction is high. We routinely find very “chatty” applications here—applications that are poorly suited for web service interfaces—but that’s perfectly acceptable in this layer. As long as those “chatty” applications are chatting with other applications within the same application domain, they can continue to work without any modifications. Figure 10-22. Inter-application communications within a domain Geared for Performance By applying these rules, you help to ensure robust performance in your SOA. Without these rules, it can be difficult to predict how each of your services will perform. Let’s use an example to help illustrate this. For our first example, let’s start with an SOA built on this methodology. In this scenario, you’re creating new business functionality in the ASL of your customer domain. Your new function needs to access the customer’s residential address history. For the sake of this argu-
    • 7974CH10.qxd 4/2/07 9:53 PM Page 230 230 CHAPTER 10 I PLANNING YOUR SERVICE LANDSCAPE ment, assume that your company tracks the different locations where customers have resided in the past ten years for insurance purposes. You look into your service catalog and you see several existing services that can return this information. Examining the service maps for each service, it becomes clear which service will both meet your needs and perform quickly. Figure 10-23 shows a sample service map. We are creating service F. Our service map shows that service E provides the information we need. However, service D also provides that information. Communication Pattern I prohibits the application layer from calling the domain layer, so having service F call service D is out of the question. However, service A also provides the information needed by service F, but service A acquires that information through service D, which in turn gets the information from service E. Obviously, accessing service E directly will be much faster than accessing it through service A. The methodology has made the decision-making process simple and unambiguous. Figure 10-23. Using the service map to make good choices However, let’s try this same exercise without the use of service maps for an SOA Coordi- nate System. The relationships between the services are exactly the same as was shown in Figure 10-23. However, without using the SOA Coordinate System or the Service Mapping methodology, you have no idea about the interrelationships between the services (because that’s implementation information and your client shouldn’t be exposed to that). Figure 10-24 shows a pool of services without this critical information. Figure 10-24. A pool of services with no coordinate system or map
    • 7974CH10.qxd 4/2/07 9:53 PM Page 231 CHAPTER 10 I PLANNING YOUR SERVICE LANDSCAPE 231 Using the metadata descriptions of each service in your service catalog, you would again see that services A, D, and E all meet your needs. But how do you determine which service to use? You can’t easily make the right decision about which service to use because you’re miss- ing the information that’s critical to your decision-making process. Summary We’ve gone through a lot of theory quickly in this chapter. We’d like to close this chapter with a few ideas about the practical application of ALSB, especially with regard to your service land- scape. Keep in mind that BEA did not name the product “AquaLogic Enterprise Service Bus.” Certainly, ALSB is designed to operate under the rigors and stresses of the ESL. However, ALSB is also well suited to perform in areas of your enterprise that aren’t immediately evident. For example, ALSB is well suited to operate in the DSL. Just point it at the various applica- tion services below it and create a more abstract set of proxy services. That alone will create an entire DSL for one of your domains. ALSB doesn’t just “speak” services, though. Starting with ALSB version 2.5, you can also easily connect to Java code and EJBs, either of which gives you access to databases. These capabilities make ALSB a candidate to act as an adapter within the ASL, allowing legacy appli- cations to participate in your SOA by service-enabling them, even though they were never designed with services in mind. It can be difficult to integrate an old mainframe system into your SOA. Mainframe appli- cations are rarely designed to integrate with anything at all. They all see themselves as the center of their software universe and often don’t even have a public API. One integration trick we’ve used in the past is to integrate at the database level. Mainframe applications commonly use an RDBMS to store data. By adding or modifying insert, update, and delete triggers, you can often push data to an outside application, such as ALSB. This is especially easy in an Ora- cle application, because Oracle provides the capability to write triggers and stored procedures in Java. We prefer to keep our code at this level asynchronous if possible, so it doesn’t interfere too much with the normal execution time of any existing triggers in the database. We usually opt to publish a database “event” over a JMS queue and have ALSB receive the JMS message. We don’t mean to represent this process as being overly simple, but it is possible and it does work. Similarly, many older systems use FTP as their messaging systems. Exchanging formatted files was probably the earliest messaging system in wide use. Using ALSB, you can receive or copy these files, monitoring the file transfers, and even reading the data in these files to per- form content-based routing. Don’t let the name fool you. ALSB has a lot of functionality. Use it wherever its functional- ity matches the needs of your architecture. As the feature list of ALSB grows with each re