File loading please wait...
Citation preview
The Complete Reference To Professional SOA With Visual Studio 2005 (C# & VB 2005) .NET 3.0
Tom Yuan Gao
Published By LULU Press Copyright © 2007 by Tom Yuan Gao
All rights reserved. No part of the content of this book may be reproduced or transmitted in any form or by any means without the written permission of the author.
About The Author Tom Yuan Gao has been developing software for over ten years. Having completed Unisys Scholarship at University of Sydney at the age of 16. He is current a Microsoft Certified Application Developer (MCAD), Microsoft Certified Solution Developer (MCSD), Microsoft Certified Database Administrator (MCDBA), Microsoft Certified Trainer (MCT) as well as Nationaly Accredited IT Trainer within Australia. He has also given lecture at universities on the benefits of Service Orientated Architecture. Tom is currently completing his Doctorate in Distributed Software Security. In his spare time he can be found on his Windows Communication Foundation Community Center at http://www.mswcf.com ran for solution/enterprise architects. Tom is currently working as the National Technical Manager for EuroRSCG World Wide.
Letter from the Author The concept of service orientation has been around for a very long time. The idea of service orientation is about developing structured reusable solutions that can be used over and over again. Although the concept itself is simplistic there has been no consistent and uniform means of achieving service orientation until recently when Microsoft has targeted the service orientation area with the release of ASP.NET. Microsoft’s support for service orientation through ASP.NET XML Web service has generated overwhelming support within the industry. The .NET framework coupled with the revolutionary development environment Visual Studio 2005 will revolutionize the way you view and develop future applications. In this book I will take you through the hype and myth of service orientation and into the real world of experience that will help you understand and transform the way you view and develop applications within your enterprise architecture. We will investigate the reasons to why service oriented architecture can help application infrastructures in terms of flexibility, interoperability, and integration. The book is divided into two parts. The first part deals with theory and concepts of service orientation. We will be exploring the risks and trade offs that are required. We will also learn how to meet enterprise requirements for availability, scalability and security. For IT managers and business stakeholders we will explore the concept of generating additional customer base through the previously taboo subject of exposing and yet protecting your intellectual property. The second part of the book focuses on the application of service orientation through ASP.NET XML Web Services. You will learn to use and take advantage of the newly released Visual Studio 2005 development environment, through step by step guides for each and every example in both Visual C# and Visual Basic .NET. You will also learn to develop XML Web Services to supplement the concepts you have learnt in part one of the book. This book is a worthwhile investment and I thank you for purchasing it. I thank you for taking the effort to take one step beyond everyone else, beyond your competitors.
Tom Yuan Gao MCAD, MCSD, MCDBA, MCT, Accredited Trainer Voting Member of OASIS for Web Service Standards Founder of Microsoft Windows Communication Foundation Community Center (www.mswcf.com)
Acknowledgement I have to say that this book would not have been possible without the support from my family and friends. To my dad, who was my role model in persistence and hard work. To my mum, who has always taught to be efficient and smart. There are a few that I would be enternally grateful to. I would have to thank Todd Meister and Fabio Claudio Ferracchiati for their relentless effort in technical review and in getting every detail perfect as it were intended. Thanks to Peter Hovany, Bill Heish, David Abraham and Marlon Deleon for their encouragements during some very difficult times.
Chinese proverb – “The journey of 1000 miles begins with a single step.”
Resource As a reward for purchasing this book I have also made The Complete Reference to Professional SOA with Visual Studio 2005 (Visual C# & VB 2005) available for you to download. You will be able to find the book on http://www.mswcf.com/BookSOA.zip Source code for both series can be found on http://www.mswcf.com/source.zip
Foreword The concepts behind SOA has been with us for many years, but it’s not until recent times with advances in Microsoft .NET and Sun’s Java that some of the services that architects, business decision takers and visionaries have envisioned, can finally be implemented in a reusable and platform agnostic manner. The hype behind SOA in recent years has helped increase the knowledge and the request for Serviceoriented solutions; which in essence is all about moving away from data silos (where information often are proprietary and hard to access), to open and interchangeable services that deliver the data you need, when you need it, and allowing you to form these services to fit your business processes and create tangible benefits. Government, military and private customers are rapidly increasing their demand for service-oriented platforms that are secure and easy-to-use. This means it has become more important to learn and understand the concepts and gain the technical skills to implement service-oriented solutions. This book delivers great content for developers and it can empower you (as a developer and architect) to better educate others about the benefits and reality behind Service-oriented solutions. It also delivers comprehensive technical content that is easily understood by business people and decision makers. This is a book I will promote to everyone involved in business and IT process improvement. The book can enable you to become better at providing new and innovative solutions that help solve your customer’s most challenging problems, and can give you inspiration to look at your own internal business processes in a new light. Tom delivers the content in a clear and concise way. Tom will guide you through how to start building a Web Service, how to consume it, how to debug it, and how to finally deploy it into your testing, staging or production environments. This book is a book for professionals who want to develop quality service-oriented solutions. Tom starts out by explaining the core concepts of SOA, allowing you to better understand and start learning some of the new and innovative ways of thinking. Then going through and giving you a real description what Web Services is all about without the hype. If you are new to the whole concept of Web Services, Tom explains the basics of XML based technologies like XML Schema, SOAP and WSDL which are the foundations of Web Services. You will learn some of the more advanced topics with building Web Services, important topics like security and logging. Tom will show you how to use some of the WS-* standard specification, especially WS-Security with encryption and signing of messages, how to make a custom username service on WSE 3.0 (Web Service Enhancements), and much more. There is a special chapter dedicated to Windows Communication Foundation which is the new and unified communication platform coming with the release of Microsoft .NET Framework 3.0, released around Windows Vista timeframe. This can prepare you for the future changes for developing communication solutions with Visual Studio. Microsoft released a version of Visual Studio for software architects, where they introduced some new features that can help you plan your overall architecture of your distributed service-oriented solutions. Part of this initiative is the Distributed System Designers that Tom covers comprehensively in this book. These give you capabilities to model and manage distributed solutions directly from Visual Studio, making deployment packages and validating them against your server-farms amongst other things. Look no further for a full in-depth review of Service-oriented architecture and technologies. Tom has written an excellent book for professionals, that will guide you through the process of building services the way they where meant to be.
Hope you all enjoy this book as much as I did!
Sondre Bjellås Microsoft Regional Director Software Architect & Product Manager
Table of Contents ABOUT THE AUTHOR ................................................................................................................................................. 3 LETTER FROM THE AUTHOR .................................................................................................................................. 4 ACKNOWLEDGEMENT............................................................................................................................................... 5 RESOURCE ..................................................................................................................................................................... 6 FOREWORD.................................................................................................................................................................... 7 PART 1 CORE CONCEPTS......................................................................................................................................... 21 CHAPTER 1: INTRODUCTION TO SERVICE ORIENTED ARCHITECTURE ................................................ 21 WHAT IS SERVICE ORIENTED ARCHITECTURE?............................................................................................ 22 EXPLAINING SERVICE ORIENTED ARCHITECTURE USING METROPOLIS ....................................................................... 22 Cities as Software Vendors..................................................................................................................................... 23 Factories and Buildings as Applications................................................................................................................ 23 Transportation as Communication ......................................................................................................................... 23 Manufactured Goods as Standardization ............................................................................................................... 24 Manufactured Components as Virtual Enterprises ................................................................................................ 24 Urban Infrastructure as IT Infrastructure Evolution ............................................................................................. 24 ENTERPRISE ARCHITECTURE............................................................................................................................... 25 ARCHITECTURAL TRADEOFF TRIANGLE ....................................................................................................................... 25 ARCHITECTURAL TRADEOFF MATRIX .......................................................................................................................... 26 UNDERSTANDING BUSINESS BENEFITS OF SOA.............................................................................................. 26 BETTER VISIBILITY INTO OPERATIONS AND PERFORMANCE ........................................................................................ 27 MORE EFFICIENT OPERATIONS .................................................................................................................................... 27 BETTER BUSINESS AGILITY ......................................................................................................................................... 27 WHAT IS A WEB SERVICE? ..................................................................................................................................... 28 LOOSE COUPLING ........................................................................................................................................................ 28 SERVICES ..................................................................................................................................................................... 29 XML WEB SERVICES ................................................................................................................................................... 29 XML and XML Schema........................................................................................................................................... 29 XPath...................................................................................................................................................................... 30 SOAP ...................................................................................................................................................................... 30 WSDL ..................................................................................................................................................................... 31 UDDI ...................................................................................................................................................................... 31 SERVICE ORIENTED ARCHITECTURE WITH WEB SERVICE ............................................................................................ 32 WEB SERVICE AND SOA TECHNOLOGY SOUP ................................................................................................. 32 SERVICE ORIENTED ENTERPRISE ARCHITECTURE...................................................................................... 33 ADOPTING THE LEGACY ENTERPRISE ARCHITECTURE BEAST...................................................................................... 33 ENTERPRISE ARCHITECTURE USING SOA .................................................................................................................... 34 SO IS SERVICE ORIENTED ARCHITECTURE A BREAKTHROUGH? ........................................................... 36 CASE STUDIES............................................................................................................................................................. 37 WHICH INDUSTRY IS BEST FOR SOA........................................................................................................................... 37 The Drive for SOA .................................................................................................................................................. 37 CASE STUDY: STARWOOD HOTELS USES SOA TO IMPROVE GUEST SERVICES AND CUT COSTS .................................. 38 CASE STUDY: HARLEY-DAVIDSON .............................................................................................................................. 39 CASE STUDY: IBM TOWARDS SOA ............................................................................................................................. 39 CASE STUDY: MICROSOFT SOA (MILTON KEYNES GENERAL HOSPITAL) ................................................................... 40 CASE STUDY: GFK MARKET RESEARCH ...................................................................................................................... 41 CASE STUDY: PUREPROFILE ........................................................................................................................................ 42
CASE STUDY: AMAZING PEOPLE .................................................................................................................................. 42 CASE STUDY: SUNSHINE SUGAR .................................................................................................................................. 43 CASE STUDY: INTELLIFIELD ......................................................................................................................................... 43 SUMMARY .................................................................................................................................................................... 43 CHAPTER 2 IMPLEMENTING SERVICE ORIENTED ARCHITECTURE ....................................................... 45 SOA ARCHITECTURAL ROADMAP ....................................................................................................................... 45 WHAT IS A SOA ROADMAP AND WHY DO YOU NEED ONE? ....................................................................................... 45 HOW TO BUILD A SOA ROADMAP ................................................................................................................................ 45 SOA planning ......................................................................................................................................................... 47 SOA maturity assessment ....................................................................................................................................... 47 SOA future vision.................................................................................................................................................... 48 SOA roadmap definition ......................................................................................................................................... 48 Iterative Quality Assurance .................................................................................................................................... 48 SOA GOVERNANCE ..................................................................................................................................................... 48 ENTERPRISE SERVICE ENABLING ARCHITECTURES.................................................................................... 49 SERVICE TYPES ............................................................................................................................................................ 49 Basic services ......................................................................................................................................................... 49 Data-Centric Services ............................................................................................................................................ 49 Logic-Centric Services ........................................................................................................................................... 50 Transitional Services .............................................................................................................................................. 50 Public Services ....................................................................................................................................................... 50 SOA WEB SERVICE TRANSFORMING LOGICAL LAYERS TO PHYSICAL TIERS............................................................... 50 STARTING YOUR ENTERPRISE SOA WITH ENTITY AGGREGATION ............................................................................... 51 Single View of Entity .............................................................................................................................................. 52 Horizontal Partitions.............................................................................................................................................. 53 Cross Entities Query............................................................................................................................................... 53 ENTERPRISE APPLICATION INTEGRATION (EAI) .......................................................................................................... 54 Web Service Choreography Interface (WSCI)........................................................................................................ 55 Business Process Execution Language for Web Services (BPEL4WS) .................................................................. 56 Coordination Services ............................................................................................................................................ 56 DISTRIBUTED EVENT DRIVEN ARCHITECTURE AND SOA ............................................................................................ 57 ENTERPRISE SERVICE BUS & SERVICES ....................................................................................................................... 57 Mediation support .................................................................................................................................................. 60 Protocol independence ........................................................................................................................................... 60 Web Service Management Orchestration ............................................................................................................... 60 SECURITY IN SERVICE ORIENTED ARCHITECTURE ....................................................................................................... 61 Security Basics ....................................................................................................................................................... 62 Web Service Security .............................................................................................................................................. 63 Message Reliability in Service Oriented Architecture............................................................................................ 70 SUMMARY .................................................................................................................................................................... 71 CHAPTER 3 BUSINESS ADAPTATION OF SOA ................................................................................................... 73 SERVICE ORIENTATION AND ITS ROLE IN OUR CONNECTED SYSTEM STRATEGY ........................... 73 WHY DO WE NEED FLEXIBILITY?.................................................................................................................................. 74 AGILITY ....................................................................................................................................................................... 74 Technology ............................................................................................................................................................. 75 Communication & Location Issue .......................................................................................................................... 75 Business Process .................................................................................................................................................... 75 Business Functionality............................................................................................................................................ 76 Integration .............................................................................................................................................................. 76 Support ................................................................................................................................................................... 76 REDUCTION IN COST OF DEVELOPMENT ...................................................................................................................... 76 IT Cost Savings....................................................................................................................................................... 77 Business Cost Saving from SOA ............................................................................................................................. 77 OPENING OUR INTELLECTUAL PROPERTY...................................................................................................... 77
SUPPLIERS .................................................................................................................................................................... 78 CONSUMERS................................................................................................................................................................. 78 PROMOTING INTER-PLATFORM CONNECTION .............................................................................................. 79 MEASURING A SOA.................................................................................................................................................... 80 ORGANIZATIONAL ROADMAP .............................................................................................................................. 82 IDENTIFYING STAKEHOLDERS AND CONFLICTS ............................................................................................................ 82 Business and IT ...................................................................................................................................................... 83 Internal Politics...................................................................................................................................................... 83 ORGANIZATION VISION ................................................................................................................................................ 83 BUDGET CONSIDERATION ............................................................................................................................................ 84 GATHERING INTERNAL SUPPORT ................................................................................................................................. 84 SOA DRIVEN PROJECT DEVELOPMENT USING MSF ...................................................................................... 84 CHALLENGES AND OPPORTUNITIES .............................................................................................................................. 85 MSF TRACKS ............................................................................................................................................................... 85 MSF CMMI............................................................................................................................................................. 86 MSF Agile............................................................................................................................................................... 86 ENVISIONING TRACK ................................................................................................................................................... 87 PLANNING TRACK ........................................................................................................................................................ 87 DEVELOPING TRACK .................................................................................................................................................... 88 STABILIZING TRACK .................................................................................................................................................... 88 DEPLOYING TRACK ...................................................................................................................................................... 88 GOVERNANCE .............................................................................................................................................................. 89 OPERATIONAL MANAGEMENT ..................................................................................................................................... 89 CONTINUOUS TRACK ................................................................................................................................................... 89 PROJECT TEAMS ........................................................................................................................................................... 89 Program Management............................................................................................................................................ 90 Architecture ............................................................................................................................................................ 91 Development........................................................................................................................................................... 91 Test ......................................................................................................................................................................... 92 Release/Operations................................................................................................................................................. 92 User Experience ..................................................................................................................................................... 93 Product Management ............................................................................................................................................. 93 MSF RISK MANAGEMENT............................................................................................................................................ 93 SIMPLIFYING SOA DEVELOPMENT USING .NET AND VISUAL STUDIO 2005........................................... 94 USING VISUAL STUDIO 2005 TO CREATE A WEB SERVICE ............................................................................................ 95 USING VISUAL STUDIO 2005 TO CONSUME A WEB SERVICE ...................................................................................... 100 SUMMARY .................................................................................................................................................................. 103 PART 2 USING .NET WEB SERVICE 2.0 WITH VISUAL STUDIO 2005.......................................................... 104 CHAPTER 4 INTRODUCING .NET 2.0................................................................................................................... 104 .NET FRAMEWORK.................................................................................................................................................. 104 FEATURES OF THE COMMON LANGUAGE RUNTIME .................................................................................................... 106 MANAGED DEVELOPMENT ......................................................................................................................................... 107 .NET FRAMEWORK 2.0............................................................................................................................................ 108 VISUAL STUDIO 2005 TEAM ROLES.................................................................................................................... 108 VISUAL STUDIO 2005 EDITIONS........................................................................................................................... 110 THE VISUAL STUDIO IDE....................................................................................................................................... 111 WEB SERVICE TEMPLATE .................................................................................................................................... 111 VISUAL STUDIO 2005 PROJECTLESS DEVELOPMENT .................................................................................. 116 MIGRATING TO VISUAL STUDIO 2005 PROJECT............................................................................................ 116
VISUAL STUDIO IDE ................................................................................................................................................ 118 SOLUTION EXPLORER................................................................................................................................................. 120 DOCUMENT WINDOW................................................................................................................................................. 122 TOOLBOX ................................................................................................................................................................... 122 ERROR LIST................................................................................................................................................................ 123 TASK LIST .................................................................................................................................................................. 124 SERVER EXPLORER .................................................................................................................................................... 126 CODE WINDOW .......................................................................................................................................................... 127 Outlining............................................................................................................................................................... 127 IntelliSense Code Member List............................................................................................................................. 128 Error Underlining ................................................................................................................................................ 129 SUMMARY .................................................................................................................................................................. 130 CHAPTER 5 XML WEB SERVICES STANDARDS AND CONCEPTS .............................................................. 131 .NET WEB SERVICE MESSAGE FLOW................................................................................................................ 132 HTTP............................................................................................................................................................................. 134 THE GET AND POST METHODS ................................................................................................................................ 135 HTTP WITH .NET ..................................................................................................................................................... 137 XML .............................................................................................................................................................................. 141 ELEMENTS.................................................................................................................................................................. 142 ELEMENTS, NAMESPACES, AND NAMESPACE DECLARATIONS ..................................................................................... 142 ATTRIBUTES AND NAMESPACES................................................................................................................................. 144 COMMENTS ................................................................................................................................................................ 144 WHITESPACE .............................................................................................................................................................. 145 PROHIBITED CHARACTER LITERALS ........................................................................................................................... 145 CDATA SECTIONS ..................................................................................................................................................... 146 The XML declaration............................................................................................................................................ 146 WELL-FORMED XML................................................................................................................................................. 146 XML WITH VISUAL STUDIO 2005 .............................................................................................................................. 147 XML SCHEMA DEFINITION (XSD) ....................................................................................................................... 150 DATATYPES ............................................................................................................................................................... 150 Numeric types ....................................................................................................................................................... 150 Date and time types .............................................................................................................................................. 151 Name and string types .......................................................................................................................................... 152 Boolean................................................................................................................................................................. 152 Byte....................................................................................................................................................................... 152 Date ...................................................................................................................................................................... 152 dateTime ............................................................................................................................................................... 152 decimal ................................................................................................................................................................. 153 double ................................................................................................................................................................... 153 duration ................................................................................................................................................................ 153 gDay ..................................................................................................................................................................... 153 gMonth ................................................................................................................................................................. 153 gMonthDay........................................................................................................................................................... 154 gYear .................................................................................................................................................................... 154 gYearMonth .......................................................................................................................................................... 154 hexBinary.............................................................................................................................................................. 154 int.......................................................................................................................................................................... 154 integer................................................................................................................................................................... 155 language ............................................................................................................................................................... 155 long....................................................................................................................................................................... 155 Name..................................................................................................................................................................... 155 NCName ............................................................................................................................................................... 155 negativeInteger..................................................................................................................................................... 156 nonNegativeInteger .............................................................................................................................................. 156 nonPositiveInteger................................................................................................................................................ 156
normalizedString .................................................................................................................................................. 156 positiveInteger ...................................................................................................................................................... 156 QName.................................................................................................................................................................. 157 short...................................................................................................................................................................... 157 string..................................................................................................................................................................... 157 time ....................................................................................................................................................................... 157 token ..................................................................................................................................................................... 157 unsignedByte ........................................................................................................................................................ 158 unsignedInt ........................................................................................................................................................... 158 unsignedLong ....................................................................................................................................................... 158 unsignedShort....................................................................................................................................................... 158 FACETS........................................................................................................................................................................ 158 enumeration.......................................................................................................................................................... 159 fractionDigits........................................................................................................................................................ 159 length.................................................................................................................................................................... 159 maxExclusive ........................................................................................................................................................ 159 maxInclusive......................................................................................................................................................... 160 maxLength ............................................................................................................................................................ 160 minExclusive......................................................................................................................................................... 161 minInclusive.......................................................................................................................................................... 161 minLength............................................................................................................................................................. 161 pattern .................................................................................................................................................................. 162 totalDigits............................................................................................................................................................. 162 whiteSpace............................................................................................................................................................ 162 LANGUAGE CONSTRUCTS ........................................................................................................................................... 163 simpleType............................................................................................................................................................ 163 restriction ............................................................................................................................................................. 163 list ......................................................................................................................................................................... 163 Union.................................................................................................................................................................... 164 XML SCHEMA STRUCTURES ................................................................................................................................ 164 XSD WITH VISUAL STUDIO 2005 ............................................................................................................................... 168 SOAP............................................................................................................................................................................. 169 WEB SERVICES DESCRIPTION LANGUAGE (WSDL) ..................................................................................... 186 DEFINITIONS ............................................................................................................................................................... 186 TYPES ......................................................................................................................................................................... 187 MESSAGE .................................................................................................................................................................... 187 PORTTYPE .................................................................................................................................................................. 188 BINDING ..................................................................................................................................................................... 189 SERVICE ..................................................................................................................................................................... 189 .NET WEB SERVICE WSDL....................................................................................................................................... 190
UDDI V3 ....................................................................................................................................................................... 190 SUPPORT FOR DIGITAL SIGNATURE ............................................................................................................................. 191 UDDI SDK ................................................................................................................................................................ 191 WS-* STANDARDS..................................................................................................................................................... 192 SUMMARY .................................................................................................................................................................. 192 CHAPTER 6 DATABASE PROGRAMMING WITH ADO.NET .......................................................................... 194 ADO.NET ..................................................................................................................................................................... 194 WHAT IS NEW IN .NET 2.0......................................................................................................................................... 195 Async Data Access................................................................................................................................................ 195 Metadata Schemas................................................................................................................................................ 195 Query Notification ................................................................................................................................................ 196 Multiple Active Result Sets ................................................................................................................................... 196 User Defined, XML Data Types ........................................................................................................................... 197
THE ADO.NET ARCHITECTURE........................................................................................................................... 197 .NET DATASETS ........................................................................................................................................................ 197 DATA PROVIDERS ...................................................................................................................................................... 198 Connection............................................................................................................................................................ 198 Command ............................................................................................................................................................. 198 DataReader .......................................................................................................................................................... 198 DataAdapter ......................................................................................................................................................... 199 XML...................................................................................................................................................................... 199 Interoperability..................................................................................................................................................... 199 Maintainability ..................................................................................................................................................... 199 Programmability .................................................................................................................................................. 200 Performance ......................................................................................................................................................... 200 Scalability............................................................................................................................................................. 200 In-Memory Representations of Data .................................................................................................................... 200 Minimized Open Connections............................................................................................................................... 200 Sharing Data Between Applications..................................................................................................................... 201 OLE DB DATA PROVIDER IN .NET............................................................................................................................ 201 .NET Data Provider.............................................................................................................................................. 201 THE OLEDBCONNECTION CLASS ............................................................................................................................... 202 THE SQLCONNECTION CLASS .................................................................................................................................... 202 OPENING AND CLOSING CONNECTIONS ...................................................................................................................... 203 The OleDbCommand Class .................................................................................................................................. 204 The ExecuteScalar Method................................................................................................................................... 205 The ExecuteReader Method.................................................................................................................................. 205 The ExecuteNonQuery Method............................................................................................................................. 206 The SqlCommand Class........................................................................................................................................ 207 Using Data Adapters ............................................................................................................................................ 208 The SelectCommand Property .............................................................................................................................. 208 The InsertCommand Property .............................................................................................................................. 208 The UpdateCommand Property............................................................................................................................ 208 The DeleteCommand Property ............................................................................................................................. 209 The DataReader Class.......................................................................................................................................... 210 The SqlDataReader Class..................................................................................................................................... 211 The IsClosed() Method ......................................................................................................................................... 212 The RecordsAffected Property.............................................................................................................................. 212 The OleDbDataReader Class ............................................................................................................................... 212 DATA ACCESS USING VISUAL STUDIO 2005..................................................................................................... 212 WORKING WITH DATASETS................................................................................................................................. 221 CREATING ADO.NET DATASETS ......................................................................................................................... 227 MANIPULATING AN ADO.NET DATASET .......................................................................................................... 229 MERGING THE CONTENTS OF DATASETS ................................................................................................................... 229 CHECK PRIMARY KEYS .............................................................................................................................................. 229 PRESERVE CHANGES .................................................................................................................................................. 229 APPLY CONSTRAINTS ................................................................................................................................................. 230 COPYING DATASET CONTENTS .................................................................................................................................. 231 Creating Data Views ............................................................................................................................................ 231 Handling ADO.NET DataSet Events .................................................................................................................... 232 CREATING A TYPED ADO.NET DATASET ......................................................................................................... 233 MANUALLY CREATING A TYPED DATASET ................................................................................................................ 235 MANUALLY DEFINE TYPED DATASET ........................................................................................................................ 241 RELATIONSHIPS WITH TYPED DATASET ..................................................................................................................... 242 ADO.NET EXCEPTION HANDLING IN .NET ...................................................................................................... 243 WRITING SQLCLR STORED PROCEDURE WITH MS SQL SERVER 2005 .................................................. 245 THE CONTEXT CONNECTION ...................................................................................................................................... 245
.NET STORED PROCEDURE WITH EXECUTEREADER() ............................................................................................... 252 SUMMARY .................................................................................................................................................................. 255 CHAPTER 7 ACCESSING MANIPULATING XML WITH .NET ....................................................................... 257 DOCUMENT OBJECT MODEL ............................................................................................................................... 257 THE XML PARSER ..................................................................................................................................................... 264 XMLREADER AND XMLWRITER ......................................................................................................................... 266 READING XML USING XMLTEXTREADER ................................................................................................................. 267 WRITING XML USING XMLTEXTWRITER ................................................................................................................. 271 XPATHNAVIGATOR................................................................................................................................................. 274 XPATH ....................................................................................................................................................................... 274 XML SCHEMA XSD................................................................................................................................................... 277 XML VALIDATION ................................................................................................................................................... 280 XML AND DATASET................................................................................................................................................. 284 SUMMARY .................................................................................................................................................................. 289 CHAPTER 8 .NET XML SERIALIZATION............................................................................................................ 290 .NET SERIALIZATION ............................................................................................................................................. 290 ENABLE SERIALIZATION USING ATTRIBUTES ............................................................................................................. 290 SERIALIZATION FORMATTER ...................................................................................................................................... 292 XML SERIALIZATION ............................................................................................................................................. 299 CONTROLLING SERIALIZATION .................................................................................................................................. 302 XMLROOT AND XMLELEMENT .................................................................................................................................. 303 IGNORING ELEMENTS ................................................................................................................................................. 313 SERIALIZING ARRAYS ................................................................................................................................................ 314 XMLANYELEMENT AND XMLANYATTRIBUTE .......................................................................................................... 316 XMLINCLUDE - DERIVED DATA TYPES ............................................................................................................ 318 DATATYPE MAPPING ................................................................................................................................................. 319 STRONGLY TYPED XML SERIALIZATION ....................................................................................................... 320 OPEN SCHEMA WITH XMLANYATTRIBUTE AND XMLANYELEMENT ................................................... 332 SUMMARY .................................................................................................................................................................. 336 CHAPTER 9 CREATING AND CONSUMING WEB SERVICE USING VISUAL STUDIO 2005 ................... 337 WEB SERVICE SUMMARY ..................................................................................................................................... 337 CREATING XML WEB SERVICES......................................................................................................................... 338 DEPLOYING WEB SERVICE .................................................................................................................................. 354 WEB SERVICE FILE TYPES ......................................................................................................................................... 357 XML WEB SERVICES DISCOVERY MECHANISM............................................................................................ 357 ADDING CUSTOM DISCOVERY INFORMATION FOR A WEB SERVICE ........................................................................... 358 CONSUMING WEB SERVICE ................................................................................................................................. 359 CLIENT APPLICATION ........................................................................................................................................... 365 SUMMARY .................................................................................................................................................................. 376 CHAPTER 10 TESTING AND DEBUGGING AN XML WEB SERVICE ........................................................... 377 OVERVIEW OF THE TESTING PROCESS ........................................................................................................... 377 ORGANIZING THE TESTING EFFORT................................................................................................................ 378
REQUIREMENTS-BASED TESTING ............................................................................................................................... 378 DEVELOPING A TEST PLAN ........................................................................................................................................ 379 APPROACHES TO DEVELOP TEST PLANS .................................................................................................................... 379 The Waterfall Approach ....................................................................................................................................... 379 The Evolutionary/Agile Approach ........................................................................................................................ 379 THE FOUR PILLARS OF SUCCESSFUL TESTING............................................................................................. 379 PILLAR I: FUNCTIONAL & REGRESSION TESTING ....................................................................................................... 380 PILLAR II: PERFORMANCE .......................................................................................................................................... 380 PILLAR III: INTEROPERABILITY .................................................................................................................................. 380 PILLAR IV: VULNERABILITY ASSESSMENT ................................................................................................................ 381 DEBUGGING............................................................................................................................................................... 381 CORDBG.EXE .............................................................................................................................................................. 381 DEBUGGING USING VISUAL STUDIO 2005 ................................................................................................................. 386 The Watch Window............................................................................................................................................... 387 The Call Stack Window ........................................................................................................................................ 387 The Locals Window .............................................................................................................................................. 388 The Autos Window................................................................................................................................................ 388 The Breakpoint Window ....................................................................................................................................... 388 TESTING WITH VISUAL STUDIO 2005 ................................................................................................................ 390 UNIT TESTING ............................................................................................................................................................ 390 RUNNING TESTS ......................................................................................................................................................... 403 CODE COVERAGE ....................................................................................................................................................... 405 INITIALIZING AND CLEANING UP TESTS ..................................................................................................................... 406 STATIC ANALYSIS ................................................................................................................................................... 407 PROFILING................................................................................................................................................................. 408 SAMPLING .................................................................................................................................................................. 409 INSTRUMENTATION .................................................................................................................................................... 409 IMPLEMENTING SAMPLING ......................................................................................................................................... 409 SUMMARY .................................................................................................................................................................. 415 CHAPTER 11 DEPLOYMENT.................................................................................................................................. 417 .NET DEPLOYMENT................................................................................................................................................. 417 MAINTAINING ASSEMBLY VERSIONS............................................................................................................... 418 PACKAGING AND DISTRIBUTION OPTIONS.................................................................................................... 421 PUBLISHING WEB SERVICE ......................................................................................................................................... 422 PUBLISHING CLIENT APPLICATION USING CLICKONCE DEPLOYMENT ....................................................................... 426 ClickOnce and Windows Installer Comparison Table ......................................................................................... 426 Using ClickOnce Deployment .............................................................................................................................. 427 Publishing to File System ..................................................................................................................................... 427 Publishing To a Web Location ............................................................................................................................. 430 How ClickOnce Deployment Works ..................................................................................................................... 432 USING WEB DEPLOYMENT PROJECTS WITH VISUAL STUDIO 2005 ........................................................ 433 INSTALLING WEB DEPLOYMENT PROJECTS................................................................................................................ 433 BUILD MENU COMMAND ........................................................................................................................................... 434 WEB DEPLOYMENT PROJECT PROPERTY PAGES ........................................................................................................ 435 MANAGING CUSTOM BUILD CONFIGURATIONS ......................................................................................................... 439 WEB SETUP PROJECTS ............................................................................................................................................... 442 CREATING A WEB SETUP PROJECT FOR XML WEB SERVICE ..................................................................................... 443 SUMMARY .................................................................................................................................................................. 447 WEBMETHOD PROPERTIES.................................................................................................................................. 448
BUFFERING RESPONSE FOR A WEB METHOD ............................................................................................................. 448 CACHING THE RESULTS FOR A WEB METHOD ............................................................................................................ 453 SPECIFYING A DESCRIPTION FOR A WEB METHOD ..................................................................................................... 455 ENABLING SESSION STATE IN WEB METHOD ............................................................................................................. 456 IDENTIFYING OVERLOADED WEB METHODS USING AN ALIAS .................................................................................. 459 WEB METHOD TRANSACTION .................................................................................................................................... 460 ASYNCHRONOUS WEB SERVICE......................................................................................................................... 462 ASYNCHRONOUS DELEGATES .................................................................................................................................... 463 CONCURRENT ASYNCHRONOUS CALLS ...................................................................................................................... 470 IMPROVING RESPONSIVENESS IN WINDOWS CLIENT .................................................................................................. 473 SOAP EXTENSIONS .................................................................................................................................................. 477 USING SOAP EXTENSIONS......................................................................................................................................... 478 USING SOAPLOGGER.................................................................................................................................................. 491 SUMMARY .................................................................................................................................................................. 492 CHAPTER 13 .NET REMOTING ............................................................................................................................. 494 .NET REMOTING PROXY ARCHITECTURE ...................................................................................................... 494 REMOTABLE AND NONREMOTABLE OBJECTS ............................................................................................. 495 MARSHAL-BY-VALUE OBJECTS .................................................................................................................................. 495 MARSHAL-BY-REFERENCE OBJECTS .......................................................................................................................... 497 SERVER ACTIVATED AND CLIENT ACTIVATED OBJECTS......................................................................... 497 SERVER ACTIVATED OBJECTS (SAOS)....................................................................................................................... 498 Using Configuration File ..................................................................................................................................... 503 CLIENT ACTIVATED OBJECTS (CAOS) ....................................................................................................................... 507 Using Configuration File ..................................................................................................................................... 512 Using Lifetime Leases........................................................................................................................................... 513 Renewing Lifetime Leases .................................................................................................................................... 517 DIFFERENCES BETWEEN SERVER ACTIVATED OBJECTS AND CLIENT ACTIVATED OBJECTS ....................................... 519 TRANSPORT CHANNELS........................................................................................................................................ 520 TCP CHANNEL ........................................................................................................................................................... 520 HTTP CHANNEL ........................................................................................................................................................ 521 IPC Channel ......................................................................................................................................................... 524 CHANNEL SINKS....................................................................................................................................................... 527 REMOTABLE BANK DEBIT LOG .................................................................................................................................. 528 The Server............................................................................................................................................................. 529 The Client ............................................................................................................................................................. 537 SUMMARY .................................................................................................................................................................. 545 CHAPTER 14 WEB SERVICE SECURITY............................................................................................................. 546 WINDOWS AUTHENTICATION............................................................................................................................. 546 MANAGING USERS BY USING MEMBERSHIP .................................................................................................. 553 CREATING A MEMBERSHIP DATABASE ON SQL SERVER ........................................................................................... 555 CONFIGURING AN APPLICATION TO USE MEMBERSHIP .............................................................................................. 559 Using Web.Config ................................................................................................................................................ 560 Using ASP.NET Configuration Settings ............................................................................................................... 561 Implementing Membership ................................................................................................................................... 563 CUSTOM AUTHENTICATION AND AUTHORIZATION WITH SOAP HEADERS....................................... 567 DEFINING SOAP HEADERS ........................................................................................................................................ 567 DEFINING A SOAP HEADER CLIENT .......................................................................................................................... 570 IMPLEMENTING TOKEN AUTHENTICATION WITH SOAP HEADERS...................................................... 573
IMPLEMENTING SECURITY TOKEN SERVICE ............................................................................................................... 574 IMPLEMENT CLIENT FOR TOKEN SECURITY ............................................................................................................... 586 SUMMARY .................................................................................................................................................................. 590 CHAPTER 15 WEB SERVICES ENHANCEMENTS 3.0 ....................................................................................... 592 WEB SERVICES ENHANCEMENTS OVERVIEW............................................................................................... 592 WS-SECURITY ........................................................................................................................................................... 593 Security Tokens..................................................................................................................................................... 593 INSTALLING WEB SERVICES ENHANCEMENTS ............................................................................................ 594 USING WEB SERVICES ENHANCEMENTS......................................................................................................... 595 WSE COMMUNICATION PROCESS...................................................................................................................... 598 REQUESTING PROCESS ............................................................................................................................................... 598 RESPONSE PROCESS ................................................................................................................................................... 599 IMPLEMENTING WSE SERVICE................................................................................................................................... 600 IMPLEMENTING WSE CLIENT .................................................................................................................................... 608 IMPLEMENTING CUSTOM USERNAME SERVICE .......................................................................................................... 617 X. 509 CERTIFICATE ................................................................................................................................................ 625 THE X.509 CERTIFICATE MANAGEMENT TOOL.......................................................................................................... 625 WSECERTIFICATE3.EXE ............................................................................................................................................ 626 SIGN AND ENCRYPT A SOAP MESSAGE (END-TO-END SECURITY) ........................................................................... 628 Configuring WSE Web service to Sign and Encrypt............................................................................................. 628 Configuring WSE Client Application to Sign and Encrypt................................................................................... 630 BEST SECURITY PRACTICE ......................................................................................................................................... 633 BINARY EXCHANGE WITH MESSAGE TRANSMISSION OPTIMIZATION MECHANISM (MTOM) .... 633 IMPLEMENTING MTOM SERVICE............................................................................................................................... 635 IMPLEMENTING MTOM CLIENT ................................................................................................................................ 639 SUMMARY .................................................................................................................................................................. 641 CHAPTER 16. WINDOWS COMMUNICATION FOUNDATION (WCF) .......................................................... 642 WCF FOUNDAMENTALS ........................................................................................................................................ 643 CONTRACTS ............................................................................................................................................................... 644 Defining Service Contracts................................................................................................................................... 644 Defining Data Contracts ...................................................................................................................................... 645 RPC/Messaging .................................................................................................................................................... 648 BINDING AND ADDRESS (ENDPOINT) ......................................................................................................................... 651 IMPLEMENTING WCF SERVICES........................................................................................................................ 653 IMPLEMENTING WCF SERVICE .................................................................................................................................. 653 IMPLEMENTING A WCF SERVICE CLIENT .................................................................................................................. 661 IMPLEMENTING HOSTING ........................................................................................................................................... 671 IMPLEMENTING SECURE RELIABABLE MESSAGING.................................................................................................... 682 IMPLEMENTING CUSTOM BINDING, RELIABLE MESSAGING AND SECURITY ............................................................... 688 IMPLEMENTING WCF WITH MICROSOFT MESSAGE QUEUE........................................................................................ 698 WCF SESSIONS .......................................................................................................................................................... 713 WCF TRANSACTIONS................................................................................................................................................. 714 DUPLEX COMMUNICATION ........................................................................................................................................ 714 SUMMARY .................................................................................................................................................................. 723 CHAPTER 17. ARCHITECTURE CONCEPTUALIZATION WITH DISTRIBUTED SYSTEM DESIGNERS ................................................................................................................................................................ 724 APPLICATION DESIGNER...................................................................................................................................... 724 IMPLEMENTING APPLICATION DESIGNER ................................................................................................................... 724
Connecting the Applications................................................................................................................................. 727 Defining Web Service Prototypes ......................................................................................................................... 732 Adding an Endpoint through WSDL ..................................................................................................................... 733 Implement the Application.................................................................................................................................... 736 UPDATING THE DESIGN .............................................................................................................................................. 740 ADDING A WEB APPLICATION .................................................................................................................................... 751 SETTINGS AND CONSTRAINTS .................................................................................................................................... 759 SYSTEM DESIGNER ................................................................................................................................................. 760 SPECIFYING LOGICAL DATACENTER DIAGRAM.......................................................................................... 765 SETTINGS AND CONSTRAINTS .................................................................................................................................... 771 Importing IIS Server Settings ............................................................................................................................... 771 DEPLOYMENT DIAGRAM ...................................................................................................................................... 775 CREATING THE DEPLOYMENT DIAGRAM .................................................................................................................... 775 VALIDATING THE DEPLOYMENT SCENARIO ............................................................................................................... 780 GENERATING DEPLOYMENT REPORT ......................................................................................................................... 783 SUMMARY .................................................................................................................................................................. 784 INDEXES...................................................................................................................................................................... 785
The Complete Reference To Professional SOA with Visual Studio 2005
Introduction -Applications must retool or perish. Organizations that fail to realize the efficiencies of integration by-design will lose in the long run to those who pursue them. – Pat Helland
Service Oriented Architecture has the potential to be the next great paradigm that will once and for all change computing as we know it. The main promise of Service Oriented Architecture is that business systems can be used by anyone, from anywhere, at any time and on any system. The popularity in Service Oriented Architecture is largely generated by the ability to allow developers to seamlessly integrate disparate systems without the requirement to understand the underlying technology specific details. This abstraction from technology is due to the ability to build Business Services which are application components that describe the application process instead of describing the technology. The use of Business Services allows developers to efficiently integrate application processes between disparate systems that are either internal to the organization or are maintained by another vendor without the requirement to have an intimate knowledge about the system process. Today more and more developers, architects and IT managers are turning to Service Oriented Architecture. This growth in popularity is due to today’s increase in pressure to provide the outmost efficiency and reliability in solution development. As a result developers and architects are driven to focus their efforts on developing reusable components to ensure that they can be easily reused in future. With the focus of reusability in mind developers and architects are able to develop and expand on existing enterprise systems quickly and efficiently. Through Service Oriented Architecture, system development is unlike before. For the first time in the history of software development, developers are able to build enterprise systems that can easily keep up with business agility and changing business requirements whilst developing new functionalities. Service Oriented Architecture is a revolution that we have all been waiting for. Following the release of the second generation of the .NET.Framework, application development is on a new level playing field. The people at Microsoft have spent enormous amounts of time and research into application development. The fruit is Visual Studio 2005. With Visual Studio 2005 applications can be developed much more easily and efficiently. Throughout the book we will use Visual Studio 2005 and .NET 2.0 to illustrate SOA development and design. This book will not only focus on the technical aspects of SOA, but also place strong emphasis on the delicate issues of establishing SOA at the enterprise level and the pitfalls associated. The principles described in this book are the foundations on which enterprise systems are constructed. Through the book we will learn to develop application systems that are flexible, agile, and secure at lower costs This book will provide developers, architects and IT managers with a roadmap for success in establishing SOA at the enterprise level. It is a concrete guide, blueprint and contains best practices for SOA architecture using the .NET Framework.
20
The Complete Reference To Professional SOA with Visual Studio 2005
Part 1 Core Concepts Chapter 1: Introduction to Service Oriented Architecture For years, large enterprises have struggled with the challenge of integrating disparate and distributed applications across their organizations and their partners. Despite continuous technological advancements, most IT departments have chosen to address this problem through custom development. Custom development may work for smaller organizations that have relatively few endpoints that need to be integrated. However this approach does not meet the needs of larger organizations whose IT environments are much more complex. Studies have shown that as the number of endpoints increases the cost and complexity of managing the environment increases exponentially. The focus today is on business solutions integration; this focus comes at no surprise when we consider the amount of time and money spent in buying and building information technology such as Enterprise Resource Planning (ERP) and Customer Relationship Management (CRM) Applications. It is no wonder companies are looking for ways to preserve and extend these investments. Unfortunately, most of these applications were implemented in Silo Architectures without considering the effects and dependencies that the applications would have on other technologies and the business itself. This lack of vision in integration only leads to poor return on investment for technology purchases and has always prevented businesses from functioning efficiently and cost effectively. In order to remain competitive in today’s fast-moving marketplace, organizations must be able to observe and understand what is happening in all areas of their business, and must be able to quickly adapt as business conditions change or as threats and opportunities arise. Due to this exact reason business leaders are constantly searching for ways to reduce costs, improve efficiency, and grow the bottom line. All of which must be accomplished with fewer resources. Achieving superior efficiency and agility of real-time business can be a daunting task for any organization, along with the technical challenges of integrating applications and automating routine tasks. Achieving architectural efficiency and agility requires a fundamental change in how IT has traditionally supported business requirements. Today, organizations are turning to Service Oriented Architecture (SOA) in order to improve their business agility. SOA is emerging as the premier design principle for new business applications as it gradually replaces monolithic architecture. SOA promises to continue to stimulate conversations within the IT industry and maintain the increase in interest to the businesses that are seeking to lower costs, increase return on investment (ROI), leverage existing assets, and integrate systems. SOA’s potential is real, and its importance cannot be understated. When appropriately implemented, it can help an organization improve ROI by allowing incremental development through reuse of existing business components. Architecturally it helps to improve the clarity of the application topology. In this chapter we will be covering SOA core concepts and what it really means for a business to implement SOA. We will also be examining the reason for the rise in popularity of SOA, as well as looking at real world case studies.
21
The Complete Reference To Professional SOA with Visual Studio 2005
What is Service Oriented Architecture? Service Oriented Architecture is a concept for providing agility and flexibility to an architecture. SOA focuses on building distributed systems through the use of components that have a common Web service interface. Though SOA does not only refer to software, it is a concept and at its most abstract, service orientation views everything from the mainframe application to the printer to the shipping dock clerk to the overnight delivery company as a service provider. These Service providers expose their functions through the means of a public interface. The interface is more like an advertisement describing what the function is and how to access it. The service-oriented architecture then maps these capabilities and interfaces so they can be orchestrated into processes. The service model itself is in segments. The new formed process is a service itself, this service can then form a higher level service by exposing new and aggregated functionality. This is referred to as entity aggregation. Fundamental to the service model is the separation between the interface and the actual implementation. The consumer of a service need only (and should only) understand the interface which describes the service. The advantage of the separation is that the implementation is allowed to evolve over time, without breaking the clients that consume these service interfaces. Through the separation, the same interface can offer many different implementations. The key benefits of service orientation derive from this abstraction from implementation. To developers and architects SOA provides a means to construct application quickly and efficiently through component reuse. By adopting service orientation applications are no longer tightly coupled. This can dramatically reduce the complexity involved when supporting or updating the application with new requirements. It also allows applications to be gracefully integrated to other architectures overtime. To the IT manager, SOA allows different enterprise systems to be integrated quickly and efficiently. As service orientation provides a model for aggregation from which improved information and business processes can be derived. Service orientation will also allow existing redundant legacy systems to be recycled to provide value back into the business again. To the Chief Information Officer, SOA can protect IT investment from changes. In the past as the business evolved and new requirement is requested by the business stakeholders. Often to cater to these new requirements entire systems are tossed out and new system constructed. SOA helps to protect applications from this process. Through separation between implementation and interface, the actual implementation of the business applications is protected behind an interface. The separation between implementation and interface allows systems to continue to evolve and be updated without any impact on the rest of the architecture. To the business analyst, SOA provides the means to map IT investment with the requirement of the business. This allows business analysts to better understand the cost and trade offs associated with the business. By moving to SOA, a constellation of services and devices can be efficiently integrated, to more effectively meet the needs of the business and its challenges. Enterprise Application development and consolidation through the use of SOA is truly a revolution for the industry not seen since the days of disconnected systems.
Explaining Service Oriented Architecture Using Metropolis Pat Helland, Micrsoft Architect, in his 2004 essay, likened service-oriented architecture to a bustling metropolis. In this analogy Metropolis consisting of many disparate systems whether local or external to the organization. If we were to think of each of these disparate systems as an individual city and SOA as the railroad network that connects these cities, we can easily picture these disparate systems working together. Metropolis is an analogy in an attempt to both explain what is happening in Information Technology today and to show us what we can expect to happen in the future. In the past, using the monolithic approach, businesses were developed to target each individual city, their supply chain to distribution was only developed to target that one specific city. In this environment, expansion into another city was difficult, because a brand new distribution chain has to be setup and the intricacies of operating in this city has to be managed. However, using a Service Oriented Architecture, a new distribution
22
The Complete Reference To Professional SOA with Visual Studio 2005
chain is not required. We can use another distribution chain that already exists, is established and operating in that city to help distribute our own product. Using the SOA approach we can easily branch out our business whenever required. This level of flexibility is transcendent and will allow the business to expand very rapidly.
Cities as Software Vendors In the world of Metropolis we symbolize cities as software vendors. Inside the cities are independent buildings with little or no connection between each other. These software vendors gradually evolved as new applications were built and extended. Each application stood apart and independent of its neighbors within the same vendor. Each Software vendor had its own culture, style and process of doing things. Economic pressures changed our cities. Economic opportunity is what really drove cities to modernize, to share services, and to devise creative means to achieve efficiencies. Economic pressures are changing our software vendors too. As new applications are developed and old applications extended. Developers must consider how to integrate them to the shared infrastructure and to maximize reusability.
Factories and Buildings as Applications We can think of factories and buildings as applications, and cities as the software vendors that have built them. Both the appetites of the local market and the sophistication of the manufacturing process limited the goods manufactured by these factories. Factories were very rigid, and produced its own components to be assembled into the products that it manufactures. In this rigid style products were created. The process was inefficient and the product was expensive and often of poor quality. Most of the applications today are just like the buildings and factories we described earlier. They’re clumsy and, poorly thought out. As a result they were very rigid and do not accept the work of other applications as input. However, with the introduction of railroad, the manufacturing processes were quickly and profoundly altered. Transportation allowed the production of higher quality, more sophisticated goods. It is only by decoupling of the product that change and efficiency can be achieved. By leveraging the work of other specialized factories to manufacture components required in production, changes in the production could be achieved more easily. The use of specialize component manufacturers also helped to improve the quality of the product. The demand for manufacturing by others provided the economic stimulus that gave reason for many factories to co-exist today. Just as in software development today, organizations are realizing the importance of third party software vendors. This new understanding in component based development, allowed enterprise applications to utilize and customize existing components instead of reinventing them. These third party components are tested and can be easily integrated into the organization’s own application. Utilizing the components improved the quality and features of the application whilst reducing considerable development and testing time.
Transportation as Communication In Metropolis, transportation refers to the movement of people and goods. This movement stimulated tremendous change. People were able to travel to different cities and visit places they were unable to previously. Retail began to expand rapidly as people were able to visit other cities and gather goods from stores in these cities. Through the movement in goods people arrived at a new expectation that things would work together. However, prior to the transportation development, one manufacturer’s goods were incompatible with another manufacturer’s. In the application world, we can see that in the past applications were structured in a rigid monolithic architecture. With the arrival of SOA through the use of business services, enterprise architectural applications are becoming more interoperable and are starting to communicate with each other.
23
The Complete Reference To Professional SOA with Visual Studio 2005
Manufactured Goods as Standardization Standardization between manufacturer processes was vital. By establishing tight controls over the specification and production, it allowed companies that produced parts with a high degree of precision to thrive, while those with less consistent processes failed. As a result standardization had expanded across manufacturers, and de facto standards had emerged for common parts. These were sizes for nuts and bolts and cylinders. Now, with the expectation that products produced by one factory would be interchangeable and interoperable with similar and complementary components produced by another. Manufacturers could pick and chose their preferred components depending on the price and quality of the component. Today majority of our data structures are still mostly non-standardized. All application models information in its own way, and a lot of time is spent adjusting the data structure to integrate different applications. However, we’re beginning to see the interoperable policy put in place through the use of XML and Web Services specifications. Through these rudimentary rules, application data structure will be able to support improved interchangeability of data.
Manufactured Components as Virtual Enterprises In the Metropolis world manufacturers begin to understand the benefits of manufacturing specialized components and utilizing components from other manufacturers. With their new understanding manufacturers begin to strive for higher quality and more sophisticated components. Competition amongst the component manufacturers drove efficiencies and quality improvements. All of which is only made possible through detailed specifications for the manufactured components. Manufacturing became driven by information, reputation, and trust. Companies partnered to change the process of bringing goods to the market. Just as manufacturers created components, today software vendors created Assemblies of their business process and functionality. Rather than building the entire application in house, many organizations today outsource small portions of work to other software vendors through the use of well-documented specifications. When these software components are finally completed they’re integrated. The use of specialized software vendors reduced cost as well as improved quality of the end product. However the engineering, marketing, and ownership of the product may still remain in house.
Urban Infrastructure as IT Infrastructure Evolution In Metropolis through gradual urban evolution common services such as water, sewer, gas, electricity and telephony were gradually built and managed by the government to achieve efficiencies and to make the city a more livable place. However hooking up these services to every building in the city proved to be extremely difficult, as no prior thought for these services were ever given when the buildings in Metropolis were first constructed. Similarly, each Software Vendor, for a long period of time, had built their own applications with numerous standards. These applications easily became stagnant as they were extended over and over, standards were lost as a result, exceptions become harder to route, parse, to take action. Processing data between these dispersed applications became inhibiting and difficult. We now understand that application architecture needs to be well-designed and well thought out in order for application services to function smoothly. Since different visions lead to different infrastructure goals care must be taken to balance infrastructure investments. If a city actively pursues growth but fails to anticipate the impact on transportation for example, congestion and inefficiency will result. In the coming section we will be covering planning and resource allocation as well as balancing the needs of the business against resource and schedule.
24
The Complete Reference To Professional SOA with Visual Studio 2005
Enterprise Architecture An Enterprise Architecture consists of the various structures and processes. Enterprise Architecture is a representation of all that exists within an organization. The structures themselves can be either the IT based or the business process based. A good representation of the enterprise architecture thus will represent the business model as it is today as well as incorporate the business strategies for the future. The Enterprise Architecture representation can thus be used as a communication bridge between business stakeholders and the IT system implementer. For our purposes Enterprise Architecture will mean the design, planning and execution of the overall IT systems of an enterprise. To see how Enterprise Architecture affects the role and circumstances of IT in business, we should first examine the concept of “architecture” itself. Architecture is the process of designing buildings so that they serve their intended purpose. If an architect designs a house, it is meant to be lived in if he or she designs an office, it is meant to be used for work. Similarly, Enterprise Architecture is the process of designing IT systems in order to develop an IT structure that realizes the needs of the business. Enterprise Architecture refers to the ability to enable the business goals of the organization. We must keep in mind when designing architecture not to over step the boundary of over indulgence and detract from the need of the organization. To do so is dangerous and costly for the organization that seeks to optimize its processes.
Architectural Tradeoff Triangle Enterprise Solutions frequently fail, are completed late, or exceed the planned budget. Ambiguous requirements can contribute to, or be the cause of, each of these problems. The scope specifies what the solution will and will not do. To effectively define and manage the scope the needs of an organization have to be identified. These are: *
Identifying project constraints
*
Managing tradeoffs
*
Establishing change control
*
Monitoring project progress
In the process of identifying and managing trade-offs in an Enterprise Architecture, the features of a solution are not necessarily reduced, but identifying the tradeoffs might result in a reduction of features. Managing tradeoffs provides a structured way to balance all parts of the project while realizing that we cannot attain all of our goals at the same time. In Enterprise Solutions, there is a clear relationship between such project variables as resources, schedule, and features of the project. The relationship between these variables is illustrated in Figure 1-1.
Figure 1-1 illustrates the trade off triangle
25
The Complete Reference To Professional SOA with Visual Studio 2005
As illustrated by the trade-off triangle, any change to any one of the components implies that a corresponding change might need to be made to the other components. The key to developing a solution that meets the customer requirements is to determine and maintain the correct balance between resources, development date, and features. Often, project teams are reluctant to reduce the number of features in the solution. The trade-off triangle helps to explain the constraints and present the options for trade-offs.
Architectural Tradeoff Matrix The Architectural trade-off matrix Figure 1-2 is a tool can be used when making trade-off decisions. These decisions are made early in the solution. The trade-off matrix helps identify the solution’s features that are considered essential, the features that are not essential but that would be good to include, and the features that can be eliminated or added to the next version to accommodate the other two variables.
Figure 1-2 illustrates the trade-off matrix used to make trade off decisions
*
In a decision making process:
*
If we are given fixed resources and fixed schedules then we must adjust the features that need to be delivered.
*
If we are given fixed resources and fixed features to develop then we must adjust the schedule.
*
If we are given fixed features and fixed schedules then we must adjust the resources.
Successfully managing and adjusting the trade off variables in a project will ensure the success of your SOA project.
Understanding Business Benefits of SOA As businesses continue to expand, demands for IT infrastructure also increases. In today’s business mergers and acquisitions can form quickly. As a result there is an even greater demand for new applications that can facilitate the new business model. This results in the formation of many distributed application islands that quickly become isolated and interoperable. In this complex environment, application silos are formed. These are applications that are tightly coupled and self contained and difficult to interoperate with other applications. As companies merge, systems and information are duplicated, these systems are for example payroll and HR. This has not been a concern in the past, since each business operated independent of each other and each system managed its own individual business. In recent years, due to new demands, the industry has adopted a new trend. This trend involves the movement towards automating business processes between similar systems.
26
The Complete Reference To Professional SOA with Visual Studio 2005
This process involves integrating and aggregating entities/information that are present in different systems. As a result instead of making phone calls to HR and Payroll and Benefits to update an employee’s address details in each of these different systems. By automating the process through entity aggregation we can update the information with just one phone call. We can also construct a self-service portal that will update personal information seamlessly across different systems. Businesses also benefit by connecting systems and providing integrated solutions to customers. By implementing SOA, the total cost of ownership (TCO) is dramatically reduced. While the integrated solution with applications such as enterprise resource planning (ERP) and customer relationship management (CRM) systems can also provide more value to the end users. The integration of all of these systems can also benefit the business by reducing the overall total cost of ownership for support individual business functionalities. Through the use of SOA, organizations are able to make better design, management, and investment decisions. This level of visibility into application usage allows companies to identify, and, more importantly, to make changes to existing business processes to take advantage of opportunities for continuous improvement. This ability to nimbly change and modify business processes as business needs require will give companies a distinct advantage over their less agile competitors. Today integrating disparate systems components is about effectively orchestrating the interaction between enterprise resources: whether it’s machine to machine, person to person, or a combination of both, in a manner that is conducive to the way business is conducted. Through SOA, IT can easily morph into a valuable asset by introducing a comprehensive process-centric integration approach that delivers that and more. Thus, allowing IT systems to make the transition from an inhibitor to an enabler of business. Organizations can expect to experience the following benefits when deploying enterprise systems built using SOA.
Better Visibility into Operations and Performance A Process-centric approach to business integration can unify lines of business using a common infrastructure that will provide vital information to different types of users at all levels of the enterprise. For instance, a Chief Financial Officer will be able to access real-time or near-real-time information from financial reporting, order management, customer relationship management, and business intelligence systems to provide a single view of the customer relationship as well as profitability. A little further down the corporate hierarchy, a vice president of logistics can access real-time information about fulfillment and logistics operations, with which he or she can make decisions to streamline the supply chain.
More Efficient Operations By gaining visibility across the enterprise, business leaders can take better inventory of their operating strengths and weaknesses, and consequently identify ways of correcting problems and optimizing efficiency. The adoption of a process centric integration approach that supports full process lifecycle management will allow IT organizations to provide the business with the information and tools they require to make these informed decisions. Business leaders must be able to constantly monitor how business activities (that is to say, processing orders and serving customers) are executed with respect to their competition and corporate goals.
Better Business Agility As the marketplace evolves, business leaders need to make changes such as introducing new products, new sales channels, and new value chains. In order to be able to do so in a consistent, efficient, cost-effective way they rely on their IT organizations to respond quickly with necessary changes to the underlying system infrastructure. IT organizations that have built a modular flexible architecture are in a position to adequately support the needs of change management.
27
The Complete Reference To Professional SOA with Visual Studio 2005
What is a Web Service? In 2000, the World Wide Web Consortium (W3C) accepted a submission for the Simple Object Access protocol (SOAP). This XML-based messaging format established a transmission framework for inter-application or interservice communication via HTTP. As a vendor neutral technology, SOAP provided an attractive alternative to traditional proprietary protocols, such as CORBA and DCOM. In the following year, W3C has accepted and published the WSDL specification. WSDL is implemented through XML and acts as the interface in the interface/implementation model of Web service. It is essentially a language that is used to describe the interface of the Web service. The interface is further supplemented by the Universal Description, Discovery and Integration (UDDI) specification. The UDDI much like a yellow page directory allows users to perform dynamic searches on the directory for a specific service implementation. Since then, XML Web services has received industry wide acceptance. The support for XML Web services has furthered the popularity and importance of a service oriented design principle.
Loose Coupling In the 1980s and earlier application architecture was developed in a fairly simple format. The architecture usually consisted of UI Components at the very top, followed by business logic in the middle and data access components at the very bottom. This was often referred to as the Silo Architecture also known as the Vertical Architecture Figure 1-3. From 1980s towards 1990s the software architecture moved towards a more horizontal architecture. This is where we are starting to see a separation of logic in layers. Layers in software refers to a way of organizing the code to provide logical abstraction and separation. Typical layers include Presentation, Business and Data layers. Layers are primarily used to gain the benefits of logical organization and grouping of similar functionalities. This in turn supports code reuse. This is referred to as the Layer Architecture or Horizontal Architecture What we’re now seeing through service oriented architecture is a steady move from layers to tiers. Tiers is about the physical separation between code. In other words tiers is about where layers run. We’re now increasingly seeing that systems are no longer running off from one Server but from several different servers located in different countries. A database on Human Resource might be located in the United States whilst another database on payroll might be located in Australia. This form of architecture is referred to distributed architecture. This is what SOA is helping us to evolve towards.
Figure 1-3 shows the evolution of software architecture from vertical to horizontal to today’s distributed architecture.
Loose Coupling refers to the act of joining things together. In application development loose coupling refers to the degree which software components depend upon each other. Traditionally applications are “tightly coupled”, where each application may or may not connect with others in a distributed environment through a combination of proprietary interfaces and network protocols. These
28
The Complete Reference To Professional SOA with Visual Studio 2005
applications were often designed within system boundary of an enterprise or even within a specific business unit of the enterprise. As a result the applications have no concept of interoperating with other units of work outside of its system boundary. A solution to the tightly coupled application is an attempt to develop applications in a loosely coupled manner. Loose coupling is seen as a way to reduce the overall complexity and dependencies of applications on each other. Loose coupling can be achieved through using XML Web service by using the interface/implementation approach. Loose coupling leads towards the same goal as service orientation, which is providing an architecture that is more agile, allowing faster response to change and improvement for overall system agility. In addition, system maintenance is much easier. Loose coupling is especially important in the enterprise architecture. As the relationships between business partners change rapidly. Vendor alliances are constantly made, altered or broken, and business processes between trading partners are constantly changing to adapt the new market requirements. Due to the severe and fast paced competition in business today it is essential that the underlying IT infrastructure could reflect the flexibility and independence of the business efficiently. Overall scalability is also a lot easier in a loosely coupled architecture. Key software components can be easily taken and deployed onto multiple servers to improve reliability and availability. Today, in Service Oriented Architecture, loose coupling is mostly implemented through the use of Web services. Once a piece of software has been exposed as a web service, it is relatively simple to access through the use of WSDL and UDDI.
Services The concept of services has been around for quite a while. Service by definition refers to any component that provides functionality and is an independent building block that can be integrated together collectively to represent an application. Unlike traditional components each service represents a unique discrete unit of work in their environment. This means that each service is responsible for its specified role in its own domain. In the business sense the service focuses on a specific business function or possibly a group of functions. This model allows for the creation of isolated units of business functionality that can be easily reused throughout development. The loosely bound services help to provide freedom within the architecture. In the past service orientation was created using services though increasingly today SOA refers to the use of XML Web services. This is because of the vendor neutral implementation and its interface/implementation provide as an ideal model for SOA.
XML Web Services The most widely accepted and successful type of service is the XML Web Service. The popularity generated in XML Web Service is largely due to its ability to be able to communicate via Internet Protocol (HTTP) and send and receive data in XML format. Using XML Web services allows a common framework for which different application environment and platform are able to communicate with each other. Using the common communication framework HTTP and XML, XML Web Services can communicate with any application that uses XML over HTTP. Today, with the introduction of Asynchronous JavaScript And XML (AJAX) we can also call and access XML Web Services from our browsers.
XML and XML Schema XML provides the ability to represent data that is independent of application, protocol, operating system and programming language. XML was quickly adopted industry wide as a technology neutral communication framework. It was exactly what everyone had been waiting for. Due to the competitiveness in IT, each vendor
29
The Complete Reference To Professional SOA with Visual Studio 2005
pushed for its own technology and proprietary standards. The industry was quickly filled with varying technologies that weren’t able to work together. With the adoption of XML, industry vendors now had a means to communicate and work together. The structure of XML documents is based on rules that are also known as grammar. These rules are specified by a XML Schema document. A schema document contains the definitions of elements, attributes, and data types. Any XML that is created can be validated against an XML Schema. Though XML can be used independently of XML Schema, in Web Services the XML that we work with will be governed by an XML schema called Web Services Description Language (WSDL).
XPath XPath is used to refer to parts of an XML document. XPath gets its name from its use of a path notation as in URLs for navigating through the hierarchical structure of an XML document. In addition to its use for addressing, XPath is also designed so that it has a natural subset that can be used for matching and testing whether or not a node matches a pattern. XPath models an XML document as a tree of nodes. There are different types of nodes, including element nodes, attribute nodes and text nodes. XPath defines a way to compute a string-value for each type of node. Some types of nodes also have names.
SOAP The SOAP specification provides standards for the format of a SOAP message and how SOAP should be used over HTTP. SOAP was created to help provide the means to transport XML documents from one computer to another. SOAP can be used with a number of standard transport protocols. HTTP is one of the most common and preferred mode of transport protocols used because of its ability to work with firewalls. SOAP itself is built using XML. SOAP is used to call exposed methods of the Web service. It describes how the data being passed to those methods is structured, and what the data is. If the client passes the Web service a correctly formatted SOAP document as a web service request, effectively calling a method, the Web service will return another SOAP document containing a response. A SOAP message consists of three parts an Envelope, Header and a Body.
Figure 1-4 shows the SOAP structure.
The SOAP Envelope is used to store the XML message. This envelope is acts as a container to hold XML information contained as shown in Figure 1-4. The envelope consists of two main parts: the SOAP Header and the SOAP Body of the message. SOAP header can be used as a container for additional information about the SOAP message for example security credentials or message authentication information like message hash values. This information is then used to manage and or to help secure the package. SOAP body contains the XML message content. The body can contain information about the Web service method that we’re about to execute in a request. In a request the body would contain information about the method’s parameters, the datatypes they expect as well as the value that will be passed into those parameters. In
30
The Complete Reference To Professional SOA with Visual Studio 2005
a response the body of the SOAP message would contain the information on the datatype that is being return as well as the actual returned value.
WSDL Web Services provide an interface of its functionalities through the use of Web Services Description Language (WSDL). WSDL is an XML document, designed according to standards specified by the W3C, that describes exactly how a specific web service works. However, the WSDL document is much more than a mere instruction manual on how to use the web service that it describes. Web services development software can process the WSDL document and generate the SOAP messages automatically. Because of the capabilities of WSDL, web services are known as self describing software elements. This is a very powerful concept. Not only can web services interoperate universally through SOAP, they can also be described universally using WSDL. A software developer in Sydney, Australia can easily create software calls to a Web Service in Canada just by reading and processing WSDL document.
Figure 1-5 Depicts a web service conceptually. A Web service using WSDL can expose its methods so that they can be accessed from any application whether its windows application, web application or mobile application. Thus Web services contributes to the power of the interoperable nature of distributed systems.
UDDI Universal Discovery, Description and Integration (UDDI) directory as the general standard used as a registry of web services that are available for use in a particular network. Think of the UDDI as a sort of yellow pages for web services. If we wanted to find a web service for our enterprise application, we can look in the UDDI. The UDDI would tell us where to find that service, and it would take us to the WSDL document so we could examine the web service and make sure it was the one we wanted. A UDDI registry is a central concept as one shifts to a model that assumes a distributed, loosely coupled set of web services. The services that we want to consume could be anywhere at any given moment, and in fact the same function may be performed by a different service depending on changing criteria, such as availability or price. The magic of web services is that they are located at addresses to which any computer can connect. The web service’s URL is the basis for its universality and network transparency. Universal transparency comes from the ability to use a logical name in the consuming application that the UDDI can then translate into the appropriate URL. If we wanted to use a service that provided credit card number validation, we can invoke a logical name called “VisaAuth” and allow the UDDI to resolve the name into a URL. Thus, if the location of a
31
The Complete Reference To Professional SOA with Visual Studio 2005
service changes, the application can still resolve to the new URL location of the required Web Service. This is key to achieving the agility that web services technology promises.
Service Oriented Architecture with Web Service There is a distinct difference between an application that uses XML Web Services and an application based on Service Oriented Architecture. In SOA the concept of encapsulating application logic centers within services that interact via a common generic communications protocol. The services themselves are discrete units of work that can be reused. SOA today with XML Web service allow services to be developed and through XML and vendor neutral standards these service can be easily integrated together. We also need to keep in mind that the requirement for using Web Service for Service Oriented Architecture is slightly different to Web Service in general. SOA Web Service focuses on independence and on its ability to operate without relying on the state of other services. This independence is what makes SOA so flexible. However it is easy to make the mistake of using one Web Service A to call another Web Service B and thus becoming dependent on the operation of Service B. In essence we have created tightly coupled components using XML Web service. This should be avoided when implementing SOA, as the creation of spaghetti architecture often become imminent. In essence one Web Service should encapsulate and is responsible for its own domain.
Web Service and SOA Technology Soup Web Service is one of the key enabler for Service Oriented Architecture. Its key benefit is that it is not dependent on any one particular technology. When SOA is created using Web service (WS) it allows a mixture of technologies from various vendors. WS consequently allows the creation of enterprise level applications through the use of a soup of different vendor technologies. Due to its independent and self-describing nature, Web Service offers what other technologies could not and that is Enterprise Application Integration (EAI) with ease. Today in Service Oriented Architecture, Web Service is the most widely accepted and successful type of service technology used. The reason for its popularity is its ability to communicate via HTTP using the universal XML document as it sends and receives data. Web Service uses a XML based messaging format which was derived from Simple Object Access Protocol (SOAP). Because SOAP is an open standard adopted by the W3C it allows anyone and everyone to easily communicate with Web Services. WS using SOAP establishes a transmission framework for inter-service communication via HTTP as a vendor neutral technology. Web Service Definition Language (WSDL) specification implemented using XML. This standard provides a language for describing the interface of Web Services. WSDL is then extended by Universal Description, Discovery and Integration (UDDI) specification that provides a standard means for the dynamic discovery of service descriptions. Together, XML, SOAP, WSDL, UDDI provides Web Services with the means to consolidate technologies that otherwise would be extremely difficult to interoperate. These standards together provided a method to re-use existing legacy systems, which only required a simple Web Service layer on top to communicate with its core API. The Web Service layer can then be easily integrated into other Enterprise Systems with ease. So Enterprise systems can use and re-use existing technology investments with ease. This is ultimately what we try to accomplish. In an enterprise system it is difficult and costly to build the system using homogenous technologies. We must make do with whatever is available to reduce the cost and time of development as much as possible. This is where Service Oriented Architecture falls into place. Using Service based technology we can dramatically reduce development and integration. At the same time allowing the different technologies within the architectural technology soup to simmer and be blended together, to create a flavorsome System.
32
The Complete Reference To Professional SOA with Visual Studio 2005
Service Oriented Enterprise Architecture If we could make changes to our enterprise architecture at will, to cater for the changing needs in our business without enormous expenditures of time and money. Suddenly enormous value is created; processes are continually updated and optimized as our enterprise architecture keeps pace with frequent changes in business strategies. The architectural flexibility brought by SOA is a huge driving force behind the shift to service oriented architecture. Because each element within a SOA is an independent unit, that can be easily moved around, replaced, and modified without impacting on the rest of the architecture. The reason for this level of flexibility is due to each service existing in a loosely coupled fashion, the services can be assembled and reassembled in different forms for different purposes as circumstances warrant. The ability to create processes and composite applications from these services, combined with re-usability and standards based interoperability, creates what is the ultimate achievement in enterprise architecture-that is architectural-wide flexibility.
Adopting the Legacy Enterprise Architecture Beast Lets take some time to examine how service oriented architecture using Web service can enable enterprise architecture to become more flexible. The image below shows a large organization that has a traditional architectural plan.
Figure 1-6 shows a simplified system diagram of their current architecture.
The organization is separated regionally; each region is in charge of its own architecture. Figure 1-6 identifies one particular regional branch. We can see that the architecture contains SAP and SAS running on IBM mainframes, Analysis Services that use Microsoft Windows, and accounting systems that use Java on Sun. On top of that there is an external payment gateway component that’s being accessed. The head office also accesses the regional systems periodically to monitor certain operations. Figure 1-6 depicts a very simplified version of an organization’s architecture diagram. As we can see there are disparate systems running on many different technologies. As a result there are independent teams located in each country to maintain and implement changes to the individual systems and subsystems. Because each branch operated independently from others branches over time the architecture has evolved through years of patchwork.
33
The Complete Reference To Professional SOA with Visual Studio 2005
Each regional branch office has evolved to an untamed beast that was very rigid, non interoperable and difficult to maintain. Frequently changes to one aspect of the system alone required redevelopment to many other components. The regional CIO explained that due to the local nature of their business they were operating in each region it was difficult to centralize globally. The head office is not happy because development and maintenance is becoming costly regionally. Since there are many regional offices around the world, the cost involved was quickly adding up. In an attempt to reduce costs, and keep all systems changes in check, common functionalities consolidated and centralized. The head office in Nuremberg Germany, had requested that all non-regional specific systems be moved and consolidated to the head office. The move will allowed at the very least reduction on maintenance and also supported system reuse at a global level. Even though consolidating the architecture is an ambitious and necessary business change, the nightmare began. The new architecture was nearly impossible to implement because at the regional level system conflicts were rife. Applications were tightly coupled with one another and quite frankly the IT managers and developers were not really sure where to start. The patched architecture that had evolved over the years had become the legacy architecture beast. In order to switch to the new architecture a lot of the existing system had to be re-written in order for the systems to be more interoperable. Temporary systems were built, patch tools were created and temporary solution put in place to attempt to bridge the gap between the existing architecture and the new architecture. A change for better soon became an exhausting, expensive and time-consuming exercise. The scenario outlined is not dissimilar to many enterprise architectures that currently exist in the industry today. Diagrammatically Figure 1-6 is a standard architecture that can easily become overwhelming depending on the business’s need and change in focus. Today business directions change constantly as new partnerships are forged and broken. To have IT architectures that inhibit the merge of another partner or the quick separation between the business and an ex-partner for security reasons can be detrimental to the business. Often legacy architectures like the one outlined are inherited, and constantly patched. As a result it easily becomes unmanageable, filled with traps and system conflicts. Changing one dimension of the architecture to meet the change in business needs will result to change in almost every other dimension of the architecture. Tight coupling in system architecture always results in a nightmare in maintenance and overall does not support the change in business needs.
Enterprise Architecture using SOA The diagram shown in Figure 1-7 shows the same organization with a service-oriented architecture approach.
34
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 1-7 shows the regional office using a Service Oriented Architecture configuration.
Now, each component application in the architecture is exposed as a web service. Since each component is now a web service it is now loosely coupled. As a result, it can be accessed from anywhere on the network regardless of the makeup of the requesting computer. There are several distinct advantages using service-oriented architecture over the traditional architecture. By moving to web services the entire architecture experiences flexibility that was not there previously. Services can now be called by different systems regardless of the technologies that they use complexities of deployment of these services are reduced, and change management is also simplified. If the custom internal financial system required changes and as long as the interface of the service is unchanged, the consumer of that service would not be impacted or even know about it in any way. Now that we have the service-oriented architecture established, we shall examine how it can help with the head office’s request to centralize non-regional specific systems at a global level. With an architecture that’s now built using SOA, the systems that are not region specific can be easily aggregated and re-deployed at the head office. Reintegration from the regional system to head office is fairly simple and straightforward. By moving to service-oriented architecture the organization has also experienced more flexibility at the global level.
35
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 1-8 shows a separated architecture through the use of SOA the organization’s architecture becomes much more agile and flexible.
So how will Service Oriented Architecture affect the Enterprise Architecture? Actually, not much. We can start by building Web service on top of existing system components. Then we can build or integrate these Web services into applications. The applications that use these Web services will immediately benefit from the agile properties of SOA. The flexibility is in the ability of Web services to work with each other regardless of the underlying technology or platform. If an organization is adopting SOA for the first time, and is converting its existing infrastructure to SOA. The initial shift to SOA will be difficult and time consuming. However, in the long run, the amount of time and money required making those changes would be a fraction of what would be required under the traditional model. Not only will the entire architecture become more flexible, there will be considerably less maintenance, and the cost savings on Enterprise Application Integration for new developed component will be enormous. The main benefit of the SOA is its ability to deliver agility to the enterprise. The entire enterprise will become simple, fast, and inexpensive to implement changes at the enterprise level. Service Oriented Architecture really gives the system the ability to keep up with business changes, and not the other way around. Business decisions are made based on business requirements instead of IT limitations. The adoption of service-orientation is both liberating for the business manager and the IT manager. The business manager can act according to strategic directive without the classic constraints of IT. While the IT manager can deliver results in an efficient and cost-effective manner.
So is Service Oriented Architecture a Breakthrough? The concept of SOA is not new. Distributed computing was first available as early as 1980s. However, it was mainly confined to the academic world until around mid 1990s. As the need for distributed application development became more recognized within the industry. In the world of the distributed computing the separation between client and server was first noted when Sybase introduced the concept of functions that were executed within the database and that did not need to be shipped with the client application. The concept later became known as stored procedures. Followed by Novell’s NetWare Loadable Modules (NLM), which were programs that ran on the server. A few years of combining concepts from distributed computing platforms such as Distributed Computing Environment (DCE) with the newly emerging paradigm of object-oriented development, CORBA (common object request broker Architecture) was created. Instead of providing servers, which expose large numbers of remotely accessible functions, the functionality was now broken down into uniquely identifiable, remotely accessible objects that were able to manage their own state. Different objects could communicate with each other by means of an Object Request Broker (ORB). CORBA’s vision of distributed business objects never fully materialized because of its fine-grained model often proved to be too complex to be suitable for the purposes of enterprise-level software reuse. Driven by the high demand for more sophisticated platforms for Internet applications Sun Microsystems introduced Enterprise java Beans (EJB) in 1997. Similar to CORBA, EJB also relies on a distributed object model. However, the EJB model is based on a controlled and therefore usually limited number of servers that host the actual objects. In addition to core-application remoting technologies, such as RPC, CORBA, DCOM, and EJB, the 1990s saw the emergence of a large number of additional distributed computing middleware solutions, addressing distributed transaction management these are X/Open-based CORBA Object Transaction Service, the Java Transaction Service, and the Microsoft Transaction Server. Now there are many types of infrastructures for the development of individual systems. However the sheer number of different development distributed computing concepts, standards, and products also caused an issue.
36
The Complete Reference To Professional SOA with Visual Studio 2005
Interoperability was difficult between these infrastructures. As a result it proved almost impossible to impose enterprise-wide standards in large enterprise systems. Its no wonder Service Oriented Architecture had almost disappeared briefly. However it was quickly revived as soon as Web Service became widely adopted within the industry. Through the use of XML essentially is the lowest common denominator that the industry could agree on. Unlike previous technologies XML is not bound to a particular vendor or technology standard and thus provided a common communication framework. Because of its flexibility it is frequently used as a way of transferring data across largely different platforms. As we move through the book we will see that XML Web Services is a great provider for Service Oriented Architecture. However, it is important to keep in mind that Web Services are not the only valid technology platform for an SOA. As SOA concept is not dependent on any one single technology platform.
Case Studies Service-oriented architecture is catching on. According to a recent Industry Development Center (IDC) report, SOA spending has reached $8.6 billion in 2006 a 138% increase from 2005 at $3.6 billion. By 2010, IDC estimates companies will spend upwards of $33 billion on SOA services.
Which Industry Is Best For SOA SOA can be used in any industry. As all businesses need to have the flexibility to change or create business processes dynamically. The need to quickly and seamlessly take elements of processes that weren't built to work together and make them work together is ever more important in today’s fast paced industry. Achieving this level of flexibility used to be time-consuming, labor-intensive and expensive. It involved building your own custom integration systems. However, with SOA and the recent developments in Internet standards now we can easily make software applications talk to each other even if they're written in different languages or for different types of hardware.
The Drive for SOA The fact is SOA can be used in any industry. The underlying benefits of SOA are not just IT systems but in fact improvement on agility of business processes itself. It is a simple matter of taking stock of what we have in an architecture, take it apart, and put it back together in new ways. Or alternatively we can view it from a different light as breaking up a business process into reusable components, even if those components span across applications. We can then draw upon new and old components from the business or business partners and mix the old and new to create a new business process. Within a service-oriented architecture, applications, information and other IT assets are viewed as services or “building blocks.” Each of these services can be mixed and matched to create new, flexible business processes. Let us examine some of the common scenarios that are plaguing different industries today. 1.
Problem: Healthcare industry must address accelerating costs, slow response times and inconsistent quality of patient records.
Solution: Use SOA approach to integrate payer systems, provider systems with hospitals record system. 2.
Problem: The electronics industry is converging from traditional manufacturing to configure to order market.
Solution: Build SOA that facilitates mass production with easy to configure last-minute customization ability.
37
The Complete Reference To Professional SOA with Visual Studio 2005
3.
Problem: The banking industry must deal with information silos, redundancy and underutilization of data, while constantly under pressure to grow.
Solution: To address this we can utilize a SOA to add flexibility to existing infrastructures. Once systems are serviceoriented we can reduce information silos, redundancy and improve on the growth of the architecture to provide new products and services. 4.
Problem: Retailers are confronted with exponentially increasing data such as radio frequency identification (RFID) that's not leveraged effectively.
Solution: To resolve this we can use SOA to deliver near real-time information to optimize the supply chain. 5.
Problem: Telecom companies cope with island like infrastructures. As the industry spurs ahead many legacy systems and heterogeneous environments are left costly to interoperate. These systems provide services such as billing, account activation and other specialized customer care services.
Solution: Use SOA to aggregate and consolidate all services to deliver Enterprise Resource Planning (ERP) application.
The case studies below demonstrates some of the use for SOA to resolve current issues. However the key to SOA is not only in what it offers to resolve architectural issues but also its ability to support application reuse. This aspect of SOA is not a result that can be seen immediately but over time service-oriented architectures has a significant reduction on development costs through component reuse.
Case Study: Starwood Hotels Uses SOA to Improve Guest Services and Cut Costs Starwood Hotels, realized five years ago that service-oriented architecture was in its future, says Israel Del Rio, Starwood's senior vice president of technology solutions. The international hotel chain, which includes such brands such as the St. Regis Hotels, Sheraton, Westin's and the W Hotels, saw that its costly, clunky old mainframe system was limiting its ability to accommodate rapidly growing distribution channels like the Internet. "It was too difficult to add capabilities to our CRM system, do proper searching to find properties basically many of the things a modern IT environment needs," says Del Rio. Starwood's current systems were also having difficult handling the rapidly increasing traffic on its Web sites, what hospitality professionals refer to as the "look-to-book" ratio. "In the old days of the Internet, the lookto-book ratio was 50 to 1. Now it's 300 to 1. So we needed an IT environment that could handle all those requests." To keep the legacy mainframe system would have required a multi-million-dollar investment in upgrades and technical support. "It was very costly, and we didn't want to be held down," he says. So Starwood began the long process of moving its systems to an open SOA framework. "It was the best way to let us map our technology with our various brands," says Del Rio. Instead of having each of Starwood's hotel chains build their own applications, SOA allows the brands to share the same programs and features—but they can be customized specifically for each hotel's look and feel. Sheraton's search function, for example, may deliver information differently than, say, the W Hotels', even though it's the same program. "That way we benefit from using all the same tools that can be called up by different applications and interfaces," says Del Rio. Because SOA is built on an open framework (meaning it can be called up by different operating systems), it also creates greater flexibility for the company to create new tools. Starwood has put in place an application that tracks guest requests and complaints, for example. "We created a workflow around that to ensure that our guests' needs are satisfied," says Del Rio. The company also created a program that stores and tracks frequent guests' preferences. "These are functions that didn't exist in the mainframe at all," he says. Software from Burlington,
38
The Complete Reference To Professional SOA with Visual Studio 2005
Mass.-based SOA vendor Systinet helps Starwood track all the SOA tools it has created. "That way everyone across our brands knows which applications are available," he says. But it didn't happen overnight. After five years, the company is finally ready to officially dismantle its mainframe—an endeavor Del Rio expects will save the company as much as $20 million per year in maintenance costs. He expects Starwood to be entirely up and running on SOA by 2007. "It's a very complex initiative with a lot of moving parts," says Del Rio, "but if applied to the right business problem, it produces good results."
Case Study: Harley-Davidson Here's how loose coupling had a direct impact on Harley-Davidson's business: When the weather warms up, people begin to wander into Harley's showrooms with visions of the wind whipping through their hair on an open roadway. "We have specific marketing programs geared towards that customer base," Haney explained. "Those programs are targeted to get those people that are dreaming about motorcycles to actually purchase one. We want to put together a good financial package to entice and incite people to get into the sport." Enter Harley's credit and loan origination process. Until recently, however, the financial services applications were tightly coupled, and thus weren't very flexible, Haney explained. Making a change in one program meant having to go in and change countless other applications as well. "The way our systems are very tightly coupled, being very rigid from how they are architected, if we made one change to one of those systems that supports one of those processes, we basically have to touch all of the systems." The answer? Break it all up. "We actually busted apart all of those systems, and put the SOA with WebSphere in the middle of all that," Haney said. "We loosely coupled these things. Our goal is to be able to change any one of those systems. If we see key indicators in the industry, we want to very quickly put different marketing programs in place, and not have to go and touch and test every single system." If ever there was a case of IT agility supporting new business opportunities, this is it. "We can bring applications to the forefront as services, and arrange them differently," Haney said. "But more importantly, we can change an application, and do it quickly. We can be a lot more responsive to the business, which helps us sell motorcycles — the business we're in."
Case Study: IBM towards SOA Recently, IBM has been quite eager to deliver SOA to the enterprise world, with countless product and service announcements. Howie Miller, IBM’s vice president for enterprise architecture told us that Big Blue currently has 77 shareable and reusable services in production ranging from authentication to order fulfillment as part of its service-oriented architecture. The most notable outcome of IBM’s internal SOA efforts is the fact that Big Blue was able to reduce its inventory of 16,000 applications in 1998 to 4,000 applications today. The secret sauce to streamlining down to a quarter of its applications was governance, Miller explained. “The governance model helped us achieve that nice statistic. It’s how we plan to go from more big integrated spaghetti code applications to more component-based Web services. That same governance model will be part of what gets us moving forward to the SOA-based approach.” Decisions about new technology investments are vetted through an Enterprise Architecture Council and Investment Review Board run by the CIO (Miller's boss). IBM’s CIO's office is leading the SOA charge internally at IBM, but doesn’t have a central bucket of money or huge staff to plan and build SOA. Instead, Miller, said, the office — which has 10 architects — plays a role in influencing Big Blue’s annual internal $4 billion annual technology spend. "About 28 percent of our investment of our total IT spend is what we call 'transformational investment,' or new development.” That's where SOA comes in. “What we do, through roadmaps, standards, and target architecture is try to influence the behavior of the way that our development teams are doing transformation initiatives to spend their money.”
39
The Complete Reference To Professional SOA with Visual Studio 2005
Web identity service: This is an authentication and authorization service for end-users accessing IBM
applications. "When an employee or partner signs into a Web site, they have a single user ID and password for sign-on," Miller explained. "It used to be, every time I used a different application in IBM, I had a different user ID and password. Now, all these applications call the Web service to validate the user ID and password. This common Web service is callable from any application.” Factory in a box: IBM's semiconductor group built a set of services called "semiconductor factory in a box.," Miller said. "It has enabled us to do is invest, acquire, or divest, or outsource manufacturing plant very quickly. If we divest a manufacturing plant, we had to rip out all the connections to various systems. Or, to acquire a new company that comes with a manufacturing plant, we had to integrate them into our systems. The process used to take several weeks — now it's two hours.” Customer order and tracking system: IBM's customer order analysis and tracking system (COATS) "was a big spaghetti-code application, all integrated into one big app," said Miller. The huge application was being overwhelmed by order volumes, which "were causing problems with performance with the application." MIller's staff decomposed the entire application into 13 separate components. "We found that the logjam in the application was only in a couple of the pieces of the app. We pulled out that application code for those two pieces and wrapped them as Web services. It was a way to rewrite a legacy application in pieces, without having to go do the full 13 big chunks of functional capability."
Miller says SOA enablement didn't happen overnight, even for IBM. "A lot of time, when we talk to folks about this stuff, they say, ‘oh my gosh, I could never do an enterprise architecture of that size, with the complexity of my company. It must have taken you years.’ The answer is yes, it did take years," he related. "But you can start in a corner of the business, business unit or functional area, and work it out from there."
Case Study: Microsoft SOA (Milton Keynes General Hospital) ROI: 61% Payback: 1.65 years
Located in Buckinghamshire, England, Milton Keynes General Hospital is a 460-bed District General Hospital serving the needs of the people of Milton Keynes and surrounding areas for the past 20 years. Milton Keynes is part of England’s National Health Service (NHS), which provides healthcare for all citizens in England, Scotland, Wales, and Northern Ireland. All NHS hospitals are subject to the recently-initiated NHS National Program for IT. This is a broad integration initiative across the entire NHS hospital system that will be phased in over a number of stages. Its objective is for each hospital to replace the functionalities of its various local disparate IT systems into a single, cost effective service that can deliver far greater patient data transmission. Integration requirements under this mandate include the following: *
Paperless or near-paperless transmission of patient files such as documents, care records, and X-rays.
*
Viewability of any document from any location.
*
Capacity for data entry from any point.
*
Elimination of redundant data entry.
NHS is pursuing this degree of integration because it believes that for any given patient, the hospital’s ability to provide rapid and effective prognosis and treatment is directly impacted by the ability of the organization to
40
The Complete Reference To Professional SOA with Visual Studio 2005
transmit critical patient data among the various departments and hospitals within the NHS system. In the face of the NHS integration mandate, Milton Keynes determined its existing patient admission system was no longer capable of delivering the requirements of a modern day healthcare system. The patient admission system, which is 22 years old, annually processes 60,000 in-patient admissions and 100,000 out-patient admissions, resulting in approximately 1.5 million transactions per year. Upon receipt of the integration mandate, this enterprise was comprised of 28 systems spread across more than 80 servers. There were numerous heterogeneous systems in this configuration. Additionally, there were numerous disparate connections of both a point-to-point and manyto-many nature within the system. As a result, the system was far from rationalized, and required much work in order to comply with the NHS integration mandate. Early in 2005, the hospital began looking for an integration solution that could be used to rationalize its complex patient admission system. They chose to use Web service and along with Microsoft BizTalk Server 2004 for integration. Subsequent to selecting Microsoft BizTalk Server 2004 as the integration platform for Milton Keynes, the hospital formed a deployment team. Milton Keynes staff members, including a project manager, a systems architect, and an integration and systems developer were joined by four consultants from WCI, a British Microsoft partner. Over a 4-month period, the team completed the necessary development testing and deployment for the Microsoft BizTalk solution. The process concluded with a 3-week long installation of Microsoft BizTalk Server 2004 for interfacing with the existing 28 local departmental systems that are currently tied together with point-to-point interfaces. During the deployment, Milton Keynes made extensive use of Web service and along with Biztalk’s prebuilt messaging tools designed for healthcare institutions, which helped to accommodate local compliance requirements such as those requested by the Health Insurance Portability and Accountability Act (HIPPA). By converting to a service oriented architecture and integrating the existing patient admission system with Microsoft BizTalk Server 2004, Milton Keynes is now able to accelerate its IT integration, reduce costs, and improve patient service. Some of the key benefits are: *
Rapid system rationalization. The hospital can now transform the current state of the patient admission system from one characterized by numerous point-to-point and many-to-many connections to one resembling a huband-spoke structure.
*
Reduced programming costs. Because Milton Keynes will make vigorous use of its service oriented architecture, the hospital can complete its integration tasks with far less programming costs than had been budgeted.
*
SOA adoption. Service oriented architecture adaptation is viewed as an enabler of new practices, including solution reuse, business-to-business integration, and business activity monitoring. These are viewed as critical going forward, as other systems within Milton Keynes are rationalized and integrated as required under NHS National Program for IT.
*
Improved patient service. By improving data flows, the hospital will be able to provide better scheduling, diagnostic services, and treatments to its patients.
Case Study: GfK Market Research GfK is one of the largest market research organizations in the world. Like many large organization it is facing the global challenge to improve organization revenue and reduce operational costs. In order to be a truly global market research organization GfK must have offices locally in every country to collect local regional sales information from retailers on weekly basis. For the last twenty years GfK has left local operations to its own. As a result through the years each regional operation center has evolved with its own suite of systems to process and collate data. In a bid to reduce operation costs the head quarter in Germany has requested that all operations to be
41
The Complete Reference To Professional SOA with Visual Studio 2005
consolidated to a single point. This will essentially remove local processing at a regional level and all work will be now done at head quarters. The regional operations center has several departments, each department focused on a particular industry within the local retail market. Because of the difference in the type of data that is submitted from the retailers and difference in requirement for each department. The department themselves also has their own IT operation teams which also developed different sub systems. Some of these systems relied on SAS others relied on Access and MS SQL Server with different Business Intelligence (BI) tools such as Cognos, Microsoft Data Analyzer, Analysis Services and even MS Excel tied onto the front of each of the systems. It was a difficult task sorting out what can really be consolidated at the regional level which in turn can be consolidated to the central system in Germany. Each regional operation center differed from each other. Industry information and categories within each region also differed greatly from each other. This posed an issue when trying to consolidate data and applications at a regional level. On top of these problems with changes the operation teams were having a hard time maintaining operation of the current systems. For quite awhile it seemed that the entire consolidation process to Germany was on the verge of failure. To ensure stability and operation at the regional office the head office has requested all regional offices construct Web services on top of each application. With this request regional offices quickly established scalable Web services on top each of its proprietary systems. The head quarter operation team was then able to duplicate all applications to the head quarter level and using a hub and spoke approach with Enterprise Service Bus (ESB) integrated the local proprietary systems into its centralized process.
Case Study: PureProfile PureProfile an online market research organization offers virtual credits for all those who participate in their online market research service. PureProfile wishes to rapidly expand their business internationally. To achieve this PureProfile needs to establish a base from which services can be rapidly launched to meet the requirements of its clients. With limited resources this was almost impossible to achieve. PureProfile CIO, Basil Karam, decided to expose their Intellectual Property through the use of XML Web service. This was quickly achieved as Web services was already being implemented internally to help ease integration within the organization. PureProfile quickly gained supported from a number of other market research organizations wishing to support broaden their own capabilities by implement PureProfile’s IP into their own market research system. As such PureProfile without requiring to expand additional resources into their operations team has increased their Market base exponentially.
Case Study: Amazing People Amazing People is one of the leading training organizations in Australia. Amazing people was rated by Business Review Weekly (BRW) as one of the fastest growing organizations in Australia. Trainers facilitated training within Amazing People on premises and outside on client sites. However growth in this manner is always limited. Amazing People wanted to be able to access the global market without the need to fly facilitators from country to country. To achieve this Amazing People opened their business processes and course materials to partners through the use of XML Web service. By incorporating the course contents of Amazing People other training organizations are able to provide Amazing People courses for them. Whilst by incorporating Amazing People XML Web services into their own architecture, they have constant access to updated course work and lectures. The partners then pay a royalty for the materials that they use. Using XML Web service Amazing People was able to quickly expand their business globally without the need to increase in business costs.
42
The Complete Reference To Professional SOA with Visual Studio 2005
Case Study: Sunshine Sugar Sunshine Sugar in NSW has been struggling with their legacy systems. These systems had provided reliable services to the organizations for many years. However, Sunshine sugar is bringing in a new suite of software system which will help the business to cater for today’s business requirement. The CIO does not wish to lose the old systems as they can still provide valuable service to the organization. The integration process between the legacy and the new system proved to be difficult. Proprietary interfaces were required to be implemented to interface with the new system this proved to be costly and not an optimal solution. The CIO decided to implement generic interfaces using XML interoperate requests and response operations between applications. XML Web service was used as a method for exposing legacy capabilities whilst the newer application then consumed these capabilities. This was a great success at a fraction of the original costs.
Case Study: Intellifield One of the difficulties today for component manufacturer is trying to provide information in an industry neutral standard. This is especially the case in the oil rigging industry. Intellifield an independent supplier of products and systems to oil rigs needed to provide an out of the box plug and play component that can be used on the field with any application available today. To do this Intellifield used XML and XML Web services. Intellifield sensors are used in the oil drilling industry to transfer drilling sensor data from offshore oil rig back onshore. In order to facilitate a plug and play scenario XML Web services were used to provide the service. Data is gathered in different proprietary formats before converting the information to a XML based document for transfer, which client applications can then readily access to acquire the information.
Summary Web services uses SOAP messages a specific type of XML message format determined by the W3C standards to communicate over a number of protocols such as HTTP. Due to the open nature of web services, it is possible for many web service consumers to access the same service regardless of operating system or programming language. As long as a consumer invokes the web service using a SOAP request in standardized format. It does not care for the language the service is written in nor does it care for the platform the Web Service is currently on. Each web service can contain a Web Service Description Language (WSDL) document that provides the potential consumer of the service with an explanation of how the service works and how to access it. The WSDL describes how to create a SOAP request that will invoke that specific web service. If a developer wanted to create a Web Service consumer application, they simply need to retrieve this XML document, which will provide all the information the developer require to develop the new application to invoke the relevant functions within that Web Service. Due to the self-describing nature of the web service it allowed developers to quickly develop distributed applications without requiring understanding of the underlying technology or functionality of the service. Web Service also uses Universal Discovery, Description, and Integration (UDDI), which is a listing of web services available within a particular network. The UDDI functions like a “yellow pages” of web services. Potential web service consumers can search for the web services that are available for use through the UDDI directory. Web Services play a key role in the promotion of Service Oriented Architecture. As it is technology neutral and uses an open-communication framework such as XML. This quality allows distributed applications to be
43
The Complete Reference To Professional SOA with Visual Studio 2005
developed, integrated and maintained with ease and most importantly it supports the reuse of existing technology investments.
44
The Complete Reference To Professional SOA with Visual Studio 2005
Chapter 2 Implementing Service Oriented Architecture In order to successfully adopt SOA into enterprise architecture we must first determine its goals or destinations. To do this we need a clear idea of where we are and a vague idea of where we want to be. In this chapter we will continue to discuss SOA theories and concepts and most importantly we will focus on the implementation side of SOA.
SOA Architectural Roadmap Any great journey starts with a goal or destination, and the decision to implement SOA is no different. We may start with only a vague idea of where we want to be, or how we could get to our destination. To be successful, we must assess our strengths and weaknesses, establish clear a direction, to choose a route, and then consistently reevaluate our progress as we follow it. To put it simply, we must create our own unique roadmap for the journey. On the journey to create service oriented enterprise architecture, we are likely to encounter many obstacles and will need to cope with the frequently changing requirements of the organization. It is therefore important for our architecture and roadmap to be designed to cope with the complexity and dynamics of the enterprise environment. In this section we will learn to develop our own architectural roadmap to help us reach our goals
What is a SOA Roadmap and Why Do You Need One? Service-Oriented Architecture refers to an IT strategy. This strategy incorporates an organization’s plan for its architecture. To achieve this, organization need to breakdown its applications into discrete reusable components and build standards based services such as XML Web services as the interface for these components. This will allow the architecture to quickly reflect changes and be combined with reusable components to meet the business’s needs. Creating a SOA roadmap will require a delicate balance between the long-term goals and the shorter-term needs of the business. This balance can be maintained by instituting a set of organizational, financial, operational, design, and delivery practices from the outset of your SOA initiative. But rather than making enterprise wide changes, it is important to deploy culture-changing disciplines in an incremental and iterative fashion to allow for an organizational learning curve. In essence, an SOA roadmap provides an iterative and incremental way to capture your organization’s unique plan as you progress. The SOA roadmap should clearly outline the boundaries of your SOA initiative and establish a transparent and flexible timeline for achieving SOA goals. These goals should be broken down into manageable phases, which can then be realized in an iterative and incremental manner.
How to build a SOA Roadmap In any organization one key area for any form of budget or financial allocation is through the justification of return on investment. As such we must provide an adequate roadmap to rationalize the reasoning behind a switch or to build in a SOA manner.
45
The Complete Reference To Professional SOA with Visual Studio 2005
There are four phases to developing your SOA roadmap: SOA Planning, SOA Maturity Assessment, SOA Future Vision, and SOA Roadmap Definition. Once the roadmap had been defined and development begins, at the end of each iterative development phase there must be an Iterative Quality Assurance stage to ensure that the overall development is in sync and on track with the SOA roadmap defined.
Figure 2-1. Six-domain model for a SOA roadmap (Copyright BEA Systems - Used with permission)
In order to plan for a successful SOA implementation. Our SOA roadmap should encompass six domains Figure 2-1. These domains, while distinct, are interrelated and interdependent. Implementation on each domain is fundamental to the success of an enterprise-wide SOA. Our SOA roadmap should clearly outline the boundaries of our SOA initiative and establish a transparent timeline for achieving our SOA goals. Each domain’s area of responsibility is illustrated in the table below. Table 2-1. Responsibilities of domains.
Domain
Focus
Business Strategy and Process
SOA-enabled Business strategies Business process architecture is derived
Architecture
Reference Architectures Manageability/Availability Scalability Security
Building Blocks
Public Services, Logic Centric Services, Data Centric Services, Transitional Services, and Basic Services
Projects and Applications
Existing Applications Key “in-flight” Projects Infrastructure Construction Plans
Organization & Governance
Organization Design Funding Skill sets Roles and Responsibilities
46
The Complete Reference To Professional SOA with Visual Studio 2005
Standards Operational Processes and Tools Change Management Cost & Benefits
Constructions costs Business & IT Benefits Key Measures
SOA planning Defining a plan for the implementation of SOA is vital to the success of the overall architecture. In any organization alteration or new development needs to be justified. After all there is no point in moving to SOA without a strategy. The return on investment in the exercise must also be justified in the long run. Planning also allows constant monitoring of the progress as well as successful evaluation of the architecture. During this phase, your SOA initiatives are organized and defined. Stakeholders are brought into the process through communications and briefings and mutually agreed upon priorities and parameters are set. Because this phase involves employees across your organization, clear and ample communication is critical. During this phase you will: *
Define the scope of SOA.
*
Establish boundaries and alignments with other IT initiatives.
*
Appropriately showcase the business justification for SOA.
*
Show alignment of existing and future business initiatives.
It is important to define your SOA strategy in terms of long-term business goals, but its equally important to meet short-term business goals. A business cannot possibly cease to function simply because of the change to service orientation.
SOA maturity assessment To develop a successful roadmap you must treat your SOA roadmap as a “living document” that continually captures experiences and lessons learned. As your SOA roadmap matures, your SOA initiative reaches higher levels of sophistication in a controlled manner. The creation of an SOA roadmap begins with an assessment of your organization’s current capabilities and disciplines applicable to SOA. During the SOA maturity assessment phase, you will establish a metric for where you are today. Here you will define what services and capabilities you currently have that can serve as a starting point for SOA, as well as identify projects that may serve as foundation projects. Through a series of interviews and questionnaires, your teams should examine the various domain analyzing, base lining, and validating the “as-is” current situation for each. Use Domain Model to structure your examination of the following: *
Business Strategy and Process: Top-down view of business strategies and processes.
*
Architecture: Review of current architectures, policies, and standards.
*
Cost and Benefits: Overview of existing cost structures and benefits cases.
*
Building Blocks: Analysis of existing services, processes, tools, and technologies.
47
The Complete Reference To Professional SOA with Visual Studio 2005
*
Projects and Applications: Review of existing systems, and in-flight and planned projects.
*
Organization and Governance: Analysis of existing governance structures and policies.
SOA future vision In this phase, teams use workshops to determine and define the desired “should-be” state and ensure crossorganizational buy-in. *
Business Strategy and Process: Correlation of SOA future vision with business strategies and processes.
*
Architecture: Guiding principles, requirements, policies, standards, and reference architecture.
*
Cost and Benefits: Metrics and measurement requirements.
*
Building Blocks: Shared services infrastructure requirements and standardized tools.
*
Projects and Applications: SOA mapping to projects and applications.
*
Organization and Governance: Governance and compliance structures and policies.
SOA roadmap definition This phase is where the SOA roadmap is initially defined. A complete gap analysis should be performed for your corporation’s SOA goals and appropriate timelines, based on the information gathered in the previous three phases. Near-term events will be more detailed, while later events will be more fluid—so that they may incorporate lessons learned as you move forward. *
Business Strategy and Process: Opportunity alignment by business value.
*
Architecture: Near-, medium-, and long-term reference architecture roadmap.
*
Cost and Benefits: Roadmap of future metrics, cost structures, and benefits cases.
*
Building Blocks: Prioritization of shared services strategy and standardized processes.
*
Projects and Applications: Project and application impact.
*
Organization and Governance: Proposed governance structures and policies.
Iterative Quality Assurance By learning and adapting process at each milestone, and by being both iterative and incremental, your roadmap will remain relevant throughout the SOA initiative. To ensure your SOA roadmap’s quality, communicate and validate it with all stakeholders, soliciting feedback from all quarters at each iterative level.
SOA Governance Governance in SOA is particularly vital in its ability to assess and ensure flexibility of the enterprise architecture. The definition of the word governance implies the action or manner of governing. Further, IT governance is a decision and accountability framework to encourage desirable behavior in IT. Participants of the governance body lay down policies around different categories of decisions that need to be made. That body also decides upon the people in the enterprise who are empowered to make those decisions; that is, it carries out role identification. The members of the governance council also identify subject matter experts who are expected to provide input to firm up the decisions and also identify the group of people who may be held accountable for
48
The Complete Reference To Professional SOA with Visual Studio 2005
exercising their responsibilities (based on their roles). An effective IT governance council must address three questions: 1.
What decisions must be made to ensure effective management and use of IT?
2.
Who should make these decisions?
3.
How will these decisions be made and monitored?
Establishing successful governance will align software governance and business governance. SOA governance is really an extension of IT governance that focuses on managing service and the related service level abstractions. The SOA governance policies and processes should establish a governing body within the enterprise that has representation from each service domain and the different business units and from subject matter experts who can understand key technological components of the solution. This governing body should define the policies and processes for identifying, implementing, deploying and versioning services. SOA governance policies and processes should identify mandatory and optional training that members of the SOA team and the larger project teams should complete to effectively implement the SOA roadmap.
Enterprise Service Enabling Architectures Service Types An important aspect of any software architecture is to be able to break down the overall structure of a software system into smaller components. These components can then be used as flexible building blocks. Being able to classify service types is a precondition for effective designs to SOA. Here we will learn to describe and differentiate the different types of services.
Basic services These are silo like services, which access data and contain certain amount of data operations and also some basic business logic. These services are predominantly simple services that could easily be used and reused. Basic services that provide both data and business logic can be referred to as agile and reusable as services. For example, a social security number validation service will access the database to find the name that the social security number belongs to. At the same time there is some simple logic to validate the social security number before a call is placed to the database. In this regard this service both contains basic data access and some basic business logic.
Data-Centric Services A data-centric service handles the storage and retrieval of data, these services also handles transaction management. These data-centric services often retrieve data from a database; as such it acts similar to that of the data layer. These are important part of any enterprise application development and often provide as a solution to data ownership. It allows access to data from different data vendors. The user of the service does not care for the vendor of the service or what kind of query language the service uses to query the database. All that the consumer of the service need is the interface. This improves the flexibility, transparency and allows more efficient reuse of the service.
49
The Complete Reference To Professional SOA with Visual Studio 2005
Logic-Centric Services These are services, which contain complex business rules or business logics. In the past these functionalities in application development are deeply nested within the application. It was difficult to reuse these encapsulated logics as it was too tightly coupled with the application. Through the use of Logic-Centric Services complex logic can be exposed and easily reused by any application that requires it. The Logic-Centric Service may be sitting on a proprietary system, which does not usually interoperate with applications requesting the service. However through the use of Web service we can expose the service and allow other users to request for its service. A good example of Logic-Centric Service is a bank that’s providing home loan. The home loan formula is extremely sensitive and should not be known by its competitors, however the bank wishes to provide the home loan service to its partners. With every request personal account details and income information are sent to the service. The service then takes these values and calculates against the imbedded business rules to work out an estimated loan. This amount is then returned to the requesting client. There is minimal data processing and the service is purely business logic. With the Logic-Centric Service exposed, the bank can easily provide the loan estimate service to its partners whilst keeping its business logic secure and central within the bank. Because of the nature of Web service’s interoperability, it allows this particular functionality to be integrated with internal applications as well as utilized by external applications from its partners.
Transitional Services These are services that are generally placed on top of an existing legacy system to allow access from external applications. Traditionally components are not always interoperable with each other as a result it was difficult to work with one another. These could be components that provided any level of services. They can be data centric, logic centric components or components that provided network access. Transitional services provide access to these components by placing a transitional layer between these legacy components and that of the outside world. This allowed for reuse. Transitional services provide a huge amount of flexibility, to applications and components that had already been developed. They allow existing systems to be more robust and agile.
Public Services These are services that were exposed to the public in the sense that they’re outside the domain of business logic. In SOA these services are used to provide cross-enterprise integration. These can be services that are offered by a company to its partners and customers. An example of Public Services in use would be Amazon. Amazon provides public services to allow its partners to build applications that utilize these services to retrieve information about books that are currently available on Amazon. Public Services are versatile they provide a gateway for the outside world to access functionalities within a business domain. This allows the business to sell and promote its product in this case Amazon is allowing its partners to build applications that access Amazon’s database. Allowing them to integrate Amazon into part of their applications. Public Services really is the face of SOA and one of the most popular and used service types.
SOA Web Service Transforming Logical Layers to Physical Tiers In this chapter, we have already discussed different service types. Now we will look at the overall structure of service types in the enterprise landscape. Firstly, let’s clarify the difference between Layers and Tiers in application. Layers, refers to a way of organizing the code to provide logical abstraction and separation. Typical layers include Presentation, Business
50
The Complete Reference To Professional SOA with Visual Studio 2005
and Data. Layers, refers to the logical organization of code. Layers are primarily used to gain the benefits of logical organization and grouping of similar functionalities. In application development logical layers offer reuse, easier maintenance and shorter development cycles. Proper layering of software reduces the cost to develop and maintain an application. Tiers however, are only about where the code runs. Specifically, tiers are places where layers are deployed and where layers run. In other words, tiers are the physical deployment of layers. Tiers refer to boundaries these are either process or network based. A one-tier model has all of its layers running from a single memory or processor space on the same machine. A two-tier model has two separately working memory spaces with tiers in each of the working space. The number of boundaries for an n-tier model with can be calculated as having n-1 boundaries. Traditionally, software that were developed were isolated and thus and layering provided all the abstraction required for code reuse in this silo architecture. However as application development had evolved to become more distributed, layering is no longer an adequate way to provide abstraction at the enterprise level. This is especially the case when parts of the application are located in other regions of the world. SOA layers should not be confused with the traditional software layers, and tiers. In SOA layers are effectively traditional tiers. SOA layers provide a conceptual structure at the enterprise level. Let’s have a look at SOA layers. Figure 2-2 shows different service types possible within a SOA, though SOA is flexible enough to not to conform to this one particular model. Each service type essentially has the ability to become a public service. Although for security reasons public services should always be documented and noted.
Figure 2-2. Web service layers
Starting Your Enterprise SOA with Entity Aggregation As businesses continued to expand over the years, mergers and acquisitions became more frequent. As a result, today’s enterprises place increasing demand on IT systems to reflect the change in organizational restructuring quickly. Whether it’s a new partnership that has just been forged where certain core business functionalities or services needs to be provided. Or, when a partnership had ceased and access to information needs to be restricted. The requirement to provide flexibility at this level gave rise to the emergence of a new trend in software development and architecture.
51
The Complete Reference To Professional SOA with Visual Studio 2005
This trend, in its movement towards automating business processes between systems, promotes the value of Service Oriented Architecture (SOA). Integrating and aggregating information (entities) that is present in different systems and is essential in building solutions that will support this trend. For example, in many businesses employees must make separate phone calls to HR, Payroll, and Benefits to have their addresses updated in the different systems. Through SOA, however, multiple systems can become integrated and the entities in the different systems aggregated. By automating these simple processes, employees can now make one phone call or use a self-service portal and update their personal information seamlessly across numerous systems. Businesses can also reduce total cost of ownership (TCO) by connecting systems with Service Oriented Architecture. Over time, the Enterprise IT group may plan to deliver services directly to end-users by integrating multiple systems. This means that services, offered by applications such as enterprise resource planning (ERP) and customer relationship management (CRM) systems, will be available to end-users, which results in an overall reduction in the TCO for supporting the business functionalities. This is where Entity Aggregation plays a large role. An Entity Aggregation solution can be designed to not only act as a single point in accessing information that exists in multiple systems, but it also provides a holistic view of an entity and the entity model. Additionally, Entity Aggregation solutions address several design issues to ensure the success of Service Oriented Architecture. The underlying goal of Entity Aggregation service is to design an Entity Aggregation layer that acts as a single point to access information that may exist in multiple systems. There’re three main reasons why entity aggregation is important.
Single View of Entity Information in today’s Enterprise IT is essentially disparate and spanned across a number of systems and maybe supported by different vendors. A typical example of these disparate systems would be a Human Resource Management System (HRMS) application, Payroll application, and Benefits application. Typically these systems define their own individual Employee entities, which result in incoherency between systems. As a result, the trend should be toward enforcing consistency between systems by maintaining a holistic view that is concerned with the whole instead of just the parts. In the case of building an Employee Self-Service portal, a holistic view, not the bits and pieces, of what constitutes an employee is necessary.
52
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 2-3 shows the aggregation of the employee table between the payroll system and the benefit system. Previously update of information required users to log into both systems to update their personal information. However with entity aggregation update to the aggregated view of the employee table will result in update of both Payroll System and the Benefit System.
Horizontal Partitions There are cases where geographical constraints require a partitioning of entries across services. At certain times, however, a solution may require a complete set of information to obtain a detailed picture across services. One example of this of a distributed of stock trades as an entity that is partitioned across various geographical locations.
Figure 2-4 shows the horizontal partitioning across services provided by a UK stock trader and a US stock trader. If a company wished to request information on the performance logging into individual stock trader is troublesome especially if you need to check regularly. By aggregating the available information to a higher level. We can perform queries and check performance at the click of a button.
Cross Entities Query Some cases require special handling of entities. In these cases, different services encapsulate related entities, and the solution requires a complicated join between them.
53
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 2-5 depicts cross system join between an ordering system and an inventory system. In Service-Oriented Architecture it is often necessary to query independent systems to bring a more simplified, holistic view to the consumer of the service.
Enterprise Application Integration (EAI) As we enter an era of enterprise computing where components and systems providing different services are easily distributed through out the world. A crucial focus is placed on technologies that will enable the integration between these different systems. Until recently, integration between disparate systems and unrelated technology were extremely frustrating and painful. This is mostly caused by the competitiveness of the industry, as each vendor promoted and pushed for its own technology creating a mayhem of similar technologies in the architectural landscape. However thanks to the growth of XML an industry wide accepted communication framework and the use of XML web services, a vendor neutral technology, enterprise wide integration can now be achieved relatively easily through the use of SOA. SOA is slowly changing the way we think about applications and how they relate to each other and, in doing so, is fundamentally changing the nature of enterprise application integration (EAI). The first stage in application integration is to ensure that the components are interoperable. This means the mapping of each application’s functionality and internal data model to some normalized format. Historically the normalized format used was implicit to the integration broker that an organization purchased, meaning that any interactions with the application would be limited to the capabilities of the broker, greatly restricting the reusability of the interface. With SOAs, it’s now possible to express application functionality and data in a more generalized, standards based way, through the use of Web services. Instead of plugging directly into a proprietary integration broker, the application is ready to be invoked by any software that understands its service interface. The SOA approach provides significantly greater reuse and flexibility. Currently the industry supports two emerging standards Web Service Choreography Interface (WSCI) and Business Process Execution Language for Web Services (BPEL4WS). They are both designed to reduce the inherent complexity of connecting Web services together. Without them, an organization is left to build proprietary business protocols that shortchange true Web services collaboration. Recently, the terms orchestration and choreography have been employed to describe this collaboration: *
Orchestration: Refers to an executable business process that may interact with both internal and external Web services. Orchestration describes how Web services can interact at the message level, including the business logic and execution order of the interactions. These interactions may span applications and/or organizations, and result in a long-lived, transactional process. With orchestration, the process is always controlled from the perspective of one of the business parties. See Figure 2-6.
*
Choreography: More collaborative in nature, where each party involved in the process describes the part they play in the interaction. Choreography tracks the sequence of messages that may involve multiple parties and multiple sources. It is associated with the public message exchanges that occur between multiple Web services. See Figure 2-6.
54
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 2-6. Outlines the difference between Orchestration and Choreography
The difference between orchestration and choreography is that orchestration is a more detailed, execution-driven mechanism, viewed from the perspective of routing a particular set of messages through a process, and choreography is more abstract and descriptive, viewed from the perspective of the parties that exchange messages to accomplish a particular process.
Web Service Choreography Interface (WSCI) WSCI defines an extension to WSDL for Web services collaboration. WSCI is a choreography language that describes the messages exchanged between Web services that participate in a collaborative exchange. A key aspect of WSCI is that it describes only the observable behavior between Web services. It does not address the definition of an executable business process. A single WSCI interface describes only one partner’s participation in a message exchange. A WSCI choreography would include a set of WSCI interfaces, one for each partner in the interaction. In WSCI, there is no single controlling process managing the interaction. WSCI can be viewed as a layer on top of the existing Web services stack. Each action in WSCI represents a unit of work, which typically would map to a specific WSDL operation. WSCI can be thought of as an extension to WSDL, describing how the operations can be choreographed. In other words, WSDL describes the entry points for each service, while WSCI would describe the interactions among these WSDL operations. As Figure 2-7 illustrates, a WSCI choreography would include a set of WSCI interfaces, one for each partner in the interaction. In WSCI, there is no single controlling process managing the interaction.
Figure 2-7. WSCI choreography.
55
The Complete Reference To Professional SOA with Visual Studio 2005
Business Process Execution Language for Web Services (BPEL4WS) When coordinating the message exchange pattern involved in the execution of a business task, it is often necessary to encapsulate the interaction between web services into a dedicated business process. This provides a central source of business logic that determines the rules, conditions, and exceptions relating to the workflow scenarios that can occur within a solution. BPEL4WS specification has received the broadest industry support. It is complemented by WSCoordination and WS-Transaction standards to provide a framework for building sophisticated and fully managed business workflows. BPEL4WS uses XML to describes its control logic required to coordinate Web service in the workflow process. BPEL4WS operate much like an ESB in that it supports internal workflow management and also supports transaction in its workflow. BPEL4WS has its own WSDL which defines interfaces for all the services involved in its execution process. Though the interfaces themselves do not specify specific binding information this is intentional so that it remains implementation neutral. The BPEL4WS specification supports basic activities for communicating with Web services. When a message is received by a BPEL4WS process, the process will then invoke a series of other predefined external Web services when the workflow is complete the process responds back to the requesting application see figure 2-8.
Figure 2-8. BPEL4WS work flow
In Figure 2-8, the messages all represent basic activities for connecting the services together. In BPEL4WS we can predefine a number of models we can define sequential processing for workflow where services are executed one after the other. Alternatively we can specify a parallel processing model for workflow where messages are sent to several service at the same time for processing. A third model where conditional looping is supported.
Coordination Services WS-Coordination is closely associated with the WS-Transaction specification, which defines two distinct coordinated types, both of which are relevant to enterprise integration environments. The first, atomic transactions, enables the management of ACID like transactions. The service model for atomic transaction
56
The Complete Reference To Professional SOA with Visual Studio 2005
coordinators is the most common type of coordination service used in legacy integration architectures. The second coordination type provides a model for long running transactions, and is represented as part of the coordination service model. Business service coordination is a typical characteristic of EAI solutions, which is why coordination services for business activities are utilized exclusively for the management of business activities. Coordination services are generally used in conjunction with logic-centric services as a means of handling success and failure conditions related to the execution of the overall process activities. The WS-Coordination specification provides an assembly of services with predefined interfaces that support the management of a coordination context. Specifically, this collection of services provides separate operations for the creation of a context, the registration for a context, and the selection of a protocol.
Distributed Event Driven Architecture and SOA Service Oriented Architecture is slowly changing the IT world, as we know it today. A new emergence in technology is the requirement to quickly respond to real-time changes and events in a timely manner. It is also one of the most important requirements for an enterprise framework. This requirement has given rise to Event Driven Architecture (EDA). EDA is an architecture that allows a service-oriented framework to effectively respond to real-time stimuli and, therefore, send and receive synchronous and asynchronous events across layers of an architectural stack without knowing the details of the underlying event system. Internet transactions, business-to-business systems, peer-to-peer processes, and real-time workflows are too dynamic and too complex to be modeled by traditional sequential-processing methods. Therefore, the need for more sophisticated asynchronous processing techniques is quickly becoming apparent. To address these unpredictable environments, the current trend in systems architecture is service-oriented design and event-driven programming. A service-oriented architecture (SOA) presents a dynamic runtime environment, where loose couplings between service providers and/or service consumers enable powerful and flexible component interactions. Building a communication model to exploit this power and flexibility is a high priority for competitive software development. An event-driven communication model is able to respond better to real-time changes and stimuli than conventional request/reply mechanisms. Service-oriented and event-driven architectures are natural fits for distributed systems since they share many of the same characteristics, such as modularity, loose-couplings, and adaptability. Unlike a request/reply system, where callers must explicitly request information, an event-driven architecture (EDA) provides a mechanism for systems to respond dynamically as events occur. In an EDA, events are published by event producers, and event consumers receive events as they happen. Business systems benefit from the features of both an SOA and an EDA, since an EDA can trigger event consumers as events happen and loosely coupled services can be quickly accessed and queried from those same consumers. For systems to be most responsive, they must be able to quickly determine the necessary actions when events are triggered. To this end, events should be published and consumed across all boundaries of the SOA, including the layers of the architectural stack and across physical tiers. Distributed event driven architecture is supported through the use of Enterprise Service Bus (ESB). We will examine ESB in more details in the coming section.
Enterprise Service Bus & Services Successfully implementing an SOA requires applications and infrastructure that can support the SOA principles. Each application will have a service interfaces to existing or new functions. The abstraction from implementation allows its consumers to remain functional regardless of the changes to the underlying
57
The Complete Reference To Professional SOA with Visual Studio 2005
implementation. The service interfaces should be accessed using an infrastructure that can route and transport service requests to the correct service provider. As organizations expose more and more functions as services, it is vitally important that this infrastructure should support the management of SOA on an enterprise scale. One of the key enablers in a SOA enabling architecture is the Enterprise Service Bus (ESB). Enterprise Service Bus is used by large organizations to enforce standardization on Service Oriented Architecture. The role of the service bus is to enable the basic interactions between different service components across a range of varied platforms. It also provides a new way to build and deploy enterprise SOA. ESB is a concept that is increasingly gaining the attention of architects and developers, as it provides an effective approach to solving common problems such as service orchestration, application data synchronization, and business activity monitoring. Enterprise Service Bus helps to support the concepts of SOA implementation through decoupling of the consumer’s view of a service from the actual implementation of the service, decoupling the technical aspects of service interactions, and the Integrating and managing services within the enterprise. Decoupling the consumer’s view of a service from the actual implementation greatly increases the flexibility of the architecture. It allows the substitution of one service provider for another (for example, because another provider offers the same services for lower cost or with higher standards) without the consumer being aware of the change or without the need to alter the architecture to support the substitution. In SOA, services are described as being loosely coupled. However, at implementation time, there is no way to loosely couple a service or any other interaction between systems. The systems must have some common understanding to conduct an interaction. Instead, to achieve the benefits of loose coupling, consideration should be given to how to couple or decouple various aspects of service interactions, such as the platform and language in which services are implemented, the communication protocols used to invoke services, the data formats used to exchange input and output data between service consumers and providers. Traditionally, Web service interactions between consumers and providers are relatively straight forward. It generally involves a Web service consumer requesting an operation directly by sending a message to the Web service provider. The provider then responds with a SOAP message to the consumer with the operation results. This sort of interaction pattern is easily maintained in small to medium architecture. However as the number of Web services increase so does the complexity involved and a pattern using simple point-to-point link is not sufficient. In applications that require large amount of Web service calls with spaghetti type interactions requiring multiple security and transactional supports is where ESB’s value can be realized. The ESB helps to provide an abstraction between the service providers and service consumers Figure 2-9. This abstraction aids the decoupling nature between service consumers and the service providers. Requirements as routing control, logging and monitoring and over all interaction management can be implemented easily through the use of ESB, in an environment that would otherwise require considerable modification to applications to implement.
58
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 2-9. Architecture without Web service
The diagram above Figure 2-9 shows the implementation of an architecture without the use of Web service. This results in complex bindings at each component endpoint. As the number of components increases, the complexity of the application increases exponentially.
Figure 2-10. Architecture implementing Web service but not ESB
The diagram in Figure 2-10 shows the implementation of an architecture using Web service. This results in simplified and interoperable bindings at each component endpoint. However, as the number of components increases, the complexity of the application also increases due to the complexity of message interactions between components.
Figure 2-11. Architecture using Web service and Enterprise Service Bus
The diagram in Figure 2-11 shows the implementation of an architecture using Web service as well as enterprise service bus. This results in simplified and interoperable bindings at each component endpoint. The
59
The Complete Reference To Professional SOA with Visual Studio 2005
complexities of message interactions between components are governed by the enterprise service bus. As such if the number of components increases the application does not necessarily increase in complexity.
Mediation support The ESB provides mediation support to enable service interactions for example, the ESB can help a consumer service find services that provide the requested capabilities and or to help take care of a interface mismatch between the consumers and the providers. In many ways the ESB is much more than just a transport layer. It must support a variety of ways to get on and off the bus, such as adapter support for existing applications or business connections, that enable external partners in business-to-business interaction scenarios. To support these different ways to get on and off the bus, it must support service interaction with a wide variety of service endpoints. It is likely that each endpoint will have its own integration techniques, protocols, security models and so on. This level of complexity should be hidden from service consumers. They need to be offered a simpler model. In order to hide the complexity from the consumers, the ESB is required to mediate between the multiple interaction models that are understood by service providers and the simplified view that is provided to consumers.
Protocol independence Services can be offered by a variety of sources. Without an ESB infrastructure, any service consumer that needs to invoke a service needs to connect directly to a service provider using the protocol, transport, and interaction pattern that is used by the provider. With an ESB, the infrastructure shields the consumer from the details of how to connect to the provider. By using an ESB there is no longer a direct association between the service consumer and the service provider. The ESB acting as a tier shields the service consumer to the location of the service provider. The consuming service in turn accesses the ESB to invoke the required service. The ESB can then convert the request to the appropriate protocol or format before passing the information on. The ESB generally supports several protocols and standards. Even if it in some cases the location information is stored in a Customer Information Control System (CICS®) transaction and using a Java 2 Enterprise Edition platform resource adapter as protocol integrated with the CICS Transaction Gateway. By using the ESB, the consumers are unaware of how the service is invoked on the provider. ESB thus allows applications that do not implement service interfaces to become interoperable and aid in the migration of architectures towards SOA.
Web Service Management Orchestration In an ESB, each application’s service interface and logical address are referenced in a global directory. ESBs support message movements between services and provide location transparency to the consuming service. The interactions between consumer and provider can be configured internally within the ESB. Generally there are several common models that can be configured between applications: *
Logical point-to-point connectivity can be defined,
*
Broadcasting messages across the bus or to multiple predefined receivers
*
Intelligent routing based upon message rules and message content.
Additional, process management engines can be integrated into an ESB allowing the process management engine to manage and monitor the interactions of services within the ESB. Unlike traditional integration brokers these service oriented process engines can control an entire network of loosely coupled service components. This
60
The Complete Reference To Professional SOA with Visual Studio 2005
can dramatically increases the scalability of applications whilst improving business process management throughout the architecture. Within the ESB events are triggered whenever messages are received. With both service consumers and service providers none the wiser about the interactions that happen between requests. An architect can easily configure interactions between two points as point-to-point then later alter the configuration to broadcasting. All of these changes can be made without altering the underlying application implementation or its interfaces.
Figure 2-12 shows the inner working of orchestration happening within an enterprise service bus.
Orchestration-managed messaging tends to be more sophisticated than the standard SOAP messages you may be using in simpler integration scenarios. For instance, messages processed by EAI components can contain routing and transaction information in addition to standard data structure. Also, messages undergo various states. The use of orchestration will often classify an integration solution as a virtual application. Abstracting process and business logic into orchestration workflows also results in elaborate service assemblies that encapsulate aggregated process logic.
Security in Service Oriented Architecture The IT community is slowly embracing service oriented architecture because of its promise of efficiency and improved IT management. However the openness that it brings raises another issue and that is security. This has caused many organizations to proceed slowly or in some cases avoid implementing SOA all together. Security has always been a concern for IT managers in large enterprise systems. Major systems have typically been designed to protect against unauthorized use, intrusion, and viruses. Today however, the issue has taken on even more seriousness in the wake of terrorist attacks and global viruses. SOA security concerns are real and IT managers are realizing that they must soon identify and implement various security solutions for SOA as more and more applications are exposed by developers as web services. A pressing need exists to produce better security architecture as well as measures to ensure secure usage.
61
The Complete Reference To Professional SOA with Visual Studio 2005
The SOA’s inherent security problems stems from the way in which the SOA replaces traditional security parameters with new, open standards. The security problem exists in that not only are the new standards completely open but also the onus of which its security ownership belongs to is uncertain in a distributed world. Web Services were developed over a period of years by industry consensus as a way to enable the creation of reusable distributed code, simplify development, and streamline system integration. However these did not address security. Specifically, XML, SOAP, WSDL, and UDDI are open standards that enable the transmission and description of data and procedure calls between systems. However, none of these open standards contain any inherent security aspects of their own. If left alone, they are completely non-secure. In fact, web services were designed to be able to move more efficiently through firewalls. This very loose coupling and flexibility increased its usability but decreased its security in this regard. The main issues of any basic security infrastructure are authentication, authorization, and confidentiality. The focus broadens where the infrastructure is exposed as in the case of SOA. In this case, concerns such as nonrepudiation, message integrity, and legally binding identity assertion become vital. In this section, we will discuss these principles. The goal is to use security as a tool to foster and encourage the use of Service-Oriented enterprise architecture.
Security Basics Authentication Authentication is used to establish that the requesting consumer is genuine and that the account is valid. The caller must provide identity credentials such as username and password or in some cases a digital certificate. In SOA there can be three levels of authentication: *
First level refers to application level authentication
*
The second refers to SOA framework authentication
*
The third refers to service level authentication.
Authentication at the application level is generally straight forward and mandatory for the business in order protect from unauthorized access. Authentication at the infrastructure level is preferred instead of requesting access to each Web Service. This allows security policies to be maintained more easily at a central place instead of for each web service. A single sign-on framework can provide credential mapping, providing the correct logon credentials for each invoked service or even backend applications. Single Sign-on is usually straight forward and transparent to implement.
Authorization In security authorization refers to the process of validating that a client has the necessary security privileges to perform certain functions, or in our instance invoke a particular method on the Web service. Most Web services coming in over the public network to an enterprise require authentication. A payment gateway can not provide the service to debit money from an account until it knows who is using it. So fundamentally, authorization requires authentication. One method for authorization to be implemented is through a set of credentials that a subject identity carries and presents. These credentials are then mapped to allow access to certain contents.
62
The Complete Reference To Professional SOA with Visual Studio 2005
Integrity In security integrity refers to examining a message to see if it has been tampered with since it was initially created. In SOA generally communication is facilitated through open publicly available networks. There is every chance that as a message is produced and put on the wire that the message is intercepted and its content altered. The altered content is then put back on the wire and sent as the original message to the receiver. This is a form of deception and it is a possible form of attack that is possible in an open network unless security procedures are implemented. We can ensure the validity of message integrities through process such as encryption and hashing we will be talking about Web service security later in Chapter 13 (Web Service Security) and Chapter 16 (Windows Communication Foundation). Message integrity check thus refers to validating the message was received precisely as it was sent with no content altered.
Confidentiality In security confidentiality refers to keeping a message confidential. Implementing confidentiality is important in SOA context. This is because of the open architecture of SOA. With the necessary access to network it is possible to intercept messages. Thus keeping information secure and confidential is especially important when financial applications are concerned. By using encryption we can scramble the messages so that only the authorized recipients can decrypt and view the message. Even if messages are intercepted without the decryption key the message itself remain scrambled and useless. In XML Web service we can use a number of encryption techniques to keep the message confidential. The most popular method is to use a Public Key Infrastructure (PKI) where a message is encrypted using a public key and decrypted with a private key issued through a trusted third-party authority.
Non-repudiation Non-repudiation proves that one identity sent the data to another identity. This proves that the recipient entered into this specific transaction, and neither party can refute or deny that it occurred later. Non-repudiation is achieved through the use of public key cryptography. One identity prove that it had sent the data only to another identity because the sender used the recipient’s public key, and it is only the recipient with his secret private key who can decrypt the data. To achieve non-repudiation, separate timestamp notary is required to prove when the transaction occurred as well as independent verification of the participant’s identities.
Web Service Security Point-to-Point vs End-to-End Security Point to point refers to the lower layers of security. This is usually achieved through the use of SSL short for Secure Sockets Layer, SSL is a protocol developed by Netscape. SSL uses Asymmetric Encryption where messages are encrypted using public key that is shared with the public and decrypted with a private key that is only known by the recipient of the message. SSL support was integrated into browsers so that security can be implemented for messages traveling from the server to the browser. Today most browsers support SSL. Web sites that require SSL must have a valid security certificate. Web sites that implement SSL security are identified by HTTPS instead of the usual HTTP.
63
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 2-13. Shows point to point security only
In the above diagram Figure 2-13 transmission of data between Partner X and that of its Web service only implements Point to Point security. This means that whilst data traveled in the first segment of the network from Partner X it is protected by SSL encryption. However due to various reasons, most commonly network ownership issues. We can not enforce network security upon rest of the segments of the network. It is at these other networks segments that our data become vulnerable. Figure 2-14 is point-to-point and end-to-end.
Figure 2-14. is point-to-point and end-to-end
In the above diagram Figure 2-14 we’re implementing point-to-point security added with end-to-end security. Even though data travel through networks that does not implement the necessary SSL data security (point-to-point). The data itself is encrypted (end-to-end). Thus data protection is ensured at all stages of travel.
Another protocol for transmitting data securely over the World Wide Web is Secure HTTP (S-HTTP). Whereas SSL creates a secure connection between a client and a server, over which any amount of data can be sent securely, S-HTTP is designed to transmit individual messages securely. SSL and S-HTTP, therefore, can be seen as complementary rather than competing technologies. Both protocols have been approved by the Internet Engineering Task Force (IETF) as a standard. However point-to-point based security has its limitations. Firstly, SSL is designed to provide point-to-point security, which falls short for Web services because we need end-to-end security, where multiple intermediary nodes could exist between the two endpoints. In a typical Web services environment where XML-based business documents route through multiple intermediary nodes, it proves difficult for those intermediary nodes to participate in security operations in an integrated fashion. Secondly, SSL secures communication at transport level rather than at message level. As a result, messages are protected only while in transit on the wire. For example, sensitive data on your hard disk drive is not generally protected unless you apply a proprietary encryption technology.
64
The Complete Reference To Professional SOA with Visual Studio 2005
Thirdly, point-to-point in its current form does not support non-repudiation well. Non-repudiation is critical for business Web services and, for that matter, any business transaction. What is non-repudiation? Nonrepudiation means that a communicating partner can prove that the other party has performed a particular transaction. For example, if E-Trade received a stock transaction order from one of its clients and performed the transaction on behalf of that client, E-Trade wants to ensure it can prove it completed that transaction to an arbitration committee, for example, if a dispute arises. We need some level of non-repudiation for Web servicesbased transactions. Finally, point-to-point does not provide element-wise signing and encryption. For example, if you have a large purchase order XML document, yet you want to only sign or encrypt a credit card element, signing or encrypting only that element with SSL proves rather difficult. Again, that is due to the fact that SSL is a transport-level security scheme as opposed to a message-level scheme. Even though point-to-point provides some aspects of security such as confidentiality and authentication, however, web services require data validation, accountability, and distributed authentication and authorization. None of these are provided by point-to-point security. However, these security requirements can be supplemented with the use of XML security technologies, including XML Signature and SAML, which apply security at the message layer. Please note that point to point does not compete with end to end in fact the two complement each other however point to point alone is not adequate enough for the purpose of providing SOA level security. For the purpose of this book we will focus on achieving end-to-end security.
Web Service Authentication As computer systems have increased in complexity so has the challenge of authenticating users. As a result there’re a variety of models for authentication in Web service. For example, clients accessing a web application may directly provide credentials, such as a user name and password for authentication. However, a third-party security broker, such as a Kerberos domain controller, may be used to provide a security token for authentication.
Figure 2-15 illustrates the Web service authentication models.
The mechanism that we choose to use for authentication will have an affect on other security implementations such as encryption and signatures.
65
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 2-16 depicts a direct authentication when a client and service share a trust relationship.
In Web service a consumer of a Web service can directly submit authentication information to the web service when a client and service share a trust relationship Figure 2-16. This is regarded as Direct Authentication. This is simplest form of authentication in terms of implementation. In a more complex model where a client and service do not share a direct trust relationship, a mutually trusted broker can be used to perform authentication. The client will send a request to the authentication broker who then validates the client and sends a security token. The client then using the security token can send requests to the Web service. Upon receiving the request the Web service then sends the token to the authentication broker for validation. If the broker returns a valid response then the Web service will process the request. Though, typically the Web service does not always send the token to the broker for authentication. As receiving the token is often enough proof of the client’s relationship with the broker.
Figure 2-17 using a broker to perform authentication when client and service do not share a trust relationship.
WS-Security WS-Security is the name given to the set of security standards that have been ratified by the Organization for the Advancement of Structured Information Standards (OASIS). WS-Security is a conceptual model that abstracts
66
The Complete Reference To Professional SOA with Visual Studio 2005
different security technologies into “tokens”. It formalizes a way to package security tokens into SOAP messages. WS-Security provides a set of additional roadmap specifications built on these concepts and integrated into XML specifications. These roadmaps describe how to apply for a security token, how tokens are linked to identity and how they’re linked to a web service and more.
XML Encryption XML Encryption utilizes cryptography technology using shared key encryption. Shared key encryption was selected because it allowed for the encryption of varying sized XML messages efficiently. Encryption provides for message confidentiality (the message remains a secret from all but its recipient). The reason XML encryption is needed over and above point-to-point encryption mechanisms like SSL is because confidentiality of messages needs to be maintained while the message is taking multiple server hops on its way to its destination. This will be common when shared services are utilized. We also need confidentiality when the XML message is stored even after it reaches its final destination. This requirement is called persistent confidentiality. There are two types of encryption typically used in Web service security these are symmetric key encryption and asymmetric (public) key encryption otherwise known as Public Key Infrastructure (PKI), both encryptions can be used in conjunction with one another.
Symmetric Key Encryption, refers to encrypting and decrypting a message using the same key. The key is always kept private and only known to each of the parties that is one who encrypt and send the message and one who receive and then decrypt the message. Symmetric Key Encryption is simpler to implement than Asymmetric Key Encryptions and performance wise it is faster because it requires less computation. Asymmetric (Public) Key Encryption, also known as Public Key Infrastructure (PKI) refers to encrypting and decrypting using two different keys a public key which is used to encrypt a message and a private key is used to decrypt the message. When the owner of the private key wishes to send a message to other parties the private key can be used to encrypt the message and the public key used to decrypt the message. Today Asymmetric Key Encryption can be implemented through X.509 certificates. A client uses the public key (of an X.509 certificate) to encrypt his message and only the owner of the private key (of that X.509 certificate) can decrypt the message. Due to the open nature of Web service security is very important, since SOAP messages are essentially just plain texts that are transported across the wire. Anyone can intercept the message and read its content. The Web Service Extension (WSE ) specification supports both symmetric and asymmetric encryption. Using WSE, in symmetric encryption the Web Service and the client share a secret key outside the SOAP message communication, the client encrypts the message using this key and the Web Service decrypts the message using the same shared key.
XML Signature XML Signature is the foundational technology for the Web service security standard called WS-Security. XML signature is built on top of mature digital signature technology. The purpose of digital signatures is to provide a mechanism for message integrity (to ensure no alteration on the message) and non-repudiation (can not contest that the transaction had occurred). XML Signature enables you to encode digital signatures into XML.
SOAP Message Monitoring SOAP message monitoring based on SOAP interception is one way to build the foundation of an effective SOA security solution. SOAP interception involves placing a special piece of software called a “SOAP interceptor” in
67
The Complete Reference To Professional SOA with Visual Studio 2005
the path of the SOAP messages that travel back and forth between a web services consumer and a web service. Because of their ability to process, monitor, copy, and forward the data-rich SOAP messages. SOAP interceptors are a very prominent element in SOA security. An SOA security solution examines the SOAP invocation messages approaching the web service as well as the response to those service calls. It analysis the message, the SOA security solution checks to ensure that the requesting entity is authenticated and authorized to use the web service. The SOA security solution accomplishes this by checking the user data contained in the SOAP message header. Your SOA security solution should be complementing an existing security solution that you deployed to secure your entire enterprise before beginning transitioning to an SOA. This may mean that your SOA security solution will need to plug into existing security infrastructures to authenticate and authorize access requests.
Figure 2-18 Shows a SOAP Message interceptor, interception and authorizing messages.A vendor requires access to a particular service from the supplier, the request is interrogated against an existing security infrastructure before it is forwarded onto the service within the network.
The authentication and authorization of the users on the SOA occurs when their credentials are checked with the security infrastructure of authorized users Figure 2-18. This is achieved by intercepting the SOAP messages and comparing the users listed in the message header with those users stored in existing security infrastructure.
Security with Federation and SOAP Interceptor One of the key security problems associated with SOA is its openness. It is this openness that introduced new problems with authentication. We can no longer authenticate a client requesting service just from our own user database alone because with SOA, business partners when given permission can also access the same required services. So then how do we authenticate and check authorization with clients that don’t originate from the same enterprise architecture? To deal with this we can use the Web service standard for federation (WS-Federation) for security access. Federated authentication refers to creating a federated identity management system, it can access security information from a number of sources. This identity management system can gather user security information through established trusts with each of the enterprises. So now when a request is received it is validated against the federated identity management system first. If required the federated identity management system will query the relevant security database on either of the systems before returning a response.
68
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 2-19. shows a federated authentication user database created from a Partner X with a LDAP system and a Partner Y with an internal custom security solution system.
In Figure 2-19 a request is sent by one of the partners requesting for service from our server. The message passes through the firewall and is received by our security infrastructure which then validates for authentication and authorization. If the request is from a valid client then the message is forwarded on to the service. Otherwise the message will simply be dropped
Security with Federation and SAML Alternatively to SOAP message interceptor we can also use Security Assertion Markup Language (SAML). In the model of using federated security infrastructure it is also common to use SAML. SAML is an XML standard for exchanging authentication and authorization. SAML assertion much like SOAP message interceptor in that it watches the messages as it arrives. The SOAP message is then authenticated and authorized before a SAML tag is inserted into the SOAP message. The tag can contain security information and attach additional information about the requesting client such as security group it belongs to.
69
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 2-20. SAML
Figure 2-20 shows the use of WS-Federation to authenticate an income SOAP message once the message has been authenticated a secure assertion markup language (SAML) is appended to the SOAP message. A vendor in this case sends a request to the supplier. The request is checked against a security infrastructure if found valid a SAML message is appended to the request which is then forwarded onto the supplier. The supplier then checks the SAML before it responds to the request.
Application Proxy One highly effective way to protect the security of core systems is to avoid letting an unauthorized requests to reach the server that is hosting the web service. Through the deployment of a firewall to secure the server and then applying proxy for the web services within the SOA. A secured application proxy can receive and respond to all web service requests on behalf of the actual web service, and is protected from unauthorized requests. The proxy can also manage and cache requests to authenticate and authorize web service requests. The proxy can also append SAML to SOAP messages there by eliminating the need for actual requests to security systems at the web service level.
Message Reliability in Service Oriented Architecture One of the biggest challenging in developing for Service-Oriented Architecture is maintaining reliability for mission-critical applications. This is because of the nature of unreliable network transports, such as HTTP, and the lack of reliable message delivery. However by adopting a reliable messaging specification for Web services and adding reliability headers into SOAP messages, Web services can be used for a broader range of applications, and application development can be dramatically simplified. Reliability for Web services is defined independently of the transport as a series of SOAP messages exchanged within a group or sequence and some processing rules governing the use of acknowledgements and message numbers to ensure that all the messages are received, duplicates are eliminated, and that message
70
The Complete Reference To Professional SOA with Visual Studio 2005
ordering is preserved. Of course, Web service reliability does only refer to messaging. Security, transactions and execution environments such as clustering and redundant storage all have an impact on reliability. Reliable messaging technology requires a piece of software infrastructure deployed on both ends of connections. The reliability-messaging agent handles errors in the transmission of messages from one computer to another over a potentially unreliable network. Typically the agents are symmetrical implementations so that mutual handshakes can be implemented. The reliability-messaging agent assigns a sequence ID to a group of related messages and message IDS to the individual messages within the group. The requester’s agent marks the last message in the group, and the provider’s agent returns an acknowledgement to indicate whether all messages in the group were received. If one or more message IDs are missing from the acknowledgement, the missing message is resent until the provider’s agent returns an acknowledgement containing all the message numbers in the group. The sequence IDs and message IDs can also be used to prevent duplicate message processing and to require that messages be processed in the order they were sent. Reliable messaging mechanisms can be used with SOAP Message Exchange Protocol (MEP). A MEP is a template specified for exchanging SOAP messages between nodes to ensure reliability. Typically the message exchange between nodes is predefined synchronous data exchange.
Figure 2-21 depicts a reliable messaging architecture.
A reliability layer is introduced between the transport and the application that interprets and executes a series of message acknowledgements Figure 2-21. Acknowledgement from the provider allows the consumer to know if a message has been successfully received by the Web service. This is very important in a mission critical system. The reliability allows both parties to temporarily store their message within a file or a database incase of unsuccessful or missing messages. The sequence of messages is then removed from the database when acknowledgement is received from receiving party. However if a message acknowledged as missing then it will be retrieved from the database and resent to the receiving party. In Web service specification both WS-ReliableMessaging and WS-Reliability establishes standard processes for the acknowledgement of successful message deliveries and the notification of transmission failures. It can be used in conjunction with other specifications, such as WS-Security, WS-Policy, WS-Coordination, and WSTransaction.
Summary Developing for any architecture requires a great deal of requirements gathering and planning, and with it comes a great deal of responsibility. The initial step is to plan out the roadmap that you will need to take through out the development of your SOA. This will help you realize your long-term goals whilst keeping your short term goals in check.
71
The Complete Reference To Professional SOA with Visual Studio 2005
Your SOA needs to be agile and flexible and structured according to business domains and business requirements. This can be achieved through the use of several service types. These are Basic Services, DataCentric Services, Logic-Centric Services, Transitional Services and Public Services. These services are used to provide SOA layer, which abstracts the constraints such as location, operating system, and language. Together the different service types help to create a balanced SOA architecture. If you’re developing on top of legacy systems or large enterprise systems that already has web services quite often you will need to aggregate these entities to a higher level. This is important in maintaining abstraction at a higher level and ensures that the overall SOA remains flexible and agile so that they do not need to consider physical location constraints. In SOA, Enterprise Application Integration (EAI) is aided by an integration middleware. Its role is to connect a broad range of applications and let the organization decide how they should be logically coupled to automate key business functionalities. The middleware provides organizations with flexibility to allow services to publish and subscribe asynchronously. This resulted in the rise of Event-Driven Architecture (EDA) which uses SOA based concepts to provide a more flexible and robust system of collaboration. However due to the flexibility and openness of SOA it opens up security vulnerabilities. We have examined various security concepts within the chapter to lock down and secure a real enterprise SOA. These techniques include: point-to-point and end-to-end security, web service authentication, xml encryption, xml signaturing, SOAP message monitoring, Security Assertion Markup Language and Application Proxying. Understanding of these techniques are essential in providing your enterprise with a secure and yet flexible architecture that will save you in the long run. We have also discussed the importance of ensuring message reliability in a largely unreliable delivery system. This is essential in any form of mission-critical systems where successful transmissions of message to destinations are vital. Overall we have examined various aspects of SOA and by now you should have a firm grasp and understanding of SOA and the tasks involved in approaching planning, development and deployment.
72
The Complete Reference To Professional SOA with Visual Studio 2005
Chapter 3 Business Adaptation of SOA Previous chapters focused on what SOA really is and provided technical concepts to the implementation of SOA. In this chapter we will be focusing on the challenge of introducing SOA to the business as well as discuss the benefits to the business and pitfalls that may arise. Up until now we have discussed a lot of positive aspects of SOA. However as much as we love SOA to be everything and some what of a silver bullet but it is not. Far from it, SOA is often described as a journey not a destination. The journey of SOA realistically is quite difficult and time consuming, however weighing in the positive outcomes the journey is well justified. In a service-oriented enabled architecture, the total cost of ownership is reduced, development time of new systems through the use of existing components is reduced, total system maintenance is reduced and system scalability improved. Even though the journey of becoming service oriented is very difficult and costly at first. Organizations that have gone through this journey will dramatically benefit from it. While those organizations that have architecture that are rigid and difficult to change and improve will comparatively eventually perish. It is a journey that organizations should and must undertake sooner or later.
Service Orientation and Its Role in Our Connected System Strategy The primary reason for most organizations to adopt a service-oriented architecture is to increase agility of the enterprise IT systems. On top of this SOA also allows the reduction of technology dependency to a simplification of the development process. This allows for flexibility and reusability of the business infrastructure. The focus of additional flexibility is to allow processes and services to be rapidly developed and configured. The reason for efficiency and speed is the ability to reuse existing technology investments. This allows organizations to save tremendous amounts of resources on redevelopment and testing. Let’s face it no matter how great the new component will be there is always an integration phase and there may always be that few bugs that will cause headaches to the users. Existing investments that have worked for many years will continue to work and continue to do what it is suppose to do. Isn’t it much safer to just place a service on top of that piece of business logic to promote inter-operability instead of redeveloping the component again? With the vision of agile enterprise, it allows a much superior time to market for new business initiatives. This allows the reconciliation of the growing demands of a rapidly changing business environment with the limitations of current technological and organizational infrastructures. Consequently, the Agile Enterprise is not characterized by a fixed state of the enterprise but by an ongoing change process within the enterprise. The value of the agile enterprise architecture can not be understated. In today’s business world new mergers are forged continuously. It is therefore vital for the IT infrastructure to support Enterprise Application Integration (EAI) so that new components can be registered onto the infrastructure quickly. It’s important for IT infrastructures to keep up with the business requirements in order to improve the competitiveness of a business. Not only will an agile structure support this, but also take the pressure of the enterprises with on going maintenance and changes. Due to the competitiveness within the business world businesses are continually forced to reinvent themselves by offering their customers new or better products to stay ahead or keep up with
73
The Complete Reference To Professional SOA with Visual Studio 2005
their competitions. In order to remain efficient, partners and suppliers must regularly evaluate to find better quality, prices and conditioned products.
Figure 3-1 illustrates the benefit of a service-oriented agile architecture.
Why do we need flexibility? In the past changes required to an organization resulted in technological obstacles. For example replacing a partner or supplier might be straightforward in theory, but it could require major efforts in reality. These efforts could involve a complete redevelopment of technical components and a major redesign of business processes. Similarly, integrating a newly merged or acquired company’s IT infrastructure and processes might call for a large-scale integration project. In addition, although offering new or better services might be desirable from the business perspective it often proves to be technologically infeasible. Primarily due to lack of time and lack of resource. These are the primary limiting factors to a business. Quite often developing the desired practical solution would take too long to be of use. For most products, there often is a window of opportunity (time-tomarket) that must not be missed. Or developing the requirement functionality is simply not possible because of the cost involved. For example replacing a supplier is only profitable if the cost does not exceed the saving obtained through the replacement. Recent research on 365 organizations found that 82% of the IT projects are late, over budget, or have reduced features. On average IT projects are 189% over budget and 1/3 of late projects are late by 100-200% with 70% of IT work being reworked. With a record like this we can easily see that there are serious problems with the way IT currently works. From the statistics we can see 70% of IT work being rework. If we were to reduce that 70% rework surely it will decrease some of the other percentiles. This will in turn reduce the time taken for delivery as well as the total cost involved in development. SOA provides the means for achieving flexibility by leveraging an appropriate architecture and reducing the amount of rework within an architecture.
Agility We’ve constantly mentioned agile architecture. In case we’re still confused or wondering what it is, agile architecture simply means an architecture that is responsive to the need of that of the business its serving. However to reach agility is no simple matter. In order to fully understand the benefit of agility we must identify
74
The Complete Reference To Professional SOA with Visual Studio 2005
the different levels at which enterprise projects may be threatened by complexity. These inevitably, diminish the effect of an agile architecture.
Technology Technology and the ability to understand the complexity of different technologies as well as its functionalities is always going to be an issue. Often complexity comes as a result of yearlong efforts to add patches to existing systems which provide more functionality. Whilst other complexities come as a result of using cutting edge / bleeding edge technologies that have not yet matured. This results in complex configuration as well as proprietary systems that is not backward compatible in its future releases. Finding the right people to manage these technologies will always be a key limiting issue.
Communication & Location Issue In the past one of the key issues with developing enterprise applications when different components are developed by different teams from different countries is communication. A very high level of communication is required and as well as comprehensive understanding of requirements is vital. However reality is vastly different and chances are people from these teams speak different native languages and communication is and always will be an issue. Even when the language is the same see Table 3-1. As we can see even when we speak the same language sometimes different meanings are implied and could result in different outcomes. This is an issue when developing cross country. Table 3-1. Outlines the difference in meaning even when they’re common words in English.
Expression
Meaning in countries listed
Meaning in countries listed
pavement (noun)
paved area at side of road set aside for pedestrians (CA, GB, HK)
paved surface of road (US)
biscuit (noun)
A crisp, generally sweet, confection (AU, GB, HK, ZA)
Soft, flakey savoury pastry eaten with gravy (US)
corn (noun)
Grain, or a cereal crop, as in “cornfield” (GB)
Maize (AU, CA, US)
table (verb)
To put forward a proposal (AU, CA, GB, HK)
To abandon a proposal (US)
Business Process Business process complexity is not always obvious. However it is as important as the technological complexity. Typically a complex business process will result in a complex implementation. It is often during implementation that the real complexity comes through. Another issue with Business process complexity is that there is quite often a lack of documentation. In any business, processes should be documented. However, realistically this is not always the case. Quite often documentations were made at the start of a process and as the business processes evolve the documentation is left behind. This is an inherent issue in IT as outdated business process documentation often finds their way to an unsuspecting developer. Sometimes the issue does not become immediately visible until solution becomes complete.
75
The Complete Reference To Professional SOA with Visual Studio 2005
Business Functionality Business functions themselves can be complex. They can contain complex contradicting logic between different functions. The complexity associated with any one function could exponentially explode at its component level. A very good example of this is insurance, the complexity involved in calculating something as simple as premium could easily become exponential based existing data. At a global level each service providing logical functions has the potential to have its complexity increased exponentially. In this case careful planning and detailed documentation is required at every level. This will save tremendous amount of time on future support and maintenance.
Integration Integration is key to any enterprise application. Typically, enterprise projects combine functionality from existing applications. Even if the individual application is stable and has been well tested, using it in a new context and integrating with them and other application generally can become complex and unpredictable.
Support Supportability is vital to the on going maintenance of an application after it has been deployed and is running in a production environment. However maintenance of a complex application can be quite difficult. It is important to plan out trace and logging functionalities and exception handling within the application early during development. This will save considerable time in support. Typically customers are not interested about how complex the application is. All they’re interested is whether it takes 30mins to fix something or 3 days. Often applications are frequently updated such as when additional functionality has been introduced or when a new version of software has been released. Such updates can cause the complex issues similar to those encountered during the initial integration of the application. Without an appropriate architecture planning, all of the outlined complexity could easily get in the way of our agile architecture. Thus preventing all the real benefits of a service-oriented architecture. SOA can help to significantly reduce complexity at all levels. This is a key aspect of SOA which allows existing infrastructures to react as quickly as possible to the changing business environments and offer new services to its customers. In order to achieve SOA the following must be carefully considered. *
Decomposition. SOA decomposes large, complex systems into application frontends and services.
*
Appropriate granularity. The granularity of services is well suited to gain a high-level understanding of the entire system. Unlike other approaches SOAs do not confuse practitioners by presenting too much detail.
*
Decoupling from technology. SOAs can be well understood without in-depth knowledge of technology
*
Reuse. SOAs result in the high-level reuse of existing components. This streamlines the code base and reduces complex redundancies.
*
Documentation. Due to the service contracts every service is well documented, which adds to the comprehensibility of the SOA.
Reduction in Cost of Development One of the main reason that we strive towards agility and efficiency is because of the benefits of reuse that SOA brings. By having a greater support for reuse commercial organizations can benefit with increased return on investment (ROI) and faster and more efficient development. Generally, we differentiate between direct IT cost saving and direct business cost saving.
76
The Complete Reference To Professional SOA with Visual Studio 2005
IT Cost Savings SOA in an enterprise project will be able to considerably reduce project costs because it allows for more efficient implementation and deployment. However in order to achieve reduced project costs initial SOA infrastructure must already in place. To convert to a SOA infrastructure from a rigid infrastructure could initially be costly. For those organizations that undergo this process the benefit will be evident in future development compared to those that have not. By adopting SOA early, the long-term maintenance of SOA is also reduced. This is due to the simplification of application. Future changes can be made more easily. Maintenance efforts can be targeted to business functionality. Side effects can also be reduced and comprehensibility can be increased due to a clear decomposition of the application landscape within components. Finally, correct adaptation of SOA guarantees future proof solutions. This is due to the ability for web services to provide abstraction from the underlying technology. Thus the service itself is not tied to any shortcomings of technology. SOA also allows the preservation of IT investments because it enables us to integrate functionality from existing systems in an enterprise instead of replacing them. This support for reusability is central to so much of better future IT development.
Business Cost Saving from SOA SOAs can help to reduce costs in the enterprise’s core business. These cost savings come from SOA’s agility. Because of the flexibility of SOA it allows organizations to pick and chose the cheapest service supplier. In the past organizations were held ransom by these services suppliers as in order to change to another service supplier often meant considerable cost to infrastructure redevelopment. SOA solves the issue that are related to changing suppliers. By providing the means to have more flexibility within the architecture, so that re-integration with another cheaper supplier can be achieved in a timely manner. SOA helps to streamline business processes. Allowing a business to make use of internal resources in the most efficient way. In traditional environments, adaptation of existing applications are costly and typically prohibit IT system changes and thus prohibit rapid changes of business process. With improved agility businesses can monitor every section of the business process. Allowing more detailed financial analysis and tracking which was costly and difficult to implement in the past. Due to its ability to make different parts of the architecture share live data, SOA financial reporting on the spot is possible. This gives live statistics and reason to allow management to make more appropriate business decisions on daily basis. We can see the value of SOA and its benefits to an organization. Most of these benefits are related to SOA’s flexibility and agility, solving the age long issue of rigid architecture.
Opening Our Intellectual Property The Web is evolving from a collection of linked pages to a network of interactive applications that communicate and collaborate. Today we see the websites starting to work together to introduce a new compelling concept of no longer just one lonely website but a new series of connected web services creating a limitless platform. With this change the question the organizations are asking is how can they benefit from this advance and adaptation in technology? As internets old and new considers the best ways to profit from the evolving Web. Originally the HTML-based Web began as a better interface between humans and information stored on servers. Largely due to the popularity and the mutual adaptation of XML and Web Service organizations are able to open up specific APIs to their partners and clients. This openness, allowed developers to come up with more innovative ways to share and access data. This in reality worked well for both parties.
77
The Complete Reference To Professional SOA with Visual Studio 2005
Suppliers Organizations had always longed for more development resource after all swiftness to act is the key to any success in business. However to act quickly has always been extremely expensive and the solution produced are often bug ridden and not always guaranteed to have rewards that were expected. As a result, businesses have learned to be patient with technology. This meant that they’re no longer competing at the level that they like. With SOA an entire architecture can be opened up. Organizations have the control on what component and functionality to make available to its partners and clients. This changed the world of supply/customer relationship in business. Previously the supplier developed applications for its customer and then in turn sold the solution to the customer. This was rigid and the intellectual property often belonged to the supplier and therefore the business restrained from making subtle changes to streamline business processes. This often made both parties feel unhappy and tied down. The supplier of the system who uses its functionalities is reluctant to make client-by-client changes. From a business perspective it was just not possible to develop and maintain for each and every customer. While the customer was not happy with the rigidness of the application and the lack of flexibility and support is constantly an issue for the business. Suppliers are beginning to see the benefits of SOA as they’re able to open up their functionalities and leave the rest to the consumers. This reduced the responsibility and maintenance costs of maintaining client side applications. Suppliers could simply charge a service fee for each usage or its service. An example is a payment transaction service, each time a client used the service a fee is charged to the registered client account holder. This essentially allows consumers to build a provider’s business for them. In fact the supplier is able to gain additional market and users through its client’s users. Which in turn requires the supplier’s web services to function. This is an alternative strategy to expand one’s business through the aid of others. Opening up functionalities seems simple, and is simple. So what is the catch ? There really is none. It is exactly the same as before but now there’s just a web service in between the client and the provider.
Consumers The consumers of the business services are mostly the victims of rigid supplier-consumer relationships. Consumers are nearly always given what they don’t want and functionalities that they don’t really need for a costly price. Even after paying such high prices, support is poor. When the suppliers opened their functionalities as web services. Their clients could programmatically consume required functions. This gave the consumers unlimited flexibility on how they can use the functionalities and how they can integrate their existing systems with the these services. Consumers could quickly streamline their internal systems. This provided them with more value and control to their business. They no longer have to purchase the pre-packaged bundle that was designed for everyone and catered for every scenario. All they needed was to integrate the web services that their internal systems required to begin operation. The integration process is usually straight forward and overall it’s a reduction on cost and thus better return on investment. Web services are the key to the platform evolution, because they provide a standard, controlled way for outside machines to interact with corporate systems. A company can “expose” only what it wants in the form of Web services: access to a database or product attributes, for example, or to an application such as search. Clients “consume” these Web services by embedding them in their own applications or Web sites. For example, instead of having to license and host a geospatial database, a site that publishes restaurant reviews could embed a tag that calls on a third-party database when a user wants directions to a particular restaurant. This is just like how suppliers build applications for consumers in the past. Except now the clients are building the applications they want themselves, and thus expanding the supplier’s business by integrating supplier functionalities within client applications.
78
The Complete Reference To Professional SOA with Visual Studio 2005
Take eBay. The online auction giant has offered APIs since 1999, as well as Simple Object Access Protocol and Java integration capabilities to its software development kit. eBay has around 100 public Web services calls available, while about a quarter of the money exchanged in the online marketplace is via PayPal, which is effectively a Web service on eBay. This is a good example of an organization using third-party developers to provide the growth that the organization need. Organizations will often find that when outsiders build onto the platform, they often do it in surprising ways that the mother company wouldn’t have considered. For example, when Amazon.com exposed data from its Alexa Web Information Service (AWIS) program, it kicked off a wave of creativity as it provided aggregated, close-to-real-time information about Web traffic, including the top sites visited and where visitors to one site go next. By offering web services to the public and generating a public following is like employing an army of developers dedicated to a common course except without the cost. Third-party developers are often able to see an aspect not seen from the business perspective. This promotes innovations but the focus is still on the organization as it is still the public service that the third-party application is using. With this strategy in mind an organization can quickly grow where growth was not possible previously.
Promoting Inter-Platform Connection Independence from technology thus allowing inter-platform connection Software increase – complexity has also increased therefore impossible and frequently difficult to develop inter-platform solutions. Many large organizations generally have applications that reside on a range of platforms. This is often because development technologies at the time were appropriate for certain aspects of the overall system. However over time the result is a library of technologies sitting on different platforms that is difficult to interoperate. Today the focus on technology can be a huge issue in IT projects. We’re reaching a new generation of interconnectivity where everything must be connected with everything else. To achieve interconnectivity between various software solutions a large number of “helper” software applications were created they were used to simplify certain integration tasks between systems. However as industry grew so did the different types of software and also the number of “helper” solutions. Now we’re faced with a dilemma. This is because in order to develop one particular solution as an architect we would need to know the ins and outs of a dozen “helper” solutions. As a result valuable solution development time is often spent on debates about the right technology to use often threaten to tie up resources that could be better spent designing and optimizing business processes. These “helper” solutions often determined a project’s functionality and features due to its limitations.
79
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 3-2 illustrates that as the number of “helper” software increased the agility of development becomes inhibited.
SOA helps to shift the attention from technological issues to questions of service functionality and service design. Allowing a more productive development cycle through the use of a range of technologies that was frustrating and tedious to work together in the past.SOA provides an abstraction from the underlying technology of different systems. This independence offers several benefits to an organization. Most important is the agility that is brought to the business, subsequently allowing it to make important business decisions instead of waiting on IT. This is all achieved through SOA’s ability to support inter-platform connections between some very different systems. Independence from technology also increases independence from software vendors. Applying SOA allows a software system to choose the best of products and to combine them to formulate a well rounded solution that’s not restricted by one software vendor. The two most common contemporary application landscapes are characterized by two incompatible development frameworks J2EE and .NET. This make it particularly difficult to create and maintain crossdepartmental business processes. Due to the tight coupling of business functionality to specific technology, it is arbitrarily difficult to force different parts of the architecture to work together. SOA avoids these obstacles by decoupling the technologies of the provider and consumer of specific business functionality. SOAs do not interfere with the development framework itself. But rather it allows more efficiency and agility within the application. It also promotes future reuse which allows for a reduction in development resource in future projects. Independence from underlying technology supports decoupling of technology lifecycles from the lifecycles of business services. Therefore, the introduction of a new technology within an enterprise does not require a makeover of the business processes and services. Similarly, new business service can be introduced without the need to wait for new, innovative technology to become mature, stable and affordable.
Measuring a SOA Determining ROI for service-oriented architecture can provide valuable information. It also justifies the reasoning behind the push for SOA. However, putting together a realistic ROI is not a simple task and often takes many revisions as new ROI information becomes available. Determining a ROI ahead of a project will often shape an enterprise’s migration strategy. Whilst by examining the migration strategy also contributes to the outcome of a ROI. Nevertheless realistically there is no real way of knowing the ROI until a project is actually deployed. Even then measuring the real ROI will take months if not years. Often determining ROI takes considerable research that tends to be performed for migration strategies and is more focused on technology and implementation, rather than high-level organizational benefits. An intelligent strategy for integrating a service-oriented architecture can lead to much greater cost benefits than an ROI can originally predict. Even though if an ROI is used to justify the migration path of a project. The ROI can be refined further on as new information is obtained. The initial SOA migration phase is the most expensive phase of an enterprise-wide initiative however, the scope of our ROI will likely always go beyond the migration phase. Further revisions to an ROI will improve the accuracy of its predictions as they relate to subsequent phases in a long-term program. The benefits for SOA tend to be tangible, because the interoperability enabled by the service integration layer results in immediately recognizable savings. To be able to measure a SOA a measurement plan must be drawn up from the start. The best method of measuring of a SOA is to start with a small project and to expand and iterate as new information becomes available. Make sure that the service is something that is simple and measurable such as a service which provides access to a database. Because even small things have ROI value attached to them. The service should be monitored and the results measured.
80
The Complete Reference To Professional SOA with Visual Studio 2005
To measure the success of a SOA it is important to draw up a projected ROI ahead of development. The real ROI should then be tracked and monitored. By comparing the two values we can assess whether SOA implemented is successful. Of course depending on the industry that the system is designed for the ROI will vary, as not all industries have the same benefit from SOA. Typically Banking, Insurance, Telecommunication, Retail and Government have the greatest ROI partly because they service such a large range of users. If we’re not in these industry types we will still benefit from savings in asset re-use and business labor savings.
Figure 3-3 shows the four areas of ROI benefits.
In measuring SOA we look into four areas where ROI can be examined. 1.
The simplest and most straightforward is short-term, tactical ROI, which is gained from the immediate reduction in the cost of integration. This should be able to save us money the day after we implement SOA from an immediate savings on integration. We will be able to get rid of middleware, reduce the time in transformational mapping and get other similar benefits. It’s easily quantifiable, because we can identify the business processes and systems that were replaced.
2.
The second ROI can be obtained through application reuse. This is a little more difficult to get than integration costs. To achieve it, a company has to identify areas of commonality between applications, and build services for them. That way, the total amount of design, programming and development time can be reduced, because the service can be designed only once, instead of multiple times.
3.
The third area is in business agility, and this ROI benefit can be gained in the medium to long term. This allows an organization to make rapid changes to its IT infrastructure when required. These are necessary in today’s environment where alliances with other organizations are quickly forged and then broken. Traditionally IT systems have always been a limiting factor in slowing down business process. So this ROI is particularly valuable and allows for a faster time to market.
4.
The fourth area of ROI is provided in a way of reputation. By having a faster time to market value to changes in business process an organization can slowly build up reputation in the form of reliability. Although a company will not gain anything from the ROI however it is possible for this ROI to generate potential income.
All these areas should be iteratively analyzed through our ROI evaluation.
81
The Complete Reference To Professional SOA with Visual Studio 2005
Organizational Roadmap Identifying Stakeholders and Conflicts Before implementing SOA at the enterprise level, we need to examine the different stakeholders within the organization and avoid potential conflicts of interest to ensure a successful implementation of the new implementation. Even though it is true that every organization is different, and as such has different stake holders. Generally an organization contains two types of stakeholders the decision makers who make financial and high-level strategic decisions and the end users who are often operating the systems on day to day basis. It is essential to have open and transparent meetings where all aspects of implementation and business process can be examined. This will provide everyone within the organization with an opportunity to address any concern they might have. An area of impact is the CEO and the board of directors that are responsible for high-level strategic decisions, which often will have a direct impact on IT systems and system implementations. While another area to be mindful is the business functional requirements, they often present the IT department with conflicting requirements because their interests sometimes may conflict. It is therefore important to identify the stakeholders and potential conflicts early on. Figure 3-4 represents the equal stake holders within an SOA.
Figure 3-4. Stakeholders representation
IT is typically a cross-sectional service as such it is easy to become constrained by other business decisions. These obstacles involve; *
It is more difficult to provide ROI for the push towards SOA. CEO and Business executives generally only have a understanding towards investing in business applications that has a measurable return on investment.
*
Difficulty with managing changing functionalities and changes in business strategy.
*
Division in internal departmental conflicting interests,
82
The Complete Reference To Professional SOA with Visual Studio 2005
Business and IT After executives have completed their decision making process, it is up to the business units and the related IT projects and departments to implement systems that meet business requirements. The daily interaction between business and IT people has traditionally been difficult. Business people often have a difficult time comprehending why technical issues are so complicated, while IT people often struggle with the complexity of having to understand detailed business procedures. Typically, business requirements require a large number of specialists who have slightly different understandings of the environment and often differing agendas and perspectives. While external vendors with their own consultants and products add to this complexity, all of this increased complexity of matching business requirement to their corresponding technology.
Internal Politics Internal Politics play a large role in the decision making process. Though, typically IT people coming from a development background are not always aware of the intricacies involved. The CIO and technology architecture boards often have different interests in the path of individual projects. These conflicts can have various reasons sometimes disagreement may occur from difference in position of a particular employee. But it is an area which one should be aware of. An architect for example will introduce standards that allow for technology reuse. While a Project manager, on the other hand, often have a bigger interest in getting their projects out the door and costs low, instead of investing the time to examine reusability. In these situations, it is often not a matter of reasonable decision making but a question of who has the power to enforce a particular course of action. Similarly, project managers and operations managers can have conflicting interests. How fast the project delivers certain business functionality often measures the success of a project. Consequently, speed is the major concern of a project manager. In order to ensure the successful delivery of the project the project manager must ensure all aspects of the application had been thoroughly tested. These may include System Management Integration, exception handling, CPU and Memory consumption, Scalability and over all application performance testing. However these tests do not have any bearings to the operations manager and take up development time and money. It is necessary to consult stakeholders and identify potential conflicts of interest before a project begins. It is important to hold meetings where all key stakeholders can attend and discuss issues that concern them. In this manner solutions or alternative resolutions can be drawn up in an open manner.
Organization Vision Once all the stakeholders have been consulted and potential conflicts identified and resolved, the next step is to gather the key stakeholders once again to agree on the vision of the new enterprise SOA and the role the SOA will play within the organization. The meeting can begin by formalizing a vision statement which states the ultimate goal and how it can be achieved. People from both the business and technology side should be involved in formulating this vision. It is in reality that the actual technology that drives business goals and the new vision. However it is vital for the people from business section to validate the concepts of the vision from the business point of view. Once the vision statement is agreed upon, the next step is to define a plan that outlines how the goals defined in the vision can be achieved. This does not require a detailed project plan but it is more about motivating the organization towards a common goal. The development of the vision will have future impact and bearing on all future development and business decision making process, which will eventually lead to budget allocations, which is so important to the maintenance and the growth of the existing infrastructure. It is important to keep in mind that once the vision statement had been defined we should consistently check the process of existing development and ensure that the SOA is steered towards the new vision milestones. The
83
The Complete Reference To Professional SOA with Visual Studio 2005
introduction of an SOA is not a one-off project but it is a journey and requires constant efforts to ensure that future development projects will stand by the principles of the SOA.
Budget Consideration With the initial introduction of SOA the starting projects must be chosen with great care. As these initial projects is what the business often judges the success of SOA on. Even though fundamentally the success of SOA should be judged later on as it promotes reuse and thus reduces costs with later projects. Thus it is important to select simple initial projects that can be developed as pilots. This will slowly ease the fear of everyone else who is afraid of change. It is important that these initial projects are equipped with sufficient time and budget to meet any unexpected issues that may arise. Over all the initial beginning of SOA is always more expensive and has more overhead. This is because the reuse and agility of the infrastructure still does not exist; as a result reuse simply does not occur. Thus instead of merely focusing on the immediate challenges, potential future applications must be taken into account to ensure maximum reusability and cost reduction in future. After implementing SOA, Verizon Communications claims it averages about 2.5 million to three million Web services transactions a day. The company claims that it was through implementing its internal application IT Workbench, which was constructed on SOA principles and is built on XML and SOAP messaging. The system became operational in 2004 and Verizon says it was able to slash its IT budget by 50% by eliminating redundant systems inherited from the merger of Bell Atlantic and GTE. By adopting SOA, the company claims that it also helped integrate the operations of some 7,000 developers. Verizon’s SOA covers about 250 services, and the company says it plans to eventually support 33 million Web services transactions per year.
Gathering Internal Support No matter what we do everything amounts to nothing if we do not have support. The focus on SOA is no different. Support comes in various forms, whether it is a mind set support for SOA or financial support in budget allocation. It is vital that we consistently gather and maintain these supports around us to ensure current and future success of SOA. To gather support we will need to please key areas within our organization that means providing better services to key departments. While having the right people on the team is also vital. Our SOA team should be consisting of SOA evangelists whose task is to explain the benefits of SOA to different departments. The importance of the implementation of SOA is a mind set so it takes a lot of encouragement. But with consistent iteration on the benefits of SOA and with increased service and support to key departments they will soon be thinking the way we do. We should keep in mind that these supporters of SOA always have their own interests and agendas and that they have to sell the SOA to others. In order to successfully introduce SOA it is important to prepare specific reasoning for various groups. The easier it is for our supporters to sell SOA the more likely it is for them to support it.
SOA Driven Project Development using MSF This section provides some overview to SOA project management using Microsoft Solution Framework (MSF). Microsoft Solutions Framework provides an adaptable framework for successfully developing solutions faster, with fewer resources and provides the medium to manage risk while also ensuring higher quality output. MSF helps teams directly address the most common causes of technology project failure in order to improve success rates, solution quality and reduce business impact.
84
The Complete Reference To Professional SOA with Visual Studio 2005
MSF provides a flexible and scalable framework that can be adapted to meet the needs of any organizations with projects that varied in size and complexity. It also focuses on the planning, building and deploying of business driven technology solutions. MSF can be applied to improve success rates for the following types of projects: *
Software development projects, including mobile, Web and e-commerce applications, Web services, mainframe, and n-tier.
*
Infrastructure deployment projects, including desktop deployments, operating system upgrades, enterprise messaging deployments, and configuration and operations management systems deployment
*
Packaged application integration projects, including personal productivity suites, enterprise resource planning (ERP), and enterprise project management solutions.
*
Any complex combination of the above.
Challenges and Opportunities In software development projects rarely go smoothly and majority of projects will never meet their deadlines. This is often due to a number of factors mostly to do with people, other resources and technology involved. Sometimes complexity involved in technology alone is enough to cause a project to fail. Success in project planning thus requires a detailed understanding of the project requirements and the capabilities required to meet goals. But most importantly an understanding of the development process is required. When projects fail the following causes are often observed: *
Stakeholders were disconnected from the development process.
*
Lack of communication and understanding of business needs by the development teams.
*
Failure to address the real problem or omission of important features, and including unsubstantiated features.
*
Unclear project requirements that are not understood by the participants which results in confusion, overwork and missing elements.
*
Lack of training or documentation after a complex system has been deployed resulting in misunderstanding over system functions.
Generally organizations that have development processes in place avoid the need to overcome these issues and thus derive better results for their business through higher product and service quality. This also improves customer satisfaction and business reputation, which always leads to wining more projects through word of mouth. These factors translate into a positive influence on bottom line and improvements in the organization’s strategic effectiveness. MSF was designed and built to provide organizations with a clear roadmap towards successful project planning and development.
MSF Tracks The MSF Tracks describe a generalized sequence of activities for building and deploying enterprise solutions. This process is flexible and can accommodate the design and development of a broad range of enterprise projects. The MSF Tracks is a track-based, milestone-driven, and iterative model that can be applied to developing and deploying enterprise solutions for SOA. There are two sets of tracks following MSF 4.0 for Agile Software Development (MSF Agile), and MSF 4.0 for CMMI Process Improvement (MSF CMMI).
85
The Complete Reference To Professional SOA with Visual Studio 2005
MSF CMMI
Figure 3-5. MSF CMMI Tracks
The MSF CMMI represented in Figure 3-5 consists of seven distinct tracks: *
Governance
*
Envision
*
Planning
*
Building
*
Stabilizing
*
Deploying
*
Operational Management
MSF Agile
Figure 3-6. MSF Agile Tracks
The MSF CMMI represented in Figure 3-6 consists of six distinct tracks:
86
The Complete Reference To Professional SOA with Visual Studio 2005
*
Envision
*
Planning
*
Building
*
Stabilizing
*
Deploying
*
Continuous
Envisioning Track The MSF process begins with the envisioning track. It is in this track where a broad description of the goals and constraints of the project is defined. Here we identify the team and what the team must accomplish for the organization. The purpose of the envisioning track is to build a shared vision of the project among all the key stakeholders of the project. *
Setting up the team. Creation of a project team that represents all roles within the SOA. When setting up a team, it is important to consider the skills, experience, and performance level of the team members. In addition, there are practical considerations such as availability of resources and project budget.
*
Defining the project structure. Identifying the administrative structure for the project team and the standards for managing the project.
*
Defining the business goals. Analysis of the business problem and opportunities in order to identify the objectives for the solution.
Planning Track Following Envision is the planning track, during this track the team determines what to develop and plans how to create the solution. The team prepares the functional specification, creates a design of the solution, and prepares work plans, cost estimates, and schedules for the various deliverables. It is during this track analysis of requirements is performed. These requirements can be: Business requirements *
User requirements
*
Operational requirements
*
System requirements.
Obtaining requirements are important because they in turn are used to design the solution and its features and to validate the correctness of the design.
During the planning track, the team performs multiple tasks. The milestones of the planning track are: *
Technology validation. During technology validation, the team evaluates the products and technologies that will be used to create or deploy the solution. The team also audits the customer’s current production environment.
*
Functional Specification. The functional specification is completed and submitted for review to the customers and stakeholders. Remember that the design document is different from the functional specification. The design document is written for the project team and describes the internal workings of the solution.
87
The Complete Reference To Professional SOA with Visual Studio 2005
*
Mast Plan & Schedule. The mast plan is a combination of plans of various roles on the team. The master project schedule includes all detailed milestone project schedules and the solution release date.
Developing Track During the developing track, the project team creates the solution. This process includes creating the code that implements the solution and documenting the code. In addition to developing code, the team also develops the infrastructure for the SOA solution. The team performs the following tasks during the developing track: *
Starting the development cycle. Verification that all tasks identified during the envisioning and planning track have been completed so that the team can begin developing the solution.
*
Creating a prototype application. Verification of the concepts of the solution design in an environment that resembles the environment to which the solution will be eventually deployed.
*
Building the solution. Developing the core functionalities, within the requirement for the project.
Stabilizing Track During this track, the solution progresses from the state of all features being complete as defined in the functional specification for this version to the state of meeting the defined quality level. On the completion of this track the solution must be ready for deployment to the business. During this track the team will need to perform integration, load testing on the solution. The teams also need to address any issues that may arise to prepare for the project release. During the stabilizing track the following milestones are reached: *
Bug Convergence. A milestone of the stabilizing track that marks the point at which the team makes measurable progress against the active issue and bug count.
*
Release. A series of milestones of the stabilizing track that reflects the incremental improvements in the reduction of the issue and bugs.
*
Zero-bug release. A goal of stabilizing track that marks the point at which the issue and bug count has met the zero-defect metric for this particular point in time in the project.
Deploying Track The team deploys the solution to the organization. The team transfers the skills and support to the relevant department members, and obtains final customer approval of the project. After deployment, the team conducts a project review and a customer satisfaction survey. During the Deployment Track the following milestones are reached: *
Major components are deployed. Successful deployment of sites depends on these components.
*
Site deployment complete. At the completion of this milestone, all intended users must be able to access the solution. Leading developers for each component within the SOA must confirm that their sites are operating.
*
Deployment stable. At this milestone, the customer and team agree that the sites are operating as required. Issues may arise and will be tracked and resolved by relevant parties.
88
The Complete Reference To Professional SOA with Visual Studio 2005
Governance Is a continuous track through out the lifecycle of MSF CMMI usually performed by people in the role of Auditor. System governance and supports covers subprojects focusing on the transition of system wide structures to govern and support the delivery of direct services. There are governance structures being developed to facilitate inter-Authority communication and coordination. Governance requires the continuous process of: *
Identify Inconsistencies
*
Analyze Review Minutes
*
Review Design and Code Guidelines
*
Track Corrective Actions to Closure
Operational Management Is another continuous track through out the lifecycle of MSF CMMI. Operational Management allows us to better anticipate disruptions in day-to-day business operations and quickly take a direct and proactive approach to improve results. Operational Management can be performed by people of the roles of: Project Manager and Business Analyst. Operation Management requires the continuous process of: *
Start with business activity monitoring to anticipate and eliminate disruptions
*
Apply business integration to optimize processes by identifying performance improvement opportunities.
*
Improve the ability to anticipate and act
Continuous Track The continuous track is used by the MSF Agile track model. It is performed by people of the roles of Business Analyst and Project Manager through out the life cycle of the project. *
Define Personas
*
Refine Personas
*
Review Objective
*
Assess Progress
*
Triage Bugs
*
Identify Risk
Project Teams MSF provides the MSF Team Model for organizing project teams. The MSF Team Model emphasizes the importance of clear roles, responsibilities, and goals of individual members to the success of the project. This model also increases the accountability of each team member. The flexibility of the MSF Team Model helps us to adapt it to the scope of the project, the size of the team, and the skills of the team members. This forms the basis of creating effective, resilient, and successful project teams.
89
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 3-7. MSF Team Model.
Program Management The project manager advocates for the program management constituency in the MSF Team Model. The project manager is responsible for the flow of knowledge creation and ultimately the realization of value, which comes from delivery of the product outlined in the vision statement. The project manager owns the life cycle of the project from end-to-end. The main goal is to deliver business value within the agreed upon schedule and budget. The project manager is charged with planning and scheduling duties including developing project and iteration plans, monitoring and reporting status, and identifying and mitigating risk. The project manager is also expected to consult with business analysts to plan backlog for the project and its iterations, consult with architects, developers, testers, user education specialists, and user experience architects to estimate work and facilitate communication within the team. The program management’s responsibilities are as follows: *
Capture Product Vision
*
Create Product Requirements
*
Develop Documentation
*
Establish Project Process
*
Manage Issues
*
Plan an Iteration
*
Plan Project
*
Manage Risk
*
Test a Customer Requirement
*
Verify a Product Requirement
90
The Complete Reference To Professional SOA with Visual Studio 2005
Architecture The architect role is to advocate for the architecture constituency in the MSF Team Model. The architect is responsible for maintaining the architectural integrity of the product and ensuring the success of the project by designing the foundations upon which all the value can be realized. This includes defining both the organizational structure of the application and the physical structure of its deployment. In these endeavors, the architect’s goal is to reduce complexity, decrease coupling and regression effects, and increase the cohesiveness of components by partitioning the system into parts which can be built and tested independently. The resulting architecture is extremely important because it not only dictates how the system will be built going forward but also establishes whether the application will exhibit the many traits that are essential for a successful project. These include its usability, whether it is reliable and maintainable, whether it meets performance and security standards, and whether it can be evolved easily in the face of changing requirements. The architect’s responsibilities are as follows: Analysis *
Create a Quality of Service Requirement
*
Create Product Requirements
*
Create Solution Architecture
*
Establish Environments
*
Establish Project Process
*
Test a Customer Requirement
*
Verify a Product Requirement
Development The developer advocates for the development constituency in the MSF Team Model. The developer is responsible for the bulk of the work of building the product. Other development roles such as the lead developer and development manager have additional communication and project management responsibilities. The developer should suffer a minimum of communication overhead allowing for a maximum effort on construction of code. In addition, during the early stages of a project, developers may be expected to help specify product requirements not included in the customer requirements and to work on analysis and architecture activities as part of a multi-disciplinary team. A lead developer's role is to lead and to communicate on behalf of other developers. A lead developer advocates for the development constituency in the MSF Team Model. A lead developer lends experience and skill and shows leadership by coaching fellow developers. Lead developers carry responsibility for code reviews, design, and unit testing coverage. Lead developers act as a conduit to the rest of the project for the developers. As an aid to productivity, lead developers funnel communications between the wider project team and external organizations, and shield developers from noise and random interference in their daily schedules. Because of this, lead developers can seldom dedicate themselves to development tasks. Typically, they spend about 50% of their time on communication and split the remainder between leading and coaching the developers on their team, and actually writing code for development tasks. The developer’s responsibilities are as follows: *
Analysis
*
Create Solution Architecture
91
The Complete Reference To Professional SOA with Visual Studio 2005
*
Develop Documentation
*
Establish Environments
*
Establish Project Process
*
Fix a Bug
*
Implement a Development Task
*
Release a Product
*
Test a Customer Requirement
*
Verify a Product Requirement
Test The tester advocates for the test constituency in the MSF Team Model. The tester's main goal is to discover and communicate problems with the product that could adversely impact its value. The tester must understand the context for the project and help others to make informed decisions based on this context. A key goal for the tester is to find and report the significant bugs in the product by testing the product. Once a bug is found, it is also the tester’s job to accurately communicate its impact and describe any workaround solutions that could lessen its impact. The tester makes bug descriptions and steps for recreating the bugs easy to understand and follow. The tester participates with the entire team in setting the quality standards for the product. The purpose of testing is to prove that known functions work correctly and to discover new product issues. The tester’s responsibilities are as follows: *
Analysis
*
Close a Bug
*
Develop Documentation
*
Establish Environments
*
Establish Project Process
*
Release a Product
*
Test a Customer Requirement
*
Verify a Product Requirement
Release/Operations The release manager advocates for the smooth delivery and deployment of the solution into the appropriate infrastructure. This role's goal is to manage the rollout of the product. The release manager coordinates the release with operations or media control. They create a rollout plan and certify release candidates for shipment or deployment. The release manager’s responsibilities are as follows: *
Baseline Configuration Management
*
Create Product Requirements
*
Establish Project Process
92
The Complete Reference To Professional SOA with Visual Studio 2005
*
Manage Change Requests
*
Release a Product
User Experience The user education specialist is typically a technical writer who advocates for the user experience constituency in the MSF Team Model. The user education specialist focuses on consumer-focused technical writing which reinforces or enhances product value and helps to realize the product vision. A user education specialist may work on product manuals, on-line Help, operations manuals, maintenance manuals, training manuals, and any other documentation which can be used to enhance the usage and value delivered with the product. User experience architects typically work closely with user education specialists. A good user experience and product design typically leads to a lower workload for the technical writing team. Excessive documentation may be an indicator that the user experience is poor and the writing is compensating for poor overall product design. The user education specialist’s responsibilities are as follows: *
Analysis
*
Develop Documentation
*
Establish Project Process
*
Release a Product
Product Management The product manager is the main advocate for the customer in the MSF Team Model. The product manager is the proxy for the end consumer of the product. The product manager has overall product mix responsibility for the requirements. The product manager must ensure that the product vision is met through the requirements and the acceptance tests developed to validate the product. The product manager must show that the product aligns with the organizations strategic planning and fits the market segment(s) intended in the original vision statement. The product manager will ensure that the project stays within budget and that the business case is realized. The product manager's work is used as the primary source for the track checkpoints in the MSF Governance Model. The project manager’s responsibilities are as follows: *
Capture Product Vision
*
Release a Product
MSF Risk Management MSF risk management process promotes proactive risk management, continuous risk assessment, and decision making throughout the project life cycle. The team continuously assesses, monitors, and actively manages risks until they’re either resolved or turn into problems that can be broken down and allocated to relevant parties to be resolved. MSF risk management defines six steps through which teams can manage and avoid potential risks. 1.
Risk identification, individuals are encouraged to identify risks so that other team members are aware of any potential problems.
2.
Risk analysis, in this step risks identified during risk identification are investigated these risks are assigned a priority by the team.
93
The Complete Reference To Professional SOA with Visual Studio 2005
3.
Risk planning, uses the information obtained from risk analysis to formulate strategies, plans, and actions.
4.
Risk tracking, monitors the status of specific risks and document the progress of risk in their respective development plans.
5.
Risk control occurs when we are required to execute relevant risk management action plans, detailed status report of the risk and its progress is then required.
6.
The last step in the MSF risk management is, risk learning, the learning process will give teams an opportunity to reflect upon the risk so that the knowledge can be formalized into documentation as a reusable form for future use within the team and by the enterprise.
Simplifying SOA development using .NET and Visual Studio 2005 Developing service-oriented applications has never been simpler with .NET Framework. The .NET Framework provides facilities for creating, deploying and managing service-oriented applications. Using Visual Studio 2005 developers are able to develop web services that they can call from any other applications with ease. The environment abstracts many of the specifics away from the developer, allowing us to focus more on the business logic for our service rather than actual implementation. With Visual Studio 2005, developers can support .NET objects natively that remove coding responsibility from the developer (such as marshalling infrastructure, data structure management, and service discovery). Additionally, we can support multiple versions of components for the same application, allowing for rapid update and system modification. The .NET platform provides built-in support for building and consuming standards-based XML Web services. Unlike other development platforms, developers do not require additional tools or plug-ins to build XML Web services with .NET. XML Web services are natively supported within .NET. Developers could develop Web Services to improve interoperability (possibly across multiple platforms such as .NET and J2EE). Visual Studio also has the advantage of having greater support for a set of commonly used pseudo-standards such as Simple Object Access Protocol (SOAP), Web Services Description Language (WSDL), and Universal Description, Discovery, and Integration (UDDI). While the process of developing service consumer applications is also simplified through Visual Studio. The Microsoft .NET Framework 2.0 also allows developers to use Web Services Enhancements or WSE (pronounced “wizzy”). WSE 3.0 simplifies the development and deployment of secure Web services. It enables developers and administrators to apply security policies to Web services running on the .NET Framework 2.0. Using WSE 3.0, Web services communication can be signed and encrypted using Kerberos tickets, X.509 certificates and other custom binary and XML-based security tokens. In addition username/password credentials can be used for authentication purposes. An enhanced security model provides a policy-driven foundation for securing Web services. WSE also supports the ability to establish a trust-issuing service for retrieval and validation of security tokens, as well as the ability to establish more efficient long-running secure communication via secure conversations. Microsoft has also included Microsoft Solutions Framework (MSF) a highly customizable, scalable, fully integrated set of software development processes with its Visual Studio Foundation Server. Visual Studio Team Foundation Server is a set of client/server tools for team projects. It provides a seamless experience with Visual Studio 2005 Team System for process automation and guidance within the software development life cycle (SDLC). It also allows for Version control, work item tracking and reporting. It is easy to see why .NET is one of the predominant development frameworks used today. Not only does it support simplified development but it streamlines the entire life cycle of the enterprise SOA solution.
94
The Complete Reference To Professional SOA with Visual Studio 2005
Using Visual Studio 2005 to create a Web service For now, we will look at building a very simple Web service. Having launched Visual Studio 2005, select File menu ~TRA New ~TRA Web Site. We will be presented with the New Web Site dialog box, as shown in Figure 3-8.
Figure 3-8. New Project Template.
Select Language as Visual C# or Visual Basic, Location as HTTP and select the ASP.NET Web Service template as shown in the figure. We could select Visual J# and also be able to create an ASP.NET Web service. For the purpose of this book we will only be concentrating on Visual C# and VB .NET. In the Location text box (Figure 3-8) change the address for the Web service to http://localhost/SOAWebService/CSSimpleWebService. When we click OK, the Web service will be created for us. In Visual Studio 2005 we’re not forced to install Internet Information Service (IIS) as had been the case with Visual Studio 2003. This allows us to even launch web projects in the file system through Visual Studio 2005’s integrated web server called ASP.NET Development Server. In this case we have selected Visual C# the following code would have been generated for us by Visual Studio 2005. Listing 3-1. Visual C# using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class Service : System.Web.Services.WebService { public Service () { //Uncomment the following line if using designed components
95
The Complete Reference To Professional SOA with Visual Studio 2005
//InitializeComponent(); } [WebMethod] public string HelloWorld() { return "Hello World"; } }
If we had selected Visual Basic then the following code would be generated. Listing 3-2. Visual Basic Imports System.Web Imports System.Web.Services Imports System.Web.Services.Protocols _ _ _ Public Class Service Inherits System.Web.Services.WebService _ Public Function HelloWorld() As String Return "Hello World" End Function End Class
Within the generated code we can see that Visual Studio has generated a public method decorated with the WebMethod attribute. A WebMethod is the function that the Web service exposes to our consumers. In this case, it’s a pretty dull method that takes no parameters and returns the string “Hello World” to the caller. The [WebMethod] or label is called an attribute and it is used by the compiler to help generate the
details for the WSDL document. That’s the job of an attribute to give special instructions to the compiler about how to handle the code. Many developers prefer to start with a WSDL description of the service and move into the code from there, instead of the other way around as this example shows. Either way is good, but Visual Studio leads us in the direction of building code first and foremost, and auto-generating WSDL from our Web services code. Let’s try something a little more interesting. We will pass in a parameter string. Listing 3-3. Visual C# using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class Service : System.Web.Services.WebService { public Service () { //Uncomment the following line if using designed components //InitializeComponent();
96
The Complete Reference To Professional SOA with Visual Studio 2005
} [WebMethod] public string HelloWorld(string param1) { return "Hello " + param1; } }
Listing 3-4. Visual Basic Imports System.Web Imports System.Web.Services Imports System.Web.Services.Protocols _ _ _ Public Class Service Inherits System.Web.Services.WebService _ Public Function HelloWorld(ByVal param1 As String) As String Return "Hello " & param1 End Function End Class
The method will now accept a parameter of type String, which it uses to build the output. If we run this Web service, Visual Studio will construct a test harness for us. A test harness is an IDEsupplied set of pages or applications that are used to test our applications. So we don’t need to build these pages ourselves. We can see the test harness in action in figure 3-11. We can run the Web service by selecting Debug ~TRA Start Debugging Visual Studio will detect that we have not enabled debugging and will prompt us if we wish to enable debugging. In this case we will select the Modify Web.config file to enable debugging selection and click Ok. As show in Figure 3-9.
Figure 3-9. Visual studio auto-prompting debugging options
97
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 3-10. Auto-generated ASMX page.
Clicking the HelloWorld hyperlink will take us to a form generated by the test harness based on the method signatures. In this case, the method takes a single string, so the form will have one text box. This can be seen in Figure 3-11.
Figure 3-11. Auto-generated WebMethod test harness.
98
The Complete Reference To Professional SOA with Visual Studio 2005
If we enter our name in the text box and click the Invoke button, the Web service will be called, passing whatever we typed as the parameter to the HelloWorld method. The results may be seen in Figure 3-12 if we enter the name Kim.
Figure 3-12. SOAP from the WebMethod result
Another thing that Visual Studio 2005 does for us is that it generates the WSDL document that describes our Web services. If we look back to Figure 3-10, we will see a hyperlink to the Service Description at the top of the page. Clicking this will navigate us to the page containing the WSDL, which of course will also indicate to us the URL that we can use to consume the WSDL. We can see an example of this WSDL in Figure 3-13.
Figure 3-13. Shows the WSDL document generated by Visual Studio for the Hello World web method
We can see that the URL for the WSDL is the URL for the Web service with the ?WSDL appended to it. For example, Service.asmx?wsdl.
99
The Complete Reference To Professional SOA with Visual Studio 2005
Using Visual Studio 2005 to Consume a Web Service Now that we have built our Web service, the next thing to do is consume it in an application. It doesn’t have to be an application. A Web service can be consumed by anything that talks SOAP, even another Web service. For simplicity we will create a windows application using Visual Studio’s Windows Forms application. First, we need to create the application. We do this by selecting the File Menu ~TRA New ~TRA Project dialog. This time, select Windows Application as the Template within the C# or Visual Basic (see Figure 3-14). We are doing this because we are creating a Windows application that runs on our PC as an executable that will access the web service for information.
Figure 3-14. New project template for windows application. (please note that Visual Studio 2005 comes with a range of editions catering to different roles in development. The screen shot that you see may differ slightly depending on the edition that you use.)
Once the project has generated the windows form for us. We can drag and drop a button and label onto the form (see Figure 3-15).
100
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 3-15. Windows form designer allows drag and drop to add controls.
Now we can establish contact with the web service by adding a reference to the web service we created earlier.
Figure 3-16. Solution explorer
Simply right mouse click on the Project within the Solution Explorer then select “Add Web Reference”.
101
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 3-17. Add a web service reference to the project.
Enter the location of the web service from the HelloWorld Web service application that we had created earlier and click the go button. Click the Add Reference name. Note that the web service is added under the web reference name of localhost. On the winform Double clicking on the button will bring us to the code behind the form. Listing 3-5. Visual C# private void button1_Click(object sender, EventArgs e) { localhost.Service helloworld = new WinAppService.localhost.Service(); label1.Text = helloworld.HelloWorld("Kim"); }
Listing 3-6. Visual Basic Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click Dim helloworld As New localhost.Service Label1.Text = helloworld.HelloWorld("Kim") End Sub Now when that we had entered the above code into the code behind we can compile and run the code. We will see the result of the execution in Figure 3-17.
102
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 3-18. Windows application result from invoking the Web service.
From the example above we can easily see why developing with .NET is so simple. Visual Studio helps us take care of all the subtleties so that we don’t need to touch them. The job of a developer is simplified. .NET Framework takes care of the web service requests as well as response by marshalling of SOAP information to and from the wire. Visual Studio also generates a Proxy class from the information obtained from the WSDL of the web service. This allows the developer to access development information from the Web service. Developers can use the proxy class created by Visual Studio to map to the Web service that they’re currently accessing. To aid the developer’s development effort all functions accessible via the Web service can be accessed through Visual Studio’s intellisense.
Summary Through this chapter we have focused on various areas in the domain of business adaptations of SOA. These are: Role of SOA within the organization Opening our private infrastructure *
Roadmaps for SOA
*
Measuring a SOA
*
SOA driven project development using MSF
Lastly we looked at the ease of creating Web service using .NET and Visual Studio 2005.
103
The Complete Reference To Professional SOA with Visual Studio 2005
Part 2 Using .NET Web Service 2.0 with Visual Studio 2005 In Part 1 of this book we learned about the core concept of SOA which was its ability to provide agility and better ROI to the enterprise architecture. We will now cover the implementation of a SOA through the use of .NET 2.0 Web Service and Visual Studio 2005.
Chapter 4 Introducing .NET 2.0 The reality is that developing software today is inherently difficult. Enterprise developers can no longer generate a script and deploy it with a proprietary db on a floppy disk. Today’s enterprise scale applications can have many layers of services and quite often data is distributed throughout the enterprise. These projects require a lot more development effort and demand a high level of standards compared to the past. Today enterprise-scale software has significantly more moving pieces than it did 10 to 15 years ago. Webbased applications such as XML Web services make systems more interoperable and extensible but this is only from an architect, stakeholder and user point of view. However as a developer plugging the various elements together and ensuring that they’re working efficiently together can be extremely challenging and daunting. Microsoft took a great deal of effort to study the way that software shops and teams successfully, and sometimes unsuccessfully, developed software. This knowledge and experience is then poured into the earlier version of ASP.NET, which contains the culmination of web technologies. ASP.NET 2.0 is a major upgrade to the platform, even though no new programming paradigm has been introduced. ASP.NET 2.0 is a fundamental milestone in the Microsoft Web development roadmap. ASP.NET 2.0 is currently the most advanced, feature-rich and powerful platform for building distributed applications. ASP.NET 2.0 simplifies development tasks and presents itself as a paradise for developers. ASP.NET 2.0 is complemented through Microsoft’s Visual Studio 2005. Unlike its earlier version Visual Studio .NET 2003 it is no longer just a slick IDE for development. Visual Studio 2005 contains a powerful suite of rapid application development (RAD) tools that integrates the enterprise team with the entire solution across the life cycle of the project. The Visual Studio 2005 IDE has been considerably enhanced in the areas of exception assistant, code snippets, and visualizers. The emphasis is on providing useful information that improved the quality of development of developers and their productivity. Visual Studio 2005 provides an edge to development. It aims to increase team’s productivity by reducing the complexity of service-oriented solutions and increase the team’s collaboration by integrating all required tools within the IDE. Its aim is to increase the predictability of a successful project.
.NET Framework The .NET Framework was developed to work with the Windows operating system. It is an integral part of Windows components and will play a further role with the release of the Vista operating system. The framework supports building and running various types of Windows applications such as console applications, Winform applications as well as support for Web based applications such as Webforms and also support for the
104
The Complete Reference To Professional SOA with Visual Studio 2005
development and running of the next generation of XML Web service developed for .NET. The .NET Framework aims to: *
To ensure a consistent object-oriented programming environment.
*
To remove software deployment and version conflicts
*
To ensure a secure execution environment by promoting safe and secure code execution
*
To improve the performance of code execution
*
To ensure a consistent development experience across different type of applications, such as Windows-based applications and Web-based applications.
*
To provide a consistent framework where developer are free to choose their favorite programming language.
The heart of .NET Framework consists of two main components: the Common Language Runtime and the .NET Framework class libraries. The Common Language Runtime is fundamental principle of runtime. It works as the agent that manages the execution of code while also governs the type safety and other code securities. Code that is managed by the .NET Framework runtime is known as managed code while code running outside of the runtime management is known as unmanaged code. The other main component of the .NET Framework is the class library. The class library is an object oriented collection of reusable types that we can use to develop different types of .NET applications. These .NET applications range from traditional command-line applications to graphical user interface (GUI) applications to Web based applications such as ASP.NET Web form and XML Web service. The .NET Runtime was designed with performance in mind. Managed code is never interpreted. A feature called just-in-time(JIT) compiling enables all managed code to run in native machine language of the system on which it is executing. The memory manager also helps to remove possible memory fragments to increase memory locality-of-reference to further improve performance. The .NET Framework provides several runtime hosts which allow hosting of managed and unmanaged components. These hosts can be Microsoft SQL Server and Internet Information Services (IIS). The host loads the common language runtime into their process and handle the managed code execution. By doing so the runtime can access both managed and unmanaged features of the components. This infrastructure allows developers to develop applications with managed code whilst still enjoying the superior performance of the .NET Runtime.
105
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 4-1 illustrates .NET Framework in context
Figure 4-1 Demonstrates the separation of managed applications and unmanaged applications. Managed applications are managed by the .NET Framework’s runtime. Whilst IIS is an unmanaged application which provides a hosting environment for the ASP.NET Runtime. The ASP.NET Runtime time manages the execution of applications such as ASP.NET web applications as well as XML Web services.
Features of the Common Language Runtime In the .NET Framework the Common Language Runtime (CLR) looks after the managed code it manages features such as compilation, code execution, manages memory, thread execution, code safety verification, and other system services. In managed components we can specify a number of varying degrees of trusts. This trust for example depends on the origin of the component for example if they’re from Internet, from a network or a local machine. This mean that managed components have more control in terms of registry access operations, file access operations, and other functions that are deemed as sensitive even if code is launched from the same application different security levels can be configured. The .NET runtime also implements a verification infrastructure for type and code. This is called the Common Type System (CTS). CTS is what allows other third-party language compilers to work with .NET Framework. This is because CTS ensures that all managed code are self describing this means managed code can be consumed by other managed types and instances whilst the CLR maintains security and type safety. The .NET managed environment addresses many of the common issues today in software development. For example the runtime automatically takes care of object management. The garbage collection automatically cycles through memory and remove objects that are no longer used. This resolves two common issues that is memory leak and invalid memory reference. The runtime also fast tracks development through CTS by allowing third party compilers to compile into .NET managed code. This means that developers can develop in their favorite language and yet still take
106
The Complete Reference To Professional SOA with Visual Studio 2005
advantage of the full features of the .NET Framework. This greatly eases the migration process for developing new and existing applications. The runtime also maintains interoperability with legacy applications through the support for the use of unmanaged code components such as COM and DLLs. The runtime is also optimized for enhanced performance. Unlike script based languages the managed code is never interpreted by using features like Just-In-Time (JIT) all managed code are compiled into native machine language for that particular system on which it is execution. This greatly improves the performance and execution of applications. While memory management reduces fragmentation to increase the locality of reference to further increase performance. Lastly the .NET runtime is now integrated to other high performance applications such as Microsoft® SQL Server™ and Internet Information Services (IIS). We can now develop and embed SQL stored procedures, SQL data types, SQL Triggers in .NET code. This is very exciting.
Managed Development In .NET managed applications are implemented through the .NET runtime hosts. In development such as applications for ASP.NET the unmanaged host in our case the Internet Information Services (IIS) hosts the common language runtime, which allows us to manage code. This is a proven model which give us all the capabilities of the common language runtime and class library. This also allows us to gain the performance and scalability benefit of utilizing the host server. Figure 4-2 shows a basic network schema with managed code running in different server environments. Servers such as IIS and SQL Server can perform standard operations while our application logic executes through the managed code.
Figure 4-2 Managed code running on different environments
Web Forms together with XML Web services both use ASP.NET and IIS to host its deployed applications. ASP.NET is more than just a managed runtime host. ASP.NET is a complete architecture from which developers can build web based applications and Internet based distributed applications such as XML Web services. XML Web services is a type of distributed server side application. In some ways it is similar to a web sites in terms of requiring to be hosted on IIS and developing using the same managed environment. However it differs in that XML web service do not require user interfaces they are essentially much like COM components or simply a DLL providing functionalities to all that required its services. Despite the requirement to be hosted on IIS XML Web services do not target browsers such as Internet Explorer and Netscape. Instead it offers its service to the public through a description document called Web Server Description Language (WSDL) which details all the functionalities provided by the web service. XML Web service technology is rapidly evolving because of its distributed nature and its separation between interface and implementation it is fast becoming the choice of many who implement SOA.
107
The Complete Reference To Professional SOA with Visual Studio 2005
The .NET Framework supports the development of XML Web services with a collection of classes and tools. The .NET Framework has internal support for Simple Object Access Protocol (SOAP) a remote procedure protocol and Extensible Markup Language (XML) the framework also helps to generate the WSDL document which describes the Web service. All of this greatly reduces the workload of a developer. The .NET Framework with internal support using these standards to help promote interoperability with applications with even nonMicrosoft solutions. The .NET Framework has built-in WSDL tool so it can parse the WSDL document of another Web service and produce C# or Visual Basic source code. This is called a Web service proxy. The proxy can then be used to invoke the functions on the Web service. If we develop and publish our own XML Web service, the .NET Framework provides a set of classes that conform to all the underlying communication standards, such as SOAP, WSDL, and XML. Using those classes enables us to focus on the logic of our service, without concerning ourselves with the communications infrastructure required by distributed software development. The best thing is unlike other script languages the XML Web service will be able to utilize the managed environment the code will be compiled to native machine language for performance.
.NET Framework 2.0 The .NET Framework 2.0 is the infrastructure for building applications using .NET. The .NET Framework provides a consistent object-oriented programming model that we can use to build all types of applications. The approach for creating various applications such as Windows-based applications and XML Web services is the same. To create a .NET application, we create a class and define the functionality of the application in terms of properties, events, and methods of the class. Even for Web applications, the code that controls the behavior of the Web page is encapsulated within a class. In addition, classes support object-oriented features such as inheritance, encapsulation, and polymorphism. Therefore, classes are fundamental to programming in the .NET environment. We can create classes in any language supported by the .NET Framework. A class written in one language is reusable by classes written in other languages. We can also inherit classes across language boundaries because the .NET Framework allows language interoperability and supports cross-language inheritance. The .NET Framework 2.0 provides four CLS-compliant languages: Microsoft Visual Basic Microsoft Visual C#, Microsoft Visual C++ .NET, and Microsoft Visual J# .NET. Visual C# was ratified by ECMA as an international standard on December 13, 2001. The compilers of these languages generate an intermediate code, called Microsoft Intermediate Language (MSIL), which makes programs written in the .NET languages interoperable. Therefore, in the .NET Framework, we can use any language to create applications, and these applications can interoperate with the applications written by others in different languages.
Visual Studio 2005 Team Roles
108
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 4-3: Visual Studio Team System overview
Microsoft has mapped the roles of individual members of development team into Visual Studio 2005 Team System to provide more specialized functionalities specific to their role. Team System’s value is realized in teams that include project manager, architect, developer, and tester roles. These four roles are in turn mapped to:
Visual Studio 2005 Team Edition for Software Architects This edition is designed for both the infrastructure and application architecture roles. It includes visual designers, referred to as the distributed application designers or service-oriented architecture (SOA) designers. The architect can create diagrams to represent the logical datacenter, the application, application systems, and the deployment of the application. These designers follow a simple drag, drop, and connect heuristic that has long been popular with Visual Studio. More than just pretty shapes, the diagrams have intelligence and metadata that can be validated against well-known and custom defined constraints, and then turned into code with a quick click. While similarly code within a project can be generated into diagrams just as easily.
Visual Studio 2005 Team Edition for Software Developers This is the specialized edition for developers or programmers on the team. This will be the most common of the Team System role-based editions. In addition to all of the base Visual Studio 2005 professional features,
109
The Complete Reference To Professional SOA with Visual Studio 2005
developers will get the static code analyzer (much like FxCop), unit testing (like NUnit), code coverage (like NCover), and code profiler. Some of the features share with the Visual Studio 2005 Team Edition for Software Testers. Figure 4-3. It is expected that as a developer some basic testing would be done before the component is passed onto the software testers.
Visual Studio 2005 Team Edition for Software Testers This edition provides coverage, quality, and load-testing facilities access to developers and testers to thoroughly test their solution before deployment. The Team Edition for Testers includes load Web testing (like Application Center Test), Unit Testing, Code Coverage, as well as test-case management tools for managing all the tests and running and monitoring them from a centralized area. The ability to plug in whatever manual tests we might have is also supported in Team Edition for Testers.
Visual Studio 2005 Team Foundation Server This edition of Visual Studio will provide many back-end databases and Web services to enable the team to collaborate, by sharing work items, source code, builds and other artifacts. If we intend to run Team system for a team, as it is advertised, we will need this product to connect all our team members together. Team Foundation Server is easily integrated into Visual Studio and is more than just an “edition” of Visual Studio 2005 Team System. It’s the engine behind our software development life cycle. It includes a standalone client called Team Explorer. This client is essentially a lightweight edition of Visual Studio 2005 that offers an alternate way of creating and managing work items i.e. Checking in documentation, manage images for Web project and so on.
Visual Studio 2005 Team Suite For the team member who plays more than one role, or for the consultant who plays all the roles, there’s the Team Suite. Microsoft has wrapped up all three roles based editions (architect, developer, and tester) into a single edition for simplicity.
Visual Studio 2005 Editions Team System is not part of all editions of Visual Studio. For novices, hobbyists, students and professional developers, there are express, standard, and professional editions of Visual Studio.
Visual Studio 2005 Express Editions The Visual Studio 2005 Express Editions were made for hobbyists, students, novices and enthusiasts in general. You can select from Microsoft Visual C# Express, Visual Basic express, Visual C++, Visual J#, and Web Developer Express. Express editions are made available to almost anyone who wants them so that developers will start using Visual Studio 2005. The Express Edition is Free and is downloadable from Microsoft.
Visual Studio 2005 Standard Edition Visual Studio 2005 Standard Edition is similar to standard editions of the previous versions of Visual Studio. This is the entry level for anyone who is serious about developing applications. The intended audience includes Web Professionals, Visual Basic 6.0 developers, and part-time developers who want to build standalone applications in Visual Basic 2005 or C#.
Visual Studio 2005 Professional Edition
110
The Complete Reference To Professional SOA with Visual Studio 2005
Similar to the professional editions of the previous versions of Visual Studio, this is the edition for serious development in Visual Studio. This edition is for consultants, solo professionals, and those who work in small teams for which team System may be more than they need. The professional edition also differs from the standard edition in that it has all the features required to build distributed applications.
The Visual Studio IDE Microsoft’s Visual Studio 2005 IDE is one of the most advanced IDE in the industry today. For developers who had used the previous version, Visual Studio .NET 2003 it is an obvious choice to use Visual Studio 2005. It offers valuable benefits in terms of being a Rapid Application Development (RAD) tool. *
Visual Studio is WYSIWYG developing application whether it is for windows or web is extremely simple. Simply drag and drop the required controls to create an executable application. The code can be modified easily to allow custom functionalities.
*
Visual Studio offers Intellisense to aid coding, Intellisense helps to format your code as you type, indenting and automatic code coloring to distinguish different elements within your class. This makes your code much more easier to read and also debug. Intellisense also provides code snippets that provide templates for simplifying common coding tasks
*
Visual Studio helps to auto-generates our code. For example when we need to access a Web service Visual Studio takes care of creating the proxy class for us. The code generated is a strongly typed proxy class which provides us with all the details that we need to develop.
*
Visual Studio takes care of these basic tasks to provide us with an intuitive and efficient development environment.
*
Visual Studio comes with an integrated web server. Usually to host an ASP.NET application such as a Web service, we need a web server software like IIS installed. The web server waits for web requests and serves the appropriate pages. Setting up IIS is not difficult but it may be inconvenient. Thanks to the integrated development web server in Visual Studio, we can run a website directly from the design environment.
*
Visual Studio supports multiple languages. This allows us to effectively code in our favorite language or languages of choice using the same development environment. Visual Studio 2005 adds the ability to put web pages coded in C# in the same project as web pages written in Visual Basic. The only limitation is that we can’t use more than one language in the same web page (which will create obvious confusion).
*
Visual Studio is geared with many features to allow us to get our work done faster. Convenience features allow users to develop applications at a much faster rate.
*
Visual Studio comes with a suite of debugging tools and utilities. We can execute code one line at a time, set intelligent breakpoints based on certain conditions, and view current in-memory information at any time.
Visual Studio IDE has a wealth of features that allow us to better project manage, integrate source code and has rich extensibility features.
Web Service Template When the IDE first loads, it shows an initial start page. The start page contains recent projects that we have worked on as well as a MSDN section which shows the latest news. To start using the Web service template, choose File -> New -> Web Site to create a new ASP.NET Web Service application. Visual Studio will then show the New Web Site dialog box see Figure 4-4.
111
The Complete Reference To Professional SOA with Visual Studio 2005
TIP: We don’t use Visual Studio’s File -> New Project command. That is because web applications are regarded as separate to traditional windows based applications such as WinForm and Console application projects.
Figure 4-4 New Project
Since we will be developing for XML Web service we will be predominantly using the New Web Site to create ASP.NET Web service. The New Web Site window allows us to specify the templates, location of the project and as well as the language we would like to use. Template: In the New Web Site we can select several Templates. We can select: *
ASP.NET Web Site
*
ASP.NET Web Service
*
Personal Web Site Starter Kit
*
Empty Web Site
*
ASP.NET Crystal Reports Web Site
We will be working with Web based applications which include both ASP.NET Web Site and ASP.NET Web Service. So determining what we type of project we will be creating first is essential to selecting the right templates. The Web Site and Web Service applications are actually compiled and executed in the same way. We can also add Web pages to a Web service application and vice versa. The only difference is that by selecting a template we are asking Visual Studio to create specific pre-defined files for us. In a Web service application we will start with a sample service whilst in Web Site application we start with a sample Web page. Location: The location section determines where we will be storing the working files. Previously in Visual Studio 2003 we could only specify HTTP locations this meant that we could only save files to a Web service with IIS. However in Visual Studio 2005, we can take advantage of a number of modes. We can now save our working files to the File System or store the files to a network address. We can also save our project to a FTP or
112
The Complete Reference To Professional SOA with Visual Studio 2005
a HTTP location. The best part is that Visual Studio 2005 now comes with an integrated Web server called ASP.NET Development Server. This server is launched when our Web based projects are stored on the file system. However if we want to work on a live remote website we should use the Remote Site option, though care should be taken when working on a production server as changes can be irreversible. Rather than typing the location details in we can alternatively use the browse button which will show a Choose Location dialog window. There are four types of locations that we can select here File System, Local IIS, FTP Site. Language: We have the option of selecting Visual Basic, Visual C# and Visual J# (In the following example we will be using Visual C#)
Figure 4-5. File System
File System: The file system is preferred by most developers because its easily accessible we can save to any particular location we like figure 4-5. In Visual Studio 2005 when execution occurs an Integrated Web server called ASP.NET Development Server will be launched. This environment is essentially what hosts the Web application during execution. If we want to create a new directory for our application, just click the Create New Folder icon above the top right corner of the directory tree. We can also specify a new directory to create by adding a new directory name to the end of our path.
113
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 4-6. Local IIS
Local IIS : Selecting the Local IIS option will allow us to browse through the Virtual Directory lists made available through the IIS figure 4-6. We can also create a new virtual directory by using the Create New Web application icon on the top right hand corner of the dialog window.
Figure 4-7. FTP Site
FTP Site : By selecting FTP Site we are essentially connecting to a FTP server from where our working files will be stored figure 4-7. To do this we need to specify the server details, credential information as well as the directory we want to store the files in.
114
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 4-8. Remote Web Server
Remote Web Server: Selecting the Remote Site means that we will be storing the files on a remote IIS server with FrontPage Extension installed figure 4-8. We will be prompted for username and password information upon successful connection to the site. Language: The language option allows us to select between Visual Basic, Visual C# and Visual J#. The language that we choose will become the default language for the project. We can explicitly add Visual Basic web pages to a J# website, and vice versa. And if the project is in a solution we can also add other projects that is using different language to our project. Once we have completed our selection simply click Open Visual Studio returns us to the Create Web Site dialog box. Click OK, and Visual Studio will create the new web service application. The new Web Service starts with the file called Service.asmx.
115
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 4-9 A newly generated Web Service from the ASP.NET Web Service template.
Visual Studio 2005 Projectless Development In the past with Visual Studio .NET 2003 each web application must be contained in their own particular web project. Web Service must be in a Web Service project while ASP.NET Web Site must be in a Web Site project. In Visual Studio 2005 this limitation is removed web applications no longer need to be contained within a project for what they do. In Visual Studio 2005 web applications no longer contain files, such as .csproj project files and .sln solution files. Instead, every file in our web folder automatically is considered part of the web application. Now when we create a web application, Visual Studio stores project information in a user-specific directory, like c:\Documents and Settings\[UserName]\Visual Studio 2005\Projects\[ProjectName]. This is because even though Visual Studio no longer creates a project file and a solution file (.csproj, .vbproj, .sln) it must still retain some project information. For example if we have added more class library projects to our current web project or if we have configured special build modes. Those details will be stored in the solution file under the user directory so that on Visual Studio startup the project will be displayed under Recent Projects section.
Migrating to Visual Studio 2005 Project Visual Studio has traditionally come with an upgrade utility that allowed developers to migrate their projects created from the previous version of Visual Studio 2005. We can start the migration process simply by opening the project in Visual Studio 2005 Visual Studio 2005. When we do, Visual Studio begins the Conversion Wizard. The Conversion Wizard will prompt us to choose whether to create a backup and, if so, where it should be placed Figure 4-10. If this is our only copy of the application, a backup is a good idea in case some aspects of our application can not be converted successfully.
116
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 4-10 Project Conversion Wizard
One the wizard has completed the process we select Finish to begin the conversion process,. Any errors and warnings are added to a conversion log, which we can display when the conversion is complete. In general we will always receive one warning about IIS reference. Figure 4-11. A quick look at the ConversionReport.txt shows the following: Listing 4-1. Conversion Report This report shows the steps taken to convert your Web application from ASP.NET 1.1 to ASP.NET 2.0. There may be some unresolved conversion issues you will need to manually fix. For more information, please refer to http://go.microsoft.com/fwlink/?LinkId=46995 or search for the help topic "Converting from Visual Studio .NET 2002 or 2003". Conversion Started on project file WebService1.csproj at March 14 2006, 13:17:48. =========================ERRORS=================== =========================WARNINGS================= Warning: This web project was converted as a file-based web application. If your site contained any IIS meta-information, e.g. sub-folders marked as virtual directories, it is recommended that you close this web site and re-open it using the Open Web Site command and selecting the Local IIS tab. =========================COMMENTS================= Web.Config: Added 'xhtmlConformance' attribute. Removed attribute Codebehind from file Global.asax. Added folder App_Code. Moved file Global.asax.cs to the App_Code\ directory. Moved file Service1.asmx.cs to the App_Code\ directory. Moved file AssemblyInfo.cs to the App_Code\ directory. Changed HTML validation schema for all projects to 'Internet Explorer 6.0'.
117
The Complete Reference To Professional SOA with Visual Studio 2005
Removed file Bin\WebService1.dll. Removed file Bin\WebService1.pdb. Removed file WebService1.csproj. Removed file WebService1.csproj.webinfo. Project WebService1.csproj has been converted successfully at March 14 2006, 13:17:56.
Figure 4-11. Converted project
Visual Studio IDE Microsoft’s Visual Studio is one of the most advanced IDE in the world. Visual Studio is smart enough to help developers through the daily repetitive tasks, while at the same time ensuring the quality of the overall project.
118
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 4-12. Visual Studio IDE Table 4-1 Visual Studio Windows
Windows
Description
Solution Explorer
Lists all of the files that are used in the project directory.
Toolbox
Shows built-in controls and any third-party controls or custom controls that we have built ourselves and added to the Toolbox. These controls can be used to build user interface quickly or to implement certain actions such as retrieving data from a database. To use these control simply drag and drop or double click. Controls can be written in any language and used in any language.
Server Explorer
Server Explorer provide details on Servers that are accessible these could include database connections to SQL Server or to Crystal Reports Services, Event Logs, Message Queues, Managed Classes, other Services on the System and Performance Counters. From the Server Explorer we can have direct connection to the SQL Database allowing to perform live queries and test commands.
Properties
Allows us to configure the currently selected element, whether it’s a file in the Solution Explorer or a control on the design surface of a web form. To access the properties window we can right click on any object on the design surface and then select properties.
119
The Complete Reference To Professional SOA with Visual Studio 2005
Error List
During development Visual Studio helps us to keep track of potential issues that may arise. This occurs while we develop or after we have built an application. These issues are reported in the Error List window.
Task List
Task List can list comments that are predefined through aliases through out the code. For example if we wanted to leave a comment about a section of code that we’re still yet to implement we can use the //TODO: syntax to leave a message. This message will then be populated under Task List.
Document
The document window or otherwise known as the source code window allow us to modify the actual code behind a web based application. The document window can also support file types, such as static HTML and XML files.
Class View
The Class View window organizes a code in a class into a logical tree with methods, properties and events represented in different nodes.
Solution Explorer
Figure 4-13. Solution Explorer
The Solution Explorer is very much like a file explorer where we can explore all the files contained with a project figure 4-13 above. It is also very versatile because we can add files outside of a project into the project. The solution explorer also comes with a number of tools for specific file types. We can view the difference in options for different file extensions by right clicking on the file. Table 4-2 Typical Web Service File Types
File
Description
Ends with .asmx
All files represented with .asmx are used as ASP.NET Web Services. When a request is received to a .asmx file the request is passed to the .NET Runtime where it is handled. Depending on the request for example ?WSDL a request for a WSDL document ?DISCO for discovery files a response is generated. A direct request to the .asmx from a browser could result in the generation of a web based test page which we can use to invoke the Web service.
120
The Complete Reference To Professional SOA with Visual Studio 2005
web.config
This is the XML-based configuration file used for our ASP.NET application. It includes settings for customizing security, state management, memory management, and much more. Visual Studio adds a web.config file when we need it. (For example, it adds a web.config file that supports debugging if we attempt to run our web application.) When we first create a website, we don’t have a web.config file. We can nest one web.config in each of the directory the web.config within the directory will overwrite settings of the higher level web.config. Generally only one web.config is maintained for a project for ease maintenance.
global.asax
The global.asax file is used to define global events that occur in an application. This could be when an error from a specific web application occurs in this case a custom error handler will then be invoked to process the error.
Ends with .vb
These are files that contain Visual Basic 2005 code classes.
Ends with .cs
These are files that contain C# code classes.
Within a project we can include other resources that are not ASP.NET file types. These can be XML, XSLT and XSD file types that are used by our Web service application. Visual Studio can also distinguish between different file types there are associated tools that help us to modify specific file types. We can view these tools by simply right click on the specific files. For example right mouse click on a XML file will give us the option of viewing the file in a browser. The solution explorer is incredibly handy in development it allows us to add predefined file types into the project figure 4-14 below. To add a new item to a project simply right click on the solution explorer and select “Add New Item”. We can add different types of files these range from HTML Page to DataSet to Class files to XML Schemas.
Figure 4-14. New Items
121
The Complete Reference To Professional SOA with Visual Studio 2005
To add an existing item simply right click and select “Add Existing Item” from which we can browse for a particular file that we want to add to the project. We also have the ability to drag and drop files in and out of the solution explorer. One of the features of Solution Explorer is that it allows us to exclude certain items from the project. This means that even though the specific item exist in the project it is not compiled and evaluated. This is handy when we’re working on a piece of code that we know will cause errors. We can simply exclude that specific CS or VB file from the project temporally to compile the project and see if the rest of the code is working. Visual Studio also helps us to keep track of files modified. If a file is changed outside of Visual Studio, Visual Studio will prompt us to either refresh or keep our changes. This is important when we need to modify a particular file in the solution outside of Visual Studio using possibly a third-party tool.
Document Window The document window is what allows us to modify changes to the design of an application. Not all applications have a Graphical User Interface (GUI) for example windows service, console applications and XML Web service. However each file type has a default editor assigned to it for example an ASPX file would open the Visual Studio HTML editor which can be used to modify HTML code and as well as view the visual representation of the HTML. We can view or change the default editor by selecting the file in solution explorer and then right click on the file to bring up the context menu. For example selecting a Web service .asmx file and then selecting the “Open With” option will bring up an Open With dialog window figure 4-15 below.
Figure 4-15. Open With
The default editor used by that file type will be labeled with a (Default) after the editor name. Also depending on the applications that we have installed we may also see additional editors appearing in the Open With dialog window.
Toolbox The Toolbox window works in conjunction with the designer window. The toolbox stores a number of controls. These controls are either internal to the .NET Framework or they can be custom controls that we have developed and included onto the toolbox. Simply by selecting the tool and drag and drop onto the design surface will create the tool on the designer surface. The content of the Toolbox depends on the context of the current designer window that we are working in as well as the current project type.
122
The Complete Reference To Professional SOA with Visual Studio 2005
In the toolbox we can add/remove tools as well as add tabs and remove tabs. We can also drag and drop tools from one tag group to another.
Error List The Error List manages the error and the warning information that’s generated by Visual Studio during development. Each entry in the Error List contains a description column, a file column to show which file the error is located in, a line column to shown which line the error is on, a code column is also shown to show the location of the error, lastly a project column is also shown incase we have more than one project in the solution. We can select whether we want to see each of the column by right click on the Error List window Figure 4-16 below.
Figure 4-16. Columns
To go to the offending error we can simply double click on the error message. This will take us straight there. The error list window also has a number of options we can select on the columns to view the column of interest. We can also sort the error list by right click on the Error List and sorting either by category, default order, description, file, line, column or project.
Figure 4-17. Sort by
With the default Visual Studio settings, the Error List appears automatically whenever we build a project that has errors. In the example below we will intentionally leave an error by leaving the hello world message unclosed with quote see Figure 4-18. Listing 4-1. Desmonstration of error in Visual C# using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class Service : System.Web.Services.WebService
123
The Complete Reference To Professional SOA with Visual Studio 2005
{ public () { //Uncomment the following line if using designed components //InitializeComponent(); } [WebMethod] public string HelloWorld() { return "Hello World } }
Figure 4-18. Error List
Task List There are two lists of tasks that exists these are User Tasks and Comments. User tasks are entries that we have added specifically to the list. These are things that we want to do but have not quite started. To create a User Task simply click the icon next to the drop down list in the Task List window. There are three things we can assign to a User Task item we can specify the priority of the item, add a description to the item, and select to indicate whether the item has been complete Figure 4-19.
124
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 4-19. User Task List
The comment list of the Task List allow us to add comments as we program. To do this we can simply add a //TODO alias which is a comment but whatever is after the TODO will be displayed under the comments list of the Task List. For example // TODO: Debug this section
Because our comment uses the alias TODO, Visual Studio recognizes it and automatically adds it to the Task List figure 4-20 below. To remove the comment from the task list simply remove the //TODO: from the code. Visual Studio will automatically update the Task List.
Figure 4-20 Task List with TODO comment
Figure 4-21. Task List
125
The Complete Reference To Professional SOA with Visual Studio 2005
By default Visual Studio comes with several aliases for Task List comments. There is Hack, TODO, UNDONE and UnresolvedmergeConflict. However we can always add more. Simply enter a name under the Tokens section and select Add button to add the token.
Server Explorer
Figure 4-22. Server Explorer
The Server Explorer provides an integrated means for us to access different resources all from the comfort of Visual Studio. It allows us to access databases, establish a connection to services such as Crystal reports Services, Event Logs, Management Classes, management Events, Message Queues, Performance Counters, and other Services on the system figure 4-22. The Server Explorer allows us to interact with the above server resources. For example we can execute database queries and display the result all from the Server Explorer in much the same way as we would otherwise use SQL Server’s Management Studio To find out what we can do with a server item on the server explorer, simply right-click it. In the example below we are opening a table definition in a database. We can then add/modify/remove definition from the table just as we would from the Enterprise Manager Figure 4-23.
126
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 4-23. Using Server Explorer to open a database table.
Code Window The code window is where majority of our development will be done in. It is here that we will spend majority of our time developing ASP.NET XML Web services. To start developing we can select a particular file in the solution explorer right click then select View Code.
Outlining Outlining is a very useful function as it provides as an indicator where a class or a method starts and ends. We can also collapse the outline to reduce the clutter in the code window. It allows us to view only the code that interests us whilst blocking out the rest. To collapse a block of code simply click on the [-] minus outline to the left of the code. To expand a block of code simply click on the [+] plus outline to expand the section see Figure 424.
127
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 4-24. Code outline
IntelliSense Code Member List IntelliSense provide us with an automatic way of completing code as well as perform automatic syntax check. This proves as an important tool for Rapid Application Development (RAD). With IntelliSense Visual Studio makes it easy for us to interact with class, controls and objects. IntelliSense is automatic as soon as we type a class name or a object name Visual Studio will display a list of methods or properties that we can access and use in our code Figure 4-25. The intellisense will also provide a list of parameters and their data types when we need to call a method. Simply hover the mouse over the interested method and use the up and down key to scroll through a list of overloads for the method and their requirements in terms of data types and parameters Figure 426.
128
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 4-25 Intellisense member list
Figure 4-26 Intellisense shows the overload requirements
Error Underlining One of the most useful feature during development is the intellisense’s ability to automatically underline code that contain errors. This automatic underlining underlines all problematic code with a red underline. Because it is automatic we can see the error almost immediately without the need to wait for compiling. Thus it’s the first line of defense against code error. Visual Studio is able to detect a variety of error conditions, such as properties, undefined variables, invalid data type conversions and missing code elements. We can place our mouse over the underlined error to see a brief tooltip description of the problem Figure 4-27.
Figure 4-27 Intellisense Error underlining
129
The Complete Reference To Professional SOA with Visual Studio 2005
If an error is detected during the compiling stage Visual Studio will prompt us whether we want to continue. If we choose to continue Visual Studio will use the last successful build of our application to execute because it can not build a program with error. It is always a good habit to correct the error as soon as we are made aware.
Summary In this chapter we have examined the role of the 2.0 version of the .NET Framework and the role that Visual Studio 2005 plays in helping developers develop their service-oriented web applications. *
.NET is a comprehensive and yet flexible framework that allows developers to develop Console Application, Windows GUI Application, ASP.NET Application, XML Web Service Application, Windows Service Application and Mobile Applications. It is further enhanced with the release of .NET 2.0. All this is possible from the Visual Studio 2005 IDE.
*
.NET is more than just one language it is a framework that can be developed using different languages.
*
.NET uses Common Language Runtime to provide the execution environment to .NET applications. All .NET language compiles into MSIL code.
*
.NET has a common type system where common data types, value and object types are common regardless the .NET language we use to develop. This means all languages are equally powered.
*
.NET ensures type safety, .NET Framework ensures that operations to be performed on one value or object are performed on that value or object only.
*
.NET manages code execution. The .NET Framework manages the state of objects during the program execution. The Framework ensures automatic memory allocation and garbage collection.
*
.NET supports side-by-side execution, allowing us to develop multiple versions of an application on a system by using assemblies.
130
The Complete Reference To Professional SOA with Visual Studio 2005
Chapter 5 XML Web Services Standards and Concepts Web services are definitely changing the way we think about distributed software systems. In this chapter we will examine the concepts behind the basic Web services technologies and their implementations. An XML Web service is a programmable component that supports interoperability between distributed systems. This is achieved through Web service’s adoption of vendor neutral standards such as XML and other Internet standards. XML Web service relies on the internet standard Hyper Text Transfer Protocol (HTTP) as its message delivery protocol. By adopting XML Web service we can create an infrastructure that supports interoperability at all levels and ease the process towards SOA. XML Web service is quite flexible we can use it internally within our enterprise or expose the service for external access over the internet. This allows an enterprise to expose internal intellectual properties to the public and develop a customer base from third-party application implementers. XML Web service allows access through a standard generic interface thus it distributed components to work together as a single unit through integration. XML Web service is defined through an interface and an implementation of that interface. This abstraction from interface allows a XML Web service to reside above existing system components, such as application servers, messaging applications and other packaged applications. Web services because of their support for vendor neutral technology can work with any operating system, hardware platform or programming language. Developers no longer have to find ways to work between different protocols, standards and technology for two piece of applications to work together. Using XML based messaging both service consumers and service providers do not require more knowledge than each other’s input, output and location details Web services are distributed applications based on standards. In essence, this chapter introduces the major standards that we are likely to encounter in our Web services development: SOAP, WSDL, XML, XML Schema (XSD), HTTP, and WSDL. See figure 5-1
Figure 5-1. Web service technology stack
131
The Complete Reference To Professional SOA with Visual Studio 2005
.NET Web Service Message Flow In the following sections, we will be exploring how to build a web service with ASP.NET and how to test it using different protocols. Listing 5-1. Demonstrates a simple web service using Visual C# using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class Service : System.Web.Services.WebService { public Service () { //Uncomment the following line if using designed components //InitializeComponent(); } [WebMethod] public string HelloWorld(string param1) { return "Hello " + param1; } }
Listing 5-2. Demonstrates a simple web service using Visual Basic .NET Imports System.Web Imports System.Web.Services Imports System.Web.Services.Protocols _ _ _ Public Class Service Inherits System.Web.Services.WebService _ Public Function HelloWorld(ByVal param1 As String) As String Return "Hello " & param1 End Function End Class
Using the HelloWorld Web service example in listing 5-1 and listing 5-2. The process of invoking a web service involves sending a message to the Web service itself. When a request first enters into IIS for the HelloWorld (WebMethod), SimpleWebService (Web service) we had constructed earlier, it looks something like this:
132
The Complete Reference To Professional SOA with Visual Studio 2005
POST /SOAWebService/CSSimpleWebService/Service.asmx HTTP/1.1 Host: localhost Content-Type: text/xml; charset=utf-8 Content-Length: length SOAPAction: "http://tempuri.org/HelloWorld"
This flow of the message to the Web service itself is shown below in figure 5-2.
Figure 5-2. Web service message routing
1.
IIS examines the request and determines that it is being sent a request that ends with the extension .asmx. The ASP.NET handler is registered with IIS as handling this extension; therefore, the request in its entirety is handed over to the ASP.NET process.
2.
At this point, the ASP.NET worker process examines the request and discovers that it has a handler registered in machine.config, the system-level .NET configuration file, for a request for resources with the extension .asmx. It therefore kicks up this handler and passes the request onto it.
3.
Next, the handler creates an instance of the class defined in the handler, and uses reflection to examine which operations the class supports and how those operations should be routed. By default, operations are mapped to methods using the SOAPAction HTTP header, but this can be changed to map to the first child element of the SOAP body.
4.
Once the message is routed, the handler uses the XML Serializer to deserialize the request XML into the parameters that the method is expecting. Once the method returns, this return value and any out parameters are mapped back into XML with the XML Serializer. Then, a response SOAP message is created that wraps this XML, and the response is sent back, via ASP.NET’s HttpResponse context.
5.
If an exception is thrown, then it is wrapped inside of a SoapException, and a SOAP fault is returned instead, with the HTTP status code set to 500. (For non-error responses, the status code is 200, or OK.). These messages typically transferred through HTTP.
133
The Complete Reference To Professional SOA with Visual Studio 2005
HTTP Hyper Text Transfer Protocol (HTTP) is a World Wide Web Consortium (W3C) standard protocol for transferring documents on the Internet. XML Web services use HTTP for communication. It is a generic, stateless, protocol, which can be used for many tasks in addition its original use for hypertext. A resource location is specified in HTTP through a mechanism known as a Uniform Resource Locator (URL). Strictly speaking, the mechanism that is used in HTTP is a Uniform Resource Identifier (URI), but we can also think of it as a URL. The syntax of a URL is as follows: http://host[:port][path[?querystring]]
The following is an example of a URL: http://www.mswcf.com/url.aspx?id=23
In the preceding example, www.mswcf.com is the host, url.aspx is the path and id=23 is the query string. If the port number is not specified (as in the preceding example), the default port for HTTP, which is port 80, is used. HTTP is a stateless protocol. This means that whenever the client makes a request, the connection to the server is closed after the client receives the response. Therefore, if any state must be maintained between the client and the server, the server must pass on state information with the response to the client. This will enable the server to recover this information from the client when it receives the next request. For example, if we implement a Web site that displays user-specific content, we would have to implement a mechanism that retains information about the current user to display personalized content. Listing 5-3. Demonstrates a HTTP Request POST /urlpost.aspx HTTP/1.1 Host: localhost Content-Type: application/x-www-form-urlencoded Content-Length: 11 Id=23
Listing 5-4. Demonstrates a HTTP Response HTTP/1.1 200 OK Content-Type: text/xml; charset=utf-8 Content-Length: 75
Above shows the request and response structure of HTTP. The first line in an HTTP request is known as the request line, and the methods that a request supports are as follows: *
OPTIONS
*
GET
*
HEAD
*
POST
*
DELETE
134
The Complete Reference To Professional SOA with Visual Studio 2005
*
TRACE
*
CONNECT
*
extension-method
A HTTP response has the following structure format: Version Status-Code Description headers a blank line message body
The following code shows an example of an HTTP response: HTTP/1.1 200 OK Content-Type: text/xml; charset=utf-8 Content-Length: 75
The GET and POST Methods HTTP-Get and HTTP-POST are the most common way of transferring information from one web page to the next. Both are standard protocols that use HTTP (Hypertext Transfer Protocol) for the encoding. These protocols will encode and pass values in a name /value pair from one web page to the next. This information is part of the HTTP request headers which contains requesting information as well as the location of the page that we’re requesting for. If the request is successful HTTP will respond with a series of HTTP response headers and the requested information. The difference between HTTP-GET and HTTP-POST is that HTTP-GET uses MIME application/x-wwwform-urlencoded to encode its name/value pair parameters in the url. The encoding process ensures that characters such as space values are in turn encoded to %20 so that a valid and consistent text can be formed. The appended parameters can also be referred to as a query string. Since the query string is embed in the URL there is a limit to how much information we can store in the URL the limit for the length for a valid URL is 1024 characters. Listing 5-5 demonstrates using HTTP-GET Listing 5-5. Demonstrates a HTTP request using GET GET /url.aspx?id=23 HTTP/1.1 Host: localhost
While HTTP-POST similar to HTTP-GET both uses HTTP, and both uses MIME encoding to encode name/value pairs. Though HTTP-POST instead of passing the query string as part of the URL, the name/value pairs are passed inside the actual HTTP request message. Listing 5-6 shows the same request as listing 5-5 with the same name/value pair using HTTP-POST. Listing 5-6. Demonstrates a HTTP request using POST POST /url.aspx HTTP/1.1 Host: localhost Content-Type: application/x-www-form-urlencoded Content-Length: 11 id=23
135
The Complete Reference To Professional SOA with Visual Studio 2005
The GET and POST request methods are ideal for communicating with an XML Web service. These methods are designed specifically for submitting data to a Web server and retrieving a specified resource from a Web server. This makes it possible to layer a function call model on top of these methods, which is exactly the model that XML Web services requires. HTTP GET uses an URL request to communicate information to a Web Page or an XML Web Service. The most important feature of the request line is the querystring. The querystring is the portion of the URI that follows the question mark, and consists of a set of URL-encoded name/value pairs. In an HTTP-GET request, there is typically no message body. The response for an HTTP-GET request is just a standard HTTP response. Listing 5-7. Demonstrates a HTTP-POST request: POST /Trading/GetStockPrice.aspx HTTP/1.1 Host: localhost Content-Type: application/x-www-form-urlencoded Content-Length: 11 id=23
In the preceding code, notice that there is no querystring as part of the URI. This is because the information about the request is contained in the message body. This feature of an HTTP-POST request makes it a very convenient way of passing larger sets of data to the server in contrast to an HTTP-GET where the size of the querystring is restricted to 1024 bytes. Also, transmitting the data as part of the message body imposes fewer restrictions on the kind of data that is sent to the server.
Tip: Both HTTP GET and POST can be applied to web applications as a standard form of execution. However in .NET 2.0 GET is disabled as form of security precaution. To enable GET we must insert the below configurations into Web.Config.
Alternatively, we can enable the GET protocol for all Web services on the computer by editing the section in Machine.config. The section is located under the section. The following example enables HTTP GET, HTTP POST, and also SOAP and HTTP POST from localhost:
136
The Complete Reference To Professional SOA with Visual Studio 2005
The Machine.config file can be found at c:\\Microsoft.NET\Framework\\config\machine.config Once HTTP-GET is enabled for Web service we can invoke the methods in the web service directly using the syntax below: http://server/webServiceName.asmx/functionName?parameter=parameterValue
Therefore, the call for our Web Service will be http://localhost/SOAWebService/CSSimpleWebService/service.asmx/HelloWorld?param1=kim
This will produce the same result as clicking the Invoke button.
Figure 5-3. Web service call using HTTP GET
HTTP With .NET Issuing an HTTP request and receiving a response is easy using the .NET Framework. The following classes in the .NET Framework provide all of the required basic functionality: *
HttpWebRequest and HttpWebResponse classes in the System.Web namespace
*
StreamReader and StreamWriter classes in the System.IO namespace
*
WebRequest and WebResponse are abstract base classes in the .NET Framework for accessing data from the Internet in a protocol-neutral way.
The HttpWebRequest and HttpWebResponse classes, which are derived from WebRequest and WebResponse respectively, encapsulate the HTTP-specific aspects of the communications with a Web server. Most importantly, they provide easy access to the HTTP headers, and the underlying request and response streams. The StreamReader and StreamWriter classes are two utility classes that are used to read and write streams by using a specific encoding (UTF-8/UTF-16, etc.). Let’s create a simple console application to call the Web Service we had created earlier using HTTP POST.
TIP: Normally we do not need to call a Web service in this manner. As Visual Studio will automatically create a proxy for us which will manage all Web service calls for us.
Having launched Visual Studio 2005, select File menu ~TRA New ~TRA Project. We will be presented with the New Project dialog box, as shown in Figure 5-4. Simply select the language that we want to develop with under the Project Types section. Then select Console Application from the Templates section.
137
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 5-4. New Project
Note
If we are developing using Visual Basic .NET we can select the Console Application Template from the Visual Basic list
Once the template starts we will be presented with an empty code template shown in Figure 5-5.
Figure 5-5. Console program template is automatically created for you Listing 5-8. Demonstrates a console application to send a HTTP POST request to a Web service using Visual C# using System; using System.Collections.Generic; using System.Text; using System.Net; using System.IO; namespace CSHTTPRequest
138
The Complete Reference To Professional SOA with Visual Studio 2005
{ class Program { static void Main(string[] args) { string url = "http://localhost/soawebservice/" + "firstservicecs/service.asmx/HelloWorld"; string contentType = "application/x-www-form-urlencoded"; string method = "POST"; string content = ""; HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); req.ContentType = contentType; req.Method = method; req.ContentLength = content.Length; Stream s; s = req.GetRequestStream(); StreamWriter sw = new StreamWriter(s, Encoding.ASCII); sw.Write(content); sw.Close(); HttpWebResponse res = (HttpWebResponse) req.GetResponse(); s = res.GetResponseStream(); StreamReader sr = new StreamReader(s, Encoding.ASCII); StringBuilder sb = new StringBuilder(); char[] data = new char[1024]; int nBytes; do { nBytes = sr.Read(data, 0, (int)1024); sb.Append(data); } while (nBytes == 1024); Console.WriteLine(sb); Console.ReadLine(); } } }
Listing 5-9. Demonstrates a console application to send a HTTP POST request to a Web service using Visual Basic .NET Imports System Imports System.Collections.Generic Imports System.Text Imports System.Net Imports System.IO Namespace VBHTTPRequest Module Program Sub Main() Dim url As String = "http://localhost/soawebservice/" + _ "firstservicecs/service.asmx/HelloWorld"
139
The Complete Reference To Professional SOA with Visual Studio 2005
Dim contentType As String = _ "application/x-www-form-urlencoded" Dim method As String = "POST" Dim content As String = "" Dim req As HttpWebRequest = _ CType(WebRequest.Create(url), HttpWebRequest) req.ContentType = contentType req.Method = method req.ContentLength = content.Length Dim s As Stream s = req.GetRequestStream Dim sw As StreamWriter = _ New StreamWriter(s, Encoding.ASCII) sw.Write(content) sw.Close() Dim res As HttpWebResponse = _ CType(req.GetResponse, HttpWebResponse) s = res.GetResponseStream Dim sr As StreamReader = _ New StreamReader(s, Encoding.ASCII) Dim sb As StringBuilder = New StringBuilder Dim data(1024) As Char Dim nBytes As Integer Do nBytes = sr.Read(data, 0, CType(1024, Integer)) sb.Append(data) Loop While nBytes = 1024 Console.WriteLine(sb) Console.ReadLine() End Sub End module End Namespace
Once we have completed the code simply press F5 to run and debug or CTRL + F5 to run without debugging. We should see the message returned from the Web service invocation see Figure 5-6.
Note: If you are not using IIS and are using the ASP.NET Development Server as your web server then you will need to adjust the port number for example http://localhost/webservice would become http://localhost:portnumber/webservice.
Figure 5-6. Result from Web service call
To use HttpWebRequest simply use WebRequest.Create the return value is converted to HttpWebRequest.
140
The Complete Reference To Professional SOA with Visual Studio 2005
HttpWebRequest req = (HttpWebRequest )WebRequest.Create(url);
In most cases, the WebRequest and WebResponse classes provide all of the functionality that we need to perform a HTTP request. However, if we need to access HTTP-specific features such as HTTP headers, we need a protocol-specific derived class of WebRequest. req.ContentType = contentType req.Method = method req.ContentLength = content.Length
In the above code HTTP-specific properties such as the ContentType, Method of call and ContentLength are set. Listing 5-10. Demonstrates content steam using Visual C# Stream s; s = req.GetRequestStream(); StreamWriter sw = new StreamWriter(s, Encoding.ASCII); sw.Write(content); sw.Close();
Listing 5-11. Demonstrates content steam using Visual Basic .NET Dim s As Stream s = req.GetRequestStream Dim sw As StreamWriter = New StreamWriter(s, Encoding.ASCII) sw.Write(content) sw.Close()
The content for the request is written to a stream named content. Note that the type of encoding is specified as ASCII for the stream. Listing 5-12. Demonstrates using GetResponse in Visual C# HttpWebResponse res = (HttpWebResponse) req.GetResponse();
Listing 5-13. Demonstrates using GetResponse in Visual Basic .NET Dim res As HttpWebResponse = CType(req.GetResponse, HttpWebResponse)
The HTTP response is retrieved through the use of GetResponse().
XML XML is used to implement XML Web services in a number of ways. This includes the use of XML as the wire format between an XML Web service consumer and the XML Web service, and the use of XML to describe the XML Web service interface. XML is a big topic and full coverage is out of scope of this book. If you’re unfamiliar with XML it is highly recommended that you find additional information on XML. We will cover some basic notion of XML here, while later in the book we will focus on XML data manipulation with .NET 2.0. It is recommended that the XML Web service developer have a solid understanding of XML. XML is a complete tag-based language which uses tagged syntax to structure data. Documents that conform to XML schema is structured from a variety of elements, namespace declarations, and attributes. Let’s have a closer look.
141
The Complete Reference To Professional SOA with Visual Studio 2005
Elements
Value
Elements make up majority of the XML document. There exist exactly one top level element known as the document element. Elements have a name and may also contain child elements. An element with children
John Doe 44
The child of elements can be elements themselves or they can also be processing instructions, or CDATA sections. The children of an element can contain attributes and or namespaces. Attributes and namespaces contained by the elements are unordered. Elements are defined by an open tag and a close tag. The open tag consists of a less angle bracket < followed by the name of the element, then followed by a closing greater than angle bracket >. The syntax for the close tag is essentially the same but with a forward slash /: close tags consist of a less than angle bracket < followed by a / then the same tagname followed by a greater than angle bracket >. The children of an element are contained between the open and close tags of their parent. In cases when an element has no children, the element is said to be “empty”. An empty element
A short hand way of writing an empty element is simply to complete the start tag with a forward slash immediately after the tag name. Empty element shorthand
XML itself does not define any particular element names, it allows the developer of the XML document to choose any name for the tag. There are a few restricts such as XML names are case sensitive and must begin with a letter or an underscore. The initial characters may be followed by any number of alpha numerical characters as well as hyphens - and underscores _.
Elements, namespaces, and namespace declarations
children
Since XML allows us to define our own tagname for elements it is thus possible to define the same tagname twice. To be able to distinguish between the two tagnames XML offers namespaces as a means to distinguish
142
The Complete Reference To Professional SOA with Visual Studio 2005
between the two elements. This is done by associating an element with a namespace. A namespace acts as the scope containing all the elements that have been associated to it. A namespace name is defined by a uniform resource identifier (URI). URI serves as an ideal unique identifier string. The namespace name and the local name together forms a globally unique name called “Qualified Name”. Namespace declarations associated with the element will be defined within the element’s start tag. A typically shorter string known as the “namespace prefix” will be used. The syntax for the namespace declaration will be xmlns:prefix='URI'. It is also possible not to map a namespace declaration to a prefix. We can use the default namespace declaration. The syntax for a default namespace declaration is xmlns='URI'. In eiher cases only one default namespace declaration may appear on an element. The URI can be defined by either single quotes ‘ or double quotes “. It is also possible to map the same namespace to more than one prefix. All namespaces have a scope to which is applied for the element on which it is declared and all of the element’s descendants. The mapping of a given prefix for a namespace can be overridden by associating the prefix with a new mapping for the element’s descendants. The in-scope default namespace if not using a prefix can also be overridden by providing a new namespace declaration. All names of elements in a XML document that conform to the Namespace are regarded as qualified names (QNames). In the following example an element with a local name of Person and a prefix of pre is mapped to a namespace URI of urn:example-org:People. The element person has decendents or child elements of name and age. Both child elements are assigned to the prefix of pre with the namespace URI of urn:example-org:People.
John Doe 44
Syntactically all Qualified Names have an associated local name and prefix is optional. Both the local name and also the prefix can be referred to as a NCName, an NCName is a name that does not contain a colon. The syntax for an element associated with the prefix is defined by the prefix followed by colon then the local name of the element. A namespace must be defined if prefix is to be used. If the local name does not contain a prefix then the element is contained by the default namespace declaration. However, if no default namespace had been declared in the scope the element then the element is regarded as an unqualified element, which simply means that it does not have a namespace. In the example below an element contains a local name of person is assigned a prefix name of pre that is mapped with the namespace uri of urn:example-org:People. The person element has two decendents or two child elements of name and age and none of them are associated with the pre prefix. This means that both of these child elements are unalified elements as they are not contained in any namespace
John Doe 44
The namespace URI of an unqualified element is defined by the empty string “”. If a default namespace declaration is defined and in scope then an unqualified namespace is required. We can overwrite the default namespace declaration by defining the URI as an empty string in the form of xmlns=”” on the element. The example below demonstrates using default namespace declaration. An element with the local name of person is assigned a default namespace uri of urn:example-org:People. The element has two decendents or child elements of name and age.
143
The Complete Reference To Professional SOA with Visual Studio 2005
Both elements are not assigned to any prefix. As such they both automatically fall under the namespace of its parent element of urn:example-org:People. This example is equivalent to the previous example
John Doe 44
Attributes and Namespaces name='value' name="value"
In XML, elements can be decorated with attributes. An attribute is used to provide data or metadata about an element. Attributes are a way of providing additional information to what the element already describes. Attributes are defined as name/value pairs separated by the equal sign =. A simple example would be that the person element can contain two attributes describing properties about that particular person. These are defined as attributes rather than child elements.
Attributes are defined by the same requirement as the element in that it must be alphanumerical and its value must be quoted using either a single quote ‘ or a double quote “. An element may have a number of attributes but they must contain the different names so that they can be distinguished. Some elements with metadata attributes 20 32
Attribute names are also Qualified Names (QNames). The namespace of an attribute is defined in the inscope namespace declaration for the prefix. Attributes that are not defined in the namespace declaration are considered to be unprefixed even if default namespace is declared in the scope. In the following example an element of person contains an child element of name and age. The age element contains attributes of base and units. Base attribute is associated to the namespace of urn:example-org:People:base through a prefix of ‘b’ while the Units attribute is associated with the namespace of urn:example-org:units with a prefix of ‘u’.
John Doe 44
Comments sequence. Character sequences such as – may not appear within the comments.
The simpleType element is used to define new types based on existing simple types. Simple type definitions appearing as children of a schema element are named types available for use elsewhere in the schema and in other schemas. Simple types may also appear as the children of element or attribute declarations or of other simple type definitions, in which case they are anonymous types local to the context in which they appear.
restriction
The list element appears as a child of the simpleType element and denotes that the simple type is a whitespace-delimited list of some other, atomic simple type. The simple type on which the list is based may be referred to using the itemType attribute or may be provided as an inline anonymous type in a simpleType child element. A list type
163
The Complete Reference To Professional SOA with Visual Studio 2005
Union
Empire Burlesque Bob Dylan USA Columbia 10.90 1985
The above xml document shows the output from listing 7-16 and listing 7-17.
273
The Complete Reference To Professional SOA with Visual Studio 2005
XPathNavigator In the previous section we had examined how to read and write XML Documents. In this section we will examine how to use XPath to access a node or a set of nodes. The .NET Framework provides the XPathNavigator class which contains the methods that we use to perform XPath queries on an XML document. XPath allows us to perform specific operations on a XML document through specific XPath expressions. These operations can manipulate strings, perform calculations and check for conditions. XPath treats a XML document as a tree that contains different types nodes of elements and attributes. We can create XPath expressions that identify specific nodes in the document based on their type, name and value. In addition, XPath expressions can identify relationships between nodes in a document.
XPath To execute XPath queries we need to first select a set of nodes to perform the XPath queries against. The Select method provided by the XPathNavigator object is used to select a set of nodes. The Select method is used to select a particular node which then returns an object of XPathNodeIterator class. We can use then use the XPathNodeIterator object to iterate through the selected nodes. In addition there are also several other select methods that can be used these are SelectChildren, SelectAncestors, SelectDecendents. The following example demonstrates how to iterate a set of nodes using the the XPathNavigator object. Listing 7-18. Demonstrates how to use XPath query to select a node usingVisual C# using System; using System.Collections.Generic; using System.Text; using System.Xml.XPath; namespace CSXMLXpath { class Program { static void Main(string[] args) { XPathDocument Doc = new XPathDocument("cd_catalog.xml"); XPathNavigator navigator = Doc.CreateNavigator(); XPathNodeIterator iterator = navigator.Select("/CATALOG/CD/TITLE"); while (iterator.MoveNext()) { Console.WriteLine(iterator.Current.Name + " -> " + iterator.Current.Value ); } Console.ReadLine(); } } }
Listing 7-19. Demonstrates how to use XPath query to select a node using Visual Basic .NET Imports System.Xml.XPath Module Module1
274
The Complete Reference To Professional SOA with Visual Studio 2005
Sub Main() Dim Doc As XPathDocument = New XPathDocument("cd_catalog.xml") Dim navigator As XPathNavigator = Doc.CreateNavigator Dim iterator As XPathNodeIterator = _ navigator.Select("/CATALOG/CD/TITLE") While iterator.MoveNext Console.WriteLine(iterator.Current.Name + " -> " + _ iterator.Current.Value) End While Console.ReadLine() End Sub End Module
Figure 7-2. shows the output from listing 7-18 and listing 7-19
Aside from the Select method, the XPathNavigator class also provide additional methods which can be used to select a set of nodes. These methods allow us to retrieve nodes faster than retrieving nodes using the corresponding XPath query. The optimized methods are: *
SelectChildren, which selects all the child nodes of the current node that match the selection criteria.
*
SelectAncestors, which selects all the ancestor nodes of the current node that have a matching XPathNodeType.
*
SelectDescendants - which selects all the descendant nodes of the current node that match the selection criteria.
*
and IsDescendant - Determines whether the specified XPathNavigator is a descendant of the current XPathNavigator.
Calling the above methods will not affect the state or position of the XPathNavigator object. All the methods return an XPathNodeIterator object with exception of IsDescendant which returns a Boolean value.
Table 7-6. Navigation Methods of the XPathNavigator Object
275
The Complete Reference To Professional SOA with Visual Studio 2005
Method
Description
MoveTo
This method allows us to move the XPathNavigator object to another node and make it the current position. The MoveTo method returns a Boolean value to indicate the success or failure of the movement.
MoveToNext
This method allows us to move the XPathNavigator object to the next sibling of the current node.
MoveToPrevious
This method allows us to move the XPathNavigator object to the previous sibling of the current node.
MoveToFirst
This method allows us to move the XPathNavigator object to the first sibling of the current node.
MoveToFirstChild
This method allows us to move the XPathNavigator object to the first child of the current node. We can use the MoveToFirstChild method only when the current node is the root node or is a node that has child nodes. If no child nodes exist then a Boolean value is returned indicating that the move had failed.
MoveToParent
This method allows us to move the XPathNavigator object to the parent node of the current node. We cannot call the MoveToParent method when the root node is the current node because the root node does not have a parent node.
MoveToRoot
This method allows us to move the XPathNavigator object to the root node.
MoveToId
This method allows us to move the XPathNavigator object to the node that has an ID attribute. You need to specify the ID of the node to which you want the XPathNavigator to move.
The XPath expression needs to be compiled first using the Compile method to convert the string representation to an XPathExpression object. Compiling allow us to cache the expression for improved performance and it also allows for verification to ensure the expression is valid. Once the expression is compiled we can pass in the compiled XPath expression object and use the Evaluate method. The Evaluate method takes the XPath expression and executes the expression against the XML document. It returns a typed result. We can use Evaluate to perform calculations. In the following example we have created an expression to calculate the sum of all prices in an XML document using Evaluate to execute. Listing 7-20. Demonstrates executing an XPath expression using Visual C# using System; using System.Collections.Generic; using System.Text; using System.Xml; using System.Xml.XPath; namespace CSXMLXpath2 { class Program { static void Main(string[] args)
276
The Complete Reference To Professional SOA with Visual Studio 2005
{ XmlDocument XPathDocument = new XmlDocument(); XPathDocument.Load("cd_catalog.xml"); XPathNavigator navigator = XPathDocument.CreateNavigator(); XPathExpression XPathExpr = navigator.Compile("sum(//PRICE/text())"); Console.WriteLine(navigator.Evaluate(XPathExpr)); Console.ReadLine(); } } }
Listing 7-21. Demonstrates executing an XPath expression using Visual Basic .NET Imports System.Xml Imports System.Xml.XPath Module Module1 Sub Main() Dim XPathDocument As XmlDocument = New XmlDocument XPathDocument.Load("cd_catalog.xml") Dim navigator As XPathNavigator = XPathDocument.CreateNavigator Dim XPathExpr As XPathExpression = navigator.Compile("sum(//PRICE/text())") Console.WriteLine(navigator.Evaluate(XPathExpr)) Console.ReadLine() End Sub End Module
In listing 7-20 and listing 7-21 we load the cd catalog xml document into XPathDocument. We then ask it to calculate the sum of all prices for the XML Document by compiling and evaluating through the query sum(//PRICE/text()).
Figure 7-3. Result from the evaluated XML document
XML Schema XSD In Chapter 5 we had examined XML Schemas. In this section we will read and write XML Schemas using .NET. A XML Schema is an XML file that is used to define the content and grammar of a XML file. The schema can then be used to validate the XML file. A file that complies to the requirements of its schema is called Valid. Listing 7-22 demonstrates an example of XML Schema. Listing 7-22. cd_catalog.xsd
277
The Complete Reference To Professional SOA with Visual Studio 2005
We can also programmatically create schemas using the Schema Object Model (SOM). SOM part of the System.Xml.Schema namespace consists of a set of classes that allow us to read and manipulate schema
278
The Complete Reference To Professional SOA with Visual Studio 2005
definitions. When we manipulate the schema, it resides in memory. We need to validate and compile the schema before we can write it to a file. Listing 7-23. Demonstrates creating a Schema programmtically using Visual C# using System; using System.Collections.Generic; using System.Text; using System.Xml; using System.Xml.Schema; using System.IO; namespace CSXMLXsd { class Program { static void Main(string[] args) { try { XmlTextReader reader = new XmlTextReader("cd_catalog.xsd"); XmlSchema myschema = XmlSchema.Read(reader, null); myschema.Write(Console.Out); Console.WriteLine("Press to exit."); Console.Read(); FileStream file = new FileStream("New.xsd", FileMode.Create, FileAccess.ReadWrite); XmlTextWriter xwriter = new XmlTextWriter(file, new UTF8Encoding()); xwriter.Formatting = Formatting.Indented; myschema.Write(xwriter); } catch (Exception e) { Console.WriteLine(e); } } } }
Listing 7-24. Demonstrates creating a Schema programmtically using Visual Basic .NET Imports System Imports System.Collections.Generic Imports System.Text Imports System.Xml Imports System.Xml.Schema Imports System.IO Module Module1 Sub Main()
279
The Complete Reference To Professional SOA with Visual Studio 2005
Try Dim reader As XmlTextReader = New XmlTextReader("cd_catalog.xsd") Dim myschema As XmlSchema = XmlSchema.Read(reader, Nothing) myschema.Write(Console.Out) Console.WriteLine("Press to exit.") Console.Read() Dim file As FileStream = _ New FileStream("New.xsd", FileMode.Create, FileAccess.ReadWrite) Dim xwriter As XmlTextWriter = New XmlTextWriter(file, New UTF8Encoding) xwriter.Formatting = Formatting.Indented myschema.Write(xwriter) Catch e As Exception Console.WriteLine(e) End Try End Sub End Module
XML Validation We can ensure that the XML documents that we create are well formed. Any XML parser can read a wellformed XML document. We should also ensure that the XML document matches its schema or conforms to the constraints defined by its DTD. For example, if we specify a specific data type or a specific range for a record then we need to ensure that the XML document must conform to the condition or it will be considered invalid. We can ensure the validity of a XML document by using the XmlValidatingReader class. The XmlValidatingReader class is a derived class of the XmlReader class and adds validation support to the XmlTextReader class. The XmlValidatingReader class provides the DTD, XML-Data Reduced (XDR), and XSD schema validation services that allow us to validate an XML document or a fragment of an XML document. The XmlValidatingReader class takes XmlTextReader as the input and applies the properties that we specify in the XmlTextReader class. Listing 7-25. Reading an XML document using XmlReader using Visual C# using System; using System.Collections.Generic; using System.Text; using System.Xml; using System.Xml.Schema; namespace CSXMLValidate { class Program { static void Main(string[] args) { XmlReader reader = XmlReader.Create("cd_catalog.xml");
280
The Complete Reference To Professional SOA with Visual Studio 2005
// Parse the file. while (reader.Read()) ; Console.ReadLine(); } } }
Listing 7-26. Reading an XML document using XmlReader using Visual Basic .NET Imports System.Xml Module Module1 Sub Main() Dim reader As XmlReader = XmlReader.Create("cd_catalog.xml") While reader.Read End While Console.ReadLine() End Sub End Module
In the above code we read in the cd_catalog.xml file using the XmlReader class. In the below example we will be using XmlSchemaSet to validate our CD catalog against an invalid Xml cd catalog document. First we will create an invalid Xml CD catalog document by injecting a SubTitle element into the document. Listing 7-27. cd_catalog_fail.xml which causes the validation to fail
This title should throw an error
Bob Dylan USA Columbia 10.90 1985
Hide your heart Bonnie Tyler UK CBS Records 9.90 1988
Greatest Hits Dolly Parton USA RCA 9.90
281
The Complete Reference To Professional SOA with Visual Studio 2005
1982
In our CD catalog schema file we have not catered for this new SubTitle element as a result it will fail the validation. Listing 7-28. cd_catalog.xsd schema file for the cd_catalog Xml documents
Listing 7-29. Validating the XML document against the Schema using Visual C# using System; using System.Collections.Generic;
282
The Complete Reference To Professional SOA with Visual Studio 2005
using System.Text; using System.Xml; using System.Xml.Schema; namespace CSXMLValidate2 { class Program { static void Main(string[] args) { // Create the XmlSchemaSet class. XmlSchemaSet sc = new XmlSchemaSet(); // Add the schema to the collection. sc.Add("urn:cd_Catalog-schema", "cd_catalog.xsd"); // Set the validation settings. XmlReaderSettings settings = new XmlReaderSettings(); settings.ValidationType = ValidationType.Schema; settings.Schemas = sc; settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack); // Create the XmlReader object. XmlReader reader = XmlReader.Create("cd_catalog_fail.xml", settings); // Parse the file. while (reader.Read()) ; Console.WriteLine("__________________"); Console.WriteLine("Parse complete!"); Console.ReadLine(); } // Display any warnings or errors. private static void ValidationCallBack (object sender, ValidationEventArgs args) { if (args.Severity == XmlSeverityType.Warning) Console.WriteLine("\tWarning: Matching schema not found." + " No validation occurred." + args.Message); else Console.WriteLine("\tValidation error: " + args.Message); } } }
Listing 7-30. Validating the XML document against the Schema using Visual Basic .NET Imports System Imports System.Collections.Generic Imports System.Text Imports System.Xml
283
The Complete Reference To Professional SOA with Visual Studio 2005
Imports System.Xml.Schema Module Module1 Sub Main() Dim sc As XmlSchemaSet = New XmlSchemaSet sc.Add("urn:cd_Catalog-schema", "cd_catalog.xsd") Dim settings As XmlReaderSettings = New XmlReaderSettings settings.ValidationType = ValidationType.Schema settings.Schemas = sc AddHandler settings.ValidationEventHandler, AddressOf ValidationCallBack Dim reader As XmlReader = XmlReader.Create("cd_catalog_fail.xml", settings) While reader.Read End While Console.WriteLine("__________________") Console.WriteLine("Parse complete!") Console.ReadLine() End Sub Private Sub ValidationCallBack(ByVal sender As Object, _ ByVal args As ValidationEventArgs) If args.Severity = XmlSeverityType.Warning Then Console.WriteLine("Warning: Matching schema not found." + _ " No validation occurred." + args.Message) Else Console.WriteLine("Validation error: " + args.Message) End If End Sub End Module
Note: In the listing above an error will be thrown. This is because that the XML file cannot be validated against the schema.
After we load the Xml schema using XmlSchemaSet’s Add function where we specify the namespace and the xsd document, we use the ValidationType property to specify the type of validations that we want to perform on that document. The default value of ValidationType is Auto. The other values for this property can be DTD, Schema, XDR, and None.
XML and DataSet In Chapter 6 we learned about ADO.NET DataSets. They’re an important part of ADO.NET and is a vital part of .NET development. A DataSet stores data that is obtained from a data source. This data source can be any source, such as a relational database or an XML document. A DataSet can either be typed or untyped. A typed DataSet is a class that is derived from a DataSet class and has an associated XML Schema. On the other hand, an untyped DataSet does not have an XML Schema associated with it. Table 7-7. A DataSet has the following XML related methods.
284
The Complete Reference To Professional SOA with Visual Studio 2005
Method
Description
GetXml
This method allows us to retrieve the XML representation of the data stored in a DataSet in a string variable.
GetXmlSchema
This method allows us to retrieve the XSD schema for the XML representation of the data stored in the DataSet.
InferXmlSchema
This method allows us to extrapolate the structure of data in the DataSet by using the schema provided in the TextReader, XMLReader, or Stream object.
ReadXml
This method reads the XML data and schema into the DataSet.
ReadXmlSchema
This method allows us to read XML Schema into the DataSet.
WriteXml
This method allows us to write the data of the DataSet into an XML file.
WriteXmlSchema
This method allows us to write the data in the DataSet into an XML Schema.
In ADO.NET we have the option to save a DataSet as a XML file and also save its XML schema to a file. While vice-versa we can also read an XML schema back into a DataSet and load XML file as data into the DataSet. To save the content of the DataSet into an XML document we use the WriteXml() method. While to save its schema we would use the WriteXmlSchema() method.
NOTE: The connectionstring used in each of these examples may vary depending on your Sql Server Database setup.
Listing 7-31. Writing the data and schema to XML files using Visual C# using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Data.SqlClient; namespace csDataSet { class Program { static void Main(string[] args) { SqlConnection sqlcon = new SqlConnection( "Data Source=DEVSERVER\\;Initial Catalog=AdventureWorks;"+ "Integrated Security=True");
285
The Complete Reference To Professional SOA with Visual Studio 2005
sqlcon.Open(); SqlDataAdapter sqladapter = new SqlDataAdapter( "select * from HumanResources.Employee", sqlcon); DataSet employeeDS = new DataSet(); sqladapter.Fill(employeeDS, "EmployeeTable"); int rowcnt = employeeDS.Tables["EmployeeTable"].Rows.Count; employeeDS.WriteXml("EmployeeTable.xml"); employeeDS.WriteXmlSchema("EmployeeTableSchema.xml"); Console.WriteLine(rowcnt.ToString()); Console.ReadLine(); sqlcon.Close(); } } }
Listing 7-32. Writing the data and schema to XML files using Visual Basic .NET Imports System.Data Imports System.Data.SqlClient Module Module1 Sub Main() Dim sqlcon As SqlConnection = New SqlConnection( _ "Data Source=DEVSERVER\;Initial Catalog=AdventureWorks;" + _ "Integrated Security=True") sqlcon.Open() Dim sqladapter As SqlDataAdapter = New SqlDataAdapter( _ "select * from HumanResources.Employee", sqlcon) Dim employeeDS As DataSet = New DataSet sqladapter.Fill(employeeDS, "EmployeeTable") Dim rowcnt As Integer = _ employeeDS.Tables("EmployeeTable").Rows.Count employeeDS.WriteXml("EmployeeTable.xml") employeeDS.WriteXmlSchema("EmployeeTableSchema.xml") Console.WriteLine(rowcnt.ToString) Console.ReadLine() sqlcon.Close() End Sub End Module
In the listing above we first retrieve the data from the Employee table then will use Fill to enter the data into the dataset. Once the DataSet is filled we can write out the data contained in the DataSet into the XML document using the WriteXml() method, we can then write out the Schema using WriteXmlSchema(). Listing 7-33. This is the EmployeeTable.xml document that was created.
1
286
The Complete Reference To Professional SOA with Visual Studio 2005
14417807 1209 adventure-works\guy1 16 Production Technician - WC60 1972-05-15T00:00:00+10:00 M M 1996-07-31T00:00:00+10:00 false 21 30 true aae1d04a-c237-4974-b4d5-935247737718 2004-07-31T00:00:00+10:00
. . .
Listing 7-34. The EmployeeTableSchema.xml document that was created
287
The Complete Reference To Professional SOA with Visual Studio 2005
Similarly we can write the XML data representation of the DataSet directly into a string. Listing 7-35. Writing the XML representation of DataSet into a string using Visual C# String XmlData; XmlData = employeeDS.GetXml();
Listing 7-36. Writing the XML representation of DataSet into a string using Visual Basic .NET Dim XmlData As String XmlData = employeeDS.GetXml()
We can also read the data back into the DataSet by using ReadXml() method. The schema can also be read back using ReadXmlSchema(). Listing 7-37. Reading the the schema and the XML document containing data back into the DataSet using Visual C# using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Data.SqlClient; namespace CSDataSetRead { class Program { static void Main(string[] args) { DataSet employeeDS = new DataSet(); employeeDS.ReadXmlSchema("EmployeeTableSchema.xml"); employeeDS.ReadXml("EmployeeTable.xml"); int rowcnt = employeeDS.Tables["EmployeeTable"].Rows.Count; Console.WriteLine(rowcnt.ToString()); Console.ReadLine(); } } }
Listing 7-38. Reading the the schema and the XML document containing data back into the DataSet using Visual Basic .NET Imports System.Data Imports System.Data.SqlClient
288
The Complete Reference To Professional SOA with Visual Studio 2005
Module Module1 Sub Main() Dim employeeDS As DataSet = New DataSet employeeDS.ReadXmlSchema("EmployeeTableSchema.xml") employeeDS.ReadXml("EmployeeTable.xml") Dim rowcnt As Integer = _ employeeDS.Tables("EmployeeTable").Rows.Count Console.WriteLine(rowcnt.ToString) Console.ReadLine() End Sub End Module
Summary In this chapter we have examined how to access and manipulate XML document using .NET. As all modern systems today can understand and work with XML document it is therefore important part of our development towards an interoperable architecture. We have looked XML DOM. XML DOM is a representation of the XML document in memory. The DOM class allows us to read and write, and manipulate an XML document. The DOM class contains a set of libraries which allow us to navigate through the XML document to the relevant information. We have also learnt to write an XML Parser in .NET using XmlDocument. We have looked at Reading and Writing XML using XmlTextReader and XmlTextWriter. Both classes provide fast access to XML data. XmlTextReader class should be used when we don’t need to read the entire document into memory. While the XmlTextWriter a derived class of XmlWriter, allows us to create XML streams and write data to well-formed XML documents. We have also examine utilizing XPath queries in our XML documents. In our XML document we can use XPath to access a particular node. We can also perform XPath queries on an XML document within .NET. We have looked at validating an XML document through using a XML Schema. This ensures that the XML document conforms to its schema. Lastly we looked at the XML options that the ADO.NET DataSet provided which allowed us to save a DataSet and its schema as XML. Vice versa we could also read the XML schema and the XML document back into the DataSet.
289
The Complete Reference To Professional SOA with Visual Studio 2005
Chapter 8 .NET XML Serialization Serialization is a process through which an object's state is transformed into some serial data format, such as a XML or a binary format, so that it can be sent over the Internet or be stored in a file so that it can be retrieved at a later date. In XML Web services serialization plays a vital part of interoperability between services. It allows information to be converted into a transportable format. The .NET Framework uses XML serialization extensively to facilitate communication between two XML Web services. The .NET XML serialization model is responsible for serializing and deserializing XML instances of .NET types to and from XML. XML serialization is also responsible for serializing .NET type definitions to XML schemas and deserializing XML schemas to .NET type definitions. In this chapter we will be looking at serialization using Binary and Soap formatters as well as XML serialization and customizing serialization handling in .NET.
.NET Serialization .NET serialization performs a key role in facilitating communication in the .NET Remoting and .NET XML Web services infrastructure. The serialization process reduces objects into a transportable representation that can be sent across the wire or stored on disk.
Enable Serialization using Attributes In .NET not all objects are serializable. The simplest way to support serialization is to include our class with a Serializable attribute. In listing 8-1 and listing 8-2 we have included our class with a Serializable attribute. This allows the class to be serialized. Listing 8-1. Enabling serializable for SerializableClass using Visual C# [Serializable] public class SerializableClass { private string _name; public string Name { get { return _name; } set { _name = value; } } private string zipCode; public string ZipCode { get { return _zipCode; }
290
The Complete Reference To Professional SOA with Visual Studio 2005
set { _zipCode = value; } } }
Listing 8-2. Enabling serializable for SerializableClass using Visual Basic .NET _ Public Class SerializableClass Private _name As String Public Property Name() As String Get Return _name End Get Set _name = value End Set End Property Private _zipCode As Integer Public Property ZipCode() As String Get Return _zipCode End Get Set _zipCode = value End Set End Property End Class
By default, all members of a class that is marked as Serializable can be serialized. However we can also restrict this behavior by attaching NonSerialized attribute to certain fields. For example we could specify not to serialize ZipCode’s value in which case we would add the attribute in front of the zipCode field . See Listing 8-3 and Listing 8-4 below. Listing 8-3. disable serialization for ZipCode using NonSerialized attribute in Visual C# [NonSerialized()] private string _zipCode; public string ZipCode { get { return _zipCode; } set { _zipCode = value; } }
Listing 8-4. disable serialization for ZipCode using NonSerialized attribute in Visual Basic .NET Private _zipCode As Integer Public Property ZipCode() As String Get
291
The Complete Reference To Professional SOA with Visual Studio 2005
Return _zipCode End Get Set(ByVal value As String) _zipCode = value End Set End Property
Serialization Formatter .NET offers us two forms of serialization, Binary and SOAP. Binary, form of serialization is more compact and provides as an excellent model performance wise. The SOAP format allows us to serialize data into a readable form. This is achieved through the use of a formatter. The formatter helps to determine the serialized format for the objects that we serialize. To serialize into a Binary format we need to use the .NET BinaryFormatter class which is a part of the System.Runtime.Serialization.Formatters.Binary namespace. The BinaryFormatter provides ability to encode objects into a compact binary format. We need to provide a stream containing the objects to serialize to the BinaryFormatter see listing 8-5 and listing 8-6 below. Listing 8-5. Serializing objects to file using Binary formatter in Visual C# using System; using System.Collections.Generic; using System.Text; using System.Runtime.Serialization.Formatters.Binary; using System.IO; namespace CSBinarySerialization { [Serializable] public class SerializableClass { private string _name; public string Name { get { return _name; } set { _name = value; } } private int _zipCode; public int ZipCode { get { return _zipCode; } set { _zipCode = value; } } } class Program { static void Main(string[] args) {
292
The Complete Reference To Professional SOA with Visual Studio 2005
SerializableClass sc = new SerializableClass(); sc.Name = "John Doe"; sc.ZipCode = 2000; SerializeToFile(sc, "SerializedObj.bin"); //read the object back from file SerializableClass deserializedobj = DeserializeFromFile("SerializedObj.bin"); Console.WriteLine("Name: " + deserializedobj.Name); Console.WriteLine("ZipCode: " + deserializedobj.ZipCode); Console.ReadLine(); } public static void SerializeToFile(SerializableClass obj, String filename) { Stream str = File.OpenWrite(filename); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(str, obj); str.Close(); } public static SerializableClass DeserializeFromFile(String filename) { Stream reader = File.OpenRead(filename); BinaryFormatter formatter = new BinaryFormatter(); SerializableClass obj = (SerializableClass)formatter.Deserialize(reader); reader.Close(); return obj; } } }
Listing 8-6. Serializing objects to file using Binary formatter in Visual Basic .NET Imports System Imports System.Collections.Generic Imports System.Text Imports System.Runtime.Serialization.Formatters.Binary Imports System.IO Namespace VBBinarySerialization _ Public Class SerializableClass Private _name As String Public Property Name() As String Get Return _name End Get Set(ByVal value As String) _name = value End Set End Property
293
The Complete Reference To Professional SOA with Visual Studio 2005
Private _zipCode As Integer Public Property ZipCode() As Integer Get Return _zipCode End Get Set(ByVal value As Integer) _zipCode = value End Set End Property End Class Class Program Shared Sub Main(ByVal args As String()) Dim sc As SerializableClass = New SerializableClass sc.Name = "John Doe" sc.ZipCode = 2000 SerializeToFile(sc, "SerializedObj.bin") Dim deserializedobj As SerializableClass = _ DeserializeFromFile("SerializedObj.bin") Console.WriteLine("Name: " + deserializedobj.Name) Console.WriteLine("ZipCode: " + _ deserializedobj.ZipCode.ToString()) Console.ReadLine() End Sub Public Shared Sub SerializeToFile(ByVal obj As SerializableClass, _ ByVal filename As String) Dim str As Stream = File.OpenWrite(filename) Dim formatter As BinaryFormatter = New BinaryFormatter formatter.Serialize(str, obj) str.Close() End Sub Public Shared Function DeserializeFromFile(ByVal filename As String) _ As SerializableClass Dim reader As Stream = File.OpenRead(filename) Dim formatter As BinaryFormatter = New BinaryFormatter Dim obj As SerializableClass = _ CType(formatter.Deserialize(reader), SerializableClass) reader.Close() Return obj End Function End Class End Namespace
In the above example we have created a SerializableClass which includes the Serializable attribute. This allows the class to be serialized. We then set values for the SerializableClass object which we then pass to the BinaryFormatter as well as an open stream to a file which we will be writing the result to. Using the Serialize method the BinaryFormatter then saves the values into the file SerializedObj.bin.
294
The Complete Reference To Professional SOA with Visual Studio 2005
To deserialize the SerializeObj.bin file we use the deserialize method from the BinaryFormatter object. After the object has been deserialized we need to cast the object back to a particular type before we can access its value. The result from the deserialization can be seen in the image figure 8-1 below.
Figure 8-1. Deserialized object
If we open the file in Visual Studio’s binary editor we can see that the information that we had assigned to the object has been serialized to a binary format. See figure 8-2 below.
Figure 8-2. SerializedObj.bin
To serialize using the SOAP formatter we need to use the .NET SoapFormatter class which is a part of the System.Runtime.Serialization.Formatters.Soap Namespace. The SoapFormatter allows objects to be serialized
using the SOAP protocol into a ascii format that can be transferred over the web. Using the SoapFormatter class is similar to the BinaryFormatter class see listing 8-7 and listing 8-8 below.
Tip: To use SOAP formatter we will need to add reference to SOAP formatter we can do this by selecting the References node in the Solution Explorer right click and select “Add Reference”. Then under the .NET tab browse to the System.Runtime.Serialization.Formatters.Soap component.
Listing 8-7. Implementing SoapFormatter in Visual C# using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Runtime.Serialization.Formatters.Soap;
295
The Complete Reference To Professional SOA with Visual Studio 2005
namespace CSSOAPFormatter { [Serializable] public class SerializableClass { private string _name; public string Name { get { return _name; } set { _name = value; } } private int _zipCode; public int ZipCode { get { return _zipCode; } set { _zipCode = value; } } } class Program { static void Main(string[] args) { SerializableClass sc = new SerializableClass(); sc.Name = "John Doe"; sc.ZipCode = 2000; SerializeToFile(sc, "SerializedObj.soap"); //read the object back from file SerializableClass deserializedobj = DeserializeFromFile("SerializedObj.soap"); Console.WriteLine("Name: " + deserializedobj.Name); Console.WriteLine("ZipCode: " + deserializedobj.ZipCode); Console.ReadLine(); } public static void SerializeToFile(SerializableClass obj, String filename) { Stream str = File.OpenWrite(filename); SoapFormatter formatter = new SoapFormatter(); formatter.Serialize(str, obj); str.Close(); } public static SerializableClass DeserializeFromFile(String filename) { Stream reader = File.OpenRead(filename); SoapFormatter formatter = new SoapFormatter();
296
The Complete Reference To Professional SOA with Visual Studio 2005
SerializableClass obj = (SerializableClass)formatter.Deserialize(reader); reader.Close(); return obj; } } }
Listing 8-8. Implementing SoapFormatter in Visual Basic .NET Imports System Imports System.Collections.Generic Imports System.Text Imports System.IO Imports System.Runtime.Serialization.Formatters.Soap Namespace VBSOAPFormatter _ Public Class SerializableClass Private _name As String Public Property Name() As String Get Return _name End Get Set(ByVal value As String) _name = value End Set End Property Private _zipCode As Integer Public Property ZipCode() As Integer Get Return _zipCode End Get Set(ByVal value As Integer) _zipCode = value End Set End Property End Class Class Program Shared Sub Main(ByVal args As String()) Dim sc As SerializableClass = New SerializableClass sc.Name = "John Doe" sc.ZipCode = 2000 SerializeToFile(sc, "SerializedObj.soap") Dim deserializedobj As SerializableClass = _ DeserializeFromFile("SerializedObj.soap") Console.WriteLine("Name: " + deserializedobj.Name) Console.WriteLine("ZipCode: " + _ deserializedobj.ZipCode.ToString()) Console.ReadLine()
297
The Complete Reference To Professional SOA with Visual Studio 2005
End Sub Public Shared Sub SerializeToFile(ByVal obj As SerializableClass, _ ByVal filename As String) Dim str As Stream = File.OpenWrite(filename) Dim formatter As SoapFormatter = New SoapFormatter formatter.Serialize(str, obj) str.Close() End Sub
Public Shared Function DeserializeFromFile(ByVal filename As String) _ As SerializableClass Dim reader As Stream = File.OpenRead(filename) Dim formatter As SoapFormatter = New SoapFormatter Dim obj As SerializableClass = _ CType(formatter.Deserialize(reader), SerializableClass) reader.Close() Return obj End Function End Class End Namespace
Using SOAP formatter is very similar to using the Binary formatter. In the above example we have created a SerializableClass which is decorated with a Serializable attribute. This allows the class to be serialized. We then set values for the SerializableClass object. We then pass this object to the SoapFormatter as well as an open stream to a file which we will be writing the result to. The SoapFormatter the saves the values into the file SerializedObj.soap. To serialize we use the Serialize method from the SoapFormatter object. To deserialize we use the Deserialize method from the SoapFormatter object. Listing 8-9. SerializedObj.soap
John Doe 2000
In the listing above we can see that the SerializedObj.soap contains the serialized values of the object in a SOAP format.
298
The Complete Reference To Professional SOA with Visual Studio 2005
XML Serialization In the previous section we have examined how to serialize objects into binary files and soap files. There is also another means of serialization which translates serializable objects into XML files. The ASP.NET XML Web service relies on XML serialization heavily to serialize instances of .NET types to XML and then deserialize them from XML back to instances of .NET types. Through XML serialization applications can interoperate with one another. To serialize objects into XML document we need to use the XMLSerializer class from the System.Xml.Serialization namespace. In the following example we have serialized the SerializableClass to XML. Listing 8-10. Implementing XmlSerializer using Visual C# using System; using System.Collections.Generic; using System.Text; using System.Xml.Serialization; using System.IO; namespace CSXMLSerialize { public class SerializableClass { private string _name; public string Name { get { return _name; } set { _name = value; } } private int _zipCode; public int ZipCode { get { return _zipCode; } set { _zipCode = value; } } } class Program { static void Main(string[] args) { SerializableClass sc = new SerializableClass(); sc.Name = "John Doe"; sc.ZipCode = 2000; //serialize the object to file SerializeToFile(sc, "SerializedObj.xml"); //read the object back from file SerializableClass deserializedobj = DeserializeFromFile("SerializedObj.xml"); Console.WriteLine("Name: " + deserializedobj.Name);
299
The Complete Reference To Professional SOA with Visual Studio 2005
Console.WriteLine("ZipCode: " + deserializedobj.ZipCode); Console.ReadLine(); } public static void SerializeToFile(SerializableClass obj, String filename) { Stream str = File.OpenWrite(filename); XmlSerializer xmlserial = new XmlSerializer (typeof(SerializableClass)); xmlserial.Serialize(str, obj); str.Close(); } public static SerializableClass DeserializeFromFile(string filename) { TextReader reader = new StreamReader(filename); XmlSerializer xmlserial = new XmlSerializer (typeof(SerializableClass)); SerializableClass obj = (SerializableClass)xmlserial.Deserialize(reader); reader.Close(); return obj; } } }
Listing 8-11. Implementing XmlSerializer using Visual Basic .NET Imports System Imports System.Collections.Generic Imports System.Text Imports System.Xml.Serialization Imports System.IO Namespace VBXMLSerialize Public Class SerializableClass Private _name As String Public Property Name() As String Get Return _name End Get Set(ByVal value As String) _name = value End Set End Property Private _zipCode As Integer Public Property ZipCode() As Integer Get Return _zipCode End Get
300
The Complete Reference To Professional SOA with Visual Studio 2005
Set(ByVal value As Integer) _zipCode = value End Set End Property End Class Class Program Shared Sub Main(ByVal args As String()) Dim sc As SerializableClass = New SerializableClass sc.Name = "John Doe" sc.ZipCode = 2000 'serialize to file SerializeToFile(sc, "SerializedObj.xml") 'deserialize from file Dim deserializedobj As SerializableClass = _ DeserializeFromFile("SerializedObj.xml") Console.WriteLine("Name: " + deserializedobj.Name) Console.WriteLine("ZipCode: " + _ deserializedobj.ZipCode.ToString()) Console.ReadLine() End Sub Public Shared Sub SerializeToFile(ByVal obj As SerializableClass, _ ByVal filename As String) Dim str As Stream = File.OpenWrite(filename) Dim xmlserial As XmlSerializer = _ New XmlSerializer(GetType(SerializableClass)) xmlserial.Serialize(str, obj) str.Close() End Sub Public Shared Function DeserializeFromFile(ByVal filename As String) _ As SerializableClass Dim reader As TextReader = New StreamReader(filename) Dim xmlserial As XmlSerializer = New XmlSerializer _ (GetType(SerializableClass)) Dim obj As SerializableClass = _ CType(xmlserial.Deserialize(reader), SerializableClass) reader.Close() Return obj End Function End Class End Namespace
Serializing using XmlSerializer is similar to using Binary and SOAP formatter. To serialize use the Serialize method from the XmlSerializer object and to deserialize use the Deserialize method from XmlSeializer object. The result of the XML serialization is that the objects are saved to a XML file see listing 8-12. As we can see the objects are serialized to a format that corresponds to the structure of the object. Listing 8-12. Representation of the SerializableClass in SerializedObj.xml
John Doe 2000
Controlling Serialization Serialization is automatic. We don’t need to implement anything in code for serialization and deserialization to occur. It is all taken care of by the .NET runtime. However, sometimes the default serialization and deserialization process do not meet our requirements. In these instances we need to take control in order to customize serialization to our needs. .NET provides a mechanism for altering the way .NET types are serialized to XML. We can do this by using the attributes defined in the System.Xml.Serialization namespace. See Table 8-1for commonly used attributes. Table 8-1: lists attributes defined by the System.Xml.Serialization namespace
Name
Description
XmlAnyAttribute
Gets or sets the XmlAnyAttributeAttribute to override.
XmlAnyElements
Gets the collection of XmlAnyElementAttribute objects to override.
XmlArray
Gets or sets an object that specifies how the XmlSerializer serializes a public field or read/write property that returns an array.
XmlArrayItems
Gets or sets a collection of objects that specify how the XmlSerializer serializes items inserted into an array returned by a public field or read/write property.
XmlAttribute
Gets or sets an object that specifies how the XmlSerializer serializes a public field or public read/write property as an XML attribute.
XmlChoiceIdentifier Gets or sets an object that allows you to distinguish between a set of choices. XmlDefaultValue
Gets or sets the default value of an XML element or attribute.
XmlElements
Gets a collection of objects that specify how the XmlSerializer serializes a public field or read/write property as an XML element.
XmlEnum
Gets or sets an object that specifies how the XmlSerializer serializes an enumeration member.
XmlIgnore
Gets or sets a value that specifies whether or not the XmlSerializer serializes a public field or public read/write property.
Xmlns
Gets or sets a value that specifies whether to keep all namespace declarations when an object containing a member that returns an XmlSerializerNamespaces object is overridden.
XmlRoot
Gets or sets an object that specifies how the XmlSerializer serializes a class as an XML root element.
XmlText
Gets or sets an object that instructs the XmlSerializer to serialize a public field or public read/write property as XML text.
XmlType
Gets or sets an object that specifies how the XmlSerializer serializes a class to which the XmlTypeAttribute has been applied.
302
The Complete Reference To Professional SOA with Visual Studio 2005
XmlRoot and XmlElement The first attribute that we need to specify is the XmlRoot attribute. The Root Attribute will represent the root element within the body of the message. We can then use XmlElement attribute to define the elements in the XML. Using serialization attributes we can define how the class is to be serialized and in fact change the behavior of the serialization if required. In the following example we will rename the attributes of Name and ZipCode in the SerializableClass object. By controlling the serialization process we will change the name of each of the attribute of the XML file generated see listing 8-13and listing 8-14.
Tip: We can use the word XmlElement in our code instead of the longer XmlElementAttribute.
Listing 8-13. Implementing XmlRoot and XmlElement attributes using Visual C# using System; using System.Collections.Generic; using System.Text; using System.Xml.Serialization; using System.IO; namespace CSXMLSerialize2 { [XmlRoot("NewRootName", Namespace="http://www.CustomNamespace.com", IsNullable=true)] public class SerializableClass { private string _name; [XmlElement("NewElementName")] public string Name { get { return _name; } set { _name = value; } } private int _zipCode; [XmlElement("NewElementZip")] public int ZipCode { get { return _zipCode; } set { _zipCode = value; } } } class Program { static void Main(string[] args) {
303
The Complete Reference To Professional SOA with Visual Studio 2005
SerializableClass sc = new SerializableClass(); sc.Name = "John Doe"; sc.ZipCode = 2000; //serialize the object to file SerializeToFile(sc, "SerializedObj.xml"); //read the object back from file SerializableClass deserializedobj = DeserializeFromFile("SerializedObj.xml"); Console.WriteLine("Name: " + deserializedobj.Name); Console.WriteLine("ZipCode: " + deserializedobj.ZipCode); Console.ReadLine(); } public static void SerializeToFile(SerializableClass obj, String filename) { Stream str = File.OpenWrite(filename); XmlSerializer xmlserial = new XmlSerializer (typeof(SerializableClass)); xmlserial.Serialize(str, obj); str.Close(); } public static SerializableClass DeserializeFromFile(string filename) { TextReader reader = new StreamReader(filename); XmlSerializer xmlserial = new XmlSerializer (typeof(SerializableClass)); SerializableClass obj = (SerializableClass)xmlserial.Deserialize(reader); reader.Close(); return obj; } } }
Listing 8-14. Implementing XmlRoot and XmlElement attributes using Visual Basic .NET Imports System Imports System.Collections.Generic Imports System.Text Imports System.Xml.Serialization Imports System.IO Namespace VBXMLSerialize2 _ Public Class SerializableClass Private _name As String
304
The Complete Reference To Professional SOA with Visual Studio 2005
_ Public Property Name() As String Get Return _name End Get Set(ByVal value As String) _name = value End Set End Property Private _zipCode As Integer _ Public Property ZipCode() As Integer Get Return _zipCode End Get Set(ByVal value As Integer) _zipCode = value End Set End Property End Class Class Program Shared Sub Main(ByVal args As String()) Dim sc As SerializableClass = New SerializableClass sc.Name = "John Doe" sc.ZipCode = 2000 SerializeToFile(sc, "SerializedObj.xml") Dim deserializedobj As SerializableClass = _ DeserializeFromFile("SerializedObj.xml") Console.WriteLine("Name: " + deserializedobj.Name) Console.WriteLine("ZipCode: " + _ deserializedobj.ZipCode.ToString()) Console.ReadLine() End Sub Public Shared Sub SerializeToFile(ByVal obj As SerializableClass, _ ByVal filename As String) Dim str As Stream = File.OpenWrite(filename) Dim xmlserial As XmlSerializer = _ New XmlSerializer(GetType(SerializableClass)) xmlserial.Serialize(str, obj) str.Close() End Sub Public Shared Function DeserializeFromFile(ByVal filename As String) _ As SerializableClass Dim reader As TextReader = New StreamReader(filename) Dim xmlserial As XmlSerializer = _ New XmlSerializer(GetType(SerializableClass)) Dim obj As SerializableClass = _
305
The Complete Reference To Professional SOA with Visual Studio 2005
CType(xmlserial.Deserialize(reader), SerializableClass) reader.Close() Return obj End Function End Class End Namespace
The example creates a XML file that is shown in the listing 8-15 below. Listing 8-15. The new SerializedObj.xml
John Doe 2000
Compare this xml with the previous xml without using XmlRoot and XmlElement see listing 8-16 below. Listing 8-16. The old SerializedObj.xml without using XmlRoot and XmlElement
John Doe 2000
As we can see there is a difference between the XML file generated. This is because using XmlRoot and XmlElement we can control the way XML document is serialized. In the above example we have specified an XmlRoot name NewRootName this changes the original name SerializableClass to NewRootName. Similarly using XmlElement we have changed the element name of Name and ZipCode to NewElementName and NewElementZip respectively. One property to note is XmlRoot’s IsNullable attribute. Using this attribute we can specify whether the XML serialization will allow null value. Table 8-2. below describes some of the possible properties of the XmlRoot attribute. Table 8-2: Describes the properties exposed by the XmlRootAttribute.
Name
Description
DataType
Gets or sets the XSD data type of the XML root element.
ElementName Gets or sets the name of the XML element that is generated and recognized by the XmlSerializer class's Serialize and Deserialize methods, respectively. IsNullable
Gets or sets a value that indicates whether the XmlSerializer must serialize a member that is set to a null reference (Nothing in Visual Basic) .
306
The Complete Reference To Professional SOA with Visual Studio 2005
Namespace
Gets or sets the namespace for the XML root element.
TypeId
When implemented in a derived class, gets a unique identifier for this Attribute.
The XmlElement attribute also exposes additional properties that we can use to control how a .NET type is serialized to XML. Table 8-3: properties of XmlElementAttribute.
Name
Description
DataType
Gets or sets the XML Schema definition (XSD) data type of the XML element generated by the XmlSerializer.
ElementName Gets or sets the name of the generated XML element. Form
Gets or sets a value that indicates whether the element is qualified.
IsNullable
Gets or sets a value that indicates whether the XmlSerializer must serialize a member that is set to a null reference (Nothing in Visual Basic) as an empty tag with the xsi:nil attribute set to true.
Namespace
Gets or sets the namespace assigned to the XML element that results when the class is serialized.
Order
Gets or sets the explicit order in which the elements are serialized or deserialized.
Type
Gets or sets the object type used to represent the XML element.
TypeId
When implemented in a derived class, gets a unique identifier for this Attribute.
The XmlElementAttribute can be applied several times to a particular entity. This is useful when we need to specify an array of objects. This will specify through the Type property different types of values that can be used within the array. See listing 8-17 and listing 8-18 for an array that accepts both string and integer. Listing 8-17. Multiple XmlElement using Visual C# public class Things { [XmlElement(DataType = "string", Type = typeof(string)), XmlElement(DataType = "int", Type = typeof(int))] public object[] StringsAndInts; } Listing 8-18. Multiple XmlElement using Visual Basic .NET Public Class Things _
307
The Complete Reference To Professional SOA with Visual Studio 2005
Public StringsAndInts As Object() End Class
This results in XML with the following structure.
Hello 999 World
In the following example we will be applying an XmlElement attribute to an array, this instructs the XmlSerializer to serialize the array as a series of XML elements, instead of a nested set of elements. The example uses an a organization which contains a particular group located in a building. Each group contains a manager and employees. See Listing 8-19 and listing 8-20. Listing 8-19. Implementing XmlElement for array using Visual C# using System; using System.Collections; using System.IO; using System.Xml.Serialization; public class Group { [XmlElement( ElementName = "Members", Namespace = "http://www.cpandl.com")] public Employee[] Employees; [XmlElement(DataType = "double", ElementName = "Building")] public double GroupID; [XmlElement(DataType = "hexBinary")] public byte [] HexBytes; [XmlElement(DataType = "boolean")] public bool IsActive; [XmlElement(Type = typeof(Manager))] public Employee Manager; [XmlElement(typeof(int), ElementName = "ObjectNumber"), XmlElement(typeof(string), ElementName = "ObjectString")] public ArrayList ExtraInfo; } public class Employee { public string Name;
308
The Complete Reference To Professional SOA with Visual Studio 2005
} public class Manager:Employee{ public int Level; } public class Run { public static void Main() { Run test = new Run(); test.SerializeObject("FirstDoc.xml"); test.DeserializeObject("FirstDoc.xml"); }
public void SerializeObject(string filename) { // Create the XmlSerializer. XmlSerializer s = new XmlSerializer(typeof(Group)); // To write the file, a TextWriter is required. TextWriter writer = new StreamWriter(filename); /* Create an instance of the group to serialize, and set its properties. */ Group group = new Group(); group.GroupID = 10.089f; group.IsActive = false; group.HexBytes = new byte[1]{Convert.ToByte(100)}; Employee x = new Employee(); Employee y = new Employee(); x.Name = "Jack"; y.Name = "Jill"; group.Employees = new Employee[2]{x,y}; Manager mgr = new Manager(); mgr.Name = "Sara"; mgr.Level = 4; group.Manager = mgr; /* Add a number and a string to the ArrayList returned by the ExtraInfo property. */ group.ExtraInfo = new ArrayList(); group.ExtraInfo.Add(42); group.ExtraInfo.Add("Answer"); // Serialize the object, and close the TextWriter. s.Serialize(writer, group);
309
The Complete Reference To Professional SOA with Visual Studio 2005
writer.Close(); } public void DeserializeObject(string filename) { FileStream fs = new FileStream(filename, FileMode.Open); XmlSerializer x = new XmlSerializer(typeof(Group)); Group g = (Group) x.Deserialize(fs); Console.WriteLine(g.Manager.Name); Console.WriteLine(g.GroupID); Console.WriteLine(g.HexBytes[0]); foreach(Employee e in g.Employees) { Console.WriteLine(e.Name); } } }
Listing 8-20. Implementing XmlElement for array using Visual Basic .NET Imports System Imports System.Collections Imports System.IO Imports System.Xml.Serialization
Public Class Group ' Set the element name and namespace of the XML element. _ Public Employees() As Employee _ Public GroupID As Double _ Public HexBytes() As Byte _ Public IsActive As Boolean _ Public Manager As Employee _ Public ExtraInfo As ArrayList End Class Public Class Employee
310
The Complete Reference To Professional SOA with Visual Studio 2005
Public Name As String End Class Public Class Manager Inherits Employee Public Level As Integer End Class Public Class Run Public Shared Sub Main() Dim test As New Run() test.SerializeObject("FirstDoc.xml") test.DeserializeObject("FirstDoc.xml") End Sub Public Sub SerializeObject(filename As String) ' Create the XmlSerializer. Dim s As New XmlSerializer(GetType(Group)) ' To write the file, a TextWriter is required. Dim writer As New StreamWriter(filename) ' Create an instance of the group to serialize, and set ' its properties. Dim group As New Group() group.GroupID = 10.089f group.IsActive = False group.HexBytes = New Byte() {Convert.ToByte(100)} Dim x As New Employee() Dim y As New Employee() x.Name = "Jack" y.Name = "Jill" group.Employees = New Employee() {x, y} Dim mgr As New Manager() mgr.Name = "Sara" mgr.Level = 4 group.Manager = mgr ' Add a number and a string to the ' ArrayList returned by the ExtraInfo property. group.ExtraInfo = New ArrayList() group.ExtraInfo.Add(42) group.ExtraInfo.Add("Answer") ' Serialize the object, and close the TextWriter. s.Serialize(writer, group) writer.Close()
311
The Complete Reference To Professional SOA with Visual Studio 2005
End Sub Public Sub DeserializeObject(filename As String) Dim fs As New FileStream(filename, FileMode.Open) Dim x As New XmlSerializer(GetType(Group)) Dim g As Group = CType(x.Deserialize(fs), Group) Console.WriteLine(g.Manager.Name) Console.WriteLine(g.GroupID) Console.WriteLine(g.HexBytes(0)) Dim e As Employee For Each e In g.Employees Console.WriteLine(e.Name) Next e End Sub End Class
The example above produces a FirstDoc.xml shown in listing 8-21. Listing 8-21. FirstDoc.xml
Jack
Jill
10.088999748229981 64 false
Sara 4
42 Answer
We can see that the result shows each element that was added to the ArrayList if the value is an integer it is saved as ObjectNumber, if the value is a string it is saved as a ObjectString. Through the XmlElement definition shown below. Listing 8-22. Defining XmlElement for arraylist using Visual C# [XmlElement(typeof(int), ElementName = "ObjectNumber"), XmlElement(typeof(string), ElementName = "ObjectString")] public ArrayList ExtraInfo;
312
The Complete Reference To Professional SOA with Visual Studio 2005
Listing 8-23. Defining XmlElement for arraylist using Visual Basic .NET _ Public ExtraInfo As ArrayList
Ignoring Elements During serialization if we wanted to we can exclude certain entities from serialization by using the XmlIgnore attribute. Listing 8-24. XmlIgnore attribute using Visual C# [XmlRoot("NewRootName", Namespace = "http://www.CustomNamespace.com", IsNullable = true)] public class SerializableClass { private string _name; [XmlElement("NewElementName")] public string Name { get { return _name; } set { _name = value; } } private int _zipCode; [XmlIgnore] public int ZipCode { get { return _zipCode; } set { _zipCode = value; } } }
Listing 8-25. XmlIgnore attribute using Visual Basic .NET _ Public Class SerializableClass Private _name As String _ Public Property Name() As String Get Return _name End Get Set(ByVal value As String)
313
The Complete Reference To Professional SOA with Visual Studio 2005
_name = value End Set End Property Private _zipCode As Integer _ Public Property ZipCode() As Integer Get Return _zipCode End Get Set(ByVal value As Integer) _zipCode = value End Set End Property End Class
By adding the XmlIgnore attribute the ZipCode attribute is excluded from the serialization process. As we can see from the listing 8-26 below. The ZipCode has been removed from the result. Listing 8-26. SerializedObj.xml with ZipCode ignored
John Doe
Serializing Arrays Occasionally we need to define an array the serialization attribute for array is XmlArray and the items in the array XmlArrayItem. In the following example we will define an array of CDs for an online record catalog system. The following listing demonstrates how to add an array of CD elements to the array CDS which is part of the CATALOG class. Two attributes can be used to control how an array is serialized to XML: XmlArray and XmlArrayItems. Here is the CATALOG class definition: Listing 8-27. Catalog class using Visual C# [XmlRoot(IsNullable=false)] public class CATALOG { [XmlArray("CDS", IsNullable=false)] [XmlArrayItem("CD", IsNullable=false)] public CD [] CDS; }
Listing 8-28. Catalog class using Visual Basic .NET _ Public Class CATALOG _ _
314
The Complete Reference To Professional SOA with Visual Studio 2005
Public CDS As CD() End Class
The XmlArray attribute is used to control how the root element of the array is serialized. Since we have specified IsNullable=false in XmlArray("CDS", IsNullable=false) for the CDS array. The CDS array is valid only if the array of CDS is not null. The XmlArrayItem attribute is used to control how each item within the array is serialized. Since we have specified IsNullable=False in XmlArrayItem("CD", IsNullable=False) none of the items within the array can be set to null. In XML serialization, by default each element within the array has the same name as the type definition. In this example, the type definition name is CATALOG. Because the name of the elements within the Items array should be named CD, we explicitly set the name of the element by specifying it as the first parameter in the XmlArray and XmlArrayItems attributes. We can also use the XmlArrayItem attribute to define arrays containing instances of a mixture of datatypes. We can do this by including an array with multiple XmlArrayItem attributes. The following code defines an array that can contain items of type string and int: Listing 8-29. Implementing XmlArrayItem using Visual C# [XmlArrayItem("MyInt", typeof(int))] [XmlArrayItem("MyString", typeof(string))] public object [] TestArray;
Listing 8-30. Implementing XmlArrayItem using Visual Basic .NET _ _ Public TestArray As Object()
The preceding code will generate the following XML datatype definition:
Tip: Notice that the TestArray element can contain any combination of child elements of type string and int. To accept data of different types from the client, the XML mixed array is mapped to a .NET array of type Object. The compiler will not throw an error if the .NET type is set to something other than Object for example Integer. However, the client will receive a run-time error if the client sends an instance of an XML datatype that cannot be transformed into the underlying .NET type.
The XmlArray and XmlArrayItems attributes expose additional properties that we can use to control how an array is serialized to XML.
315
The Complete Reference To Professional SOA with Visual Studio 2005
Table 8-4. Properties of XmlArrayAttribute
Name
Description
ElementName Gets or sets the XML element name given to the serialized array. Form
Gets or sets a value that indicates whether the XML element name generated by the XmlSerializer is qualified or unqualified.
IsNullable
Gets or sets a value that indicates whether the XmlSerializer must serialize a member as an empty XML tag with the xsi:nil attribute set to true.
Namespace
Gets or sets the namespace of the XML element.
Order
Gets or sets the explicit order in which the elements are serialized or deserialized.
TypeId
When implemented in a derived class, gets a unique identifier for this Attribute. (Inherited from Attribute.)
Table 8-5. Properties of XmlArrayItemAttribute
Name
Description
DataType
Gets or sets the XML data type of the generated XML element.
ElementName Gets or sets the name of the generated XML element. Form
Gets or sets a value that indicates whether the name of the generated XML element is qualified.
IsNullable
Gets or sets a value that indicates whether the XmlSerializer must serialize a member as an empty XML tag with the xsi:nil attribute set to true.
Namespace
Gets or sets the namespace of the generated XML element.
NestingLevel
Gets or sets the level in a hierarchy of XML elements that the XmlArrayItemAttribute affects.
Type
Gets or sets the type allowed in an array.
TypeId
When implemented in a derived class, gets a unique identifier for this Attribute.(Inherited from Attribute.)
XmlAnyElement and XmlAnyAttribute It is often today for business requirements evolve and mature over time, as a result applications may also be required to change. This may cause the XML document to contain some unexpected elements or attributes.
316
The Complete Reference To Professional SOA with Visual Studio 2005
Rather than simply throwing an exception and giving up we may want to preserve the content and the structure of the data from the document so that it can be passed to another component for processing. The .NET Framework provides two attributes that allow us to capture unknown XML elements and attributes. These are XmlAnyAttribute and XmlAnyElement: *
XmlAnyElement is used to control how unknown elements.
*
XmlAnyAttribute is used to control how unknown attributes.
XmlAnyElementAttribute is essentially a wild card that allows us to access elements that are not previously defined. To use the XmlAnyAttribute we simply decorate a method with the XmlAnyElement() attribute. We typically decorate over a property with a return type of XmlNode array this is because overtime there maybe more than just one unknown node. See listing 8-31. and listing 8-32. Listing 8-31. Demonstrates using XmlAnyElement with Visual C# [XmlAnyElement()] public XmlNode[] OpenElements { get { return _openElements; } set { _openElements = value; } }
Listing 8-32. Demonstrates using XmlAnyElement with Visual Basic .NET _ Public Property OpenElements() As XmlNode() Get Return _openElements End Get Set _openElements = value End Set End Property
XmlAnyAttribute is a wild card ability to access attributes that has not been previously defined. To use the XmlAnyAttribute we simply decorate a method with the XmlAnyAttribute() attribute. Using XmlAnyAttribute is similar to using XmlAnyElement. Listing 8-33. Demonstrates using XmlAnyAttribute with Visual C# [XmlAnyAttribute()] public XmlNode[] OpenAttributes { get { return _openAttributes; } set { _openAttributes = value; } }
Listing 8-34. Demonstrates using XmlAnyAttribute with Visual Basic .NET _ Public Property OpenAttributes() As XmlNode() Get Return _openAttributes
317
The Complete Reference To Professional SOA with Visual Studio 2005
End Get Set _openAttributes = value End Set End Property
XmlInclude - Derived Data types We can use .NET serialization to define derived data types. XML serialization supports defining XML datatypes that are derived by extension from other XML datatypes. We can define derived XML datatype by creating a derived .NET type and then decorating the base type with the XmlInclude attribute. In a generic example we define three classes, two of them are the class Car and Truck inherit from the third Vehicle class. The example applies the XmlInclude attribute to a method that returns an instance of one of the two derived classes. Listing 8-35: Implementing XmlIncludeAttribute using Visual C# public class Vehicle{} public class Car:Vehicle{} public class Truck:Vehicle{} public class Sample { [WebMethodAttribute] [XmlInclude(typeof(Car))] [XmlInclude(typeof(Truck))] public Vehicle ReturnVehicle(int i){ if(i == 0) return new Car(); else return new Truck(); } }
Listing 8-36: Implementing XmlIncludeAttribute using Visual Basic .NET Public Class Vehicle End Class Public Class Car Inherits Vehicle End Class Public Class Truck Inherits Vehicle End Class Public Class Sample _
318
The Complete Reference To Professional SOA with Visual Studio 2005
_ _ Public Function ReturnVehicle(ByVal i As Integer) As Vehicle If i = 0 Then Return New Car Else Return New Truck End If End Function End Class
The preceding code will generate an XML datatype called Vehicle and two datatypes that derive by extension from Vehicle these are Car and Truck. Because Car and Truck are extended versions of the Vehicle datatype, Web service interfaces that accept the Vehicle datatype can also accept instances of Car and Truck.
Datatype Mapping XML serialization provides a default mapping between .NET types and the built-in datatypes defined by XML Schema. For example, a int type in .NET by default will be transformed by the XML serialization to the XML built-in datatype Int32. XML serialization supports all XML built-in datatypes. Table 8-6. lists the supported mappings between XML datatypes and .NET types.
XSD data type
.NET data type
XSD data type
.NET data type
anyURI
String
nonPositiveInteger
String
base64Binary
Array of Byte objects
NOTATION
String
boolean
Boolean
positiveInteger
String
Byte
SByte
QName
XmlQualifiedName
Date
DateTime
recurringDate
String
dateTime
DateTime
duration
String
decimal
Decimal
string
String
double
Double
short
Int16
ENTITY
String
time
DateTime
ENTITIES
String
token
String
Float
Single
unsignedByte
Byte
319
The Complete Reference To Professional SOA with Visual Studio 2005
gDay
String
unsignedInt
UInt32
gMonth
String
unsignedLong
UInt64
gMonthDay
String
unsignedShort
UInt16
gYear
String
IDREF
String
gYearMonth
String
IDREFS
String
hexBinary
Array of Byte objects
int
Int32
ID
String
integer
String
negativeInteger
String
language
String
NMTOKEN
String
long
Int64
NMTOKENS
String
Name
String
normalizedString
String
NCName
String
nonNegativeInteger
String
Even though XML serialization will transform an XML datatype into its corresponding .NET type, it will not perform any validation on the data. For example, the XML datatype integer maps to the String .NET type, but the client can pass non-numeric data to the Web service. Therefore, it is up to the Web service to enforce additional constraints over and above what is provided by the .NET type.
Strongly Typed XML Serialization So far we have looked at customizing and controlling XML serialization. In this section we will examine how to consume and produce XML that conforms to a particular XML schema. To do this we can automatically generate .NET classes from predefined XML schemas (XSD). These classes use of XML serialization attributes and can generate XML documents to conform to the schema. .NET Framework provides an utility to help us with the XSD to .NET class generation process. As creating serializable classes manually is possible it can easily become quite tedious. To fast track the process the XSD.exe utility can generate our classes based on a XML schema. In the following example we are presented with a schema for an online catalogue management system. The schema contains a catalog the catalog contains a collection of CDs and information relevant to each CD. Listing 8-37: Shows the XML Schema for the CD catalog document.
320
The Complete Reference To Professional SOA with Visual Studio 2005
We can generate a serialization class from this by using .NET XSD.EXE tool, Enter the command prompt via Start menu -> Microsoft Visual Studio 2005 -> Visual Studio Tools -> Visual Studio 2005 Command Prompt. (All the necessary environment variable will be setup)
The Syntax for the XSD tool is. xsd /c cd_catalog.xsd
Tip: we can specify different languages using the /language: parameter. For VB.NET we can specify /language:VB to generate classes that are VB.NET syntax
xsd /c cd_catalog.xsd /language:VB
321
The Complete Reference To Professional SOA with Visual Studio 2005
Image 8-3: using XSD
The result is a cd_catalog.cs Listing 8-38. cd_catalog.cs using System.Xml.Serialization; // // This source code was auto-generated by xsd, Version=2.0.50727.42. //
/// [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)] [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)] public partial class ARTIST { private string[] textField; /// [System.Xml.Serialization.XmlTextAttribute()] public string[] Text { get { return this.textField; } set { this.textField = value; } } } /// [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
322
The Complete Reference To Professional SOA with Visual Studio 2005
[System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)] [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)] public partial class CATALOG { private CD[] cdField; /// [System.Xml.Serialization.XmlElementAttribute("CD")] public CD[] CD { get { return this.cdField; } set { this.cdField = value; } } } /// [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)] [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)] public partial class CD { private TITLE tITLEField; private ARTIST aRTISTField; private COUNTRY cOUNTRYField; private COMPANY cOMPANYField; private PRICE pRICEField; private YEAR yEARField; /// public TITLE TITLE { get { return this.tITLEField; } set { this.tITLEField = value; } } ///
323
The Complete Reference To Professional SOA with Visual Studio 2005
public ARTIST ARTIST { get { return this.aRTISTField; } set { this.aRTISTField = value; } } /// public COUNTRY COUNTRY { get { return this.cOUNTRYField; } set { this.cOUNTRYField = value; } } /// public COMPANY COMPANY { get { return this.cOMPANYField; } set { this.cOMPANYField = value; } } /// public PRICE PRICE { get { return this.pRICEField; } set { this.pRICEField = value; } } /// public YEAR YEAR { get { return this.yEARField; } set { this.yEARField = value; } } } /// [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")] [System.SerializableAttribute()]
324
The Complete Reference To Professional SOA with Visual Studio 2005
[System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)] [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)] public partial class COMPANY { private string[] textField; /// [System.Xml.Serialization.XmlTextAttribute()] public string[] Text { get { return this.textField; } set { this.textField = value; } } } /// [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)] [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)] public partial class COUNTRY { private string[] textField; /// [System.Xml.Serialization.XmlTextAttribute()] public string[] Text { get { return this.textField; } set { this.textField = value; } } } /// [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)] [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)] public partial class PRICE { private string[] textField;
325
The Complete Reference To Professional SOA with Visual Studio 2005
/// [System.Xml.Serialization.XmlTextAttribute()] public string[] Text { get { return this.textField; } set { this.textField = value; } } } /// [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)] [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)] public partial class TITLE { private string[] textField; /// [System.Xml.Serialization.XmlTextAttribute()] public string[] Text { get { return this.textField; } set { this.textField = value; } } } /// [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)] [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)] public partial class YEAR { private string[] textField; /// [System.Xml.Serialization.XmlTextAttribute()] public string[] Text { get { return this.textField; }
326
The Complete Reference To Professional SOA with Visual Studio 2005
set { this.textField = value; } } }
For VB based generated code see listing 8-39below. Listing 8-39. cd_catalog.VB
Option Strict Off Option Explicit On Imports System.Xml.Serialization ' 'This source code was auto-generated by xsd, Version=2.0.50727.42. ' ''' _ Partial Public Class ARTIST Private textField() As String ''' _ Public Property Text() As String() Get Return Me.textField End Get Set Me.textField = value End Set End Property End Class ''' _ Partial Public Class CATALOG
327
The Complete Reference To Professional SOA with Visual Studio 2005
Private cdField() As CD ''' _ Public Property CD() As CD() Get Return Me.cdField End Get Set Me.cdField = value End Set End Property End Class ''' _ Partial Public Class CD Private tITLEField As TITLE Private aRTISTField As ARTIST Private cOUNTRYField As COUNTRY Private cOMPANYField As COMPANY Private pRICEField As PRICE Private yEARField As YEAR ''' Public Property TITLE() As TITLE Get Return Me.tITLEField End Get Set Me.tITLEField = value End Set End Property ''' Public Property ARTIST() As ARTIST Get Return Me.aRTISTField End Get Set
328
The Complete Reference To Professional SOA with Visual Studio 2005
Me.aRTISTField = value End Set End Property ''' Public Property COUNTRY() As COUNTRY Get Return Me.cOUNTRYField End Get Set Me.cOUNTRYField = value End Set End Property ''' Public Property COMPANY() As COMPANY Get Return Me.cOMPANYField End Get Set Me.cOMPANYField = value End Set End Property ''' Public Property PRICE() As PRICE Get Return Me.pRICEField End Get Set Me.pRICEField = value End Set End Property ''' Public Property YEAR() As YEAR Get Return Me.yEARField End Get Set Me.yEARField = value End Set End Property End Class ''' _
329
The Complete Reference To Professional SOA with Visual Studio 2005
Partial Public Class COMPANY Private textField() As String ''' _ Public Property Text() As String() Get Return Me.textField End Get Set Me.textField = value End Set End Property End Class ''' _ Partial Public Class COUNTRY Private textField() As String ''' _ Public Property Text() As String() Get Return Me.textField End Get Set Me.textField = value End Set End Property End Class ''' _ Partial Public Class PRICE Private textField() As String '''
330
The Complete Reference To Professional SOA with Visual Studio 2005
_ Public Property Text() As String() Get Return Me.textField End Get Set Me.textField = value End Set End Property End Class ''' _ Partial Public Class TITLE Private textField() As String ''' _ Public Property Text() As String() Get Return Me.textField End Get Set Me.textField = value End Set End Property End Class ''' _ Partial Public Class YEAR Private textField() As String ''' _ Public Property Text() As String() Get Return Me.textField End Get
331
The Complete Reference To Professional SOA with Visual Studio 2005
Set Me.textField = value End Set End Property End Class
After the class is generated we can include the class into our project. Using these classes, we can develop in an object oriented fashion to generate any XML document to conform to the original XML schema file. The generated class cd_catalog.cs for C# and cd_catalog.vb if we’re generating for Visual Basic.
Open Schema with XmlAnyAttribute and XmlAnyElement Quite often it is necessary to allow data to be included within an instance of a particular XML datatype even if we did not anticipate this when we created the schema. By doing so, we can improve the scalability of our system without the requirement to recreate our schemas. This is important especially when our Web service is made public on the internet. It allows additional information to be submitted by our consumers without the need to redefine our schemas. A good example is if an order was placed on an online music store against a particular CD and shipping details were required to be submitted. However the consumer of the Web service had provided some additional details to what we had originally specified in our schema. Normally the additional information will simply be lost. However using XmlAnyElement and XmlAnyAttribute we can still obtain the information. Listing 8-40: Shipment details with additional Location information
101
76 Reberto av Organge Bay CA
Listing 8-41. Shipping Details
102
76 Reberto av Organge Bay CA OB6527
Schemas that allow the inclusion of additional elements and attributes that are not formally defined within the schema itself are often referred to as open schemas.
332
The Complete Reference To Professional SOA with Visual Studio 2005
We can create an open schema by decorating a public field or property with the XmlAnyAttribute and XmlAnyElement attributes. The XmlAnyAttribute attribute specifies that the parent element can contain any XML attribute in addition to the ones formally defined within the schema. The XmlAnyElement attribute specifies that the parent element can contain any XML element in addition to the ones formally defined within the schema. The flexibility of open schemas can be very enticing. However, we should consider the consequences before we create an open schema because the code needed to handle and process the extended data can become a little complex. One popular method for allowing extended information to be included within an instance document in a semi-controlled fashion is to provide an area in the document definition for that information. The following example defines an element within the CD datatype that is designated for containing extended information about the CD: Listing 8-42. Using XmlAnyElement using Visual C# [XmlRoot(Namespace=”http://www.mswcf.com”)] public class Shipment { string _orderNo = string.Empty; Location _location = new Location(); public string OrderNo { get { return _orderNo; } set { _orderNo = value; } } public Location Location { get { return _location; } set { _location = value; } } } [XmlRoot(Namespace = ”http://www.mswcf.com”)] public class Location { string _addr = string.Empty; string _city = string.Empty; string _state = string.Empty; public string Addr { get { return _addr; } set { _addr = value; } } public string City { get { return _city; } set { _city = value; } } public string State { get { return _state; } set { _state = value; } }
333
The Complete Reference To Professional SOA with Visual Studio 2005
XmlNode[] _openElements = null; [XmlAnyElement()] public XmlNode[] OpenElements { get { return _openElements; } set { _openElements = value; } } }
Listing 8-42. Using XmlAnyElement using Visual Basic .NET _ Public Class Shipment Private _orderNo As String = String.Empty Private _location As Location = New Location Public Property OrderNo() As String Get Return _orderNo End Get Set _orderNo = value End Set End Property Public Property Location() As Location Get Return _location End Get Set _location = value End Set End Property End Class _ Public Class Location Private _addr As String = String.Empty Private _city As String = String.Empty Private _state As String = String.Empty Public Property Addr() As String Get Return _addr End Get Set _addr = value End Set End Property Public Property City() As String Get Return _city
334
The Complete Reference To Professional SOA with Visual Studio 2005
End Get Set _city = value End Set End Property Public Property State() As String Get Return _state End Get Set _state = value End Set End Property Private _openElements As XmlNode() = Nothing _ Public Property OpenElements() As XmlNode() Get Return _openElements End Get Set _openElements = value End Set End Property End Class
The public field or property which includes the XmlAnyAttribute attribute can be of type XmlElement or XmlNode. Because the XmlElement and XmlNode types are part of the XML DOM that ships with .NET, we can use the methods and properties exposed by these types to navigate through the additional data that accompanied the purchase order. The preceding code defines an additional element within the Shipment XML datatype called OpenElement. This element can contain any attribute as well as any element. The above code generates the following schema containing the OpenElement element definition: Listing 8-43. shows the schema that support open schema
335
The Complete Reference To Professional SOA with Visual Studio 2005
In the schema above, the namespace for the open elements are declared as '##any', which is the default value. Alternatively, we can supply the specific namespace that is allowed, or another predefined namespace tokens. These tokens are: ##other - The XML elements must be from any namespace other than the target namespace is allowed. ##local - The XML elements must not be in a namespace. ##targetNamespace - The XML must be in the target namespace.
The processContents attribute in the xs:any element is set to 'skip' in this example, which instructs a schema validator to ignore the nodes that are part of the open element. A complete list of options follows: Lax - Enforce schema if a namespace is declared and the validator has access to the schema definition. Skip - No schema enforcement. Strict - Always enforce schema for this open element.
Summary In this chapter we have examined XML serialization. XML serialization is an important aspect of Web services as all communication between Web services are achieved through data serialization. It is responsible for serializing instances of .NET types to XML and deserializing XML to instances of .NET types. This includes support for instances of built-in .NET types, classes, and structures as well as composite types such as arrays, nested object hierarchies, and objects that support the ICollection and IEnumerable interfaces. It also supports serializing .NET type definitions into an XML schema. XML serialization has default behaviors that might not be appropriate in all situations, so the .NET platform provides a collection of attributes that we can apply to .NET type definitions, variable declarations, and parameter declarations to control the behavior of .NET serialization.
336
The Complete Reference To Professional SOA with Visual Studio 2005
Chapter 9 Creating and Consuming Web Service using Visual Studio 2005 In this chapter we will be examining the XML Web Services programming in Visual Studio 2005 which allows us to build highly scalable, loosely coupled, distributed applications to enable our Service Oriented Architecture. To do this we will be using Web protocol standards such as HTTP, XML, and SOAP.
Web Service Summary Just a quick recap on XML Web Service: A XML Web Service is the building block from which to build scalable, loosely coupled, platform-independent applications. Web Service use XML to enable disparate applications to exchange messages using standard protocols such as HTTP, XML, XSD, SOAP, and Web Services Description Language (WSDL).
Figure 9-1. Communication between a client and an XML Web Service
The exchange between a client and a XML Web Service consists of several stages. A client can be any application that can facilitate a SOAP request to the XML Web Service this includes, console applications, Windows forms applications, Web form applications and or even another XML Web Service. The following steps are performed during these phases (see Figure 9-1):
337
The Complete Reference To Professional SOA with Visual Studio 2005
*
The client creates an object of the XML Web Service by creating a proxy class on the computer on which the client resides. The client calls a method on the proxy object. The request on the client system serializes the method call and arguments into a SOAP message and sends it to the XML Web Service over the network.
*
The XML Web Service on the server after receiving the request deserializes the SOAP message. The deserialized message is then used to create an instance of the XML Web Service. The instance is used to invoke the XML Web Service method with the arguments on the XML Web Service. The XML Web Service executes the method and returns the value to the requesting client.
*
The XML Web Service serializes the response return value and any out parameters into a SOAP message and sends them to the client over the network.
*
The client application after receiving the response message deserializes the SOAP message containing the return value and any out parameters and sends them to the proxy object. The proxy object passes the relevant return value and any out parameter back into the application.
In order to build XML Web Services that the clients can consume, we can use the ASP.NET Framework, which is an integral part of the .NET Framework. Visual Studio 2005 also provides tools to build, deploy, and publish the XML Web Services once development is complete. In the following section we will look at development with Visual Studio 2005.
Creating XML Web Services In the previous chapters we had already examined the simplicity involved in creating XML Web Service with Visual Studio 2005. Developing a XML Web Service is similar to creating a Component Object Model (COM) component that provides application logic to a client application. We create an XML Web Service to provide specific functionality to client applications over the Web. To create an XML Web Service, we first choose a programming language in which we want to create the service and create a class that inherits from System.Web.Services.WebService. Next, we require an infrastructure that makes the XML Web Service available for client applications to use over the Internet. Visual Studio 2005 provides us with tools that help build, deploy, and consume an XML Web Service. In this section we will be looking at manipulating employee information using the AdventureWorks database. This sample Web Service will allow modification to employee details. To provide this functionality we will need to create an XML Web Service that will support the adding and updating of employee details. The AdventureWorks XML Web Service, however, is not user-interface driven or interactive. The XML Web Service only provides the application logic. The Visual Studio 2005 IDE provides us with the environment needed to create projects for distributed desktop applications, Web applications, and XML Web Services. To create an XML Web Service, perform the following steps:
338
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 9-2: New Web Site
1.
Open the Visual Studio 2005. Start a project to create a new Web Site by pointing to File -> New -> Web Site. Figure 9-2.
Figure 9-3: New Web Site
2.
In the New Web Site dialog box, select Visual C# or Visual Basic as the language. Also select the location of the Web Service that we would like it to be in. In the Templates pane, select ASP.NET Web Service. In the Location box, type the name and location of the XML Web Service as http://localhost/soa/AdventureWorks/Employee, and click OK. Figure 9-3.
339
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 9-4: Select “Browse” button for the Choose Location dialog window
3.
.NET offers several forms of storage for Web Service, we could save our Web Service to File System, Local IIS, FTP Site or Remote Site. In this instance we will be saving to an IIS location. Figure 9-4.
NOTE: If we are creating Web Service on a remote computer. The remote computer must be running .NET Framework version 2.0 and must have IIS version 5.0 or later installed and running, ASP.NET must be enabled on IIS and FrontPage Server Extensions must be installed and enabled at the root level where we are creating the new Web site. The user must also have FrontPage administration or author permissions to create new folders and files on the remoting computer under the root folder where we want the site to be.
When we create the ASP.NET Web Service project, an .asmx file is created. After creating an XML Web Service project, we write the code to provide functionality to the XML Web Service. This code is stored in a file associated with the .cs or .vb file and is known as the code-behind file. The code-behind file depends on the language that we use to create the XML Web Service. For a Visual C# project, the code-behind file is a .cs file. The default template content of the file is shown in the listing 9-1and listing 9-2below. Listing 9-1. XML Web Service default code behind using Visual C# using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class Service : System.Web.Services.WebService { public Service () { //Uncomment the following line if using designed components //InitializeComponent(); } [WebMethod]
340
The Complete Reference To Professional SOA with Visual Studio 2005
public string HelloWorld() { return "Hello World"; } }
For a Visual Basic .NET project, the default code-behind file is the service.vb file. Listing 9-2. XML Web Service default code behind using Visual Basic .NET Imports System.Web Imports System.Web.Services Imports System.Web.Services.Protocols _ _ _ Public Class Service Inherits System.Web.Services.WebService _ Public Function HelloWorld() As String Return "Hello World" End Function End Class
The .asmx file acts as the front end of the Web Service. It specifies the language that’s used to implement the service logic, it also points to the actual file implementation of the code behind content of the Web Service. The .asmx file is shown below. Listing 9-3 and Listing 9-4. Listing 9-3. Service.asmx for a Visual C# project
Listing 9-4. Service.asmx for a Visual Basic project
Figure 9-5: Solution Explorer
341
The Complete Reference To Professional SOA with Visual Studio 2005
Under the Solution Explorer we can see the structure of the application Figure 9-5. Under App_Code the code for the webservice will be stored there. The App_Data folder is used by ASP.NET to store databases that the system maintains. The .asmx is our .NET Web Service. 1.
Rename the Service.asmx to Employee.asmx and
2.
Then the service.cs file under the App_Code folder as Employee.cs.
Or Service.vb file under App_Code folder as Employee.vb 3.
Double click on the Employee.cs to open the code behind and rename the class from Service to Employee and also change its constructor to Employee if using Visual C# see Listing 9-5. Otherwise if using Visual Basic .NET its just the class name see listing 9-6.
Listing 9-5. Renamed Class and Constructor in Visual C# implementation using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class Employee : System.Web.Services.WebService { public Employee() { //Uncomment the following line if using designed components //InitializeComponent(); } [WebMethod] public string HelloWorld() { return "Hello World"; } }
Listing 9-6. Rename Web Service template’s default Service name to Employee Imports System.Web Imports System.Web.Services Imports System.Web.Services.Protocols _ _ _ Public Class Employee Inherits System.Web.Services.WebService
342
The Complete Reference To Professional SOA with Visual Studio 2005
_ Public Function HelloWorld() As String Return "Hello World" End Function End Class
Since we have changed the file name as well as the class name we will need to adjust the .asmx accordingly. So that the correct file and class is pointed to by the Employee.asmx file. 4.
Double click on the Employee.asmx file and change the code bind pointer to CodeBehind="~/App_Code/Employee.cs" Class="Employee".
Or CodeBehind="~/App_Code/Employee.vb" Class="Employee".
Before we start to create the AdventureWorks employee management XML Web Service we need to ensure that we have the relevant database table:
NOTE: We can install the sample database when installing Sql Server 2005 by specifying the advanced selection during installation and enabling the AdventureWorks database for install. Or if Sql Server 2005 Express edition is used the database can be downloaded from the Microsoft’s download site by using AdventureWorks as the search keyword.
We will be focusing on two tables. Employee under HumanResources and Contact under Person. The Employee table contains employee information such as their national identification number, work title, and vacation and sick leave hours listing 9-7. Listing 9-7: The SQL create script for the Employee table CREATE TABLE [HumanResources].[Employee]( [EmployeeID] [int] IDENTITY(1,1) NOT NULL, [NationalIDNumber] [nvarchar](15) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, [ContactID] [int] NOT NULL, [LoginID] [nvarchar](256) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, [ManagerID] [int] NULL, [Title] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, [BirthDate] [datetime] NOT NULL, [MaritalStatus] [nchar](1) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, [Gender] [nchar](1) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, [HireDate] [datetime] NOT NULL, [SalariedFlag] [dbo].[Flag] NOT NULL CONSTRAINT [DF_Employee_SalariedFlag] DEFAULT ((1)), [VacationHours] [smallint] NOT NULL CONSTRAINT [DF_Employee_VacationHours] DEFAULT ((0)), [SickLeaveHours] [smallint] NOT NULL CONSTRAINT [DF_Employee_SickLeaveHours] DEFAULT ((0)), [CurrentFlag] [dbo].[Flag] NOT NULL CONSTRAINT [DF_Employee_CurrentFlag] DEFAULT ((1)), [rowguid] [uniqueidentifier] ROWGUIDCOL NOT NULL CONSTRAINT [DF_Employee_rowguid] DEFAULT (newid()), [ModifiedDate] [datetime] NOT NULL CONSTRAINT [DF_Employee_ModifiedDate] DEFAULT (getdate()), CONSTRAINT [PK_Employee_EmployeeID] PRIMARY KEY CLUSTERED ( [EmployeeID] ASC
343
The Complete Reference To Professional SOA with Visual Studio 2005
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY]
The Contact table contains a list of names and related information for each customer, employee, or vendor. For example, a customer (store) may provide a sales agent name as a primary contact for their company and a sales manager as a secondary contact listing 9-8. Listing 9-8. The SQL create script for the Contact table CREATE TABLE [Person].[Contact]( [ContactID] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL, [NameStyle] [dbo].[NameStyle] NOT NULL CONSTRAINT [DF_Contact_NameStyle] DEFAULT ((0)), [Title] [nvarchar](8) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, [FirstName] [dbo].[Name] NOT NULL, [MiddleName] [dbo].[Name] NULL, [LastName] [dbo].[Name] NOT NULL, [Suffix] [nvarchar](10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, [EmailAddress] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, [EmailPromotion] [int] NOT NULL CONSTRAINT [DF_Contact_EmailPromotion] DEFAULT ((0)), [Phone] [dbo].[Phone] NULL, [PasswordHash] [varchar](40) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, [PasswordSalt] [varchar](10) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, [AdditionalContactInfo] [xml] (CONTENT [Person].[AdditionalContactInfoSchemaCollection]) NULL, [rowguid] [uniqueidentifier] ROWGUIDCOL NOT NULL CONSTRAINT [DF_Contact_rowguid] DEFAULT (newid()), [ModifiedDate] [datetime] NOT NULL CONSTRAINT [DF_Contact_ModifiedDate] DEFAULT (getdate()), CONSTRAINT [PK_Contact_ContactID] PRIMARY KEY CLUSTERED ( [ContactID] ASC )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY]
344
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 9-6: ERD for Employee table and Contact table
After the database is setup, we can provide the relevant functionality to the XML Web Service. To enable client applications to access and use the XML Web Service, we expose the functionality of the XML Web Service by creating Web methods. Web methods are independent functional units that perform certain predefined operations in an XML Web Service. We use the attribute in Visual Basic .NET listing 9-10 or the [WebMethod] attribute in Visual C# to declare a Web method listing 9-9, depending on the language we choose to develop the XML Web Service in. Listing 9-9. Creating WebMethod using Visual C# [WebMethod] public string HelloWorld() { return "Hello World"; }
Listing 9-10. Creating WebMethod using Visual Basic .NET _ Public Function HelloWorld() As String Return "Hello World" End Function
In our employee management code below we have created three functions. GetEmployees, which retrieves a list of employee details GetEmployeeByID, which retrieves the employee details by a specific ID UpdateEmployeeDetailByID, which updates the personal details of a specific employee
Firstly we need to enable our connection to the AdventureWorks database using the the SqlConnection class. The listing 9-11and listing 9-12 below shows how to use SqlConnection to connect to the AdventureWorks database. In the connection string the Database login id of Book and Password Book is used. If you will need to adjust the credential information inorder for the connection to work.
345
The Complete Reference To Professional SOA with Visual Studio 2005
Listing 9-11. Constructor and Finalizer to ensure our database connection is opened and closed using Visual C# public class Employee : System.Web.Services.WebService { SqlConnection sqlcon = new SqlConnection("Data Source=DEVSERVER01;Initial Catalog=AdventureWorks;Persist Security Info=True;User ID=Book;Password=Book"); public Employee () { //Uncomment the following line if using designed components //InitializeComponent(); sqlcon.Open(); } ~Employee() { if (sqlcon.State == ConnectionState.Open) { sqlcon.Close(); } }
Listing 9-12. Constructor and Finalizer to ensure our database connection is opened and closed using Visual Basic .NET Public Class Employee Inherits System.Web.Services.WebService Private sqlcon As SqlConnection = New SqlConnection( _ "Data Source=DEVSERVER01;Initial " & _ "Catalog=AdventureWorks;Persist Security " & _ "Info=True;User ID=Book;Password=Book") Public Sub New() sqlcon.Open() End Sub Protected Overrides Sub Finalize() If (sqlcon.State = ConnectionState.Open) Then sqlcon.Close() End If End Sub End Class
In C# we use ~Classname() to specify the finalizer in VB.NET we can override the Finalize method to achieve the same result. A finalizer is the last method called before the code exits. It is usually used to clean up file handles and database connections. Within the finalizer method we also check to see if the sqlconnection is still open by using the sqlcon. If the connection is still open then we will close it. Since we are performing database operations using ADO.NET we need to add the System.Data and System.Data.SqlClient namespace to our code listing 9-13 and listing 9-14. Listing 9-13. Adding the required namespace to code using Visual C# using System.Data;
346
The Complete Reference To Professional SOA with Visual Studio 2005
using System.Data.SqlClient;
Listing 9-14. Adding the required namespace to code using Visual Basic .NET Imports System.Data Imports System.Data.SqlClient
The below listing shows how to implement the GetEmplyoees Method which is used to retrieve a list of employee details From the XML Web Service listing 9-15and listing 9-16. Listing 9-15. Implementing GetEmployees() using Visual C# [WebMethod] public DataSet GetEmployees () { SqlDataAdapter sqlda = new SqlDataAdapter( @"Select EmployeeID, FirstName, MiddleName, LastName, EmailAddress, Phone, HumanResources.Employee.Title, BirthDate, MaritalStatus, Gender, HireDate, HumanResources.Employee.ContactID from HumanResources.Employee inner join Person.Contact on HumanResources.Employee.ContactID = Person.Contact.ContactID", sqlcon); DataSet dsEmployees = new DataSet(); sqlda.Fill(dsEmployees); return dsEmployees; }
Listing 9-16. Implementing GetEmployees() using Visual Basic .NET _ Public Function GetEmployees() As DataSet Dim sqlda As SqlDataAdapter = _ New SqlDataAdapter("Select EmployeeID, " & _ "FirstName, MiddleName, LastName, EmailAddress," & _ " Phone, HumanResources.Employee.Title, BirthDate, " & _ "MaritalStatus, Gender, HireDate, HumanResources.Employee.ContactID " & _ " from HumanResources.Employee inner join Person.Contact on " & _ "HumanResources.Employee.ContactID = Person.Contact.ContactID", _ sqlcon) Dim dsEmployees As DataSet = New DataSet sqlda.Fill(dsEmployees) Return dsEmployees End Function
In listing 9-15 and listing 9-16 the GetEmployees code we are required to populate the dataset with all employees. A SqlDataAdapater is used to fill the dataset. We then return the dataset in the WebMethod. We don’t need to worry about the serialization aspect. As .NET Framework is nice enough to handle all of it for us. Listing 9-17. Implementing GetEmployeeByID() using Visual C# [WebMethod]
347
The Complete Reference To Professional SOA with Visual Studio 2005
public DataSet GetEmployeeByID(int EmployeeID) { SqlDataAdapter sqlda = new SqlDataAdapter( @"Select EmployeeID, FirstName, MiddleName, LastName, EmailAddress, Phone, HumanResources.Employee.Title, BirthDate, MaritalStatus, Gender, HireDate, HumanResources.Employee.ContactID from HumanResources.Employee inner join Person.Contact on HumanResources.Employee.ContactID = Person.Contact.ContactID where EmployeeID = @EmployeeID", sqlcon); sqlda.SelectCommand.Parameters.Add ("@EmployeeID",SqlDbType.Int, sizeof(int)).Value = EmployeeID; DataSet dsEmployees = new DataSet(); sqlda.Fill(dsEmployees); return dsEmployees; }
Listing 9-18. Implementing GetEmployeeByID() using Visual Basic .NET _ Public Function GetEmployeeByID(ByVal EmployeeID As Integer) As DataSet Dim sqlda As SqlDataAdapter = New SqlDataAdapter("Select EmployeeID," & _ " FirstName, MiddleName, LastName, EmailAddress, Phone," & _ " HumanResources.Employee.Title, BirthDate, MaritalStatus, " & _ "Gender, HireDate, HumanResources.Employee.ContactID " & _ "from HumanResources.Employee inner join Person.Contact " & _ "on HumanResources.Employee.ContactID = Person.Contact.ContactID " & _ " where EmployeeID = @EmployeeID", sqlcon) sqlda.SelectCommand.Parameters.Add("@EmployeeID", SqlDbType.Int).Value = EmployeeID Dim dsEmployees As DataSet = New DataSet sqlda.Fill(dsEmployees) Return dsEmployees End Function
In listing 9-17 and listing 9-18 above the WebMethod will return the information of a specific employee by allowing the client to pass in an integer value of the employee ID. Once the WebMethod is called we execute a sql query to return the client information into a DataSet which is then returned to the consumer of the Web Service. Listing 9-19. Implementing UpdateEmployeeDetailByID() using Visual C# [WebMethod] public void UpdateEmployeeDetailByID( int EmployeeID, string EmployeeFirstName, string EmployeeMiddleName, string EmployeeLastName, string EmailAddress, string Phone,
348
The Complete Reference To Professional SOA with Visual Studio 2005
string Title, string BirthDate, string MaritalStatus, string Gender, string HireDate) { SqlTransaction transaction = this.sqlcon.BeginTransaction("EmployeeTran"); try { // update Person.Contact SqlCommand sqlcmdEmployee = new SqlCommand( @"update Person.Contact con set FirstName = @FirstName, MiddleName = @MiddleName, LastName = @LastName EmailAddress = @EmailAddress, Phone = @Phone, inner join HumanResources.Employee emp on emp.ContactID = con.ContactID where EmployeeID = @EmployeeID; update HumanResources.Employee emp set Title = @Title, BirthDate = @BirthDate, MaritalStatus = @MaritalStatus, Gender = @Gender, HireDate = @HireDate where emp.EmployeeID = @EmployeeID; ", sqlcon); sqlcmdEmployee.Transaction = transaction; sqlcmdEmployee.Parameters.Add ("@FirstName", SqlDbType.VarChar, 50) .Value = EmployeeFirstName; sqlcmdEmployee.Parameters.Add ("@MiddleName", SqlDbType.VarChar, 50) .Value = EmployeeMiddleName; sqlcmdEmployee.Parameters.Add ("@LastName", SqlDbType.VarChar, 50) .Value = EmployeeLastName; sqlcmdEmployee.Parameters.Add ("@Title", SqlDbType.Int, sizeof(int)).Value = EmployeeID; sqlcmdEmployee.Parameters.Add ("@BirthDate", SqlDbType.VarChar, 50) .Value = EmployeeLastName; sqlcmdEmployee.Parameters.Add ("@MaritalStatus", SqlDbType.VarChar, 50) .Value = EmployeeLastName; sqlcmdEmployee.Parameters.Add
349
The Complete Reference To Professional SOA with Visual Studio 2005
("@Gender", SqlDbType.VarChar, 50) .Value = EmployeeLastName; sqlcmdEmployee.Parameters.Add ("@HireDate", SqlDbType.VarChar, 50) .Value = EmployeeLastName; sqlcmdEmployee.ExecuteNonQuery(); transaction.Commit(); } catch { transaction.Rollback(); } }
Listing 9-20. Implementing UpdateEmployeeDetailByID() using Visual Basic .NET _ Public Sub UpdateEmployeeDetailByID(ByVal EmployeeID As Integer, _ ByVal EmployeeFirstName As String, ByVal EmployeeMiddleName As String, _ ByVal EmployeeLastName As String, ByVal EmailAddress As String, _ ByVal Phone As String, ByVal Title As String, _ ByVal BirthDate As String, ByVal MaritalStatus As String, _ ByVal Gender As String, ByVal HireDate As String) Dim transaction As SqlTransaction = _ Me.sqlcon.BeginTransaction("EmployeeTran") Try Dim sqlcmdContactID As SqlCommand = _ New SqlCommand("select contactid from " & _ "HumanResources.Employee where " & _ "HumanResources.Employee.EmployeeID = @EmployeeID", sqlcon) sqlcmdContactID.Parameters.Add("@EmployeeID", _ SqlDbType.Int).Value = EmployeeID sqlcmdContactID.Transaction = transaction Dim contactID As Integer = _ CType(sqlcmdContactID.ExecuteScalar, Integer) Dim sqlcmdEmployee As SqlCommand = _ New SqlCommand(" update Person.Contact set " & _ "FirstName = @FirstName, MiddleName = @MiddleName, " & _ "LastName = @LastName, EmailAddress = @EmailAddress, " & _ "Phone = @Phone where Person.Contact.ContactID " & _ "= @ContactID; update HumanResources.Employee " & _ "set Title = @Title, BirthDate = @BirthDate, " & _ "MaritalStatus = @MaritalStatus, Gender = @Gender, " & _ "HireDate = @HireDate where " & _ "HumanResources.Employee.EmployeeID = @EmployeeID; ", sqlcon) sqlcmdEmployee.Transaction = transaction sqlcmdEmployee.Parameters.Add("@ContactID", _ SqlDbType.Int).Value = contactID sqlcmdEmployee.Parameters.Add("@EmployeeID", _ SqlDbType.Int).Value = EmployeeID sqlcmdEmployee.Parameters.Add("@FirstName", _ SqlDbType.VarChar, 50).Value = EmployeeFirstName sqlcmdEmployee.Parameters.Add("@MiddleName", _
350
The Complete Reference To Professional SOA with Visual Studio 2005
SqlDbType.VarChar, 50).Value = EmployeeMiddleName sqlcmdEmployee.Parameters.Add("@LastName", _ SqlDbType.VarChar, 50).Value = EmployeeLastName sqlcmdEmployee.Parameters.Add("@EmailAddress", _ SqlDbType.VarChar, 50).Value = EmailAddress sqlcmdEmployee.Parameters.Add("@Phone", _ SqlDbType.VarChar, 50).Value = Phone sqlcmdEmployee.Parameters.Add("@Title", _ SqlDbType.VarChar, 50).Value = Title sqlcmdEmployee.Parameters.Add("@BirthDate", _ SqlDbType.DateTime).Value = DateTime.Parse(BirthDate) sqlcmdEmployee.Parameters.Add("@MaritalStatus", _ SqlDbType.VarChar, 50).Value = MaritalStatus sqlcmdEmployee.Parameters.Add("@Gender", _ SqlDbType.VarChar, 50).Value = Gender sqlcmdEmployee.Parameters.Add("@HireDate", _ SqlDbType.DateTime).Value = DateTime.Parse(HireDate) sqlcmdEmployee.ExecuteNonQuery() transaction.Commit() Catch ex As Exception transaction.Rollback() Throw New Exception(ex.Message) End Try End Sub
In listing 9-19 and listing 9-20 we’re providing the functionality to allow the consumer of the Web Service to update a particular employee’s details. The consumer of the Web Service simply need to pass in an ID of the employee followed by its details in the form of string parameters. The Web Service will then execute an update statement on the Sql Server database on the server. Once the above-mentioned Web methods had been created, we can now build and run our ASP.NET Web Service application. To build an ASP.NET Web Service application, select Build Solution from the Build menu. In order to execute the ASP.NET Web Service project, select Start Debugging from the Debug menu. When launching debugging for the first time we will be prompted whether we wanted to enable debugging. In this instance we will enable debugging see figure 9-7.
Figure 9-7. Debug diaglog option which will create the Web.config file.
351
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 9-8. Shows the Web Service running
Once the Web Service is started we can see the three WebMethods that we had created earlier, GetEmployeeByID, GetEmployees, UpdateEmployeeDetailByID see figure 9-8. .NET will also create the test harness for each of the WebMethod. If we clicked on the links which is represented as the GetEmployeeByID WebMethod.
352
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 9-9. Test harness for WebMethod
Shows the test harness that was generated around the WebMethod figure 9-9. By entering an EmployeeID value of 1 we can then invoke this WebMethod to see the result that it produces. The result is shown in figure 910.
Figure 9-10. GetEmployeeByID WebMethod result Listing 9-21. The result of GetEmployeeByID
353
The Complete Reference To Professional SOA with Visual Studio 2005
1 Guy R Gilbert [email protected] 320-555-0195 Production Technician - WC60 1972-05-15T00:00:00+10:00 M M 1996-07-31T00:00:00+10:00 1209
From the result in listing 9-21 above we can see the actual values that will be returned by the WebMethod. In our GetEmployeeByID we returned a dataset from the result returned above we can see that the DataSet is being returned.
Deploying Web Service In the last section, we looked at how to create XML Web Services and consume them remotely. After we have created a XML Web Service, we need to deploy the XML Web Service to a Web server to make it available to the applications that want to use the XML Web Service. When we deploy an XML Web Service, we publish the discovery .disco file. The discovery file for an XML Web Service contains information such as the location of Web Services. Each client that needs to access our XML Web Service uses this file to locate the Web Service. In the following section, we will examine what we need to perform when deploying and publishing an XML Web Service. In addition, we will learn about the XML Web Services discovery mechanism and how to configure discovery information on our XML Web Service. When we deploy an XML Web Service on a Web server, the service is published on the Web and becomes accessible to client applications. We can deploy an XML Web Service on a Web server in two ways. We can either create a Web setup project or we can publish the the XML Web Service files to the Web server. We will
354
The Complete Reference To Professional SOA with Visual Studio 2005
discuss the creation of setup projects in a later chapter. We will now deploy an XML Web Service by publishing the XML Web Service files to the Web server. To deploy our XML Web Service on a Web server, perform the following steps: Click on Build -> Publish Web Site see figure 9-11.
Figure 9-11: Publish Web Site
Figure 9-12. Publish Web Site
Enter the Target Location for the Web Service to be published as http://localhost/soawebservice/deploy/employee then press the OK button. See figure 9-12 above After the Web Service has been deployed we can check by browsing to the location http://localhost/soawebservice/deploy/employee/employee.asmx in our Internet Explorer see figure 9-13 below.
355
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 9-13. Deployed Employee Web Service
We can see the deployed files by browsing to the location in the file explorer see figure 9-14 below.
Figure 9-14. Shows the files created under the deployed Employee Web Service.
When we are publishing to a HTTP location. We could also publish to a UNC share. If we wanted to publish to a remote Web site using HTTP or FTP, the Target Location box is where we would specify the remote server URL. The Allow this precompiled site to be updatable option specifies that all program code is compiled into assemblies, but that .aspx files (including single-file ASP.NET Web pages) are copied as-is to the target folder see figure 9-12.
Note: All data in the target folder and its subfolders will be deleted. Make sure that you do not type the name of a folder that contains data
356
The Complete Reference To Professional SOA with Visual Studio 2005
or contains subfolders with data.
Web Service File Types These are some of the common file types that are used in .NET Web Service. *
AssemblyInfo file, an assembly is the functional unit for sharing and reuse in the common language runtime. The AssemblyInfo file consists of general information about the assembly in the project. To modify the assembly information, such as the version number, we can change the attributes in the AssemblyInfo file.
*
Web.config file, this file contains configuration information, such as the debug mode and the authentication mode for a Web project. It also includes information about whether to display custom errors for a Web project. We can also use the Web.config file to store custom configuration information for our XML Web Service.
*
Global.asax and Global.asax.cs or Global.asax.vb files, these files enable us to manage application-level and session-level events. These files reside in the root directory of an ASP.NET Web application or ASP.NET Web Service. The Global.asax.cs or Global.asax.vb class file contains the code for handling application events such as the Application_OnError event. These files when deployed are created as App_global.asax.dll and placed under the bin directory.
*
Service.asmx and the Service.cs or Service.vb files, these two files make up a single XML Web Service. The Service.asmx file contains the XML Web Service processing directive and serves as the addressable entry point for the XML Web Service. The Service.cs or Service.vb class file is located under App_Code, dependent file of WebService.asmx and contains the code-behind class for the XML Web Service.
*
WebService.disco, the .disco file is also known as the discovery file. This file is an XML-based file that contains links or URLs to resources providing discovery information for an XML Web Service.
*
The \Bin directory, this directory contains the compiled classes and every referenced assembly for the XML Web Service.
XML Web Services Discovery Mechanism The XML Web Service discovery mechanism allows a client application to locate or discover the documents that describe an XML Web Service. The XML Web Service discovery mechanism returns a service description document to a client. The service description document is written in Web Services Description Language (WSDL) and contains information about the capabilities of an XML Web Service, its location, and how to interact with it. In the XML Web Service discovery process, files, such as service descriptions, XSD schemas, or discovery documents, which contain the details of an XML Web Service, are downloaded to the client computer. A discovery document usually defined by the .disco extension defines a document that contains information and references of resources to the location of the Web Service. This information will help the clients in discovering the XML Web Service. In the ASP.NET Framework the discovery document is automatically generated and handled by the .ASMX. We can query a Web Service for its discovery document by adding “?disco” query at the end of the .asmx address. In the case of accessing the Employee Web Service’s discovery document we would specify the following address: http://localhost/soa/AdventureWorks/Employee/Employee.asmx?disco
The generated code is shown in the listing 9-22below.
357
The Complete Reference To Professional SOA with Visual Studio 2005
Listing 9-22. Discovery document
Adding Custom Discovery Information for a Web Service At design time, the discovery process helps the client application of a Web Service learn about details, such as the location and capabilities of the Web Service. The discovery mechanism also enables the client to find out how to interact with the XML Web Service. A client application can programmatically discover a XML Web Service through a .disco file for the XML Web Service. By default the XML Web Service will automatically generate the discovery document for us. The discovery document is automatically generated for an XML Web Service when we access it using a URL with ?DISCO in the query string. For example, if the URL for an XML Web Service is in our case http://localhost/soa/AdventureWorks/Employee/Employee.asmx, a discovery document is automatically generated with http://localhost/soa/AdventureWorks/Employee/Employee.asmx?disco as the URL. To configure discovery information for an XML Web Service, perform the following steps: 1.
Create an XML document and insert the tag in the first line.
2.
Add a element, such as:
3.
Add references to service descriptions, XSD schemas, and other discovery documents within the element as displayed in the following code:
4.
Then deploy the discovery document to a location on the Web server.
358
The Complete Reference To Professional SOA with Visual Studio 2005
After we have specified the discovery information for our XML Web Service and have published the discovery file, users can browse the discovery file to locate our XML Web Service. After a client application discovers a Web Service, the client application can access and use all the exposed methods of a Web Service. The process of using an exposed method of a Web Service is known as consuming a Web Service.
Consuming Web Service To consume the Web Service with Visual Studio 2005 is quite easy. In the following section we will create a sample windows application that will consume the Web Services that we had earlier and help us maintain the employee information within the system. We will now create a windows application that will act as the client to access our Web Services that we had built earlier. Web Services are very flexible and robust they can be accessed by any application that uses SOAP to communicate with it. It is also possible to use HTTP POST, and GET to execute a Web Service.
Figure 9-15: Create a new windows application.
To create a new windows project in Visual Studio 2005 select File -> New -> Project. This will bring up a new project dialog window. In the New Project window select the language that we want to use and select Windows Application from the Templates. Specify the name of the project as EmployeeClient and select a location for the project. Then click OK see figure 9-15.
359
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 9-16: Add a reference to the Web Service
Tip: If the Web References node under the project cannot be seen the same result can be achieved by right clicking the project and selecting Add Web Reference.
We need to add a Web Reference to the Web Service that we had created earlier. It is just a way for the application to know where to execute the Web Service at. In Visual Studio 2005 by adding a Web Reference to the Web Service Visual Studio also automatically generate the proxy class for us. To add a reference in Solution Explorer. Right click on the Windows Project right mouse click and select “Add Web Reference”.
Figure 9-17: Add Web Reference
In Listing 9-17 above we’re adding a reference to the Web Service. By simply entering the location of the Web Service asmx press the Go button. We should be able to see the Employee Web Service and its
360
The Complete Reference To Professional SOA with Visual Studio 2005
WebMethods. Then we need to give it a reference name. In this case we will call it WSEmployee. Once complete select Add Reference.
Figure 9-18: Solution explorer
Tip : Click the Show All Files button within the Solution Explorer window to display other files under the WSEmployee node.
In figure 9-18 we can see that the reference to the Web Service was added onto the windows application. By adding the reference Visual Studio 2005 has also created some files for us. These are the Employee.disco, Employee.wsdl, Reference.map and Reference.cs. Employee.disco, this file contains information which is used by Visual Studio for its discovery purposes. The discovery file helps to provide location of useful resources as well as contain details about the different forms of bindings that can be used against the XML Web Service. The content of the Employee.disco is shown in the listing 9-23below. Listing 9-23. Employee.disco
361
The Complete Reference To Professional SOA with Visual Studio 2005
Employee.wsdl, the wsdl file contains the Web Service Description Language for the Employee Web Service. A .wsdl file is essentially the interface for the Web Service it describes the methods that are available to be consumed as well as the parameter and its datatype that’s required for each method. The .wsdl file is itself described by a XML grammar see listing 9-24. Listing 9-24. Demonstrates the Employee.wsdl file
362
The Complete Reference To Professional SOA with Visual Studio 2005
. .
Reference.map, this file contains an XML mapping to the WSDL file. If we expand the Reference.Map node we can see a Reference.cs or a Reference.vb file nested underneath the mapping. This file is known as the proxy. The proxy is a WSDL to code mapping. The mapping allows us to invoke methods that are exposed by the WSDL by invoking .NET code see listing 9-25below. Listing 9-25. Demonstrates the Reference.map file
Reference.cs, this is the proxy file which contains the mapped WSDL in .NET code class. It allows a .NET client to invoke methods on the XML Web Service over the network. It also handles the SOAP encoding and decoding as messages are sent to and from the XML Web Service see listing 9-26 for reference.cs and listing 9-27 for reference.vb. The code generated for the proxy is quite lengthy for our purpose only the UpdateEmployeeDeatilByID() is shown. Listing 9-26. UpdateEmployeeDetailByID method contained in the Reference.cs when using Visual C#
. . [System.Web.Services.Protocols.SoapDocumentMethodAttribute( "http://tempuri.org/UpdateEmployeeDetailByID", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public void UpdateEmployeeDetailByID(int EmployeeID, string EmployeeFirstName, string EmployeeMiddleName, string EmployeeLastName, string EmailAddress, string Phone, string Title, string BirthDate, string MaritalStatus, string Gender, string HireDate) { this.Invoke("UpdateEmployeeDetailByID", new object[] { EmployeeID, EmployeeFirstName, EmployeeMiddleName, EmployeeLastName, EmailAddress, Phone, Title, BirthDate, MaritalStatus, Gender, HireDate}); } . .
364
The Complete Reference To Professional SOA with Visual Studio 2005
Listing 9-27. UpdateEmployeeDetailByID method contained in the Reference.vb when using Visual Basic .NET . . Public Sub UpdateEmployeeDetailByID(ByVal EmployeeID As Integer, _ ByVal EmployeeFirstName As String, ByVal EmployeeMiddleName As String, _ ByVal EmployeeLastName As String, ByVal EmailAddress As String, _ ByVal Phone As String, ByVal Title As String, ByVal BirthDate As String, _ ByVal MaritalStatus As String, ByVal Gender As String, _ ByVal HireDate As String) Me.Invoke("UpdateEmployeeDetailByID", New Object() { _ EmployeeID, EmployeeFirstName, EmployeeMiddleName, EmployeeLastName, _ EmailAddress, Phone, Title, BirthDate, MaritalStatus, Gender, HireDate}) End Sub . .
The proxy file can be created automatically when we use Visual Studio’s “Add Web Reference” option to a XML Web Service. We can also generate the proxy file using the command line utility wsdl.exe in the .NET Framework. We can access the wsdl.exe utility through the Visual Studio 2005 Command Prompt where the environment variables are setup for us to use within the command window. To use the wsdl.exe tool we need to pass the location of the WSDL file to the tool. The tool by default will generate visual C# proxy. The proxy can then be used to invoke the Web Service. wsdl http://localhost/soa/AdventureWorks/Employee/Employee.asmx?wsdl
We can also specify a particular file name by using the /out: parameter : wsdl /out:ReferenceProxy.cs http://localhost/soa/AdventureWorks/Employee/Employee.asmx?wsdl
For VB.NET users we can generate VB proxy by using the /language parameter. The following syntax will create a VB proxy file called myProxyClass.vb. wsdl /language:VB /out:myProxyClass.vb http://localhost/soa/AdventureWorks/Employee/Employee.asmx?wsdl
Client Application Once the reference has been added and the proxy class to the Web Service was created. We can now start on our windows application to access the Web Service we have created earlier. In this instance we will be creating a windows application. We will need to create the user interface for the application first.
365
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 9-19: Employee Management Client
Figure 9-19 shows the user interface for our windows application we will be creating to call on our Web Service. 1.
To create the user interface first, select GroupBox from the Toolbox window. To add a GroupBox on to the Windows form we could either double click on the GroupBox component or drag and drop the GroupBox component onto the Windows form.
2.
Select the text of the GroupBox right click and select properties
3.
Change the Text property of the GroupBox to “Get Employee Details”
4.
Next drag and drop a Label control from the Toolbox window onto the GroupBox.
5.
Right click on the label select properties and change the Text property to “Employee ID”.
6.
Select a TextBox control from the Toolbox window and drag and drop the control onto the “Get Employee Details” GroupBox.
7.
Right Click on the new TextBox and select properties. Change the name property to “textBoxGetEmployeeID”
8.
Select a Button control from the Toolbox and drag and drop the control onto the “Get Employee Details” GroupBox.
9.
Right click on the new Button control select properties and change the Text of the button to “Get Employee” and change the Name property of the control to “buttonGetEmployee”.
10. Select another Button control from the Toolbox and drag and drop the control onto the “Get Employee Details” GroupBox. 11. Right click on the new Button control select properties and change the Text of the button to “Get All Employees” and change the Name property of the control to “buttonGetAllEmployees”.
366
The Complete Reference To Professional SOA with Visual Studio 2005
Now we should have a user interface that look like figure 9-20 below.
Figure 9-20. User Interface
1.
Now we need to create a second GroupBox. To do this select the GroupBox control from the Toolbox window and drag and drop the control onto the Windows form. Right click on the group box to select properties. Change the Text property of the GroupBox to “Update Employee Details”.
2.
Select a Label control and drag and drop the control into the “Update Employee Details” GroupBox. Change the Text property for the Label control to “Employee ID”.
3.
Select a TextBox control from the Toolbox window and drag and drop the control onto the “Update Employee Details” GroupBox next to the new Label.
4.
Right Click on the new TextBox and select properties. Change the Name property to “textBoxEmployeeID”
5.
Select another Label control and drag and drop the control into the “Update Employee Details” GroupBox. Change the Text property for the Label control to “First Name”.
6.
Select a TextBox control from the Toolbox window and drag and drop the control onto the “Update Employee Details” GroupBox next to the new Label.
7.
Right Click on the new TextBox and select properties. Change the Name property to “textBoxFirstName”
8.
Select another Label control and drag and drop the control into the “Update Employee Details” GroupBox. Change the Text property for the Label control to “Middle Name”.
9.
Select a TextBox control from the Toolbox window and drag and drop the control onto the “Update Employee Details” GroupBox next to the new Label.
10. Right Click on the new TextBox and select properties. Change the Name property to “textBoxMiddleName” 11. Select another Label control and drag and drop the control into the “Update Employee Details” GroupBox. Change the Text property for the Label control to “Last Name”. 12. Select a TextBox control from the Toolbox window and drag and drop the control onto the “Update Employee Details” GroupBox next to the new Label. 13. Right Click on the new TextBox and select properties. Change the Name property to “textBoxLastName” 14. Select another Label control and drag and drop the control into the “Update Employee Details” GroupBox. Change the Text property for the Label control to “Email Address”. 15. Select a TextBox control from the Toolbox window and drag and drop the control onto the “Update Employee Details” GroupBox next to the new Label. 16. Right Click on the new TextBox and select properties. Change the Name property to “textBoxEmailAddress”
367
The Complete Reference To Professional SOA with Visual Studio 2005
17. Select another Label control and drag and drop the control into the “Update Employee Details” GroupBox. Change the Text property for the Label control to “Phone”. 18. Select a TextBox control from the Toolbox window and drag and drop the control onto the “Update Employee Details” GroupBox next to the new Label. 19. Right Click on the new TextBox and select properties. Change the Name property to “textBoxPhone” 20. Select another Label control and drag and drop the control into the “Update Employee Details” GroupBox. Change the Text property for the Label control to “Title”. 21. Select a TextBox control from the Toolbox window and drag and drop the control onto the “Update Employee Details” GroupBox next to the new Label. 22. Right Click on the new TextBox and select properties. Change the Name property to “textBoxTitle” 23. Select another Label control and drag and drop the control into the “Update Employee Details” GroupBox. Change the Text property for the Label control to “Marital Status”. 24. Select a TextBox control from the Toolbox window and drag and drop the control onto the “Update Employee Details” GroupBox next to the new Label. 25. Right Click on the new TextBox and select properties. Change the Name property to “textBoxMaritalStatus”
26. Select another Label control and drag and drop the control into the “Update Employee Details” GroupBox. Change the Text property for the Label control to “Gender”. 27. Select a TextBox control from the Toolbox window and drag and drop the control onto the “Update Employee Details” GroupBox next to the new Label. 28. Right Click on the new TextBox and select properties. Change the Name property to “textBoxGender” 29. Select another Label control and drag and drop the control into the “Update Employee Details” GroupBox. Change the Text property for the Label control to “Birth Date”. 30. We need to add a DateTimePicker to the window. Select the DateTimePicker control from Toolbox and drag and drop the control onto the “Update Employee Details” GroupBox. 31. Right Click on the new DateTimePicker and select properties. Change the Name property to “dateTimePickerBirthDate” 32. In the DateTimePicker control set the CustomFormat “yyyy-MM-dd”. This will give us a datetime format of year-month-day. 33. Select another Label control and drag and drop the control into the “Update Employee Details” GroupBox. Change the Text property for the Label control to “Hire Date”. 34. Add another DateTimePicker to the window. Select the DateTimePicker control from Toolbox and drag and drop the control onto the “Update Employee Details” GroupBox. 35. Right Click on the new DateTimePicker and select properties. Change the Name property to “dateTimePickerHireDate”
368
The Complete Reference To Professional SOA with Visual Studio 2005
36. In the DateTimePicker control set the CustomFormat “yyyy-MM-dd”. This will give us a datetime format of year-month-day. 37. Select another Button control from the Toolbox and drag and drop the control onto the “Update Employee Details” GroupBox. 38. Right click on the new Button control select properties and change the Text of the button to “Update” and change the Name property of the control to “buttonUpdate”. 39. Right click on the Windows Form and select properties. Change the Text Property for the windows form to “CS Employee Client” or “VB Employee Client” accordingly.
Now we should have a user interface that look like figure 9-21 below.
Figure 9-21. User interface so far.
To display the result we will be using a DataGridView. A DataGridView is a control that can display result in a table format so we can see all the information. To add a DataGridView select the DataGridView control from Toolbox and drag and drop into the windows form. Select the Name property of the DataGridView and change it to “dataGridViewEmployee” With the datagrid the windows form should look something similar to figure 9-22 below.
369
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 9-22. The user interface
To access the methods within a Web Service we must first create an object of the Web Service. Since we had named our Web Service in an earlier figure 9-17 as WSEmployee. Listing 9-28. Creating the Proxy in Visual C# WSEmployee.Employee wsEmployee = new WSEmployee.Employee();
Listing 9-29. Creating the Proxy in Visual Basic .NET Private wsEmployee As WSEmployee.Employee = New WSEmployee.Employee
Behind each button is an event that is fired when the button is pressed. Visual Studio 2005 will automatically generate the event for us. To create these events simply double click on the button control that we’re interested in. Listing 9-30. Implementing Update button event using Visual C# private void buttonUpdate_Click(object sender, EventArgs e) { wsEmployee.UpdateEmployeeDetailByID( int.Parse(this.textBoxEmployeeID.Text), this.textBoxFirstName.Text, this.textBoxMiddleName.Text, this.textBoxLastName.Text, this.textBoxEmailAddress.Text, this.textBoxPhone.Text, this.textBoxTitle.Text, this.dateTimePickerBirthDate.Text, this.textBoxMaritalStatus.Text, this.textBoxGender.Text, this.dateTimePickerHireDate.Text); }
Listing 9-31. Implementing Update button event using Visual Basic .NET
370
The Complete Reference To Professional SOA with Visual Studio 2005
Private Sub buttonUpdate_Click(ByVal sender As Object, ByVal e As EventArgs)
wsEmployee.UpdateEmployeeDetailByID(Integer.Parse(Me.textBoxEmployeeID.Text), _ Me.textBoxFirstName.Text, Me.textBoxMiddleName.Text, Me.textBoxLastName.Text, _ Me.textBoxEmailAddress.Text, Me.textBoxPhone.Text, Me.textBoxTitle.Text, _ Me.dateTimePickerBirthDate.Text, Me.textBoxMaritalStatus.Text, _ Me.textBoxGender.Text, Me.dateTimePickerHireDate.Text) End Sub
In listing 9-30 and listing 9-31 above, we’re shown the button event for the Update button which when clicked will call on the UpdateEmployeeDetailByID WebMethod from our Web Service. We’re then passing the required parameters to the Web Service. We don’t have to worry about the serialization aspect of the call as .NET takes care of it for us. By invoking the Web Service function the proxy takes care of composing the SOAP request it will also takecare of the SOAP response from the Web Service. The format of the request being sent by the proxy is shown in the listing 9-32 below. The SOAP response format is shown in listing 9-33 below. The SOAP request and response is not something that we need to concern with as it is automatically handled by the Web Service proxy it is added here for additional information so that we have an idea what is sent and what is receieved upon each request and response. Listing 9-32. SOAP 1.1 request POST /soawebservice/deploy/employee/employee.asmx HTTP/1.1 Host: localhost Content-Type: text/xml; charset=utf-8 Content-Length: length SOAPAction: "http://tempuri.org/UpdateEmployeeDetailByID"
int string string string string string string string string string string
Listing 9-33. SOAP 1.1 response
371
The Complete Reference To Professional SOA with Visual Studio 2005
HTTP/1.1 200 OK Content-Type: text/xml; charset=utf-8 Content-Length: length
In listing 9-34 and listing 9-35 below we’re shown the button event for GetAllEmployees which when clicked invokes the GetEmployees() WebMethod. This WebMethod returns a DataSet which contains our data table. We then use this to populate the DataGridView with it. Listing 9-34. Implementing GetAllEmployees Event using Visual C# private void buttonGetAllEmployees_Click(object sender, EventArgs e) { DataSet dsEmployees = wsEmployee.GetEmployees(); this.dataGridViewEmployee.DataSource = dsEmployees.Tables[0]; }
Listing 9-35. Implementing GetAllEmployees Event using Visual Basic .NET Private Sub buttonGetAllEmployees_Click(ByVal sender As Object, _ ByVal e As EventArgs) Dim dsEmployees As DataSet = wsEmployee.GetEmployees Me.dataGridViewEmployee.DataSource = dsEmployees.Tables(0) End Sub
The format of the request being sent by the proxy is shown in the listing 9-36 below. The SOAP response format is shown in listing 9-37 below. Again the SOAP request and response is not something that we need to concern with as it is automatically handled by the Web Service proxy it is added here for additional information so that we have an idea what is sent and what is receieved upon each request and response. Listing 9-36. SOAP 1.1 request POST /soawebservice/deploy/employee/employee.asmx HTTP/1.1 Host: localhost Content-Type: text/xml; charset=utf-8 Content-Length: length SOAPAction: "http://tempuri.org/GetEmployees"
372
The Complete Reference To Professional SOA with Visual Studio 2005
Listing 9-37. SOAP 1.1 response HTTP/1.1 200 OK Content-Type: text/xml; charset=utf-8 Content-Length: length
schemaxml
In listing 9-38 and listing 9-39 below we’re shown the button event for GetEmployee button click. When this button is clicked the GetEmployeeByID() WebMethod of the Web Service is invoked. This in turn returns a dataset with the values of the specified employee. Listing 9-38. Implementing GetEmployee using Visual C# private void buttonGetEmployee_Click(object sender, EventArgs e) { DataSet dsEmployee = wsEmployee.GetEmployeeByID( int.Parse(this.textBoxEmployeeID.Text)); this.dataGridViewEmployee.DataSource = dsEmployee.Tables[0]; this.textBoxEmployeeID.Text = dsEmployee.Tables[0].Rows[0] ["EmployeeID"].ToString(); this.textBoxFirstName.Text = dsEmployee.Tables[0].Rows[0] ["FirstName"].ToString(); this.textBoxMiddleName.Text = dsEmployee.Tables[0].Rows[0] ["MiddleName"].ToString(); this.textBoxLastName.Text = dsEmployee.Tables[0].Rows[0] ["LastName"].ToString(); this.textBoxEmailAddress.Text = dsEmployee.Tables[0].Rows[0] ["EmailAddress"].ToString(); this.textBoxPhone.Text = dsEmployee.Tables[0].Rows[0] ["Phone"].ToString(); this.textBoxTitle.Text = dsEmployee.Tables[0].Rows[0] ["Title"].ToString(); this.dateTimePickerBirthDate.Text = dsEmployee.Tables[0].Rows[0] ["BirthDate"].ToString(); this.textBoxMaritalStatus.Text = dsEmployee.Tables[0].Rows[0] ["MaritalStatus"].ToString(); this.textBoxGender.Text = dsEmployee.Tables[0].Rows[0] ["Gender"].ToString(); this.dateTimePickerHireDate.Text = dsEmployee.Tables[0].Rows[0] ["HireDate"].ToString();
373
The Complete Reference To Professional SOA with Visual Studio 2005
}
Listing 9-39. Implementing GetEmployee using Visual Basic .NET Private Sub buttonGetEmployee_Click(ByVal sender As Object, _ ByVal e As EventArgs) Dim dsEmployee As DataSet = wsEmployee.GetEmployeeByID( _ Integer.Parse(Me.textBoxEmployeeID.Text)) Me.dataGridViewEmployee.DataSource = dsEmployee.Tables(0) Me.textBoxEmployeeID.Text = dsEmployee.Tables(0) _ .Rows(0)("EmployeeID").ToString() Me.textBoxFirstName.Text = dsEmployee.Tables(0) _ .Rows(0)("FirstName").ToString Me.textBoxMiddleName.Text = dsEmployee.Tables(0) _ .Rows(0)("MiddleName").ToString Me.textBoxLastName.Text = dsEmployee.Tables(0) _ .Rows(0)("LastName").ToString Me.textBoxEmailAddress.Text = dsEmployee.Tables(0) _ .Rows(0)("EmailAddress").ToString Me.textBoxPhone.Text = dsEmployee.Tables(0) _ .Rows(0)("Phone").ToString Me.textBoxTitle.Text = dsEmployee.Tables(0) _ .Rows(0)("Title").ToString Me.dateTimePickerBirthDate.Text = dsEmployee.Tables(0) _ .Rows(0)("BirthDate").ToString Me.textBoxMaritalStatus.Text = dsEmployee.Tables(0) _ .Rows(0)("MaritalStatus").ToString Me.textBoxGender.Text = dsEmployee.Tables(0) _ .Rows(0)("Gender").ToString Me.dateTimePickerHireDate.Text = dsEmployee.Tables(0) _ .Rows(0)("HireDate").ToString End Sub
The format of the request being sent by the proxy to invoke the GetEmployeeByID() WebMethod is shown in the listing 9-40 below. The SOAP response format is shown in listing 9-41 below. Listing 9-40. SOAP 1.1 request POST /soawebservice/deploy/employee/employee.asmx HTTP/1.1 Host: localhost Content-Type: text/xml; charset=utf-8 Content-Length: length SOAPAction: "http://tempuri.org/GetEmployeeByID"
int
374
The Complete Reference To Professional SOA with Visual Studio 2005
Listing 9-41. SOAP 1.1 response HTTP/1.1 200 OK Content-Type: text/xml; charset=utf-8 Content-Length: length
schemaxml
The result of the execution can be seen in figure 9-23 and figure 9-24 below.
Figure 9-23. Result of executing Get Employee to retrieve employee information.
375
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 9-24. Result from executing Get All Employees.
Summary XML Web Service allows us to build scalable, loosely coupled, platform-independent applications. XML Web Services enable disparate applications to exchange messages using standard protocols such as HTTP, XML, XSD, SOAP, and WSDL. In this chapter we have created an XML Web Service that provide specific functionality to the client applications over the Web. The Visual Studio 2005 IDE provides us with the environment that are needed to create projects for distributed desktop applications, Web applications, and XML Web Services. In this chapter we have also looked at deploying the XML Web Service to a Web server to make it available to the applications that want to use the XML Web Service. We can deploy an XML Web Service to a Web server by simply using the Publish Web Site function that’s available within Visual Studio 2005 which will allow us to deploy to a HTTP location. We could also publish to a UNC share or a remote Web site using HTTP or FTP. The XML Web Service discovery mechanism enables a client application to locate or discover the documents that describe an XML Web Service. The XML Web Service discovery mechanism returns a service description document to a client. The service description document is written in WSDL and contains information about the capabilities of the XML Web Service, its location, and how to interact with it. After we create an XML Web Service and publish it, any application having permission to access it can access our XML Web Service and consume its services. The application that consumes a Web Service is known as the Web Service client or Web Service consumer. A Web Service client can be a windows application, a web based application or a mobile application. This is because Web Services are interoperable through open standards.
376
The Complete Reference To Professional SOA with Visual Studio 2005
Chapter 10 Testing and Debugging an XML Web Service Using XML Web services to implement SOA is widely accepted in IT architectures today. Developers who implement XML Web service need to ensure their functionality is operational at all times through active and aggressive testing. Comprehensive functional, performance, interoperability, and vulnerability testing form the pillars of SOA testing. Only through vigorous and comprehensive testing can an enterprise ensure that their SOA is robust, scalable, interoperable and secure. Today, Web services have helped to blur the boundaries between network devices, security products, applications and other IT assets within an enterprise. Almost every IT asset can advertise its interface through a Web Services Definition Language (WSDL). This allows a distributed consuming application to easily consume the Web service using SOAP/XML messaging. Web services interface for the first time helped to provide unprecedented flexibility in application integration. Such flexibility makes it the responsibility of IT staff from all domains such as developers, network engineers, security & compliance officers, and application quality assurance (QA) testers to ensure that their Web services work as advertised. In this chapter we will be looking into how to test and analyze Web services with Visual Studio as well as looking at some of the internal features of Visual Studio Team System for Developers’ test functionality. We will also be learning about testing and why a testing phase should be implemented as part of the software development life cycle. In addition, we will learn about various types of testing.
Overview of the Testing Process When we develop an application, in addition to meeting the requirements of a customer, we must ensure that the application is defect-free. Therefore, we need to perform various levels of testing on the application. Testing accomplishes a number of tasks, such as checking whether the desired functionality is implemented and working. However, the most important aspect that testing measures is to ensure the quality of the application that we are developing. For a long time, creating error-free applications has been a high-priority for many organizations. In fact, organizations implement the testing phase as part of their application development life cycle. The following factors contribute to the importance of testing: *
Testing reduces the cost of developing an application. The cost of rectifying an error after an application has been created is much more than the cost of implementing a thorough testing process as part of the development life cycle.
*
Testing ensures that our application performs as specified. In most cases, if testing is not implemented, we cannot actually predict the output of a certain operation.
*
Testing reduces the total cost of ownership. If a software application functions exactly as described in the documentation, users require fewer hours of training and less support from product experts.
377
The Complete Reference To Professional SOA with Visual Studio 2005
*
Testing develops customer loyalty and word-of-mouth market share. We are more likely to build a strong customer base with high-quality, bug-free software, which only thorough testing can provide.
To ensure that our application is free of defects and bugs, we can subject our applications to the following types of testing see Table 10-1: Table 10-1: Testing Types
Testing Type
Description
Requirements testing
This is where we perform testing to verify whether our application meets the requirements as specified in the software specification.
Usability testing
We perform usability testing to test the usability and ease of use of our application. During usability testing, we perform checks to ensure that all the information that users require is provided by the application. In addition, we also perform tests to ensure that the user interface is easily navigable.
Unit testing
During unit testing, we take the smallest unit of an application usually a method within a module and test it to ensure that it functions as expected. This ensures the quality of each function before they’re integrated onto the server.
Integration testing
Regression testing
During integration testing, we combine the functions that had already been tested through our unit testing phase into a component and test the interface that combines the two units. We then combine them into components, test the components, and integrate them into modules. The various modules are then tested and integrated into an application. We perform regression testing to ensure that any change made to code that has already been tested does not break the code. We can perform regression testing by executing the existing tests on the modified code or by creating new tests for the modified code, if necessary.
Organizing the Testing Effort The earlier we incorporate testing into an application's development process, the better our chances are for producing a defect-free application. We need to organize our testing effort carefully so that it is efficient and effective. It is advisable to develop an application in modules. The modular format enables us to plan for testing the modules separately. This ensures that when the individual modules are arranged in the final application, the entire application is error-free. The testing process involves testing module interaction and not module execution. Planning is crucial to a successful testing effort because it sets expectations about the outcome of the application's development life cycle. We should also consider the cost, schedule, and performance of the application in test plans. This increases the probability of a successful, effective, and efficient testing process.
Requirements-Based Testing The first phase of the software development life cycle involves gathering and analyzing requirements. The requirements phase provides the application's necessary features. Requirements also provide the basis for all
378
The Complete Reference To Professional SOA with Visual Studio 2005
types of testing. Based on the descriptions in the requirement specification, testing identifies defects that create, cause, or allow unpredictable behavior in the software. Therefore, the test team should also be involved in the specification-writing process. We should design our test cases while writing the requirements specifications. A test case consists of sample data and its corresponding output, which is calculated manually. To design test cases, we need to analyze each specification and determine how well the requirement supports the development of test cases. Developing a test case ensures that we will critically analyze the requirement specifications.
Developing a Test Plan A test plan outlines the entire testing process and includes the individual test cases. A test case includes sample data that is included in the application. The sample data is passed to the application, and the output is verified. To develop a reliable test plan, we must systematically explore the program to ensure that we cover all the modules thoroughly. A formal test plan establishes a testing process that does not depend upon accidental, random testing.
Approaches to Develop Test Plans There are two common approaches to testing: the waterfall approach and the evolutionary approach.
The Waterfall Approach The waterfall approach to application development and testing consists of various phases, which cover requirements analysis, design and specifications requirements, coding, final testing, and release. Before we begin working on a phase, the work in the preceding phase must have been completed. To the testing team, this means waiting for a final specification and then following the pattern set by the development team. A significant disadvantage of this approach is that it eliminates the opportunity for testing to identify problems early in the process; therefore, this approach is best suited for small projects of limited complexity.
The Evolutionary/Agile Approach In the evolutionary approach, we develop a modular piece or unit of an application, test it, fix it, and then add another small piece that adds functionality. We then test the two units as an integrated component, increasing the complexity as we proceed. Some of the advantages to this approach are: *
Low-cost opportunities to reappraise requirements and refine the design, as we understand the application better.
*
Consistently deliver a working, useful product. If we add functionality in priority order, we can stop development at any time.
*
Rather than developing one lengthy test plan, we can start with small, modular pieces of the final test plan. In the interim period, we can use the smaller pieces of the plan to locate bugs.
*
We can add new sections to the test plan, explore new areas, and use each part of the plan.
The Four Pillars of Successful Testing We can use traditional software development testing methods to test and validate our XML Web services when developing towards SOA. There are four main areas in testing which are vital for the successful implementation of
379
The Complete Reference To Professional SOA with Visual Studio 2005
SOA. These are: functional and regression testing, performance, interoperability, and vulnerability assessment see figure 10-1.
There are four pillars of successful testing, as shown in Figure 10-1.
Figure 10-1: The four pillars of successful testing
Pillar I: Functional & Regression Testing Functional and regression testing is the first line of defense against human error. It is thus the first pillar and one that we must focus on first. As developers or system integrators we need to quickly setup regression test cases that will allow us to test the changes that had just been implemented. Gaining the habit of setting up simple test cases is paramount to lowering potential issues later on. Later in this chapter we will learn to setup simple test case management to help us automate testing using Visual Studio this will help to lower the time required to execute test cases and provide a more reliable means of validating functionalities.
Pillar II: Performance The second pillar of successful testing is performance testing. Performance testing is often neglected by application developers and system integrators. Systems are often only tested with functional and regression testing. It is only after the system has been deployed into production performance bottlenecks become evident. Bottlenecks can be quite serious and they can easily bring enterprise systems to a crunching halt. Developers should always test Web services changes for scalability and robustness and ensure performance characteristics. Testers should determine response times, latency and throughput profiles for the targeted Web service. In addition testers should stress test the implementation by specifying duration for measuring endurance and robustness. We can also determine the scalability of a Web service by sending varying SOAP messages.
Pillar III: Interoperability The third pillar is ensuring interoperability of our changes with the rest of the application architecture. We can validate interoperability by testing the application for both design-time and runtime characteristics for the selected Web service. Developers can run a series of comprehensive Web Service Interoperability (WSI) profile tests and report interoperability issues with the Web service WSDL. Ensuring interoperability is important especially in architectures where more than one technology is used for example a Java or C++ application may require consuming the Web service. These tests validates the selected Web service for interoperability by sending specialized requests to the Web services to determine whether the Web services complies to the WSI Profile specification.
380
The Complete Reference To Professional SOA with Visual Studio 2005
Pillar IV: Vulnerability Assessment The last pillar is perhaps one of the most important and crucial to testing of them all and that is vulnerability assessment. If not assessed properly an organization can easily lose client financial information leading to depriving the organization of reputation and eventually business. Vulnerability assessment is very important in an open architecture such as the case of SOA. We need to vigorously test the Web services that we expose to ensure that there are no possible means available of performing actions that it was not designed to perform. In the past I have seen people breaking into databases through very simple SQL statements. This was only made possible by the developer who had carelessly given himself system administrator status. They had forgotten to reduce the privileges upon deploying the changes to production. As a result the entire operation was compromised. Resulting in considerable financial losses and not to mention damaging reputations. Thus security engineers always need to ensure that Web services vulnerabilities such as buffer overflows, deeply nested nodes, recursive payloads, schema poisoning, and malware traveling over SOAP messages do not affect their critical Web services. They can do this by rapidly scanning Web services and assessing areas of exposure, determining severity levels, providing vulnerability diagnosis, and then publishing remediation techniques. Web services vulnerability assessment is a crucial pre-production and post-production step for every service oriented application.
Debugging When we compile and execute the source code for a Visual Studio 2005 application, a .NET Framework compatible compiler compiles the source code to Microsoft Intermediate Language (MSIL) code. Then, the MSIL code is interpretated by the Common Language Runtime (CLR) and uses the Just In Time (JIT) to run the native code on a computer. When we debug a Visual Studio 2005 application, the debugger first maps the native code to MSIL, and then maps the MSIL code to source code by using a programmer database (PDB) file. Visual Studio 2005 provides debugging tools, such as DbgClr and CorDbg, to help developers locate and remove errors and bugs. The Microsoft CLR debugger (DbgCLR.exe) provides debugging services with a graphical interface to help application developers find and fix bugs in programs that target the common language runtime. Alternatively, CorDbg is a command-line debugging tool. Next we’ll look at how to debug Visual Studio 2005 applications by using these tools.
Cordbg.exe The .NET framework SDK provides CorDbg.exe which can be used to debug our .NET applications from the command prompt. To use CorDbg we first need to build the application so that it includes the appropriate /debug switch. CorDbg uses the run-time Debug API to debug applications. Here's how to use the debugger: cordbg [ProgramName[Program arguments]][optional arguments] command [command arguments]
Common Command
Description
b[reak] [[file:] line number] | [[ class::] function [:offset]]
Using the break command we can set or displays breakpoints. If no arguments are specified, the tool will display a list of current breakpoints
cont [count]
cont command continues the execution of the program. It can be used after execution has stopped due to breakpoints
381
The Complete Reference To Professional SOA with Visual Studio 2005
del[ete] [breakpoint id, ...]
Delete command can be used to remove breakpoints. We can specify a specific breakpoint id to remove. We can find the relevant breakpoint id by using the break or stop command.
h[elp] [command ...]
the help command words as help it can displays descriptions for a specified command. If no command is specfied then CorDbg.exe displays a list of debugger commands. The ? command can be used the same way as the help command.
k[ill]
We can stop the current process by using the kill command.
l[ist] option
list command can be used to displays a list of loaded modules, classes, or global functions.
We can specify several options: mod
Lists the loaded modules in the process.
cl
Lists the loaded classes in the process.
fu
Lists global functions for each module in the process.
n[ext] [count]
The next command can be used to step to the next line of source code. It will also step over function calls.
o[ut] [count]
The out command can be used to steps the program out of the current function. If no argument is specified the command will only perform a set out once for its current position. If we specify a count parameter the out command will be performed for the specified number of times.
p[rint] [variable name]
The print command can be used to display a local variable and its value. If no variable is specified all local variables are displayed.
ref[reshsource] [source file]
The refreshsource command can be used to reload the source code for a given file. The source must be part of the currently executing program.
r[un] [executable [args]]
The run command is use to execute a program for debugging we can also pass in parameters by specying them as arguments.
set variable value
set command can be used to set the value of a particular variable.
382
The Complete Reference To Professional SOA with Visual Studio 2005
sh[ow] [count]
The show command is used to display the source code. If no argument is specified then it will display five lines before and five lines after the current position in the source code. We can specify in the argument the number of source code lines to display before and after.
s[tep] [count]
The step command is used to step to the next source line. It can also be used to step into a function call.
w[here] [count]
The where command can be used to display a stack trace for the current thread. A count can be specified to display the specified number of stacks.
In the following example we will attempt to debug the following code in listing 10-1 and listing 10-2using CorDbg:
Listing 10-1. Sample code for debugging using Visual C# using System; using System.Collections.Generic; using System.Text; namespace HelloWorld { class Program { static void Main(string[] args) { for (int i = 0; i < 2; i++) { Console.WriteLine("Count: " + i); } } } }
Listing 10-2. Sample code for debugging using Visual Basic .NET Module Module1 Sub Main() Dim i As Integer = 0 While i < 2 Console.WriteLine("Count: " + i.ToString()) i += 1 End While End Sub
383
The Complete Reference To Professional SOA with Visual Studio 2005
End Module
When we debug an application using CorDbg, the application is debugged in a new CorDbg session. To start a CorDbg session, we need to type cordbg inside the Visual Studio 2005 Command Prompt, followed by the required command to control the debugging session. We can start debugging the program by using the cordbg helloworld.exe command. The command run helloworld.exe is invoked automatically within the cordbg environment. We can ignore the warning about mscorlib.dll, the cordbg utility simply informs us that we can not debug the core library that contains .NET Framework class library types. We are now in the cordbg command prompt see figure 10-2 below and listing 103 for output.
Figure 10-2. Launching cordbg Listing 10-3. starting cordbg D:\Projects\CH10\SourceCode\HelloWorld\ HelloWorld\bin\Debug>cordbg helloworld.exe Microsoft (R) Common Language Runtime Test Debugger Shell Version 2.0.50727.42 ( RTM.050727-4200) Copyright (C) Microsoft Corporation. All rights reserved. (cordbg) run helloworld.exe Process 5376/0x1500 created. Warning: couldn't load symbols for C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__ b77a5c561934e089\mscorlib.dll [thread 0x1504] Thread created. 010: { (cordbg)
We can use the show command to list five lines before and five lines after the current line of code. By entering show we get the following response from cordbg see listing 10-4below. Listing 10-4. using show command (cordbg) show
384
The Complete Reference To Professional SOA with Visual Studio 2005
005: namespace HelloWorld 006: { 007: class Program 008: { 009: static void Main(string[] args) 010:* { 011: for (int i = 0; i < 2; i++) 012: { 013: Console.WriteLine("Count: " + i); 014: } 015: } (cordbg)
In the listing 10-4 above, we can see that cordbg has listed the line number next to the code. The line numbers will serve as a reference point from which will allow us to set brake points. We can see that at line 10 there is an astrix * next to the line. This indicates where we are currently in the debugging process. We can set break points by using the ‘b’ command. For the purpose of this example we want to set our point on the line with the following code Console.WriteLine("Count: " + i); this is on line 13 determined from the listing 10-4 above. To break on line 13 use the command b 13. See listing 10-5 below. Listing 10-5. Adding break point (cordbg) b 13 Breakpoint #1 has bound to D:\Projects\Book\SourceCode\Ch10\HelloWorld\HelloWorl d\bin\Debug\helloworld.exe. #1 D:\Projects\Book\SourceCode\Ch10\HelloWorld\HelloWorld\Program.cs:13 Main+0x6(il) [active] (cordbg)
After we have set the break point we can ask the debugger to continue executing until the break point this can be achieved using the go command. See listing 10-6. Listing 10-6. Executing the go command (cordbg) go break at #1 D:\Projects\Book\SourceCode\Ch10\HelloWorld\HelloWorld\Program.c s:13 Main+0x6(il) [active] 013: (cordbg)
Console.WriteLine("Count: " + i);
The deubugger is now currently on line 13 we can see this by executing the show command again. See listing 10-7 below. Listing 10-7. show command (cordbg) show 008: { 009: static void Main(string[] args) 010: { 011: for (int i = 0; i < 2; i++) 012: {
385
The Complete Reference To Professional SOA with Visual Studio 2005
013:* Console.WriteLine("Count: " + i); 014: } 015: } 016: } 017: } (cordbg)
In the listing 10-7 above we can now see the astrix * is next to line 13. Now we want to find out the value of i to do this we can use the print command by specifying print i. This will return the value of 0. Now if we wanted to continue the execution to see if the value of i changes. We can execute the go command again. Because the break point is still set on line 13 and the for condition in Visual C#, while condition in Visual Basic .NET has not yet been satisfied the execution will still remain on line 13. By executing the print i command again we can see that the value of i has changed. See listing 10-8 below. Listing 10-8. using the print command (cordbg) print i i=0 (cordbg) go Count: 0 break at #1 D:\Projects\Book\SourceCode\Ch10\HelloWorld\HelloWorld\Program.c s:13 Main+0x6(il) [active] 013: Console.WriteLine("Count: " + i); (cordbg) print i i=1 (cordbg)
We have successfully debugged in the above example the value of i. To exit cordbg debug environment simply the exit command.
Debugging Using Visual Studio 2005 To start debugging an application, choose Start from the Debug menu of Visual Studio 2005, as shown in Figure 10-3. When we choose Start Debugging, the application starts and continues to execute until it reaches a breakpoint. When the application reaches a breakpoint, execution of the code is paused and the application enters break mode. In break mode, we can examine values by moving the cursor over an object. In addition, we can modify variables' values by using either the watch window or the command window.
386
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 10-3: Start Debugging
The Watch Window We can use the Watch window (see figure 10-4) to evaluate variables and expressions and maintain the results. To open the Watch window when an application is in break mode, from the Debug menu, point to Windows and choose Watch (Visual Studio 2005 allows up to four watch windows). We can also use the Watch window to edit the value of a variable or register. However, we cannot edit the values of constant variables.
Figure 10-4: Watch window
To add a variable to the watch window simply break at the location where you’re interested. Right mouse click over the variable and select Add Watch. You can also add the variable by simply drag and dropping it into the watch window. Alternative you could simply type the variable into the name fieled of the watch window.
The Call Stack Window We can use the Call Stack window, to view the function or procedure calls that are currently on the stack. To open the Call Stack window when an application is in break mode, from the Debug menu, point to Windows and choose Call Stack.
Figure 10-5: Call stack window
387
The Complete Reference To Professional SOA with Visual Studio 2005
The Call Stack window displays the name of each function and the language in which it is written. In addition to the function name, the Call Stack window displays optional information, such as module name; parameter name, parameter type, parameter value, line number and byte offset. To select the desired information to display, right-click in the Call Stack window and choose the appropriate information type.
The Locals Window The Locals window displays variables that are local to the current context. To open the Locals window when the application is in break mode, point to Windows on the Debug menu and choose Locals. We can also change the values of variables in the Locals window. To change the value of a variable, doubleclick the value that we want to change and type the new value.
Figure 10-6: Locals
The Autos Window Visual Studio also comes with the Auto window which can help us with the debugging process. The window will appear during debugging. We can use the Autos window, to view the variables used in the current statement and in the previous statement. However, when we are debugging a Visual Basic 2005 application, the Autos window displays variables in the current statement and in the three next and previous statements.
Figure 10-7: The Autos window
The Breakpoint Window In Visual Studio 2005 we can set breakpoints within the application. These are the locations in code where the debugger pauses the execution of a program. When our program and debugger reach a breakpoint, they are said to be in a break mode. We can set, enable, disable, edit, or delete breakpoints in the source code window or through the Breakpoints window (shown in Figure 10-8). To set a breakpoint in the source code window, we identify the
388
The Complete Reference To Professional SOA with Visual Studio 2005
statement where we would like to set the breakpoint and click on the grey margin on the left. To open the Breakpoints window, from the Debug menu, point to Windows and choose Breakpoints.
Figure 10-8: Breakpoints
In Visual Studio we can specify breakpoints within the application in several ways: *
File breakpoint - causes a program to break when execution reaches a specified location within a file.
*
Condition - an optional property that determines whether the program breaks when a breakpoint is reached. The condition can be any valid expression recognized by the debugger. The debugger evaluates the condition and breaks execution only if the condition is satisfied.
*
Hit Count - Hit count, as shown in Figure 10-9, determines whether our program breaks when the breakpoint is reached. This allows us to specify a condition. If the condition is met then the debugger will break. In this instance the debugger will be stopped at the nth time the break point is reached. We can also specify for multiple times of or breaking when the hit count is greater than or equal to.
Figure 10-9: Breakpoint hit Counter
*
Filter - we can restrict the breakpoint to only being set in certain processes and threads. We can enter the expression such as ProcessID=45 which will influence the breakpoint to only be set when the ProcessID=45 (see Figure 10-10). We can also combine conditions using & (AND), || (OR), ! (NOT), and parentheses.
389
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 10-10: Breakpoint Filter
*
When Hit - when a breakpoint is hit, this option allows you to specify a task that will run, for example a Visual Studio macro or a message display. When the breakpoint is hit, the message is written to the Output window (see Figure 10-11). This means we don’t have to add or remove any code.
Figure 10-11: When breakpoint is hit the result is written to the output window.
Testing With Visual Studio 2005 Microsoft Visual Studio 2005 Team System is the first version of Visual Studio to include a suite of tools for testing. These tools are specifically designed for developers and testers. The tools support testing throughout the entire software development and maintenance life cycles. In the past, testers have typically relied on third-party products such as Nunit, NAnt to create and execute test cases. In this section we will be looking at the functionalities provided by Visual Studio 2005 Team Edition for Software Developers.
Unit Testing To build clean, well-structured code, we developers need some mechanism to ensure that the code runs effectively. One solution is for the developer to write pieces of code and then run the application to see whether it works the way it should. The developer then moves on to the next piece of code, never coming back to test that functionality until it’s close to the release date. Unit tests are a way to automate that method of testing so that the tests can be run repeatedly as the product is developed.
390
The Complete Reference To Professional SOA with Visual Studio 2005
In order to create unit tests, we need to design a series of test cases that test whether the business logic is functioning correctly and whether inputs produce the expected outputs. To be complete, many unit tests might test the same piece of code to ensure that all the branches and internal code flow are tested. We’ll see how Visual Studio solves this problem when we talk about code coverage later. Because unit tests test basic functionality at the method level, they are considered to be a developer’s responsibility and not the responsibility of the testing staff. In the example below we will be creating a calculator Web service we will then attempt to test this calculator service with our unit tests. To start with create a new Web service called TestService, as shown in Figure 10-12.
Figure 10-12: New Web service called TestService
Enter the code below. First, Listing 10-9 shows the C#: Listing 10-9: C# for the Calculator Web service using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class Service : System.Web.Services.WebService { public Service () { //Uncomment the following line if using designed components //InitializeComponent(); } [WebMethod] public int AddInt(int x, int y) { return x + y; } [WebMethod]
391
The Complete Reference To Professional SOA with Visual Studio 2005
public int SubtractInt(int x, int y) { return x - y; } [WebMethod] public int MultiplyInt(int x, int y) { return x * y; } [WebMethod] public double DivideInt(int x, int y) { return x / y; } [WebMethod] public int DivideExceptionInt(int x, int y) { return x / y; } }
Or, if you prefer Visual Basic 2005, see Listing 10-10: Listing 10-10: Visual Basic for the Calculator Web service Imports System Imports System.Web Imports System.Web.Services Imports System.Web.Services.Protocols _ _ Public Class Service Inherits System.Web.Services.WebService Public Sub New() End Sub _ Public Function AddInt(ByVal x As Integer, ByVal y As Integer) As Integer Return x + y End Function _ Public Function SubtractInt(ByVal x As Integer, ByVal y As Integer) As Integer Return x - y End Function _ Public Function MultiplyInt(ByVal x As Integer, ByVal y As Integer) As Integer Return x * y
392
The Complete Reference To Professional SOA with Visual Studio 2005
End Function _ Public Function DivideInt(ByVal x As Integer, ByVal y As Integer) As Double Return x / y End Function _ Public Function DivideExceptionInt(ByVal x As Integer, ByVal y As Integer) As Integer Return x / y End Function End Class
Once we have completed our code we need to build the Web service application to verify that there are no outstanding syntax errors. Once the build is successful using Visual Studio we can generate our test project and our test methods. Simply right mouse click on the screen then select “Create Unit Tests” (see figure 10-13).
Figure 10-13: Create Unit Tests
A dialog window will appear (see Figure 10-14). In this window we can select the methods that we’d like to Visual Studio to generate test cases for.
393
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 10-14: Create Unit Tests
Pressing the Settings button brings a dialog screen from which we can specify our settings to generate our new test project (see Figure 10-15). In our example we will leave the settings as they are.
Figure 10-15: Test Generation Settings
In the Output project selection checked that you have selected your default language either “Create a new Visual Basic test project…” or “Create a new Visual C# test project”. Make sure you have selected all the methods then click OK. Enter VBCalcUnitTest as the new project name then select Create, as shown in Figure 10-16.
394
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 10-16: New Test Project
The Test Generation Progress dialog box appears showing the test classes' generation progress (see Figure 1017)
Figure 10-17: Test generation
Visual Studio will generate the new test cases for the previously selected methods. We can see an example of the generated test case in listing 10-11 and listing 10-12. Listing 10-11: Auto generated TestMethod() in C# [TestMethod()] public void AddIntTest() { Service target = new Service(); // TODO: Use [AspNetDevelopmentServer] //and TryUrlRedirection() to auto launch and bind web service. int x = 0; // TODO: Initialize to an appropriate value int y = 0; // TODO: Initialize to an appropriate value int expected = 0; int actual; actual = target.AddInt(x, y); Assert.AreEqual(expected, actual, "UnitTest.localhost.Service.AddInt did not return the expected value."); Assert.Inconclusive("Verify the correctness of this test method."); }
Listing 10-12: Auto generated TestMethod() in Visual Basic 2005 _ Public Sub AddIntTest() Dim target As Service = New Service 'TODO: Use [AspNetDevelopmentServer]
395
The Complete Reference To Professional SOA with Visual Studio 2005
'and TryUrlRedirection() to auto launch and bind web service. Dim x As Integer 'TODO: Initialize to an appropriate value Dim y As Integer 'TODO: Initialize to an appropriate value Dim expected As Integer Dim actual As Integer actual = target.AddInt(x, y) Assert.AreEqual(expected, actual, _ "VBCalcUnitTest.localhost.Service.AddInt did not return the expected value.") Assert.Inconclusive("Verify the correctness of this test method.") End Sub
Figure 10-18. Test project in solution explorer
The exact generated code will vary depending on the method type and signature that the test targets for testing. The wizard will create code using reflection to test private member functions. The generated test classes in the test project will contain test methods that is decorated with the TestMethodAttribute. In addition, the classes that contains these test methods are decorated with the TestClassAttribute. Both of these attributes can be found under the Microsoft.VisualStudio.QualityTools.UnitTesting.Framework namespace. The Team Test uses reflection to search a test assembly and find all of the test classes decorated with TestClassAttribute. It then finds the corresponding TestMethodAttribute within the test classes to determine what to execute. The test method themselves must not take any parameters it is validated by the execution engine but not by the compiler. When the tests is run, the Assert.Inconclusive() can be used to indicate that a correct implementation could be missing. The Assert class provides a number of members which allow us to test a particular condition or particular state of an object see Table 10-3.
396
The Complete Reference To Professional SOA with Visual Studio 2005
Table 10-3: Common Assert members
Name
Description
AreEqual
Checks to see whether the specified two values are equal if the values are not equal then the test fails.
AreNotEqual
Checks to make sure that the specified two values are not equal. The test fails if the value are equal.
AreNotSame
Checks to make sure the two inputs refer to different objects and fail if they are of the same object.
AreSame
Checks to ensure that the two inputs refer to the same object. The test fails if they refer to two different objects.
Fail
Fails the assertion.
Inconclusive
This means that the result can not be concluded. The test result can not be proven true or false.
IsFalse
Test to see if the condition is false. If the result is true then the assertion fails.
IsInstanceOfType
Test to see if the specified object is an instance of a specified type. If it is not of that type the test fails.
IsNotInstanceOfType Test to ensure that the specified object is not of an instance of the wrong type. IsNotNull
Tests to ensure that the specified object is not null. The test fails if the value is null.
IsNull
Tests to ensure that the specified object is of a null value or Nothing in Visual Basic. The test fails if it is not null.
IsTrue
Tests to ensure that the specified condition is true and the test fails if test condition is false.
We will now customize the test methods to unit test our calculator methods. Listing 10-13. ServiceTest, the C# unit test class used to test the Web service // The following code was generated by Microsoft Visual Studio 2005. // The test owner should check each test for validity. using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Text; using System.Collections.Generic; using CSCalcUnitTest.localhost;
397
The Complete Reference To Professional SOA with Visual Studio 2005
namespace CSUnitTest { /// ///This is a test class for CSUnitTest.localhost.Service and is intended ///to contain all CSUnitTest.localhost.Service Unit Tests /// [TestClass()] public class ServiceTest { private TestContext testContextInstance; /// ///Gets or sets the test context which provides ///information about and functionality for the current test run. /// public TestContext TestContext { get { return testContextInstance; } set { testContextInstance = value; } } #region Additional test attributes // //You can use the following additional attributes as you write your tests: // //Use ClassInitialize to run code before running the first test in the class // //[ClassInitialize()] //public static void MyClassInitialize(TestContext testContext) //{ //} // //Use ClassCleanup to run code after all tests in a class have run // //[ClassCleanup()] //public static void MyClassCleanup() //{ //} // //Use TestInitialize to run code before running each test // //[TestInitialize()] //public void MyTestInitialize() //{ //} // //Use TestCleanup to run code after each test has run //
398
The Complete Reference To Professional SOA with Visual Studio 2005
//[TestCleanup()] //public void MyTestCleanup() //{ //} // #endregion
/// ///A test for AddInt (int, int) /// [TestMethod()] public void AddIntTest() { Service target = new Service(); Random rand = new Random(); int x = rand.Next(100); int y = rand.Next(100); int expected = x + y; int actual; actual = target.AddInt(x, y); Assert.AreEqual(expected, actual, "CSUnitTest.localhost.Service.AddInt did not return the expected value."); } /// ///A test for DivideInt (int, int) /// [TestMethod()] public void DivideIntTest() { Service target = new Service(); Random rand = new Random(); int x = rand.Next(100); int y = rand.Next(100); double expected = (double)x/y; double actual; actual = target.DivideInt(x, y); Assert.AreEqual(expected, actual, "CSUnitTest.localhost.Service.DivideInt did not return the expected value."); } /// ///A test for MultiplyInt (int, int) /// [TestMethod()] public void MultiplyIntTest()
399
The Complete Reference To Professional SOA with Visual Studio 2005
{ Service target = new Service(); Random rand = new Random(); int x = rand.Next(100); int y = rand.Next(100); int expected = x*y; int actual; actual = target.MultiplyInt(x, y); Assert.AreEqual(expected, actual, "CSUnitTest.localhost.Service.MultiplyInt did not return the expected value."); } /// ///A test for SubtractInt (int, int) /// [TestMethod()] public void SubtractIntTest() { Service target = new Service(); Random rand = new Random(); int x = rand.Next(100); int y = rand.Next(100); int expected = x-y; int actual; actual = target.SubtractInt(x, y); Assert.AreEqual(expected, actual, "CSUnitTest.localhost.Service.SubtractInt did not return the expected value."); } } }
Listing 10-14. ServiceTest, the Visual Basic 2005 unit test class used to test the Web service 'The following code was generated by Microsoft Visual Studio 2005. 'The test owner should check each test for validity. Imports Microsoft.VisualStudio.TestTools.UnitTesting Imports System Imports System.Text Imports System.Collections.Generic Imports VBCalcUnitTest.localhost
''' '''This is a test class for VBCalcUnitTest.localhost.Service and is intended '''to contain all VBCalcUnitTest.localhost.Service Unit Tests '''
400
The Complete Reference To Professional SOA with Visual Studio 2005
_ Public Class ServiceTest
Private testContextInstance As TestContext ''' '''Gets or sets the test context which provides '''information about and functionality for the current test run. ''' Public Property TestContext() As TestContext Get Return testContextInstance End Get Set(ByVal value As TestContext) testContextInstance = Value End Set End Property #Region "Additional test attributes" ' 'You can use the following additional attributes as you write your tests: ' 'Use ClassInitialize to run code before running the first test in the class ' ' _ 'Public Shared Sub MyClassInitialize(ByVal testContext As TestContext) 'End Sub ' 'Use ClassCleanup to run code after all tests in a class have run ' ' _ 'Public Shared Sub MyClassCleanup() 'End Sub ' 'Use TestInitialize to run code before running each test ' ' _ 'Public Sub MyTestInitialize() 'End Sub ' 'Use TestCleanup to run code after each test has run ' ' _ 'Public Sub MyTestCleanup() 'End Sub ' #End Region
''' '''A test for AddInt(ByVal Integer, ByVal Integer) '''
401
The Complete Reference To Professional SOA with Visual Studio 2005
_ Public Sub AddIntTest() Dim target As Service = New Service Dim rand As Random = New Random Dim x As Integer = rand.Next(100) Dim y As Integer = rand.Next(100) Dim expected As Integer = x + y Dim actual As Integer actual = target.AddInt(x, y) Assert.AreEqual(expected, actual, _ "CSUnitTest.localhost.Service.AddInt did not return the expected value.") End Sub ''' '''A test for DivideInt(ByVal Integer, ByVal Integer) ''' _ Public Sub DivideIntTest() Dim target As Service = New Service Dim rand As Random = New Random Dim x As Integer = rand.Next(100) Dim y As Integer = rand.Next(100) Dim expected As Double = CType(x, Double) / y Dim actual As Double actual = target.DivideInt(x, y) Assert.AreEqual(expected, actual, _ "CSUnitTest.localhost.Service.DivideInt did not return the expected value.") End Sub ''' '''A test for MultiplyInt(ByVal Integer, ByVal Integer) ''' _ Public Sub MultiplyIntTest() Dim target As Service = New Service Dim rand As Random = New Random Dim x As Integer = rand.Next(100) Dim y As Integer = rand.Next(100) Dim expected As Integer = x * y Dim actual As Integer actual = target.MultiplyInt(x, y) Assert.AreEqual(expected, actual, _ "CSUnitTest.localhost.Service.MultiplyInt did not return the expected value.") End Sub ''' '''A test for SubtractInt(ByVal Integer, ByVal Integer) ''' _ Public Sub SubtractIntTest() Dim target As Service = New Service Dim rand As Random = New Random
402
The Complete Reference To Professional SOA with Visual Studio 2005
Dim x As Integer = rand.Next(100) Dim y As Integer = rand.Next(100) Dim expected As Integer = x - y Dim actual As Integer actual = target.SubtractInt(x, y) Assert.AreEqual(expected, actual, _ "CSUnitTest.localhost.Service.SubtractInt did not return the expected value.") End Sub End Class
Running Tests We can run our auto-generated test service by Test ~TRA Start Selected Test Project with Debugger or Shift + Alt + X (see Figure 10-19).
Figure 10-19: Start Selected Test Project
Figure 10-20 shows the Test Results windows. Columns can be added or removed by right-clicking on the column headers and selecting the Add/Remove Columns... menu item. In addition, we can right-click on individual tests and select the Open Test menu item to jump into the test code.
Figure 10-20: Test Result window after executing all tests
We can also use a unit test to check for exception conditions. The ExpectedExceptionAttribute listens for an exception during the execution of a test. If an exception occurs, the test passes. We can specify either the type of exception or both the type of the exception and the message the exception generates. This is useful if we needed to check that we’re throwing custom exceptions upon certain conditions. In the example we will be generating an exception by dividing 0 listing 10-15 and listing 10-16. Listing 10-15: Generating test exceptions with C# [TestMethod()]
403
The Complete Reference To Professional SOA with Visual Studio 2005
public void DivideExceptionIntTest() { Service target = new Service(); int x = 0; int y = 0; target.DivideExceptionInt(x, y); }
Listing 10-16: Generating test exceptions with Visual Basic 2005 _ Public Sub DivideExceptionIntTest() Dim target As Service = New Service Dim x As Integer = 0 Dim y As Integer = 0 target.DivideExceptionInt(x, y) End Sub
We can see that an exception had been thrown in Figure 10-21.
Figure 10-21: Shows the generated exception
We will now add the ExpectedExceptionAttribute, which will return successful when the exception is encountered. See listing 10-17 and listing 10-18. Listing 10-17. Adding ExpectedExceptionAttribute in C# [TestMethod()] [ExpectedException(typeof(SoapException))] public void DivideExceptionIntTest() { Service target = new Service(); int x = 0; int y = 0; target.DivideExceptionInt(x, y); }
Listing 10-18: Adding ExpectedExceptionAttribute in VB _ _ Public Sub DivideExceptionIntTest() Dim target As Service = New Service Dim x As Integer = 0 Dim y As Integer = 0
404
The Complete Reference To Professional SOA with Visual Studio 2005
target.DivideExceptionInt(x, y) End Sub
Figure 10-22 shows the Test Results window now we have added an ExpectedExceptionAttribute.
Figure 10-22: Result of using ExpectedExceptionAttribute.
Code Coverage One key metric for unit testing is determining how much of the code is tested when the unit tests run. The metric is known as the code coverage and Team Test includes a code coverage tool for detailing both the percentage of code that is executed along with highlighting within the code to show which lines are executed and which lines are not. To enable code coverage in VSTS go to Test ~TRA Edit Test Run Configuration ~TRA Local Test Run, as shown in Figure 10-24.
Figure 10-23: Select a Test Run Configuration
Under the Code Coverage option, select the artifacts to instrument, as shown in Figure 10-24. Then select Apply.
405
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 10-24: Enable Code Coverage
Start the test by selecting Test -> Start Selected Test Project Without Debugger. This results in highlighted code when run, as shown in Figure 10-25.
Figure 10-25: Highlighted Code Coverage
Initializing and Cleaning Up Tests In general, a test class contains not only the individual test methods, but also various methods for initializing and cleaning up tests as well. The test setup and cleanup methods are decorated with TestInitializeAttribute and TestCleanupAttribute respectively. Within each of these methods we can place any additional code that needs to be run before or after every test.
406
The Complete Reference To Professional SOA with Visual Studio 2005
During debugging it is possible that the TestCleanupAttribute decorated method will not run simply because the debugger was stopped before the cleanup code executed. For this reason, it is often a good practice to check for cleanup during test setup and execute the cleanup prior to the setup as necessary. Other test attributes available for initialization and cleanup are AssemblyInitializeAttribute/AssemblyCleanupAttribute and ClassInitializeAttribute/ClassCleanupAttribute. The assembly-related attributes run once for an entire assembly while the class related attributes run once each for the loading of a particular test class.
Static Analysis Creating quality code often involves analyzing code for known defects, which can be achieved through the use of static analysis. In Visual Studio 2005 Team System, the static analysis tool is an evolution of FxCop. The static code analyzer runs against compiled code, looking for a large number of known defects and poor programming practices. In addition, it can be used to enforce corporate naming conventions. The rules used by the static analyzer are fully extensible, and it is possible to add a new rule relatively quickly. It’s also possible to enable and disable rules that will be run against the code. For instance, we might choose not to run the rules that enforce naming conventions but be very interested in the results of the tests that check for known security issues. Finally, we can choose whether a violation of a rule generates a warning or a compile-time error. For coding conventions that absolutely must not be violated, using an error is the best practice and is one of the easiest to implement. Setting a violation of code from being checked in unless it has compiled without error, results in an easy to implement yet very powerful technique for guaranteeing a certain level of code quality. We can enable code analysis in Visual Studio by right click on a project selecting properties. Then selecting the Code Analysis tab see figure 10-26. To enable code analysis we will need to select the check box “Enable Code Analysis”.
Figure 10-26: Configuring static analysis for the code
Once we have enabled the project set up for code analysis, all we need to do is recompile our application. This will cause the static code analyzer to run. The results can then be seen by examining the Errors window (see figure 10-27). If a particular line of code caused the error, double-clicking the error in the Error window will open the appropriate code window and bring us to the problem area within the code.
407
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 10-27: Result from static analysis test in Visual Studio 2005
The results can also be saved to CodeAnalysisLog.xml. Opening this file will show all the issues the compiler had uncovered.
Figure 10-28: CodeAnalysisLog.xml
Profiling Code profiling is the process where we analyze the code and how quickly it executes. It enables developers to see where the bottleneck exists within the application quickly. After the application has been completed and the code unit tested we should always profile the code. There’re two types of methods to profile an application in Visual Studio: sampling and instrumentation.
408
The Complete Reference To Professional SOA with Visual Studio 2005
Sampling Using the sampling method, the profiler will periodically determine which function is being executed. The profiler keeps track of the number of times that it has executed the function by incrementing a counter. It interrupts the application in short intervals to build up a statistical view of he application. It’s a reliable way to determine where an application spends the majority of its time. Once the application is stopped, a report is generated that provides the details.
Instrumentation The instrumentation method is more aggressive than the sampling method. In this method, the profiler inserts enter and exit probes into specific functions of an application. These functions are now monitored when the application runs. The probes capture the deterministic performance metrics for the functions. This means that we can get information about how long a method takes to execute. This method also provides a relatively complete numeric look at how often various methods are called. Once the application is stopped, a report can be generated based on the data gathered by the instrumentation profiler.
Implementing Sampling To configure the performance we can check session properties under the Tools ~TRA Options ~TRA Environment ~TRA Performance Tools page in Visual Studio, shown in Figure 10-29. This is the section where we can specify all settings related to all performance sessions.
Figure 10-29: Configuring performance session.
The first option shown in Figure 10-29 is a radio button to show time as CPU clock ticks or milliseconds. The next option lets us select how many functions are shown in summary view. Summary view is the first view that we see when analyzing a performance run and it lists the top X functions in terms of total number of calls, total number of calls to a function and all child functions, and total time taken by a function. The last option allows us to serialize symbols, which saves symbols in with our .VSP files. The .VSP files can be copied and read on different systems without chasing down symbols files. These .VSP files are the files that are created with each run of the profiler. In the example below we will create a sampling session on a Web service client we had created in Chapter 9. Select the Tools ~TRA Performance Tools ~TRA Performance Wizard option, as shown in Figure 10-30.
409
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 10-30: Performance Wizard
In Figure 10-31 we will select Profile an executable (.EXE) because the application that we wanted to profile has already been compiled. We will be asked for the path to the file, the working directory, and any command-line arguments, more of which later. If we select a project in the current solution we will proceed straight to the performance session type page shown in Figure 10-33. For a .DLL, we have the same options as for an .EXE, but we also have to specify the path to an .EXE file that utilizes the selected .DLL. And for ASP.NET we are asked for the local URL of the ASP.NET application that we want to profile.
Figure 10-31: Performance Wizard
We will now browse to the location of the executable that we had created in Chapter 9 of the employee Web service client (the CSEmployeeClient project in Chapter 9), as shown in Figure 10-32.
410
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 10-32: Browse to a location of Exe application to performance test
The next screen asks us to pick either sampling or instrumentation profiling to profile our application. Select sampling, as shown in Figure 10-33. We will cover instrumentation a little later.
Figure 10-33: Select profiling method
In Figure 10-34 select Finish to complete the process.
411
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 10-34: Performance Wizard
In the sampling mode under Performance Explorer the Targets folder contains the item that we’re interested in collecting profiling data from (see Figure 10-35). If an icon has a green arrow then it indicates that this is the startup binary that will be automatically launched at the start of our profiling session. We can change this simply by right mouse clicking on the selected binary and specifying to launch the binary or not. We can also add more binaries to the performance session, simply by right clicking on the Targets folder and select Add Target Binary this allows us to add other binaries from other projects in the solution or even from an ASP.NET web application. In the sampling mode, data is collected from all binaries that are running. But in instrumentation mode, we can specify to collect data from the specific binaries that we choose to instrument. We can select the binaries that we want to instrument by right mouse clicking them in the performance explorer then selecting instrument. These binaries are marked with 1s and 0s on their icon to indicate that they will be instrumented when the performance session is launched. We using instrumentation, we should limit the number of instrumented binaries to keep them from being overwhelmed with data. Now, right mouse click on the Performance explorer and select Launch to launch our windows application, as shown in Figure 10-35.
Figure 10-35: Launch the application to profile
You will see the application...
412
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 10-36: Running the application
Once we close the Windows application the analysis of the results collected begins, as shown in Figure 1037.
Figure 10-37: Analyzing the report
The end result is a report into which we can drill to view the result from the execution of each method (see Figure 10-38).
413
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 10-38: Sampling performance report
The summary view for sampling lists the top three (this number can be adjusted in the Tools ~TRA Options ~TRA Performance page) functions in terms of inclusive samples and exclusive samples. In the performance report there’s a result set for inclusive and one for exclusive. An inclusive sample indicates which functions during execution is spending the most amount of time. An exclusive sample indicates which functions during execution is being called frequently though its execution could be quite fast. Thus in performance tuning the first areas to focus on is the exclusive samples because the function is being executed quite often. By examining the exclusive list we see that the mscorwks.dll (see Figure 10-39), a rather large DLL that is where most of the loading is happening. This DLL according to the report is where almost thirty-five percent of the sample has taken place. While looking at the inclusive report we can see that 99 samples were taken from the Main function or its sub functions. This indicates that we’re getting very few samples in areas outside of the performance scenario that we wanted to profile.
Figure 10-39: Instrumentation performance report
In instrumentation mode the performance report summary contains three different sections (see figure 1039). These are “most called functions,” “functions with most individual work” and “functions taking longest.” The “most called functions” lists the functions that had been called the highest number of times. The report also lists the number of times that they have been called. The “Functions with most individual work” section lists the functions in which most amount of time had been spent. The report shows the amount of time spent by each of these methods and their percentage against the total execution time.
414
The Complete Reference To Professional SOA with Visual Studio 2005
Lastly the “functions taking longest” section shows the functions that took the longest to execute this includes time spent in sub-functions this is similar to the inclusive mode for sampling. By using instrumentation every function entry and exit is captured. This provides a very detailed report which is not only limited to the samples. Figure 10-40 shows the instrumentation summary view for our demo application.
Figure 10-40: Result from the profiling
Generally determining which method to use for profiling is based on our needs. Sampling is often used as a first look at an application. The sampling method is also far less intrusive than the instrumentation method, and thus allows the application to run at a normal pace. It doesn’t, however, provide a complete analysis of the application. For example, even though we can see how the code appears within a method, we cannot determine how long that particular method took to execute. Instrumentation profiling provides for very specific performance metrics. However, it performs this in an intrusive manner. This makes the application seem like it is struggling, but it does provide a much fuller profile of the application and more reliable and specific information than the sampling method.
Summary Visual Studio 2005 Team System has integrated a lot of tools for developers. It provides a vast range of tool sets over previous versions of Visual Studio especially those tools help developers to develop efficiently and quickly. After using Visual Studio Team System it is difficult to go back to any other development environments. In this chapter we had looked at testing and how to accomplish a number of tasks, such as: *
Unit testing - Unit testing helps developers to build clean and well-structured code. It also helps to support the mechanism to ensure that the code written runs effectively.
*
Code coverage - Code coverage helps a developer to determine how much of the code is tested when the unit tests run. Team Test includes a code coverage tool for detailing both the percentage of code that is executed along with highlighting within the code to show which lines are executed and which lines are not.
*
Static analysis - Creating quality code often involves analyzing code for known defects, which can be achieved through the use of static analysis. The static code analyzer runs against compiled code, looking for a large number of known defects and poor programming practices.
415
The Complete Reference To Professional SOA with Visual Studio 2005
*
Profiling - Profiling the code ensures the performance of the code. After the application has been completed and the code unit tested we should always profile the code. Code profiling is the process where we analyze the code and how it quickly it executes. It enables developers to see where the bottleneck exists within the application quickly. There’re two types of methods to profile an application in Visual Studio 2005: sampling and instrumentation.
In addition to Visual Studio Team System Developer’s implementation to application testing. Visual Studio Team System Tester’s also helps with the implementation to integration and regression testing.
416
The Complete Reference To Professional SOA with Visual Studio 2005
Chapter 11 Deployment The .NET Framework provides features and tools that enable us to easily package and distribute a variety of applications to a number of users. In this chapter, we will learn how to create setup projects to automatically install and configure our Web service. Once we have ensured that our application is free from bugs, we need to distribute our Web service applications to end users by possibly deploying the application on various computers. In this chapter we will be looking at various deployment features of the .NET Framework.
.NET Deployment Ensuring successful deployment of an application is extremely important in the software development lifecycle, especially when the majority of the deployment today is done at the client’s site. Any sort of failure during the deployment process can easily become quite embarrassing. The .NET Framework is packed full of features and tools that we can use to deploy applications successfully. These features and tools enable us to deploy different types of applications to a large number of users. In addition, we can install new versions of applications on target computers without adversely affecting the older versions of our applications. The .NET Framework provides various packaging and distribution options that make it easy to deploy applications. The features of .NET deployment include No-impact deployment: In the past an incompatible version of DLL can be installed over an existing DLL. This
was a serious issue as it caused applications to stop working and was referred to as the “DLL Hell” problem. Noimpact deployment offered by the .NET Framework resolves this problem and DLL is deployed in isolation. Controlled code sharing: Because components are private by default, multiple applications cannot share
components. We need to explicitly make the components available for sharing by assigning a strong name to an assembly containing the components and installing the assembly in the global assembly cache. XCOPY deployment and reproduction: .NET applications and components are self describing and self
contained so there is no need for registry entries or other form of dependencies. This allows application to be simply copied from source to the destination directory on the target computer. Because of its simplicity it is often referred to as XCOPY deployment. XCOPY is a MS DOS copy command. Integration with the Windows Installer: Windows Installer offers rich capabilities and allows application users
to easily manage the deployed applications. Windows installer supports advertisement, publishing, repair and install-on-demand when deploying applications. By deploying with Visual Studio we are able to build deployment projects utilizing Windows Installer. Private components by default: By default, the components are deployed to the application directory. These
components are visible only to the containing application. Because components are private by default, they have no impact on other applications. Side-by-side versioning: The .NET Framework supports the deployment of multiple versions of a component or an application. We can specify the version of components that our application must use, and the Common Language Runtime will enforce the versioning policy. On the fly updates: One of the problems in the past with application update is that every application has to be
manually updated. With .NET applications administrators can use runtime hosts, such as ASP.NET, to update program DLLs, even on remote computers. This feature enables us to update an application without stopping it.
417
The Complete Reference To Professional SOA with Visual Studio 2005
ClickOnce Deployment: ClickOnce deployment is a new feature in .NET Framework 2.0. The deployment
process is as the name suggests is very simple. It allows the deployment of Windows based client applications to desktops by placing the application files on a Web server or file server that is accessible to the client. Enterprise deployment: Using the software installation feature of Active Directory,an administrator can
automatically distribute and install .NET applications on the entire network. Downloading and caching: .NET Applications and components can take advantage of the downloading and caching feature which allows incremental downloads of applications to reduce the impact of the deployment process on the client system. The components can also be isolated for use by the application for zero-impact deployment.
Maintaining Assembly Versions .NET applications are made up of discrete units of assemblies. These assemblies enable us to implement version control, reusability, and security permissions. In addition, assemblies also provide the common language runtime with the information it requires concerning type implementations. Therefore, assemblies are the fundamental units for deploying Visual Studio 2005 applications. The following sections explain how versioning is implemented for assemblies. The details of each assembly version information is stored within the assembly’s manifest. The assembly manifest contains specific information about the assembly’s version and the version of assemblies that are dependent. The assemblies keep version information through two ways. The assembly contains a Globally Unique Identifier (GUID) as an identification number and an informational version.
Figure 11-1: Assembly Information
An assembly’s information includes the version number, name and culture information about the assembly (see figure 11-1). The common language runtime considers assemblies that contain different version numbers to be different assemblies. The version number is a four part number consists of major version, minor version, build number and revision. The format of the version number is: ...
418
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 11-2: Specifying automatic assembly version
For example, in version 1.5.1153.0, the number 1 represents the major version, 5 represents the minor version, 1153 represents the build number, and 0 represents the revision number. The version number is stored in the assembly manifest along with other identity information, including the assembly name and public key, and information regarding the relationships and identities of other assemblies referenced in the application. When we build an assembly, the development tool stores dependency information for each referenced assembly in the assembly manifest.
Figure 11-3: AssemblyInfo.CS contains information regarding the assembly
There are three ways of specifying the assembly version. One way is using the Visual Studio IDE, right mouse click on our CSEmployeeClient project in the solution explorer, and the properties. We can directly specify the version of the assembly as shown in Figure 11-1. Select the Application tab then select Assembly Information. A dialog window will appear. We can specify the version of the assembly by typing the values into the assembly version section. The second way is to let Visual Studio automatically increment the version number for us upon each publication of the project Figure 11-2. Select Publish in the properties section of the project then select the checkbox for “Automatically increment revision with each publish”.
419
The Complete Reference To Professional SOA with Visual Studio 2005
The third way to specify the assembly version is to modify the AssemblyInfo.cs or AssemblyInfo.vb file. It can be found when we enable “Show All Files” in solution explorer. Then open the Properties folder under the project under C# and open the My Project folder under Visual Basic 2005. See Figure 11-3. The following code shows the attribute that we use to specify the version of an assembly see listing 11-1 and listing 11-2. Listing 11-1: Assembly.CS Using C# using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("CSEmployeeClient")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("devorg")] [assembly: AssemblyProduct("CSEmployeeClient")] [assembly: AssemblyCopyright("Copyright © devorg 2006")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("3e7a116c-4e4c-4760-9134-746e74849513")] // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")]
Listing 11-2: Assembly.VB using Visual Basic 2005 Imports System Imports System.Reflection Imports System.Runtime.InteropServices ' General Information about an assembly is controlled through the following ' set of attributes. Change these attribute values to modify the information ' associated with an assembly.
420
The Complete Reference To Professional SOA with Visual Studio 2005
' Review the values of the assembly attributes
'The following GUID is for the ID of the typelib if this project is exposed to COM
' Version information for an assembly consists of the following four values: ' ' Major Version ' Minor Version ' Build Number ' Revision ' ' You can specify all the values or you can default the Build and Revision Numbers ' by using the '*' as shown below: '
The AssemblyVersionAttribute attribute takes a string argument that represents the version number. We could represent our AssemblyVersion as 1.3.* for example. Where only the major and minor versions are specified and a wildcard is used for build and revision numbers. The language compiler automatically generates the build and the revision numbers. Assembly versioning enables us to implement side-by-side execution of assemblies. Side-by-side execution enables us to run multiple versions of the same assembly simultaneously. The common language runtime provides the infrastructure that allows multiple versions of the same assembly to run on the same computer. We can also run multiple versions of the same assembly within the same process. Side-by-side execution provides flexibility and allows CLR to manage side-by-side execution by reading an assembly’s manifest information. This allows existing applications to continue to work with earlier versions of the assembly. While new applications can simultaneously take advantage of newer versions of the same assembly on the same machine.
Packaging and Distribution Options The .NET Framework provides us with various options to package and distribute the applications that we create in Visual Studio 2005. Whether it’s the Web service or the Windows Form or Web Form application that we create to access the Web service. .NET packaging and distribution options allow us to deploy and publish our application in various scenarios. In the following example we will learn to publish a Web service that we had created in Chapter 9 (you can also find it under the Chapter 10 source code).
421
The Complete Reference To Professional SOA with Visual Studio 2005
Publishing Web service Before we start make sure the Web service project is loaded in Visual Studio. We can open an existing Web service project by File->Open->Web site then browsing to the location of the Web service before selecting Open. Once the Web service project has been loaded we can publish the Web service by selecting Build->Publish Web Site (see figure 11-4).
Figure 11-4: Publish Web Site
At this stage a location dialog window will appear. Visual Studio provides us with several options we can publish to a local IIS server (figure 11-5), a location on the file system (figure 11-6), a remote FTP site (figure 11-7) or a Remote web location (FrontPage Server Extensions is required) (figure 11-8).
Tip: Click the (…) button on the Publish Web Site dialog window to see the Publish Web Site window below.
Figure 11-5: Select a IIS location
Figure 11-6: Select a File System location
422
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 11-7: Select a FTP location
Figure 11-8: Select a remote location
In this example we will be publishing to a local IIS server. Select a location to publish (figure 11-5) then select open. The Publish Web Site dialog window will appear. We can select a location to deploy here. There are three checks boxes available. The “Allow this precompiled site to be updatable” option allows the content of the .aspx pages to remain as it is. This allows us to update the HTML code after deploying to a Web location. This is typically used by ASP.NET Web form application. The second option is “Use fixed naming and single page assemblies”. This option specifies that we will not be compiling in batch mode during precompiling as a result we can generate assemblies with fixed names. The last option is “Enable strong naming on precompiled assemblies”. This option specifies that the generated assemblies are to be strongly named using a key file. Strong naming a assembly ensures that they will not be tampered with. If we select this option we can specify a key file or a key container. After choosing the required options, click OK to continue the deployment process.
Figure 11-9: Enter a location to publish the Web Service
Selecting OK will publish our Web Service to the desired location.
423
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 11-10: Deployed employee service
It is usually a good idea to test the service after the Web service has been deployed. Simply click on one of the Web method and .NET will generate a test harness as long as the parameters used are primitive .NET types. In our case we can easily enter a number into the EmployeeID field to test the Web method (see figure 11-11).
Figure 11-11: Testing the deployed service
The WSDL document for the deployed Web service can be located by appending the ?wsdl after the .asmx extension (see Figure 11-12).
424
The Complete Reference To Professional SOA with Visual Studio 2005
http://localhost/soawebservice/deploy/employee/employee.asmx?wsdl
Figure 11-12: WSDL for the Employee Web service
The discover document for the deployed Web service can be located by appending a ?disco after the .asmx extension (see Figure 11-13). http://localhost/soawebservice/deploy/employee/employee.asmx?disco
Figure 11-13: Discovery document for the Employee Web service
425
The Complete Reference To Professional SOA with Visual Studio 2005
Publishing Client Application using ClickOnce Deployment ClickOnce is a new deployment technology in .NET Framework 2.0. ClickOnce allows us to deploy and run application from a Web page making it very convenient in today’s distributed architecture. As the name suggests provides a one click solution to deployment with minimal user interaction. A ClickOnce application can be published through medias such as Web page, a network file sharing or from disk medias such as CD-ROM or Flash drives. A ClickOnce application can be installed locally onto a client’s computer from a Web page. These applications typically are Windows Form application or Console application and they will continue to run locally even when the computer is offline. The ClickOnce application can also be ran in an online-only mode without permanently installing anything on the end user’s computer. In configuring an application for ClickOnce deployment a developer can easily specify the update behaviors of the application. Applications deployed through ClickOnce can automatically check for newer versions as they become available and automatically install the required files. A network administrator can also control update strategies such as ensuring that automatic update for an application is fixed and binding. Both the end user and administrator have the ability to roll back updates of a deployed application to a previous version. Applications deployed through ClickOnce deployment are isolated. These applications are self contained and each application is installed to and ran from a secure per user, per application cache. This ensures that the application will not break any existing applications. Security wise each application runs within the Internet and Intranet security boundary. Application can also request to elevate their security permissions. ClickOnce deployment resolves three inherent issues in application deployment. These are: *
Application update. In the past whenever an application is updated the user must reinstall the entire application. The key with ClickOnce deployment is that applications can be automatically configured so that they can check for updates as they become available. Only portions of the application that have changed are downloaded and installed.
*
Low impact. In the past applications deployed through Windows Installer often relied on shared components. Which could potentially result in version conflicts. ClickOnce deployment offers a self-contained per user, per application cache which means your application can not interfere with other applications.
*
Security. In the past installing applications through Windows Installer required administrative permissions and allows only limited user installation. In ClickOnce deployment non-administrative users are granted rights and Code Access Security permission necessary for the application.
In the past, these issues often caused developers to decide to create Web applications rather than Windows-based applications, sacrificing the rich user interface and responsiveness of Windows Forms for ease of installation. With applications deployed using ClickOnce, we can now achieve the best of both technologies.
ClickOnce and Windows Installer Comparison Table The following table compares the features of ClickOnce deployment with Windows Installer deployment: Table 11-1: Comparison between ClickOnce deployment and traditional Windows Installer
Feature
ClickOnce
Windows Installer
Automatic update
Yes
Yes
Post-installation rollback
Yes
No
426
The Complete Reference To Professional SOA with Visual Studio 2005
Update from Web
Yes
No
Does not affect shared components or Yes other applications
No
Security permissions granted
Grants only permissions necessary for the application (more safe)
Grants Full Trust by default (less safe)
Security permissions required
Internet or Intranet Zone (Full Trust for CD- Administrator ROM installation)
Application and deployment manifest Yes signing
No
Installation-time user interface
Multipart Wizard
Single prompt
Installation of assemblies on demand Yes
No
Installation of shared files
No
Yes
Installation of drivers
No
Yes (with custom actions)
Installation to Global Assembly Cache No
Yes
Installation for multiple users
No
Yes
Add application to Start menu
Yes
Yes
Add application to Startup group
No
Yes
Add application to Favorites menu
No
Yes
Register file types
No
Yes
Install time registry access
Limited
Yes
Binary file patching
No
Yes
Application installation location
ClickOnce application cache
Program Files folder
Using ClickOnce Deployment In the following section we will walk through the steps required in creating a ClickOnce deployment application. Using ClickOnce deployment is quite straight forward. Simply open the project that we wanted to deploy in our case we can open the EmployeeClient we had built in Chapter 9 which was used to access an employee web service.
Figure 11-14: Publishing using ClickOnce
Publishing to File System Select Build Menu -> Publish (see figure 11-14).
427
The Complete Reference To Professional SOA with Visual Studio 2005
We should Build the solution first to make sure that everything is in working order first. Click the menu option to publish our solution. (see figure 11-15).
Figure 11-15: Publish the application to a location
One decision that we need to consider is where we’d like our user to install our ClickOnce application from. We can deploy application to either, File System, Local IIS, FTP Site or Remote Site (see figure 11-16). To specify another location simply click on the browse button. Select next when complete. ClickOnce has great support for different locations. In this case, we will select the File System click "Next" to accept the location.
Figure 11-16: Specifying a location.
428
The Complete Reference To Professional SOA with Visual Studio 2005
ClickOnce deployments allows us to deploy applications to a Web site, a Network location or onto a CDROM. In this example we will be deploying to disk, select From a CD-ROM or DVD-ROM. Enter your preferred location to deploy to. (You will need to have IIS installed for this to work). (see figure 11-16)
Figure 11-17: Specify how user will install the application
Click Next to continue. We will be asked if we want our application to automatically check for updates. We can specify the location from which the application periodically checks (see figure 11-18).
Figure 11-18: Specify whether the application will check for updates.
Click Next and Finish will automatically deploy the application to file system. We can see the setup files created in figure 11-19.
429
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 11-19: Created ClickOnce Files.
Publishing To a Web Location
Figure 11-20: Publishing to a web location
Since we are publishing the ClickOnce deployment application to a Web location we will be prompted whether this application will be available online or offline (see Figure 11-20). The default online or offline deployment mode will automatically create a start button menu shortcut and an uninstall option in windows. It will also link our project to a web page location. In this example we will select “yes, this application is available online or offline” mode. Select Next followed by Finish to publish the application to an online location.
430
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 11-21: ClickOnce deployment web page
ClickOnce automatically starts the default browser with the generated page once we have completed the ClickOnce publish process (see Figure 11-21). Clicking the Install button will call the setup.exe automatically to start the setup process (see Figure 11-22). Or we can execute the Setup.exe ourselves get the same result. Both setup.exe and publish.htm are in the root of the directory for the web page. Unless we have a security certificate, we will get a security warning screen that we will need to confirm the installation (see Figure 11-23).
Figure 11-22: Launch notification
431
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 11-23: Security warning if we’re not using security certificates.
How ClickOnce Deployment Works At the heart of ClickOnce deployment architecture are two XML manifest files. These are the application manifest and the deployment manifest files. The application manifest is used to describe the application. These include assembly information, application dependencies, required permissions, and the location where updates will be available. A developer can create an application manifest by using the Publish Wizard tool in Visual Studio 2005 or using the .NET Framework tool Mage.exe the .NET manifest generation tool. The second manifest file is the deployment manifest file that describes how the application should be deployed. It contains information about the location of the application manifest and the version of the application that the client need to run. Developers can create the deployment manifest using the manifest generation tool (Mage.exe) in the .NET Framework SDK (see Figure 11-24).
Figure 11-24: Mage can be used to modify the manifest
After the deployment manifest is created it is copied to the deployment location. This can be a Web server, a network file share, or media such as a CD ROM. Application manifest and the application files can also be copied to the same deployment location or a different location that is specified within the deployment manifest. When we’re performing the deployment through the Visual Studio 2005 Publishing Wizard the operation is performed automatically. After deploying the ClickOnce application to the specified location, the end users can install the application by clicking on a install icon from the Web page (see Figure 11-21) or from a deployed folder. In most cases, the end user is presented with a simple dialog box asking the user to confirm installation Figure 11-23, after which installation proceed and the application is launched without further intervention. In cases where application requires additional security permissions, the user will be prompted to grant permission before the installation is allowed to continue. Once the application has been installed an icon will be added to the user’s Start menu and to the Add/Remove Programs group in Control Panel. Unlike previous deployment technologies no additional files will be added under Program Files Folder or records added into the registry or desktop. ClickOnce is a completely isolated deployment and execution environment.
432
The Complete Reference To Professional SOA with Visual Studio 2005
Using Web Deployment Projects with Visual Studio 2005 While deployment using Copy Web Site and Publish Web Site features are quite simple to use and provide an efficient means of deploying applications. There are times when we need to do more. There are several reasons: *
Requirement for more control over assemblies and output,
*
Creating custom pre-processing and post-processing actions for the build,
*
Capability to add, exclude and transform files and directories during build.
*
The ability to alter database connection string, application settings or even URL references that is stored in the Web.config depending on the build mode that we choose. These modes maybe for development, testing, staging and release based. Each mode may contain a different set of values.
We can achieve this through the use of Web Deployment Projects add-in with Visual Studio 2005. The Web Deployment Projects add-in package itself does not change the behavior of any features in Visual Studio 2005. It simply provides additional functionality specific to Web site deployment. The Web Deployment project is integrated into the Visual Studio 2005 build configuration manager. It supports build modes such as Debug and Release used for compilation and deployment. The Web deployment project can be extended to allow us to create pre-build and post-build actions. The Web Deployment project does not change the way Visual Studio 2005 build projects. It takes an existing Web site project and generates a precompiled Web project as output. The build process does not change the source files in the Web site project in anyway. It is this precompiled Web project that we can use in our Visual Studio 2005 setup project to deploy Web based applications. We will be looking at how to create deployable Setup Projects using the precompiled web site later in this chapter. In this section we will be looking into the Web Deployment Projects for Visual Studio 2005.
Installing Web Deployment Projects In order to use Web deployment projects we need to install WebDeploymentSetup.msi (WebDeploymentSetup.msi can be downloaded from Microsoft Web site using WebDeploymentSetup.msi as the keyword for search). Installing Web Deployment projects installs both a Visual Studio 2005 add-in package and the new ASP.NET merge utility (aspnet_merge.exe). By default, the installation process installs files into the locations listed in the following table. Table 11-2: Output for Web Deployment Project
Location
Files
C:\Program Files\MSBuild\Microsoft\WebDeployment\v8.0 aspnet_merge.exe Microsoft.WebDeployment.targets Microsoft.WebDeployment.Tasks.dll C:\Program Files\Microsoft Visual Studio 8\Common7\Packages
MsWebDeployProj.dll WebDeploy.wdproj
433
The Complete Reference To Professional SOA with Visual Studio 2005
C:\Program Files\Microsoft Visual Studio 8\Common7\Packages\1033
MsWebDeployProjUi.dll
Build Menu Command
Figure 11-25: New option
Installing Web Deployment Projects adds the Add Web Deployment Project command to the Build menu (see Figure 11-25) and to the shortcut menu for the selected Web project in Solution Explorer. The new command is supported only for local IIS Web sites and for file system Web sites. Web Deployment Projects do not support remote FrontPage or FTP Web sites.
1.
From the Build menu select Add Web Deployment Project (see Figure 11-25).
Figure 11-26: Deployment Project Name
2.
Specify a name and location for the project then select OK. By default, the project name is the same as the Web site with _deploy appended to the name. The default location is in the same folder as the solution. The project file in our case will be named Employee_deploy.webdeployproj, and the project folder path will be C:\Projects\Book\SourceCode\Ch11\Employee_deploy.
434
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 11-27: Web deployment project
3. A new project is added to the solution and automatically associated with the Web site. The new Web Deployment project is now part of the build process. The new Web Deployment project does not contain any files or child nodes in the solution hierarchy. Instead, it is an MSBuild project file that enables us to customize the build rules for the associated Web site. 4.
Right click on the Employee deploy project within the Solution Explorer. Select Property Pages.
Web Deployment Project Property Pages We can create custom configurations for the Web Deployment project by using the Property pages diaglog box. The dialog box is available by right-clicking the project in Solution Explorer and then selecting Property Pages. There are four property pages dialog boxes for Web Deployment. These are: *
Compilation
*
Output Assemblies
*
Signing
*
Deployment
435
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 11-28: Compilation
The advantage of using Web Deployment Project is that we can specify unique values for each of the build configurations. We can use the predefined build configuration of Debug and Release in Visual Studio 2005 or we can define new configuration for example for staging, and production. The changes we make within each of the four property pages will be specified only for that selected build configuration. This provides the developer with more flexibility when configuring to deploy application. The Compilation page (see figure 11-28) is used to provide information on how the Web project should be compiled and where to put the precompiled output. The page properties are shown in Table 11-3 Table 11-3: Compilation property
Setting
Description
Output folder
This is folder which will contain the precompiled image of the Web project.
Generate debug information
Select this option to generate debug information when compiling. This setting will also update the element in the configuration file of the precompile Web project.
Use IIS Metabase path for source input
During compilation, if there are sub-Web sites this will result in build errors. By enablying to use IIS Metabase path which will cause the compiler to skip sub-Web sites defined in the IIS metabase. To compile the sub-Web sites, we must add a separate Web Deployment project for each of the sub-Web sites.
Allow this precompiled site to be updatable
This option is used for ASP.NET Web form. It allows HTML component of the aspx and ascx pages to be updated after compiling so that only the codebehind files are compiled.
The Output Assembly page is used to customize precompiled Web project assemblies. The Output Assembly properties are shown in Table 11-4
Figure 11-29: Output Assemblies
436
The Complete Reference To Professional SOA with Visual Studio 2005
Setting
Description
Merge all outputs to a single assembly
This option merges all output assemblies from the compiler into a single assembly. This is similar to using the aspnet_merge.exe –o assemblyname option.
Treat as library component
This option will remove the App_code.compiled file. This allows a project’s App_Code.dll assembly to be added to another Web site without conflict. It is useful for building a library of .ascx controls. This is equivalent to using aspnet_merge.exe –r command.
Merge each individual folder output to its own assembly
This option will create a separation output assembly for each folder. This allows us to update a Web Project at the folder level rather than the entire application.
Merge all pages and controls to a single assembly
This option merges all output assemblies for all pages and user controls in a Web project into a single assembly. We can use the assembly to update UI components separately.
Create a separate assembly for each page and control output
This option creates separate assemblies for each page and user control.
Version Output Assemblies
Selecting Version Output Assembly will enable the Asembly Version and File Version. We can set the Assembly Version and File Version in the following format. The format is 0.0.0.0.
Assembly Version File Version
The version information specified will override the setting information defined within AssemblyInfo.vb or AssemblyInfo.cs file.
Table 11-4: The table above describes the properties of the Output Assemblies page.
Properties of the signing page are only enabled if we select Enable strong naming see figure 11-30 the property of the page is shown in Table 11-5. Singing an assembly ensures that the assembly is free from tempering.
437
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 11-30: Signing property page. Table 11-5: The table shows the properties within the Signing section.
Setting
Description
Key file location
After enabling strong naming we can specify a keyfile used for signing the assembly. We can generate the key file using the sn.exe utility included with the .NET Framework SDK.
Delay signing
Delay signing allow us to compile assemblies with delay signing. This allows the assemblies to be signed after the build process.
Mark assemblies with AllowPartiallyTrustedCallersAttribute (APTCA).
This allows types in the strongly named assembly to be called by partially trusted code only when the assembly is marked with AllowPartiallyTrustedCallersAttribute. This removes the automatic demand for Full trust permission.
The deployment page figure 11-31 is used to customize various deployment configuration. This allows us to adjust certain configuration in Web.config for deployment setup. We can also automatically create an IIS virtual directory. Properties for the deployment page is show in table 11-6.
Figure 11-31: Deployment property screen Table 11-6: The following table describes the properties that we can set in the Deployment page.
Setting
Description
Enable Web.config file section replacement
By enabling the Web.config file section replacement we can replace any section in the root Web.config file with the matching content in a separate external .config file. We can use this option to provide configuration settings for the deployed environment.
438
The Complete Reference To Professional SOA with Visual Studio 2005
Enforce matching section replacements
This option requires that the specified section in the Web.config file matches the number of elements in the external .config file. A build error occurs if the two do not match.
Use external configuration source file This option is useful for changing database connecting strings or references for different build configurations. This option replaces elements using configSource reference with .config file. configSource attribute can be in the format of:
If this option is not selected the entire section is replaced with the .config file. Create an IIS virtual directory for the This option when selected will automatically create an IIS virtual directory output folder that will point to the output folder for the specified build configuration. To avoid conflict we should adopt the naming convention for example such as MyWeb_Staging and MyWeb_Release. Replace the existing virtual directory This option allows us to replace an existing virtual directory. For example if a virtual directory already exists we can override it to point to a different output location. Remove the App_Data folder from the output location
This option removes the App_Data from the precompiled image of the Web project. This is useful if we’re not requiring a SQL Server Express, Access or MSDE in the App_Data folder.
Managing Custom Build Configurations We can define several build configurations using Visual Studio. These build processes are necessary for producing Debug, Staging and Release builds for Web application. We can customize each configuration. The three main build configuration commonly used for Web applications are: *
Debug build configuration. Debug build is commonly used by developers during design time to test and check the Web Application. In a typical team development enivornment when multiple developers are working on the same project. To avoid impacting development and overwriting each other’s code each developer can set their own custom settings for their development environment. These may be local resources such as a local SQL Server database, or a local IIS Web reference which points to http://localhost/....
*
Staging build configuration. The staging environment is often a replica of the production or release environment. We can adjust our configurations to connect to the staging environment. This may mean rather than connecting to a local database during the debug build we may be connecting to a shared database containing test data. While Web services and Web Form applications may also be distributed onto different servers in the staging environment.
*
Release build configuration. The Web project is deployed onto a production release environment after it has been thoroughly tested on the staging environment. The release build means we would no longer require the debug information that may have been required on the staging build. We can adjust the Debug mode within the Web.config file by setting it to false.
439
The Complete Reference To Professional SOA with Visual Studio 2005
The benefit of using the Web Deployment projects is that it allows us to add and customize so many differerent variables for each of the specific builds. We can tailor our environment variables into each of the build configuration. This helps to lower the risk of deployment errors from misconfigured environment settings. The property values that we specify within Web deployment project apply only to the specific build configuration. We can easily change a build configuration for a specific build by changing the required property. For global properties we can also select All Configurations, which we can apply to change settings globablly across all configurations. To change or create a new configuration, in the project Property Page dialog window select Configuration Manager. The Configuration Manager dialog window will appear (see figure 11-32). By selecting Active solution configuration drop down list and selecting we can define a build option for deployment. The Configuration Manager dialog box allow us to create new configurations and to specify which projects to build as part of that configuration.
Figure 11-32: Select a New build configuration
In the following example we will create a setting for staging. By selecting under Active Solution Configuration. A dialog window will appear (see figure 11-33). We will be prompted to set the name of the configuration. We can also simplify the configuration process by letting the configuration manager to copy existing settings defined for Release. Once complete select OK.
440
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 11-33: Create a new staging build
After defining the settings for staging we can see that the new configuration is now active in the Configuration Manager. In the case of multiple projects we can also specify which project to build for the specific build configuration (see figure 11-34).
Figure 11-34: Staging build configuration.
Tip: We should also remember to disable building the Web Deployment project in the Debug configuration. Building a Web Deployment project unnecessarily increases the time it takes to build a solution or start a debug session. We should enable building the Web Deployment project only in solution configurations intended for deployment builds.
When we sepecify the build configurations we should keep in mind that build configuration for Web projects should be optimized for developers productivity. When we create our solution configurations, we should build
441
The Complete Reference To Professional SOA with Visual Studio 2005
either the Web site project or the Web Deployment project, but not both. See table 11-7 for suggestion towards different build solution configurations. Table 11-7: Build configuration
Solution configuration Build strategy
Debug
Staging Release
Build Web site project
True
False
False
Build Web Deployment project False
True
True
To specify the solution configuration to use when we build, select the configuration name from the Solution Configurations list on the toolbar:
Figure 11-35: Build options in the project.
When we have our build configurations established, we can initiate a build for any configuration. There are two ways to build a Web Deployment project from within Visual Studio 2005 or from the command line using MSBuild. The files generated for this build are in the MyWeb_deploy\Release folder. Note the single output assembly MyCompany.MyWeb.dll.
Location
Files
C:\Projects\Book\SourceCode\Ch11\Employee_deploy\Re Employee.asmx lease PrecompiledApp.config web.config C:\Projects\Book\SourceCode\Ch11\Employee_deploy\Re App_Code.compiled lease\bin Employee_deploy.dll Table 11-8: Web deployment project output
Web Setup Projects In this section we will learn to deploy Web projects by creating a MSI setup file. Visual Studio provides four types of projects types for deployment. These are: Setup project, Web Setup Project, Cab project and Merge Module. In Visual Studio 2005 there is now a Setup wizard which we can use to help us create a deployment project. We can see the templates and the wizard in the New Project dialog box under the Setup and Deployment Projects node.
442
The Complete Reference To Professional SOA with Visual Studio 2005
The following are guidelines for choosing the right type of deployment project for our project (see Table 11-9). Table 11-9: Setup project types
Project Type
Purpose
Merge Module Project
Merge Module Projects are used to package files or components that will be shared between multiple applications. The project will careate a a merge module (.msm) file that includes all resource files, registry entires and setup logic for the component.
Setup Project
We can use Setup project to create installers for Windows based applications.
Web Setup Project
The Web Setup Project can help with the deployment of Web projects whether its WebForm or Web services. We can specify where the files should be installed on the target machine, set special conditions or requirements for installation and set custom actions to be performed on the target machine.
Cab Project
We can use Cab Project to create a cabinet file (.cab). A cabinet file can contain a number of files but does not contain any installation logic. It is used to package components into a single file can be distributed for installation.
Creating a Web Setup Project for XML Web Service In this section we will be looking at creating a deployment project for a XML Web service we had constructed for Employee in Chapter 9. We will attempt to deploy the Employee web service project by using a Web Setup project. To create a Web Setup project, use the following procedure continuing from the previous example of Employee Web Deployment Project: 1.
From the File menu, point to Add, and click New Project. The Add New Project dialog box appears.
2.
In the Add New Project dialog box, select “Setup and Deployment Projects” under the Project Types pane (Figure 11-36).
443
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 11-36: Web Setup Project
Note: The screenshot may vary depending on the edition of Visual Studio
3.
In the Templates pane, select Web Setup Project.
4.
In the Name box, type WSEmployeeSetup and click OK. Select “Add to Solution” from the Solution dropdown list. This will add the Web setup project to the Web service project (Figure 11-37).
Figure 11-37: WSEmployeeSetup Project
5.
Once the Setup web project has been added to the existing Employee Web service project. Right click on the setup project in the solution explorer. Select Add-> Project Output from the context menu (Figure 11-38).
444
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 11-38: Add Project Output
6.
In the Add Project Output Group dialog box, ensure that the Employee_deploy project is selected in the Project dropdown list. From the list, select the “Precompiled Web Outputs” option and then click OK. Figure 11-39 shows the Add Project Output Group dialog box.
Figure 11-39: Add Project Output
445
The Complete Reference To Professional SOA with Visual Studio 2005
7.
As shown in Figure 11-40 the precompiled web deployment output from Employee_deploy is now attached to the WSEmployeeSetup project.
Figure 11-40: Precompiled Web Outputs
8.
We can specify Prerequisites for the project by right mouse click on the WSEmployeeSetup project and selecting Properties (Figure 11-41). When the dialog window appears select the Prerequisites button. This option allows us to check that the prerequistes required for the application are specified.
Figure 11-41: Prerequisites for the application.
9.
By building the setup project the two setup files will be created automatically. One of the file will be an EXE setup file while the other is a MSI file (Figure 11-42).
446
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 11-42: Setup output
Summary The Visual Studio provides various features and tools that we can use to deploy applications. These features and tools allow us to deploy different types of applications to a large number of users. These features include noimpact installation, private components, side-by-side execution, enterprise deployment, controlled code sharing, on-the-fly updates, downloading and caching, and XCopy deployment. In this chapter we have also looked at ClickOnce deployment. ClickOnce is a new application deployment technology that makes deploying a Windows Forms based application as easy as deploying a web application. With “ClickOnce” running a Windows Forms application is as simple as clicking a link in a web page. For administrators, deploying or updating an application is simply a matter of updating files on a server; no need to individually touch every client. We have also looked at deploying a Web service using Web Deployment Project to precompile the assemblies. Web Deployment Project is an add-in for Visual Studio 2005. It allows us to precompile our Web service application while it is flexible enough to allow for customization for different build cenarios. Using Visual Studio’s Web Setup project we can then create and deploy the precompiled assemblies. Visual Studio provides Web Setup project as a way to build and deploy applications into MSI files. Visual Studio comes with templates for four types of deployment projects: Merge Module Project, Setup Project, Web Setup Project, and Cab Project. *
Merge Module Project - Packages components that might be shared by multiple applications.
*
Setup Project - Builds an installer for a Windows-based application.
*
Web Setup Project - Builds an installer for a Web application.
*
Cab Project - Creates a cabinet file for downloading to a legacy Web browser.
447
The Complete Reference To Professional SOA with Visual Studio 2005
Chapter 12 Advanced Web Service Programming In previous chapters we have created simple XML Web services. In this chapter we will be looking at more advanced techniques and Web service implementations. We will be looking into modifying the properties of the WebMethod attribute that is used to define a method within a Web service. In addition we will also look at how to implement asynchronous XML Web services calls. And how we can use SOAP extensions to access and modify the SOAP messages that the XML Web services send to and receive from client applications.
WebMethod Properties There are six properties commonly used by the WebMethod. These properties control the way the WebMethod behave over the web. These are: *
BufferResponse – The BufferResponse property allows us to buffer responses for a WebMethod to improve the performance of an application by reducing communication between the worker processes and the IIS process.
*
CacheDuration - The CacheDuration property of the WebMethod attribute enables us to cache the results for a Web method for a specified period.
*
Description - The Description property allows us to specify a description for a Web method. The description that we specify using the Description property appears on the Service Description
*
EnableSession – The Web service itself is stateless though with .NET we can configure a Web method to maintain the state of objects across sessions. The EnableSession property of the WebMethod attribute allows us to enable the session state for a Web method.
*
MessageName - The MessageName property can be used to it is used to uniquely identify overloaded Web methods. The MessageName property allows us to use an alias to uniquely identify Web methods in an XML Web service.
*
TransactionOption - We can use a WebMethod to support transactions and enable a Web Method to participate as the root object of a transaction.
In the following section we will look at how these properties can be used to customize and control the behavior of the methods exposed within the Web service.
Buffering Response for a Web Method We can buffer responses for a Web method to improve the performance of an application by reducing communication between the worker process and the IIS process. To buffer responses for a Web method, we can use the BufferResponse property of the WebMethod attribute. The ASP.NET can buffer all responses before responding to the client this is activuated by setting the BufferResponse property to True. The result is that the response is serialized into a memory buffer until either the response is completely serialized or the buffer is full. Once the response is buffered, it is returned to the consuming XML Web service client over the network.
448
The Complete Reference To Professional SOA with Visual Studio 2005
If we set the BufferResponse property to False, ASP.NET buffers the responses in chunks of 16 KB each. The response to the XML Web service method is sent back to the client as it is serialized. The default value of the BufferResponse property is True. The following Microsoft Visual Basic .NET and Microsoft Visual C# code samples show how to use the BufferResponse property (see listing 12-1 and listing 12-2).
Listing 12-1. Demonstrates a program using Buffered and Unbuffered properties in Web service. Using C# using System; using System.IO; using System.Collections; using System.Xml.Serialization; using System.Web.Services; using System.Web.Services.Protocols; [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class Service { [WebMethod(BufferResponse=true)] public TextFile GetFileBuffered(string filename) { return new TextFile(filename); } [WebMethod(BufferResponse=false)] public TextFile GetFileUnbuffered(string filename) { return new TextFile(filename); } } public class TextFile { public string filename; private TextFileReaderWriter readerWriter; public TextFile() { } public TextFile(string filename) { this.filename = filename; } [XmlArrayItem("line")] public TextFileReaderWriter contents { get { readerWriter = new TextFileReaderWriter(filename); return readerWriter; } } public void Close() { if (readerWriter != null) readerWriter.Close();
449
The Complete Reference To Professional SOA with Visual Studio 2005
} } public class TextFileReaderWriter : IEnumerable { public string Filename; private StreamWriter writer; public TextFileReaderWriter() { } public TextFileReaderWriter(string filename) { Filename = filename; } public TextFileEnumerator GetEnumerator() { StreamReader reader = new StreamReader(Filename); return new TextFileEnumerator(reader); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public void Add(string line) { if (writer == null) writer = new StreamWriter(Filename); writer.WriteLine(line); } public void Close() { if (writer != null) writer.Close(); } } public class TextFileEnumerator : IEnumerator { private string currentLine; private StreamReader reader; public TextFileEnumerator(StreamReader reader) { this.reader = reader; } public bool MoveNext() { currentLine = reader.ReadLine(); if (currentLine == null) { reader.Close(); return false; } else return true; }
450
The Complete Reference To Professional SOA with Visual Studio 2005
public void Reset() { reader.BaseStream.Position = 0; } public string Current { get { return currentLine; } } object IEnumerator.Current { get { return Current; } } } Listing 12-2. Demonstrates a program using Buffered and Unbuffered properties in Web service. Using Visual Basic 2005 Imports System Imports System.IO Imports System.Collections Imports System.Xml.Serialization Imports System.Web.Services Imports System.Web.Services.Protocols Public Class Service _ Public Function GetFileBuffered(ByVal filename As String) As TextFile Return New TextFile(filename) End Function _ Public Function GetFileUnbuffered(ByVal filename As String) As TextFile Return New TextFile(filename) End Function End Class Public Class TextFile Public filename As String Private readerWriter As TextFileReaderWriter Public Sub New() End Sub Public Sub New(ByVal filename As String) Me.filename = filename End Sub _
451
The Complete Reference To Professional SOA with Visual Studio 2005
Public ReadOnly Property contents() As TextFileReaderWriter Get readerWriter = New TextFileReaderWriter(filename) Return readerWriter End Get End Property Public Sub Close() If Not (readerWriter Is Nothing) Then readerWriter.Close() End If End Sub End Class Public Class TextFileReaderWriter Implements IEnumerable
Public Filename As String Private writer As StreamWriter Public Sub New() End Sub Public Sub New(ByVal myfilename As String) Filename = myfilename End Sub Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator Dim reader As StreamReader = New StreamReader(Filename) Return New TextFileEnumerator(reader) End Function Public Sub Add(ByVal line As String) If (writer Is Nothing) Then writer = New StreamWriter(Filename) End If writer.WriteLine(line) End Sub Public Sub Add(ByVal obj As Object) End Sub Public Sub Close() If Not (writer Is Nothing) Then writer.Close() End Sub End Class Public Class TextFileEnumerator Implements IEnumerator Private currentLine As String
452
The Complete Reference To Professional SOA with Visual Studio 2005
Private reader As StreamReader Public Sub New(ByVal reader As StreamReader) Me.reader = reader End Sub Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext currentLine = reader.ReadLine() If (currentLine Is Nothing) Then reader.Close() Return False Else Return True End If End Function Public Sub Reset() Implements IEnumerator.Reset reader.BaseStream.Position = 0 End Sub ReadOnly Property Current() As Object Implements IEnumerator.Current Get Return CurrentLine End Get End Property End Class
In the example above listing 12-1 and listing 12-2 we have two exposed WebMethod. These are: GetFileBuffered() and GetFileUnbuffered(). The GetFileBuffered() WebMethod has the property of BufferResponse defined set to true. When invoked the GetFileBuffered() WebMethod will retrieve the contents of the requested file and buffer its response before sending it to the client. While the GetFileUnbuffered() has the BufferResponse set to false. When invoked the GetFileUnbuffered() WebMethod will retrieve the contents of the requested file, the response of the WebMethod will not be buffered in this instance.
Caching the Results for a Web Method The CacheDuration property of the WebMethod attribute enables us to cache the results for a Web method. When caching is enabled requests and responses are held in memory on the server. ASP .NET Framework caches results for each unique parameter set for a specified duration. This duration is defined as the value of the CacheDuration property (see listing 12-3 and listing 12-4). The default value of the CacheDuration property is zero.
Tip: If we expect requests or responses to be very large and expect requests to vary widely. Then this may result in extensive amount of data being cached which may not necessarily result in performance improvement.
Listing 12-3: The following code demonstrates the CacheDuration properties C# using System.Web.Services;
453
The Complete Reference To Professional SOA with Visual Studio 2005
using System; using System.Web; public class Service : WebService { [WebMethod(CacheDuration = 60)] public int ServiceUsage() { // If the XML Web service has not been accessed, initialize it to 1. if (Application["MyServiceUsage"] == null) { Application["MyServiceUsage"] = 1; } else { // Increment the usage count. Application["MyServiceUsage"] = ((int)Application["MyServiceUsage"]) + 1; } // Return the usage count. return (int)Application["MyServiceUsage"]; } } Listing 12-4: The above codes demonstrates the CacheDuration properties Visual Basic 2005 Imports System.Web.Services Imports System Imports System.Web Public Class Service Inherits WebService _ Public Function ServiceUsage() As Integer ' If the XML Web service has not been accessed, initialize it to 1. If Application("MyServiceUsage") Is Nothing Then Application("MyServiceUsage") = 1 Else ' Increment the usage count. Application("MyServiceUsage") = CInt(Application("MyServiceUsage")) + 1 End If ' Return the usage count. Return CInt(Application("MyServiceUsage")) End Function End Class
The above code listing 12-3 and listing 12-4 sets the CacheDuration property of the ServiceUsage Web method to 60 seconds. When the CacheDuration is set ASP.NET will cache the request response based on the
454
The Complete Reference To Professional SOA with Visual Studio 2005
parameters. In this case the response of how frequently the application has been invoked is cached for a period of 60 seconds. There are two issues that can affect output caching in an ASP.NET 2.0 Web service application. In ASP.NET 2.0 the HTTP method of the test page has changed from GET to POST. However, POSTs are not normally cached. If we change the test page in an ASP.NET 2.0 Web service application to use GET, caching will work properly. As a such we cannot test the Web method directly from the test page. There is a windows form project called TestCacheClient with the source code which allow us to test caching using SOAP see Listing 12-5 and Listing 12-6. From the test application we can see that the result to the user request is cached for 60 seconds. In addition, HTTP indicates that a user agent (the browser or calling application) should be able to override server caching by setting the "Cache-Control" to "no-cache". ASP.NET applications, therefore, ignore cached results when they find a "no-cache" header. The example below demonstrates the main logic within TestCacheClient. The application calls the web service and invokes the ServiceUsage WebMethod using SOAP (see Listing 12-5 and Listing 12-6). Listing 12-5. Invoking ServiceUsage WebMethod using C# CacheWS.Counter cws = new CSTestCacheClient.CacheWS.Counter(); this.lblDisplay.Text = cws.ServiceUsage().ToString(); Listing 12-6. Invoking ServiceUsage WebMethod using Visual Basic 2005 Dim cws As CacheWS.Counter = New CSTestCacheClient.CacheWS.Counter Me.lblDisplay.Text = cws.ServiceUsage.ToString()
Specifying a Description for a Web Method The Description property allows us to specify a description for a Web method. The description that we specify using the Description property appears on the Service Description and the Service help page. The Description property takes a string as an input value. The following code displays how to use the Description property. In the example below listing 12-7 and listing 12-8, the WebMethod is decorated with the description of “Obtains the Server Computer Name”. It is used to describe the XML Web service method in the Service Description and Service help page for the XML Web service. Listing 12-7. Implementing Description property using C# using System; using System.Web.Services; public class Desc : WebService { [WebMethod(Description = "Obtains the Server Computer Name")] public string GetMachineName() { return Server.MachineName; } } Listing 12-8. Implementing Description property using Visual Basic 2005 Imports System Imports System.Web.Services
455
The Complete Reference To Professional SOA with Visual Studio 2005
Public Class Desc Inherits WebService _ Public Function GetMachineName() As String Return Server.MachineName End Function End Class
By adding a description property to the WebMethod we can see that the test Page generated by ASMX (see figure 12-1 below) now contains the description displayed under the WebMethod.
Figure 12-1. Shows description attached to a WebMethod
The description property is also represented within the WSDL document as: Obtains the Server Computer Name
Enabling Session State in Web Method The Web service itself is stateless. This means that it does not keep information regarding the consuming application. By using ASP.NET we can configure the Web service method to maintain the object states across sessions by using the session state collection directly from HTTPContext.Current.Session namespace. We can achieve this by setting the EnableSession property to True. The session is maintained by an HTTP cookie which is returned by the XML Web service. Each XML Web service consume is uniquely identified by the HTTP cookie returned. In order for the XML Web service to maintain the session state each client must persist the cookie. Web service consumers can receive the HTTP cookie by creating a new instance of the CookieContainer and assigning the object to the Web service proxy class before calling the WebMethod. If we need to maintain session state beyond when the proxy class instance goes out of scope, the client must persist the HTTP cookie between calls to the XML Web service. For instance, a Web Forms client can persist the HTTP cookie by saving the CookieContainer in its own session state.
456
The Complete Reference To Professional SOA with Visual Studio 2005
In listing 12-9 and listing 12-10 , we have decorated WebMethod with EnableSession property set to true. This allows our WebMethod to access the underlying state management provided by ASP.NET.
Tip: The default value of the EnableSession property is False.
Listing 12-9. Implementing EnableSession using C# using System.Web.Services; public class Service : WebService { [WebMethod(Description = "Per session Hit Counter", EnableSession = true)] public int SessionHitCounter() { if (Session["HitCounter"] == null) { Session["HitCounter"] = 1; } else { Session["HitCounter"] = ((int)Session["HitCounter"]) + 1; } return ((int)Session["HitCounter"]); } }
Listing 12-10. Implementing EnableSession using Visual Basic 2005 Imports System.Web.Services Public Class Service Inherits WebService _ Public Function SessionHitCounter() As Integer If Session("HitCounter") Is Nothing Then Session("HitCounter") = 1 Else Session("HitCounter") = CInt(Session("HitCounter")) + 1 End If Return CInt(Session("HitCounter")) End Function End Class
To consume a WebMethod using session we need to specify a session container to enable the application to keep track of the Web service session. Using CookieContainer allows us to persist data within the same session. See listing 12-11 and listing 12-12.
457
The Complete Reference To Professional SOA with Visual Studio 2005
Note: If we do not wish to persist data for the web service call we do not to implement support for cookie on the client application.
Listing 12-11. Implementing CookieContainer using C# using System; using System.Collections.Generic; using System.Text; namespace CSTestSessionClient1 { class Program { static void Main(string[] args) { System.Net.CookieContainer cookieJar = new System.Net.CookieContainer(); WSSession.Service wss = new WSSession.Service(); wss.CookieContainer = cookieJar; Console.WriteLine(wss.SessionHitCounter().ToString()); Console.WriteLine(wss.SessionHitCounter().ToString()); Console.WriteLine(wss.SessionHitCounter().ToString()); Console.ReadLine(); } } }
isting 12-12. Implementing CookieContainer using Visual Basic 2005 Module Module1 Sub Main() Dim cookieJar As System.Net.CookieContainer = _ New System.Net.CookieContainer Dim wss As WSSession.Service = New WSSession.Service() wss.CookieContainer = cookieJar Console.WriteLine(wss.SessionHitCounter.ToString()) Console.WriteLine(wss.SessionHitCounter.ToString()) Console.WriteLine(wss.SessionHitCounter.ToString()) Console.ReadLine() End Sub End Module
458
The Complete Reference To Professional SOA with Visual Studio 2005
Identifying Overloaded Web Methods Using an Alias The MessageName property can be used to it is used to uniquely identify overloaded Web methods. The MessageName property allows us to use an alias to uniquely identify Web methods in an XML Web service. When we specify a value for the MessageName property, the SOAP messages use this value as the method name instead of the actual method name. The following code sample displays how to use the MessageName property. By default, MessageName is set to the name of the XML Web service method. Therefore, if an XML Web service contains two or more XML Web service methods with the same name, we can uniquely identify the individual XML Web service methods by setting the MessageName to a name unique within the XML Web service, without changing the name of the actual method name in code.
Tip: if a WebMethod of the same name but different set of parameters need to be added to a Web service we should give the new WebMethod a different MessageName and leave the original WebMethod to ensure compatibility with existing consuming clients.
Listing 12-13. Implementing MessageName using C# using System; using System.Web.Services; public class Calculator : WebService { // The MessageName property defaults to Add for this XML Web service method. [WebMethod] public int Multiply(int i, int j) { return i * j; } [WebMethod(MessageName = "Multiply2")] public int Multiply(int i, int j, int k) { return i * j * k; } } Listing 12-14. Implementing MessageName using Visual Basic 2005 Imports System Imports System.Web.Services Public Class Calculator Inherits WebService ' The MessageName property defaults to Add for this XML Web service method. _ Public Function Multiply(ByVal i As Integer, ByVal j As Integer) As Integer Return i * j End Function
459
The Complete Reference To Professional SOA with Visual Studio 2005
_ Public Function Multiply(ByVal i As Integer, ByVal j As Integer, ByVal k As Integer) As Integer Return i * j * k End Function End Class
In the example above listing 12-13 and listing 12-14 we have a WebMethod which is overloaded with another WebMethod. In Web service it is not possible to have two WebMethods of the same name. This results in a conflict. One way around this is through the use of MessageName to specify an alias name. This helps to distinguish between the two WebMethods. See Figure 12-2.
Figure 12-2: Overloaded WebMethod using MessageName
Web Method Transaction We can use a Web method to support transactions and enable a Web method to participate as the root object of a transaction, this is due to the stateless nature of the HTTP protocol. As such we can invoke COM objects that participate in the same transaction as the XML Web service method. Using the TransactionOption property we can specify whether we want the Web method to participate in a transaction or not. The TransactionOption property can be set to the following states: Disabled, NotSupported, Supported, Required, and RequiresNew. To support transactions and enable a Web method to participate as the root object of a transaction, we can set TransactionOption to Required or RequiresNew. On the other hand, to disable transaction support for a Web method, we can set TransactionOption to Disabled, NotSupported, or Supported.
Table 12-1. TransactionOption states. Item
Description
Disabled
By setting the TransactionOption state to Disabled the WebMethod will be executed without
460
The Complete Reference To Professional SOA with Visual Studio 2005
support for transaction. Any transaction in the current context will be ignored. [WebMethod(TransactionOption= TransactionOption.Disabled)] NotSupported
The NotSupported state indicates that the WebMethod will not run within the scope of a transaction. The WebMethod will be executed in a context with no governing transaction. [WebMethod(TransactionOption= TransactionOption.NotSupported)]
Supported
The Supported state indicates that the WebMethod will share a transaction if it exists. [WebMethod(TransactionOption= TransactionOption.Supported)]
Required
The Required state indicates that the WebMethod requires a transaction. A new transaction will be created for the WebMethod if no transaction exists otherwise if transaction exist it will be shared. [WebMethod(TransactionOption= TransactionOption.Required)]
RequiresNew
The RequiresNew state indicates that the WebMethod requires a new transaction regardless of the state of the current context. When a request is received the WebMethod is created within a new transaction. [WebMethod(TransactionOption= TransactionOption.RequiresNew)]
XML Web service transactions can only participate in Transactions as the root of a new transaction. XML Web service methods that call other XMLWeb service methods participate in different transactions. This is because transactions do not flow across XML Web service methods. When using transactions with ASP.NET XML Web service we can declare the Web method’s transactional behavior by setting the TransactionOption property of the WebMethod Attribute. If an exception is thrown while the WebMethod is executing the transaction is automatically aborted otherwise if no exception occurs the transaction is automatically committed. To enable Web methods to support transactions, we need to add reference to the System.EnterpriseServices namespace. This namespace contains the methods and properties that expose the distributed transaction model in COM+ services. The ContextUtil class of the System.EnterpriseServices namespace allows us to control a transaction using the SetAbort or SetComplete method. The following example listing 12-15 and listing 12-16 demonstrates using TransactionOption. Listing 12-15. implementing TransactionOption using C#. using System; using System.Web.Services; using System.EnterpriseServices; public class Bank : WebService { [WebMethod(TransactionOption = TransactionOption.RequiresNew)] public void BankTransfer(long Amount, long AcctNumberTo, long AcctNumberFrom) { //bank logic here ContextUtil.SetComplete(); //if invalid we can set ContextUtil.SetAbort(); } }
461
The Complete Reference To Professional SOA with Visual Studio 2005
Listing 12-16. implementing TransactionOption using Visual Basic 2005 Imports System.Web Imports System.Web.Services Imports System.Web.Services.Protocols Imports System.EnterpriseServices _ _ _ Public Class Bank Inherits System.Web.Services.WebService _ Public Sub BankTransfer(ByVal Amount As Long, _ ByVal AcctNumberTo As Long, ByVal AcctNumberFrom As Long) 'bank logic here ContextUtil.SetComplete() 'if invalid we can set ContextUtil.SetAbort() End Sub End Class
Asynchronous Web service Asynchronous implementation is used to allow applications to execute a method without waiting for it complete. This is very useful in a distributed architecture, because the inherent nature of the Internet, the response time between request and response can vary greatly. As such we do not want our program to wait for the method to return. In general, asynchronous implementation could result in significant improvement if we’re creating a Windows application. In this case, an asynchronous call allows the user interface to remain responsive. Or if we have other work to do that have a high degree of latency. By performing the web service call asynchronously, we can carry out our work while waiting for the response. A special case is when we need to call several independent web services. In this situation, we can call them all asynchronously, which can dramatically reduce the time of total call. However asynchronous implementation is not a silver bullet solution. For example asynchronous implementations will not speed up the time taken to receive a response. Thus, in most cases we will have no reason to call the web service asynchronously in web applications. If we were performing a series of tasks that do not have to be performed in order then we can use asynchronous implementation to allow these tasks to execute at the same time instead of waiting on each to complete (see figure 12-3). We can also use asynchronous implementation when we don’t want to wait for a WebMethod to return. For example if a WebMethod is going to take considerable amount of time to execute normally the client application will become locked because it is waiting for the WebMethod to return. By using asynchronous implementation to invoke the WebMethod the executed WebMethod will return immediately and thus allowing the application to continue execution. Once the WebMethod has completed execution the result will be returned to the client.
462
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 12-3. Difference between Synchronous and Asymchronous implementation.
In figure 12-3 a synchronous method call can create a delay in program flow, an asynchronous approach may be better in certain situations, such as when a program needs to send out requests to multiple Web services. In Asynchronous those requests are sent in parallel. However in synchronous the execution wait for the previous function to return before executing the next. Asynchronous implementation is particularly suitable in a distributed architecture where delay for request and response can vary.
Asynchronous Delegates In .NET we’re shielded from the complexities involved in Asynchronous Operation. All of the work is handled by the Proxy class that is generated for our Web service. We can implement asynchronous programming by using delegates. Delegates are typesafe function pointers that form the basis for .NET events. We can create a delegate that references a specific method, and then call that method through the delegate. All delegates provide BeginInvoke() and EndInvoke() methods that allows us to trigger methods on one of the threads in the CLR thread pool. We need to define the delegate first. We can specify the delegate at the namespace level or in the class itself. For example, here’s a delegate that can point to any method (see listing 12-17 and listing 12-18): Listing 12-17. Implementing delegate using C# public delegate string VerySlowWebMethodAsyncDelegate();
Listing 12-18. Implementing delegate using Visual Basic 2005 Public Delegate Function VerySlowWebMethodAsyncDelegate() As String
We will use this delegate to wrap around a Web service method that is called VerySlowWSFunction(). Every time we define a delegate such as VerySlowWebMethodAsyncDelegate a custom delegate class is generated and added to our assembly. The reason is because the code for each delegate is different, depending on the signature of the method we define. Through out the examples in this section we will be using the WebMethod VerySlowWSFunction() (see listing 12-19 and listing 12-20).
463
The Complete Reference To Professional SOA with Visual Studio 2005
Listing 12-19. Implementing VerySlowWSFunction() using C#. using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; using System.Threading; [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class Service : System.Web.Services.WebService { public Service () { } [WebMethod(Description = "Very slow WebMethod")] public string VerySlowWSFunction() { Thread.Sleep(5000); return "WebMethod execution complete"; } }
Listing 12-20. Implementing VerySlowWSFunction() using Visual Basic 2005 Imports System.Web Imports System.Web.Services Imports System.Web.Services.Protocols Imports System.Threading _ _ _ Public Class Service Inherits System.Web.Services.WebService _ Public Function VerySlowWSFunction() As String Thread.Sleep(5000) Return "execution complete" End Function End Class
Let us have a look at using delegate to wrap around a web service method listed above see listing 12-21 and listing 12-22.
Listing 12-21. Using delegate to call a WebMethod in C#
464
The Complete Reference To Professional SOA with Visual Studio 2005
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace CSTestAsyncClientBegin { public delegate string VerySlowWebMethodAsyncDelegate(); public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { WSAsync.Service wsa = new CSTestAsyncClientBegin.WSAsync.Service(); VerySlowWebMethodAsyncDelegate veryslowWebMethod = new VerySlowWebMethodAsyncDelegate(wsa.VerySlowWSFunction); this.labelResult.Text = veryslowWebMethod() + " " + DateTime.Now.ToShortTimeString(); } } }
Listing 12-22. Using delegate to call a WebMethod in Visual Basic 2005 Public Delegate Function VerySlowWebMethodAsyncDelegate() As String Public Class Form1 Private Sub button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles button1.Click Dim wsa As WSAsync.Service = New WSAsync.Service Dim veryslowWebMethod As VerySlowWebMethodAsyncDelegate = _ New VerySlowWebMethodAsyncDelegate(AddressOf wsa.VerySlowWSFunction) Me.labelResult.Text = veryslowWebMethod() + " " + _ DateTime.Now.ToShortTimeString End Sub End Class
465
The Complete Reference To Professional SOA with Visual Studio 2005
In listing 12-21 and listing 12-22 we have created a delegate named VerySlowWebMethodAsyncDelegate, this delegate takes no parameters and has a return type of string. This is to match the parameter and return type of our WebMethod. We then create an object of the delegate by passing in the WebMethod that we’re interested in. This will allow the delegate to wrap around the WebMethod. See listing 12-23 and listing 12-24 below. Listing 12-23. Allowing delegate to wrap around a function in C# VerySlowWebMethodAsyncDelegate veryslowWebMethod = new VerySlowWebMethodAsyncDelegate(wsa.VerySlowWSFunction); Listing 12-24. Allowing delegate to wrap around a function in Visual Basic 2005 Dim veryslowWebMethod As VerySlowWebMethodAsyncDelegate = _ New VerySlowWebMethodAsyncDelegate(AddressOf wsa.VerySlowWSFunction)
When we call a method through the delegate, we are actually relying on the Invoke() method of the delegate class. The Invoke() method executes the linked method synchronously. However, the delegate class also includes methods for asynchronous invocation these are BeginInvoke() and EndInvoke(). When we use BeginInvoke(), the call returns immediately, but it doesn’t provide the return value. Instead, the method is simply queued to start on another thread. When calling BeginInvoke(), we supply all the parameters of the original method, plus two additional parameters for an optional callback and state object. If we don’t need these details we can simply pass a null reference in C# or Nothing in VB.NET. Lets have a look at the implementing BeginInvoke() and EndInvoke() from delegates (see listing 12-25 and listing 12-26). Listing 12-25. Using BeginInvoke() and EndInvoke() in C# using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Threading; namespace CSTestAsyncClient { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void buttonSynchronous_Click(object sender, EventArgs e) { DateTime starttime = DateTime.Now; WSAsync.Service wsAsyncService = new CSTestAsyncClient.WSAsync.Service(); String result = wsAsyncService.VerySlowWSFunction(); ComplexTimeconsumingLogic();
466
The Complete Reference To Professional SOA with Visual Studio 2005
this.labelSynchTimeTaken.Text = ((TimeSpan)DateTime.Now.Subtract(starttime)).TotalSeconds.ToString(); MessageBox.Show(result); } public delegate string VerySlowWebMethodAsyncDelegate(); private void buttonAsynchronous_Click(object sender, EventArgs e) { DateTime starttime = DateTime.Now; WSAsync.Service wsAsyncService = new CSTestAsyncClient.WSAsync.Service(); VerySlowWebMethodAsyncDelegate vsd = new VerySlowWebMethodAsyncDelegate(wsAsyncService.VerySlowWSFunction); IAsyncResult handle = vsd.BeginInvoke(null, null); // perform some very length calculation in the main application ComplexTimeconsumingLogic(); String result = ""; try { result = vsd.EndInvoke(handle); } catch (Exception ex) { MessageBox.Show(ex.Message); } this.labelAsyncTimetaken.Text = ((TimeSpan)DateTime.Now.Subtract(starttime)).TotalSeconds.ToString(); MessageBox.Show(result); } private void ComplexTimeconsumingLogic() { Thread.Sleep(5000); } } }
Listing 12-26. Using BeginInvoke() and EndInvoke() in Visual Basic 2005 Imports System.Threading Public Class Form1 Private Sub buttonSynchronous_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles buttonSynchronous.Click Dim starttime As DateTime = DateTime.Now Dim wsAsyncService As WSAsync.Service = _ New VBTestAsyncClient.WSAsync.Service
467
The Complete Reference To Professional SOA with Visual Studio 2005
Dim result As String = wsAsyncService.VerySlowWSFunction ComplexTimeconsumingLogic() Me.labelSynchTimeTaken.Text = _ CType(DateTime.Now.Subtract(starttime), TimeSpan).TotalSeconds.ToString MessageBox.Show(result) End Sub
Public Delegate Function VerySlowWebMethodAsyncDelegate() As String Private Sub buttonAsynchronous_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles buttonAsynchronous.Click Dim starttime As DateTime = DateTime.Now Dim wsAsyncService As WSAsync.Service = _ New VBTestAsyncClient.WSAsync.Service ' perform some very length calculation in the main application
Dim vsd As VerySlowWebMethodAsyncDelegate = _ New VerySlowWebMethodAsyncDelegate(AddressOf wsAsyncService.VerySlowWSFunction) Dim handle As IAsyncResult = _ vsd.BeginInvoke(Nothing, Nothing) ComplexTimeconsumingLogic() Dim result As String = "" Try
result = vsd.EndInvoke(handle) Catch ex As Exception MessageBox.Show(ex.Message) End Try Me.labelAsyncTimetaken.Text = _ CType(DateTime.Now.Subtract(starttime), TimeSpan).TotalSeconds.ToString MessageBox.Show(result) End Sub Private Sub ComplexTimeconsumingLogic() Thread.Sleep(5000) End Sub End Class
In listing 12-27 and listing 12-28 we first created a delegate to wrap around our very slow WebMethod VerySlowWSFunction. See listing 12-27 and listing 12-28 below.
Listing 12-27. Declaring the delegate using C#
public delegate string VerySlowWebMethodAsyncDelegate(); Listing 12-28. Declaring the delegate using Visual Basic 2005
Public Delegate Function VerySlowWebMethodAsyncDelegate() As String We then create a wrapper around the VerySlowWSFunction WebMethod. See listing 12-29 and listing 12-30 below. Listing 12-29. Wrapping the delegate around the VerySlowWSFunction WebMethod in C# VerySlowWebMethodAsyncDelegate vsd = new VerySlowWebMethodAsyncDelegate(wsAsyncService.VerySlowWSFunction);
468
The Complete Reference To Professional SOA with Visual Studio 2005
Listing 12-30. Wrapping the delegate around the VerySlowWSFunction WebMethod in Visual Basic 2005 Dim vsd As VerySlowWebMethodAsyncDelegate = _ New VerySlowWebMethodAsyncDelegate(AddressOf wsAsyncService.VerySlowWSFunction)
Once we have wrapped our VerySlowWSFunction we can begin to call the BeginInvoke() and EndInvoke(). BeginInvoke() doesn’t provide the return value of the underlying method. Instead, it returns an IAsyncResult object, which we can examine to determine when the asynchronous operation is complete. To pick up the results later, we submit the IAsyncResult object to the matching EndInvoke() method of the delegate. EndInvoke() waits for the operation to complete if it hasn’t already finished and then provides the real return value. If any unhandled errors occurred in the method that we executed asynchronously, they’ll bubble up to when we call EndInvoke(). See listing 12-31 and listing 12-32 below. Listing 12-31. Using BeginInvoke() and EndInvoke() using C# IAsyncResult handle = vsd.BeginInvoke(null, null); // perform some very length calculation in the main application ComplexTimeconsumingLogic(); String result = vsd.EndInvoke(handle);
Listing 12-32. Using BeginInvoke() and EndInvoke() using Visual Basic 2005 Dim handle As IAsyncResult = vsd.BeginInvoke(Nothing, Nothing) ComplexTimeconsumingLogic() Dim result As String = vsd.EndInvoke(handle)
Notice that the exception handler wraps the EndInvoke() method but not the BeginInvoke() method. That is because if any errors occur while processing the request (whether because of a network problem or a server-side exception), our code won’t receive it until you call the EndInvoke() method. See listing 12-33and listing 1234below. Listing 12-33. Catching errors for EndInvoke() using C# String result = ""; try { result = vsd.EndInvoke(handle); } catch (Exception ex) { MessageBox.Show(ex.Message); }
Listing 12-34. Catching errors for EndInvoke() using Visual Basic 2005 Dim result As String = "" Try result = vsd.EndInvoke(handle) Catch ex As Exception MessageBox.Show(ex.Message) End Try
In listing 12-33 and listing 12-34 above we have also included the same functionality using synchronous implementation. See listing 12-35 and listing 12-36 below.
469
The Complete Reference To Professional SOA with Visual Studio 2005
Listing 12-35. shows the synchronous implemenation C# private void buttonSynchronous_Click(object sender, EventArgs e) { DateTime starttime = DateTime.Now; WSAsync.Service wsAsyncService = new CSTestAsyncClient.WSAsync.Service(); String result = wsAsyncService.VerySlowWSFunction(); ComplexTimeconsumingLogic(); this.labelSynchTimeTaken.Text = ((TimeSpan)DateTime.Now.Subtract(starttime)).TotalSeconds.ToString(); MessageBox.Show(result); }
Listing 12-36. shows the synchronous implemenation Visual Basic 2005 Private Sub buttonSynchronous_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles buttonSynchronous.Click Dim starttime As DateTime = DateTime.Now Dim wsAsyncService As WSAsync.Service = _ New VBTestAsyncClient.WSAsync.Service Dim result As String = wsAsyncService.VerySlowWSFunction ComplexTimeconsumingLogic() Me.labelSynchTimeTaken.Text = _ CType(DateTime.Now.Subtract(starttime), TimeSpan).TotalSeconds.ToString MessageBox.Show(result) End Sub
In our TestAsyncClient application if we execute both synchronous implementation compared with the asynchronous implementation. We can see that the asynchronous implementation has dramatic improvement in performance. This is because the application does not have to wait for the WebMethod to return before start executing the next big piece of logic. Thus we have parallel execution that allows for a dramatic performance boost. To gain some of the benefits of multithreading with this technique, we could call several methods asynchronously with BeginInvoke(). We could then call EndInvoke() on all of them before continuing.
Figure 12-4: Execution time difference between synchronous and asynchronous
Concurrent Asynchronous Calls The IAsyncState object gives us a few other options that are useful when calling multiple web methods at once. The key is the IAsyncState.WaitHandle object, which returns a System.Threading.WaitHandle object. Using this
470
The Complete Reference To Professional SOA with Visual Studio 2005
object, we can call WaitAll() to wait until all our asynchronous operations are complete. See listing 12-37 and listing 12-38. The following example uses this technique to call the our VerySlowWSFunction() method four times at once. Listing 12-37. Implement concurrent async processing using C# using System; using System.Collections.Generic; using System.Text; using System.Threading; namespace CSTestConcurrentAsyncClient { class Program { public delegate string VerySlowWebMethodAsyncDelegate(); static void Main(string[] args) { DateTime starttime = DateTime.Now; CSTestConcurrenctAsyncClient.WSAsync.Service wsAsyncService = new CSTestConcurrentAsyncClient.WSAsync.Service();
VerySlowWebMethodAsyncDelegate vsd = new VerySlowWebMethodAsyncDelegate(wsAsyncService.VerySlowWSFunction); IAsyncResult handle = vsd.BeginInvoke(null, null); IAsyncResult handle1 = vsd.BeginInvoke(null, null); IAsyncResult handle2 = vsd.BeginInvoke(null, null); IAsyncResult handle3 = vsd.BeginInvoke(null, null); WaitHandle[] waitHandles = { handle.AsyncWaitHandle, handle1.AsyncWaitHandle, handle2.AsyncWaitHandle, handle3.AsyncWaitHandle}; // perform some very length calculation in the main application ComplexTimeconsumingLogic(); String result = "", result1 = "", result2 = "", result3 = ""; try {
WaitHandle.WaitAll(waitHandles); result = vsd.EndInvoke(handle); result1 = vsd.EndInvoke(handle1); result2 = vsd.EndInvoke(handle2); result3 = vsd.EndInvoke(handle3); Console.WriteLine("Time taken: " +((TimeSpan)DateTime.Now.Subtract(starttime)).TotalSeconds.ToString()); Console.WriteLine("Execution compelte!"); Console.ReadLine(); } catch (Exception ex) { Console.WriteLine("Error" + ex.Message); }
471
The Complete Reference To Professional SOA with Visual Studio 2005
} private static void ComplexTimeconsumingLogic() { Thread.Sleep(5000); } }
}
Listing 12-38. Implement concurrent async processing using Visual Basic 2005 Imports System Imports System.Collections.Generic Imports System.Text Imports System.Threading Namespace CSTestConcurrentAsyncClient Class Program Public Delegate Function VerySlowWebMethodAsyncDelegate() As String _ Shared Sub Main(ByVal args As String()) Dim starttime As DateTime = DateTime.Now Dim wsAsyncService As VBTestConcurrentAsyncClient.WSAsync.Service = New VBTestConcurrentAsyncClient.WSAsync.Service
Dim vsd As VerySlowWebMethodAsyncDelegate = New VerySlowWebMethodAsyncDelegate(AddressOf wsAsyncService.VerySlowWSFunction) Dim handle As IAsyncResult = vsd.BeginInvoke(Nothing, Nothing) Dim handle1 As IAsyncResult = vsd.BeginInvoke(Nothing, Nothing) Dim handle2 As IAsyncResult = vsd.BeginInvoke(Nothing, Nothing) Dim handle3 As IAsyncResult = vsd.BeginInvoke(Nothing, Nothing) Dim waitHandles As WaitHandle() = {handle.AsyncWaitHandle, handle1.AsyncWaitHandle, handle2.AsyncWaitHandle, handle3.AsyncWaitHandle} ComplexTimeconsumingLogic() Dim result As String = "" Dim result1 As String = "" Dim result2 As String = "" Dim result3 As String = "" Try
WaitHandle.WaitAll(waitHandles) result = vsd.EndInvoke(handle) result1 = vsd.EndInvoke(handle1) result2 = vsd.EndInvoke(handle2) result3 = vsd.EndInvoke(handle3) Console.WriteLine("Time taken: " + CType(DateTime.Now.Subtract(starttime), TimeSpan).TotalSeconds.ToString) Console.WriteLine("Execution compelte!") Console.ReadLine() Catch ex As Exception Console.WriteLine("Error" + ex.Message) Console.ReadLine() End Try End Sub
472
The Complete Reference To Professional SOA with Visual Studio 2005
Private Shared Sub ComplexTimeconsumingLogic() Thread.Sleep(5000) End Sub End Class
End Namespace
Instead of using a wait handle, we could also launch the three asynchronous calls by calling BeginInvoke() three times and then call the three EndInvoke() methods immediately after that. In this case, our code would wait if required. However, using a wait handle clarifies our code.
Improving Responsiveness in Windows Client One of the key benefit asynchronous implementation provides is in improving the responsiveness in Windows Client. In a Windows client, the threading code that we use is a little different. This is because we want to allow the application to continue unhindered while the operation is taking place. This will allow the UI to continue to interact with the user until the call is complete. This implementation allows us to refresh the display with updated information without locking the UI. Support for this asynchronous implementation pattern is built into the proxy class. The proxy class actually includes two methods the synchronous version that we’ve seen so far and an asynchronous version that adds the suffix Async to the method (see figure 12-5).
Figure 12-5: Synchronous and Asynchronous implementation of VerySlowWSFunction.
Notice there are two versions of VerySlowWSFunction, the VerySlowWSFunction without the Async suffix is used for synchronous operations whilst the other VerySlowWSFunctionAsync is auto generated for the proxy to use for Asynchronous implementations (see figure 12-5). The idea is that we can call VerySlowWSFunctionAsync() to launch the request. This method returns immediately, before the request is even sent over the network, and the proxy class waits on a free thread until it receives the response. As soon as the response is received and deserialized, .NET fires an event to notify our application. We can then retrieve the results. The proxy class also adds an event for each web method. This event is fired when the asynchronous method is finished. Let us have a look at using this asynchronous (see listing 12-39 and listing 12-40). Listing 12-39. Asynchronous implementation C#
473
The Complete Reference To Professional SOA with Visual Studio 2005
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Threading; using CSTestAsyncClient.WSAsync; namespace CSTestAsyncClient { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void buttonCheckResponse_Click(object sender, EventArgs e) { //dummy button to test return } private void buttonSynchronous_Click(object sender, EventArgs e) { DateTime starttime = DateTime.Now; WSAsync.Service wsAsyncService = new CSTestAsyncClient.WSAsync.Service(); String result = wsAsyncService.VerySlowWSFunction(); ComplexTimeconsumingLogic(); this.labelSynchTimeTaken.Text = ((TimeSpan)DateTime.Now.Subtract(starttime)) .TotalSeconds.ToString(); MessageBox.Show(result); } public delegate string VerySlowWebMethodAsyncDelegate(); private void buttonAsynchronous_Click(object sender, EventArgs e) { DateTime starttime = DateTime.Now; WSAsync.Service wsAsyncService = new CSTestAsyncClient.WSAsync.Service(); wsAsyncService.VerySlowWSFunctionCompleted += new CSTestAsyncClient.WSAsync. VerySlowWSFunctionCompletedEventHandler (VerySlowWSFunctionCompleted); wsAsyncService.VerySlowWSFunctionAsync(); this.labelAsyncTimetaken.Text =
474
The Complete Reference To Professional SOA with Visual Studio 2005
((TimeSpan)DateTime.Now.Subtract(starttime)). TotalSeconds.ToString(); } private void ComplexTimeconsumingLogic() { Thread.Sleep(5000); } private void VerySlowWSFunctionCompleted(object sender, WSAsync.VerySlowWSFunctionCompletedEventArgs e) { try { MessageBox.Show(e.Result); } catch (System.Reflection.TargetInvocationException err) { MessageBox.Show("Error: " + err.Message); } } }
}
Listing 12-40. Asynchronous implementation Visual Basic 2005 Imports System.Threading Public Class Form1 Private Sub buttonSynchronous_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles buttonSynchronous.Click Dim starttime As DateTime = DateTime.Now Dim wsAsyncService As WSAsync.Service = _ New VBTestAsyncClient.WSAsync.Service Dim result As String = wsAsyncService.VerySlowWSFunction ComplexTimeconsumingLogic() Me.labelSynchTimeTaken.Text = _ CType(DateTime.Now.Subtract(starttime), TimeSpan) _ .TotalSeconds.ToString() MessageBox.Show(result) End Sub
Public Delegate Function VerySlowWebMethodAsyncDelegate() As String Private Sub buttonAsynchronous_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles buttonAsynchronous.Click Dim starttime As DateTime = DateTime.Now
Dim wsAsyncService As WSAsync.Service = _
475
The Complete Reference To Professional SOA with Visual Studio 2005
New VBTestAsyncClient.WSAsync.Service ' perform some very length calculation in the main application
Dim vsd As VerySlowWebMethodAsyncDelegate = _ New VerySlowWebMethodAsyncDelegate( _ AddressOf wsAsyncService.VerySlowWSFunction) Dim handle As IAsyncResult = _ vsd.BeginInvoke(Nothing, Nothing) ComplexTimeconsumingLogic() Dim result As String = "" Try result = vsd.EndInvoke(handle) Catch ex As Exception MessageBox.Show(ex.Message) End Try Me.labelAsyncTimetaken.Text = _ CType(DateTime.Now.Subtract(starttime), TimeSpan) _ .TotalSeconds.ToString() MessageBox.Show(result) End Sub Private Sub ComplexTimeconsumingLogic() Thread.Sleep(5000) End Sub
End Class
The listing 12-39 and 12-40 implements asynchronous through the proxy’s VerySlowWSFunctionAsync() function to start the process. But first, it needs to attach an event handler to the VerySlowWSFunctionCompleted event. This is so that once we have executed VerySlowWSFunctionAsync() the code will return immediately. Thus we don’t know when the VerySlowWSFunctionAsync() will finish executing. By attaching the event to the asynchronous thread. Once the VerySlowWSFunctionAsync() has finished execution it will call on the VerySlowWSFunctionCompleted() as we had specified in our event. See listing 12-41and listing 12-42. Listing 12-41. Asynchronous implementation using events using C# wsAsyncService.VerySlowWSFunctionCompleted += new CSTestAsyncClient.WSAsync.VerySlowWSFunctionCompletedEventHandler(VerySlowWSFunctionCompleted);
Listing 12-42. Asynchronous implementation using events using Visual Basic 2005 AddHandler wsAsyncService.VerySlowWSFunctionCompleted, _ New VBTestAsyncClientWinForm.WSAsync.VerySlowWSFunctionCompletedEventHandler(AddressOf VerySlowWSFunctionCompleted)
This implementation is extremely useful in Windows application because it allows the UI to remain responsive whilst the asynchronous thread did the work. Once the results are obtained by the Asynchronous thread the UI can be updated with the new results.
476
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 12-6. Shows the difference of using Asynchronous implementation with event and that of synchronous implementation.
In Figure 12-6 we can see that the asynchronous implementation utilizing events has returned immediately after the button has been pressed and thus allowing the UI to continue work and thus remain responsive. This is particularly important in distributed systems where latency between request and response greatly varies.
Soap Extensions A XML Web service sends and receives data from clients in the form of SOAP messages. These SOAP messages can consist of information about a certain operation or about the result of an operation. Whenever a client requires information from the server that hosts the XML Web service, the client sends a SOAP request to the server. The SOAP request should be in compliance with a format that the XML Web service understands. The XML Web service processes the SOAP request and sends a response to the client. The client receives the SOAP response, interprets it, and performs a specified operation. If we need to access and modify the SOAP messages that are exchanged between an XML Web service and its clients, we can use SOAP extensions. SOAP extensions enable us to access and modify the SOAP messages that are exchanged between the client and the XML Web service. For example, we can use SOAP extensions to validate the SOAP message before it reaches the XML Web service and change the SOAP message after validation so that the XML Web service receives a valid SOAP request. We can also implement an encryption or compression algorithm that can be executed within an existing XML Web service by using SOAP extensions.
Figure 12-7. ASP.NET extension architecture
In ASP.NET architecture see figure 12-7 when ever IIS receives a request, the extension is mapped to an ISAPI filter according to the IIS settings. The .NET extension types .aspx, .asmx, .asx and other file types are mapped to the aspnet_isapi.dll which is simply an ISAPI filter that launches the ASP.NET runtime. The
477
The Complete Reference To Professional SOA with Visual Studio 2005
ASP.NET Runtime then launches the relevant Web service application and executes the SOAP Extensions before passing the request into the relevant web service. ASP.NET SOAP extensions are implemented by classes deriving from the SoapExtension class. They allow us to intercept messages and modify the corresponding streams. We can easily implement SOAP extension by overriding a few simple functions. The basis of SOAP extensions is the SoapExtension class. The main methods of concern are ChainStream(), GetInitializer(), Initialize(), and ProcessMessage(). The ChainStream() helps to capture the message stream within the SOAP call. The GetInitializer() and Initialize() are used to provide a means of initialization. While the ProcessMessage() method is the heart of the extension where most of the development attention goes.
Using SOAP Extensions A SOAP extension can be entered into the Web Services infrastructure to inspect or modify the SOAP messages before they are transmitted. The SoapExtension class includes a ProcessMessage() method that’s triggered automatically as the SOAP message passes through several stages. These stages are enclosed within an enumeration called SoapMessageStage. *
AfterDeserialize – This stage is just after a SoapMessage is deserialized from a SOAP message into an object.
*
AfterSerialize - This stage just after a SoapMessage is serialized, but before the SOAP message is sent over the wire.
*
BeforeDeserialize - This stage just before a SoapMessage is deserialized from the SOAP message sent across the network into an object.
*
BeforeSerialize - This stage just prior to a SoapMessage being serialized.
At each stage, we can retrieve various bits of information about the SOAP message. In the BeforeDeserialize or AfterSerialize stage, we can retrieve the full SOAP message text. We can also implement a SOAP extension on the client. In this case, the same four stages occur. Except now, the message is being received, deserialized, and acted upon by the proxy class, not the web service. To create a SOAP extension, we need to create a class that derives from the System.Web.Services.Protocols.SoapExtension class. The SoapExtension class provides a few methods that we need to override, these are: Table 12-2: Overridable methods of the SoapExtension class Name
Description
ChainStream
This method when overridden allows a SOAP extension to access memory buffer that contains the SOAP request or response.
GetInitializer
This method when overridden allows a SOAP extension to initialize a one time only data specific to a XML Web service.
Initialize
This method when overridden allows a SOAP extension to initialize itself using the data cached in the GetInitilizer method.
ProcessMessage This method when overridden allows a SOAP extension to receive a SoapMessage to process at each SoapMessageStage.
We will now create a Web service which provides an Add WebMethod. We will use overridable methods from SoapExtension class to implement a SOAP logging application to monitor the SOAP exchange performed on the Add WebMethod (see listing 12-43 and listing 12-44).
478
The Complete Reference To Professional SOA with Visual Studio 2005
Listing 12-43. SoapLogger.cs using C# namespace Logging { using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; using System.IO; using System.Xml; // Create a new custom attribute that will allow // users to configure the log file. This attribute // will also tell the ASP.NET system which type to // load for our extension [AttributeUsage(AttributeTargets.Method)] public class SoapLoggerAttribute : SoapExtensionAttribute { private int _priority = 0; private string _logFile = @"C:\soap.log"; public SoapLoggerAttribute() { } public SoapLoggerAttribute(string logFile){ _logFile = logFile; } public string LogFile { get { return _logFile; } } public override Type ExtensionType { get { return typeof(SoapLogger); } } public override int Priority { get { return _priority; } set { _priority = value; } } } // Create a new SoapExtension class. When users // apply the above attribute to a method of their // web service, this class will be instantiated // by the ASP.NET system public class SoapLogger : SoapExtension { private string LogFile = ""; private Stream SoapStream; private Stream TempStream; public override object GetInitializer(Type serviceType) {
479
The Complete Reference To Professional SOA with Visual Studio 2005
// we need to read some service configuration // from the attribute so differ creating // an initializer return null; } public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute) { // whatever we return here will be passed back to // our initialize method every time the ASP.NET // system needs to create a new instance of // this extension class return ((SoapLoggerAttribute)attribute).LogFile; } public override void Initialize(object initializer) { // grab the logfile name that we returned in // GetInitializer LogFile = (string)initializer; } public override Stream ChainStream(Stream stream) { // by overriding ChainStream we can // cause the ASP.NET system to use // our stream for buffering SOAP messages // rather than the default stream. // we will store off the original stream // so we can pass the data back down to the // ASP.NET system in original stream that // it created. SoapStream = stream; TempStream = new MemoryStream(); return TempStream; } public void CopyTextStream(Stream src, Stream dest) { TextReader reader = new StreamReader(src); TextWriter writer = new StreamWriter(dest); writer.WriteLine(reader.ReadToEnd()); writer.Flush(); } public override void ProcessMessage(SoapMessage message) { // this method will be called several times during // the processing of a SOAP request. The // ASP.NET system tells us which stage the // SOAP request is at with the Stage property // of the SoapMessage class switch (message.Stage) { case SoapMessageStage.BeforeDeserialize: { // copy the SOAP request from the
480
The Complete Reference To Professional SOA with Visual Studio 2005
// network stream into our memory buffer CopyTextStream(SoapStream, TempStream); FileStream fs = new FileStream(LogFile, FileMode.Append, FileAccess.Write); StreamWriter sw = new StreamWriter(fs); sw.WriteLine("** BEGIN SOAP REQUEST: {0}", DateTime.Now); sw.Flush(); // copy the mem buffer stream to the // log file TempStream.Position = 0; CopyTextStream(TempStream, fs); sw.WriteLine("** END SOAP REQUEST"); sw.Flush(); fs.Close(); // reset the memory buffer position // so the ASP.NET system can parse and // decode the message TempStream.Position = 0; } break; case SoapMessageStage.AfterDeserialize: break; case SoapMessageStage.BeforeSerialize: break; case SoapMessageStage.AfterSerialize: { FileStream fs = new FileStream(LogFile, FileMode.Append, FileAccess.Write); StreamWriter sw = new StreamWriter(fs); sw.WriteLine("** BEGIN SOAP RESPONSE: {0}", DateTime.Now); sw.Flush(); TempStream.Position = 0; CopyTextStream(TempStream, fs); sw.WriteLine("** END SOAP RESPONSE"); sw.Flush(); // copy the memory buffered response // to the network stream TempStream.Position = 0; CopyTextStream(TempStream, SoapStream); fs.Close(); } break; } return; } }
481
The Complete Reference To Professional SOA with Visual Studio 2005
}
Listing 12-44. SoapLogger.vb using Visual Basic 2005 Imports System.Xml Imports System.IO Imports System.Web.Services.Protocols Imports System.Web.Services Imports System.Web Imports System.Diagnostics Imports System.Data Imports System.ComponentModel Imports System.Collections Imports System Namespace Logging _ Public Class SoapLoggerAttribute Inherits SoapExtensionAttribute Private _priority As Integer = 0 Private _logFile As String = "C:\soap.log" Public Sub New() End Sub Public Sub New(ByVal logFile As String) _logFile = logFile End Sub Public ReadOnly Property LogFile() As String Get Return _logFile End Get End Property Public Overloads Overrides ReadOnly Property ExtensionType() As Type Get Return GetType(SoapLogger) End Get End Property Public Overloads Overrides Property Priority() As Integer Get Return _priority End Get Set(ByVal value As Integer) _priority = value End Set End Property End Class Public Class SoapLogger
482
The Complete Reference To Professional SOA with Visual Studio 2005
Inherits SoapExtension Private LogFile As String = "" Private SoapStream As Stream Private TempStream As Stream Public Overloads Overrides Function _ GetInitializer(ByVal serviceType As Type) As Object Return Nothing End Function Public Overloads Overrides Function _ GetInitializer(ByVal methodInfo As LogicalMethodInfo, _ ByVal attribute As SoapExtensionAttribute) As Object Return CType(attribute, SoapLoggerAttribute).LogFile End Function Public Overloads Overrides Sub Initialize(ByVal initializer As Object) LogFile = CType(initializer, String) End Sub Public Overloads Overrides Function ChainStream(ByVal stream As Stream) As Stream SoapStream = stream TempStream = New MemoryStream Return TempStream End Function Public Sub CopyTextStream(ByVal src As Stream, ByVal dest As Stream) Dim reader As TextReader = New StreamReader(src) Dim writer As TextWriter = New StreamWriter(dest) writer.WriteLine(reader.ReadToEnd) writer.Flush() End Sub Public Overloads Overrides Sub ProcessMessage(ByVal message As SoapMessage) Select Case message.Stage Case SoapMessageStage.BeforeDeserialize CopyTextStream(SoapStream, TempStream) Dim fs As FileStream = New FileStream(LogFile, _ FileMode.Append, FileAccess.Write) Dim sw As StreamWriter = New StreamWriter(fs) sw.WriteLine("** BEGIN SOAP REQUEST: {0}", _ DateTime.Now) sw.Flush() TempStream.Position = 0 CopyTextStream(TempStream, fs) sw.WriteLine("** END SOAP REQUEST") sw.Flush() fs.Close() TempStream.Position = 0 Case SoapMessageStage.AfterDeserialize Case SoapMessageStage.BeforeSerialize Case SoapMessageStage.AfterSerialize Dim fs As FileStream = New FileStream(LogFile, _
483
The Complete Reference To Professional SOA with Visual Studio 2005
FileMode.Append, FileAccess.Write) Dim sw As StreamWriter = New StreamWriter(fs) sw.WriteLine("** BEGIN SOAP RESPONSE: {0}", _ DateTime.Now) sw.Flush() TempStream.Position = 0 CopyTextStream(TempStream, fs) sw.WriteLine("** END SOAP RESPONSE") sw.Flush() TempStream.Position = 0 CopyTextStream(TempStream, SoapStream) fs.Close() End Select Return End Sub End Class
End Namespace
The above code shows the SOAP logger library. In order to use the SOAP logger we need to have a Web service for the SOAP extensions to work with. Below is a Web service which performs addition operations (see listing 12-45 and listing 12-46).
Listing 12-45. Web service which performs addition C# using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; using System.IO; using Logging; [WebService(Namespace = "http://tempuri.org/")] public class Service : System.Web.Services.WebService { public Service () { } [WebMethod] [SoapLogger] public int Add(int x, int y) { return x + y; }
}
Listing 12-46. Web service which performs addition Visual Basic 2005 Imports System.Web Imports System.Web.Services Imports System.Web.Services.Protocols
484
The Complete Reference To Professional SOA with Visual Studio 2005
Imports Logging _ _ _ Public Class Service Inherits System.Web.Services.WebService _ _ Public Function Add(ByVal x As Integer, _ ByVal y As Integer) As Integer Return x + y End Function
End Class
Now we will look at the structure of the SOAP extensions code. We will start by inheriting from the SoapExtension class (see listing 12-47 and listing 12-48), Listing 12-47. Extending from SoapExtension C# public class SoapLogger : SoapExtension Listing 12-48. Extending from SoapExtension Visual Basic 2005 Public Class SoapLogger Inherits SoapExtension
ASP.NET then calls the GetInitializer() method the first time our extension is used for a particular web method. It gives us the chance to initialize and store some data that will be used when processing SOAP messages. We can store this information by passing it back as the return value from the GetInitializer() method. When the GetInitializer() method is called, it allows us to receive the custom attribute that was applied to the corresponding web method. In the case of the SoapLogger, this is an instance of the SoapLoggerAttribute class, which provides the LogFile and Priority property (see listing 12-49 and listing 12-50). Listing 12-49. GetIntializer C# public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute) { return ((SoapLoggerAttribute)attribute).LogFile;
} Listing 12-50. GetIntializer Visual Basic 2005 Public Overloads Overrides Function _ GetInitializer(ByVal methodInfo As LogicalMethodInfo, _ ByVal attribute As SoapExtensionAttribute) As Object Return CType(attribute, SoapLoggerAttribute).LogFile
End Function
485
The Complete Reference To Professional SOA with Visual Studio 2005
There is also another version of GetInitializer() the reason is that SOAP extension can be loaded in two ways. One way is through the attribute for the WebMethod the other way is to specify it within the Web.Config file. We will be looking at this a little later (see listing 12-51 and listing 12-52). Listing 12-51. GetInitializer used by the Web.Config load implementation file C# public override object GetInitializer(Type serviceType) { return null;
} Listing 12-52. GetInitializer used by the Web.Config load implementation file Visual Basic 2005 Public Overloads Overrides Function _ GetInitializer(ByVal serviceType As Type) As Object Return Nothing
End Function
GetInitializer() is called only the first time our SOAP extension is executed for a method. However, every time a WebMethod is invoked, the Initialize() method is triggered. If we returned an object from the GetInitializer() method, ASP.NET provides this object to the Initialize() method every time it’s called. In the SoapLogger extension, this is where we can extract the LogFile information and store it in member variables so it will be available for the remainder of the SOAP processing work (see listing 12-53 and listing 12-54).
Tip: We can not store any information in the GetInitialize() method, because it will not be called every time the SOAP extension is executed.
Listing 12-53. Intialize() using C# public override void Initialize(object initializer) { // grab the logfile name that we returned in // GetInitializer LogFile = (string)initializer; }
Listing 12-54. Intialize() using Visual Basic 2005 Public Overloads Overrides Sub Initialize(ByVal initializer As Object) LogFile = CType(initializer, String) End Sub
The majority of the work within the SOAP extensions is done by the ProcessMessage() method, this is the method which ASP.NET calls at various stages of the serialization process. A SOAP message object is passed to the ProcessMessage() method, and here we can examine this method to retrieve information about the message, such as its stage and the message text. The SoapLogger extension reads the full message only in the AfterSerialize and BeforeDeserialize stages, because these are the only stages when we can retrieve the full XML of the SOAP message (see listing 12-55 and listing 12-56). Listing 12-55. ProcessMessage() using C# public override void ProcessMessage(SoapMessage message)
486
The Complete Reference To Professional SOA with Visual Studio 2005
{ // this method will be called several times during // the processing of a SOAP request. The // ASP.NET system tells us which stage the // SOAP request is at with the Stage property // of the SoapMessage class switch (message.Stage) { case SoapMessageStage.BeforeDeserialize: { // copy the SOAP request from the // network stream into our memory buffer CopyTextStream(SoapStream, TempStream); FileStream fs = new FileStream(LogFile, FileMode.Append, FileAccess.Write); StreamWriter sw = new StreamWriter(fs); sw.WriteLine("** BEGIN SOAP REQUEST: {0}", DateTime.Now); sw.Flush(); // copy the mem buffer stream to the // log file TempStream.Position = 0; CopyTextStream(TempStream, fs); sw.WriteLine("** END SOAP REQUEST"); sw.Flush(); fs.Close(); // reset the memory buffer position // so the ASP.NET system can parse and // decode the message TempStream.Position = 0; } break; case SoapMessageStage.AfterDeserialize: break; case SoapMessageStage.BeforeSerialize: break; case SoapMessageStage.AfterSerialize: { FileStream fs = new FileStream(LogFile, FileMode.Append, FileAccess.Write); StreamWriter sw = new StreamWriter(fs); sw.WriteLine("** BEGIN SOAP RESPONSE: {0}", DateTime.Now); sw.Flush(); TempStream.Position = 0; CopyTextStream(TempStream, fs); sw.WriteLine("** END SOAP RESPONSE"); sw.Flush(); // copy the memory buffered response // to the network stream
487
The Complete Reference To Professional SOA with Visual Studio 2005
TempStream.Position = 0; CopyTextStream(TempStream, SoapStream); fs.Close(); } break; } return; }
Listing 12-56. ProcessMessage() using Visual Basic 2005 Public Overloads Overrides Sub ProcessMessage(ByVal message As SoapMessage) Select Case message.Stage Case SoapMessageStage.BeforeDeserialize CopyTextStream(SoapStream, TempStream) Dim fs As FileStream = New FileStream(LogFile, _ FileMode.Append, FileAccess.Write) Dim sw As StreamWriter = New StreamWriter(fs) sw.WriteLine("** BEGIN SOAP REQUEST: {0}", _ DateTime.Now) sw.Flush() TempStream.Position = 0 CopyTextStream(TempStream, fs) sw.WriteLine("** END SOAP REQUEST") sw.Flush() fs.Close() TempStream.Position = 0 Case SoapMessageStage.AfterDeserialize Case SoapMessageStage.BeforeSerialize Case SoapMessageStage.AfterSerialize Dim fs As FileStream = New FileStream(LogFile, _ FileMode.Append, FileAccess.Write) Dim sw As StreamWriter = New StreamWriter(fs) sw.WriteLine("** BEGIN SOAP RESPONSE: {0}", _ DateTime.Now) sw.Flush() TempStream.Position = 0 CopyTextStream(TempStream, fs) sw.WriteLine("** END SOAP RESPONSE") sw.Flush() TempStream.Position = 0 CopyTextStream(TempStream, SoapStream) fs.Close() End Select Return End Sub
We also need a CopyTextStream() method see listing 12-55 and listing 12-56. That is because the XML in the SOAP message is contained in a stream. The stream has a pointer that indicates the current position in the stream. The problem is that as we read the message data from the stream (for example, to log it), we move the pointer. This means that if the log extension reads a stream that is about to be deserialized, it will move the pointer to the end of the stream. For ASP.NET to properly deserialize the SOAP message, the pointer must be set
488
The Complete Reference To Professional SOA with Visual Studio 2005
back to the beginning of the stream. If we don’t take this step, a deserialization error will occur. Notice we have copied the stream using the CopyTextStream method then write it to a file before reseting the TempStream.Postion back to 0 (see listing 12-57 and listing 12-58). Listing 12-57. CopyTextStream() using C# public void CopyTextStream(Stream src, Stream dest) { TextReader reader = new StreamReader(src); TextWriter writer = new StreamWriter(dest); writer.WriteLine(reader.ReadToEnd()); writer.Flush(); }
Listing 12-58. CopyTextStream() using Visual Basic 2005 Public Sub CopyTextStream(ByVal src As Stream, ByVal dest As Stream) Dim reader As TextReader = New StreamReader(src) Dim writer As TextWriter = New StreamWriter(dest) writer.WriteLine(reader.ReadToEnd) writer.Flush() End Sub
Another method that we need to override is the ChainStream() method, which the ASP.NET plumbing calls before serialization or deserialization takes place. SOAP extensions should save references of the Stream passed into ChainStream and the Stream returned from ChainStream. The Stream passed into ChainStream contains the serialized SOAP request at the BeforeDeserialize SoapMessageStage. Similarily, the Stream reference returned from ChainStream is written into when the serialization occurs and thus contains the serialized SOAP response in the AfterSerializeSoapMessageStage. At this point, the extension can cache a reference to the original stream and create a new in-memory stream, which is then returned to the next extension in the chain (see listing 12-59 and listing 12-60). Listing 12-59. ChainStream() using C# public override Stream ChainStream(Stream stream) { SoapStream = stream; TempStream = new MemoryStream(); return TempStream; }
Listing 12-60. ChainStream() using Visual Basic 2005 Public Overloads Overrides Function ChainStream(ByVal stream As Stream) As Stream SoapStream = stream TempStream = New MemoryStream Return TempStream End Function
To help us run the SOAP extensions we have created a custom attribute class called SoapLoggerAttribute. It is this class that is accessed by the SOAPLogger for parameter values that’s passed in from the parameters defined in the attribute (see listing 12-61 and listing 12-62). Listing 12-61. Custom SoapLoggerAttribute using C# [AttributeUsage(AttributeTargets.Method)]
489
The Complete Reference To Professional SOA with Visual Studio 2005
public class SoapLoggerAttribute : SoapExtensionAttribute { private int _priority = 0; private string _logFile = @"C:\soap.log"; public SoapLoggerAttribute() { } public SoapLoggerAttribute(string logFile){ _logFile = logFile; } public string LogFile { get { return _logFile; } } public override Type ExtensionType { get { return typeof(SoapLogger); } } public override int Priority { get { return _priority; } set { _priority = value; } } }
Listing 12-62. Custom SoapLoggerAttribute using Visual Basic 2005 _ Public Class SoapLoggerAttribute Inherits SoapExtensionAttribute Private _priority As Integer = 0 Private _logFile As String = "C:\soap.log" Public Sub New() End Sub Public Sub New(ByVal logFile As String) _logFile = logFile End Sub Public ReadOnly Property LogFile() As String Get Return _logFile End Get End Property Public Overloads Overrides ReadOnly Property ExtensionType() As Type Get Return GetType(SoapLogger) End Get End Property Public Overloads Overrides Property Priority() As Integer Get Return _priority End Get Set(ByVal value As Integer) _priority = value End Set
490
The Complete Reference To Professional SOA with Visual Studio 2005
End Property End Class
XML Web service methods created using ASP.NET can be configured to run with a SOAP extension by applying an attribute to the XML Web service method. When a custom extension attribute is added to an XML Web service method, ASP.NET calls the associated extension at the appropriate time. An extension attribute is a custom attribute class deriving from SoapExtensionAttribute. Derived attributes must override the ExtensionType property to return the type of extension that is associated with the attribute.
Using SoapLogger There’s two ways to enable our SOAP Extensions. One way is to enable the SOAP extension through using an attribute (see listing 12-63 and listing 12-64). Listing 12-63. Invoking the SOAP Extensions using C# [WebMethod] [SoapLogger] public int Add(int x, int y) {
Listing 12-64. Invoking the SOAP Extensions using Visual Basic 2005 _ _ Public Function Add(ByVal x As Integer, _ ByVal y As Integer) As Integer
This will provide us with flexiblity in specifying which WebMethod we’d really like to add our SOAP extensions for. The second method is to specify it within the Web service’s Web.Config file. Doing so will enable our SOAP logger extensions to be executed for all Web service within control of the configuration file (see listing 21-65). Listing 12-65. Web.Config implementation
Tip: We cannot test the SOAP extensions using the asmx autogenerated test harness for web method. There is a TestSOAPExtensionsClient application on the source CD which we can use to test the SOAP extensions. Its also important to remember that we need to start the Web service first, we may also need to adjust the port number for the web service within the client application as the web service will be running off the ASP.NET Development Server Environment for file system web applications.
The client code that we use call the Web service is as how we would call a normal Web service (see listing 12-66 and listing 12-67).
491
The Complete Reference To Professional SOA with Visual Studio 2005
NOTE: Please give the correct privileges to the Web Service so that the log file can be written to the hard drive.
Listing 12-66. Client side code using C# private void button1_Click(object sender, EventArgs e) { SOAPExtension.Service wse = new winclient.SOAPExtension.Service(); this.labelResult.Text = wse.Add(5, 6).ToString(); }
Listing 12-67. Client side code using Visual Basic 2005 Private Sub buttonRequest_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonRequest.Click Dim wse As SOAPExtension.Service = New SOAPExtension.Service Me.labelResult.Text = wse.Add(5, 6).ToString End Sub
The above listing shows the client side code that we use to invoke our Web service with the addition WebMethod implementation. The call to the Web service is unaffected by the SOAP extensions implementation. Our SOAP logger extension will log the soap call before the request is deserialized and after it is serialized. The result of the SOAP extension is captured with a text file. Listing 12-68. Result captured by the SOAP Logger ** BEGIN SOAP REQUEST: 5/22/2006 11:46:04 PM 56 ** END SOAP REQUEST ** BEGIN SOAP RESPONSE: 5/22/2006 11:46:04 PM 11 ** END SOAP RESPONSE
The SoapLog extension is a useful tool when developing or monitoring web services. However, we should use it sensibly. Especially if there’re large numbers of Web methods that the SOAP extenions are monitoring.
Summary In this chapter, we have looked at a variety of advanced SOAP techniques; these include using various WebMethod properties, implementing web services using asynchronously implementations, and how to use SOAP extensions. We have also examined WebMethod properties these are BufferResponse, CacheDuration, Description, EnableSession, MessageName, TransactionOption. In this chapter we have also looked at asynchronous implementation which is used to allow applications to execute a method without waiting for it complete. This is very useful in a distributed architecture, because the
492
The Complete Reference To Professional SOA with Visual Studio 2005
inherent nature of the internet, the response time between request and response can vary greatly. As such we do not want our program to wait for the method to return. The last thing we have looked at is SOAP extensions. SOAP extensions enable us to access and modify the SOAP messages that are exchanged between the client and the XML Web service. For example, we can use SOAP extensions to validate the SOAP message before it reaches the XML Web service and change the SOAP message after validation so that the XML Web service receives a valid SOAP request. We can also implement an encryption or compression algorithm that can be executed within an existing XML Web service by using SOAP extensions.
493
The Complete Reference To Professional SOA with Visual Studio 2005
Chapter 13 .NET Remoting .NET Remoting is the .NET alternative to XML Web services. .NET Remoting is an enabler for application communication. It is a generic system for different applications to use to communicate with one another. .NET objects are exposed to remote processes, thus allowing interprocess communication. The applications can be located on the same computer, different computers on the same network, or even computers across separate networks. In the last few chapters, we have looked at how ASP.NET Web services are created and consumed. ASP.NET Web services use the ASP.NET runtime as the hosting environment to run. Using .NET Remoting directly, we can host Web service in any application we want. .NET Remoting allows different transport protocols to be used. We can also benefit from performance increase with different formatting options, and it is possible to host the server in different application types. Table 13-1. The table below outlines differences between .NET Remoting and Web services.
Web Service
.NET Remoting
.NET Web services are typically accessed over HTTP.
.NET Remoting can be used across three channels TCP, HTTP, IPC. and two formatters SOAP and Binary.
Web services work in a stateless environment. Each request results in a new object created to service the request.
.NET Remoting supports state management options and can associate multiple calls from the same client. Remoting model also support Asynchronous callbacks.
Web services serialize objects into XML that is contained in the SOAP message and as such can only handle items that can be fully expressed in XML.
.NET Remoting relies the Common Language Runtime assemblies that contain information about data types. This allows objects to be passed by value or by reference.
Web services are interoperable across platforms and are good for environment that consists of different technologies but are required to work together.
.NET Remoting can only be created using .NET
In the world of SOA .NET remoting may not be ideal for public facing as it is not as interoperable as Web service. However we can use .NET remoting internally within an architecture to improve the performance of communication between .NET to .NET applications.
.NET Remoting Proxy Architecture To communicate between server objects and clients in .NET Remoting, we simply need to add an object references of the server object in the client application. Whenever we create an instance of the remote object using the new keyword, our client receives a reference to the server object. After obtaining the object reference,
494
The Complete Reference To Professional SOA with Visual Studio 2005
the client can call methods on the server object as if the object resides in the client's process. This process of invoking methods on the server is very much like how we invoke methods of Web services. .NET Remoting uses proxy objects to allow the use of the server object in the client process. When we create an instance of the remote object type in the client application, .NET Remoting creates a proxy object and sends it to the client application. This proxy object contains references to all the methods and properties of the server object. When a call is made on the proxy object, the remoting system receives the call and routes the call to the server process. This invokes the server object, which then returns the result to the client proxy. The client proxy then in turn return the result to the client application (see figure 13-1). The .NET Remoting architecture is quite flexible we can use different transport protocols such as HTTP, TCP and IPC we can also communicate using different formatters such as SOAP and Binary.
Figure 13-1. Communication between a client process and a server process.
Remotable and Nonremotable Objects In distributed applications, there are two categories of objects: Remotable and nonremotable. Nonremotable objects do not provide the Remoting system with a method to either copy them or use them in another application domain. Therefore, we can access these objects only in their own application domain. Remotable objects can either be accessed outside their application domain or context using a proxy or copied and passed outside their application domain or context. This implies that some remotable objects are passed by reference and some are passed by value. For example, if we have a large object with a number of methods, our best option is to make the object nonremotable. Then, we can create a remotable object that is small in size that can be published or copied to the client application. We can then use the remotable object to direct the call to the larger nonremotable object.
A remotable object is an object that inherits from MarshalByRefObject. There are two types of remotable objects Marshal-by-value objects and Marshal-by-reference objects.
Marshal-by-value Objects In marshal-by-value objects are copied by the Remoting system and passed in their entirety to the caller’s application domain. Once the objects are copied to the caller’s application domain, all method calls and property accesses are executed entirely within the domain of the calling application. Since the entire object exists in the caller’s domain, there is no need to marshal access across domain boundaries. Marshal-by-value is ideal for small objects because smaller objects increase performance by reducing network traffic especially if the objects needs to be accessed frequently. However because the object exists in the caller application domain, no state change to the object will be reflected to the originating application domain or from the originator back to the
495
The Complete Reference To Professional SOA with Visual Studio 2005
caller. Marshal-by-value is not ideal for large objects which need to be accessed frequently. We should also keep in mind to only marshal the field, method or property that we really need to access. This will dramatically reduce the network requirements. We create a marshal-by-value object by decorating the class with the [Serializable] attribute see listing 13-1 and listing 13-2. Listing 13-1. Demonstrates Marshal-by-value using C# using System; namespace RemotingSamples { [Serializable] public class MarshalByValue { private int mValue = 1; public void Increment() { mValue++; } public int getValue() { return mValue; } } }
Listing 13-2. Demonstrates Marshal-by-value using Visual Basic 2005 Imports System Namespace RemotingSamples _ Public Class MarshalByValue Dim mValue As Integer = 1 Public Sub Increment () mValue += 1 End Sub Public Function getValue() As Integer Return mValue End Function End Class End Namespace
In the listing above we have defined a MarshalByValue class which is flagged with the [Serializable] attribute. This allows the class to be serialized and streamed to and from the server. Additionally, implementing the ISerializable interface gives us an opportunity to plug into the standard marshalling formatters.
496
The Complete Reference To Professional SOA with Visual Studio 2005
Marshal-by-reference Objects In marshal-by-reference when a client instantiates a marshal-by-reference object the .NET Remoting infrastructure creates a proxy object in the caller application domain and returns the reference of that proxy to the caller. When the client makes calls on the object through the proxy, the Remoting infrastructure marshals the calls, and sends them to the originator’s application domain. The application domain then invokes the call on the actual object. The return value from the call and or any out parameters are handled similarly on the way back. We should use marshal-by-reference objects when the state of the object and any executable functionality must remain in the application domain in which it was created (that is, on the server). Listing 13-3. Demonstrates Marshal-by-reference by C# using System; namespace RemotingSamples { public class MarshalByReference: MarshalByRefObject { public void PrintText(String text) { Console.WriteLine(text); } }
}
Listing 13-4. Demonstrates Marshal-by-reference using Visual Basic 2005 Imports System Namespace RemotingSamples Public Class MarshalByReference : Inherits MarshalByRefObject Sub PrintText(ByVal text As String) Console.WriteLine(Text) End Sub End Class
End Namespace This example demonstrates how to create an object that derives from MarshalByRefObject on the client.
Tip: It is generally good idea to implement the class of the remote object in a different assembly from that of the remote server itself. This assembly can then be used by different server applications, and the client application can use it to get the metadata needed to build the proxy.
Server Activated and Client Activated Objects When we develop an object, we don’t need to track the creation of the object. we only need to ensure that the object responds to the method calls. However, when we develop a remote object, we need to track the creation and initialization of the object because the way a remote object behaves depends on how the object is created and
497
The Complete Reference To Professional SOA with Visual Studio 2005
activated. We have to be aware of how remote objects are activated. We need to specify to the remoting system what type of activation is required on the objects before the remoting system provides these objects to the clients. There’re two groups Server Activated Objects (SAOs) and Client-Activated Objects (CAOs).
Server Activated Objects (SAOs) Server-activated objects are similar to classic stateless Web Services. When a client make a request to a reference to a SAO, no message is actually sent to the server. The server will only be notified when a method call is made on the remote reference. Depending on the configuration of its objects, the server then decides whether a new instance will be created or an existing object will be reused. SAOs can be marked as either Singleton or SingleCall. *
Singleton – Refers to one instance serving the requests of all clients in a multithreaded fashion. Singleton is defined by the WellKnownObjectMode.Singleton.
*
SingleCall – Refers to a new object created for each request and destroyed afterwards. SingleCall is defined by the WellKnownObjectMode.SingleCall.
Consider the following example: An insurance company has a service component that enables organizations, such as insurance brokers and vehicle repair shops, to check the validity of a claim on a car by entering its registration number. Clients connect to this service and provide the registration number of the vehicle for validation. The service validates the registration returns the appropriate information from the insurance company advising claim details on the vehicle. In this scenario, clients are always connected to the server at the insurance company. The service is activated only when a method call arrives from the clients requesting for details on the vehicle.
An example of implementation using WellKnownObjectMode.Singleton is shown below. Listing 13-5. Shows an implementation of Remoting server using WellKnownObjectMode.Singleton in C# using System; using System.Collections.Generic; using System.Text; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; namespace InsuranceServer { public class VehicleDetailsServer : MarshalByRefObject { public static void Main(string[] args) { // Create an instance of a channel TcpChannel channel = new TcpChannel(8080);
ChannelServices.RegisterChannel(channel, true); // Register as an available service with the name // ValidateRegistration
RemotingConfiguration.RegisterWellKnownServiceType( typeof(InsuranceOperation),
498
The Complete Reference To Professional SOA with Visual Studio 2005
"ValidateRegistration", WellKnownObjectMode.Singleton); System.Console.WriteLine ("Press the enter key to exit..."); System.Console.ReadLine(); } } }
Listing 13-6. Shows an implementation of Remoting server using WellKnownObjectMode.Singleton in Visual Basic 2005 Imports System Imports System.Collections.Generic Imports System.Text Imports System.Runtime.Remoting Imports System.Runtime.Remoting.Channels Imports System.Runtime.Remoting.Channels.Tcp Imports VBSampleObject Namespace InsuranceServer Public Class VehicleDetailsServer Inherits MarshalByRefObject Shared Sub Main() Dim channel As TcpChannel = New TcpChannel(8080)
ChannelServices.RegisterChannel(channel, True) RemotingConfiguration.RegisterWellKnownServiceType _ (GetType(InsuranceOperation), "ValidateRegistration", _ WellKnownObjectMode.Singleton) System.Console.WriteLine("Press the enter key to exit...") System.Console.ReadLine() End Sub End Class End Namespace
The code above shows an implementation of the .NET remoting server using WellKnownObjectMode.Singleton. By implementing Singleton we have one instance serving all in-coming
requests. The above remoting server implementation will make the remotable object available to the requesting clients. To use Single Call so that an object is created for each request and the object is destroyed afterward. We can use the code below. Listing 13-7. Demonstrates using SingleCall in C# RemotingConfiguration.RegisterWellKnownServiceType( typeof(InsuranceOperation), "ValidateRegistration", WellKnownObjectMode.SingleCall);
499
The Complete Reference To Professional SOA with Visual Studio 2005
Listing 13-8. Demonstrates using SingleCall in Visual Basic 2005 RemotingConfiguration.RegisterWellKnownServiceType _ (GetType(VBSampleObject.InsuranceOperation), _ "ValidateRegistration", WellKnownObjectMode.SingleCall)
Notice in the code we’ve specified TcpChannel and assigned a port of 8080. This means that our server will wait for incoming connections at that port. Once the designated port has been specified we will register the channel by using ChannelServices.RegisterChannel. .NET 2.0 now supports security with channels we can register our connection to use security when set to true or false otherwise. We will be going into more details on channels in a later section. Listing 13-9. Demonstrates InsuranceOperation class using C# using System; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; /// /// Sample object to demonstrate the use of .NET Remoting. ///
public class InsuranceOperation : MarshalByRefObject { /// /// Constructor /// public InsuranceOperation() {
Console.WriteLine("Constructor has been called"); } public string ValidateRegistration(string regno) { if (regno == "xyz-123") return "claim has been approved"; else return "No claim has been lodged"; } }
Listing 13-10. Demonstrates InsuranceOperation class using Visual Basic 2005 Imports System Imports System.Runtime.Remoting Imports System.Runtime.Remoting.Channels
Public Class InsuranceOperation Inherits MarshalByRefObject Public Sub New()
500
The Complete Reference To Professional SOA with Visual Studio 2005
Console.WriteLine("Constructor has been called") End Sub Public Function ValidateRegistration(ByVal regno As String) As String If regno = "xyz-123" Then Return "claim has been approved" Else Return "No claim has been lodged" End If End Function End Class
The above code implements InsuranceOperation class. the class implements MarshalByRefObject which is used to marshal the reference calls from the client back to the server. This allows a proxy to be created for the operations on the server the proxy will then be used to invoke and marshal calls to the server. The constructor in marshal-by-reference will not be invoked. The SampleObject refered to below is actually the assembly for InsuranceOperation. Listing 13-11. The client application using C# using System; using System.Collections.Generic; using System.Text; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; namespace InsuranceClient { class Program { public static void Main(string[] args) { // Create a channel for communicating with the remote object TcpChannel chan = new TcpChannel(); ChannelServices.RegisterChannel(chan, true); // Create an instance of the remote object
SampleObject obj = (SampleObject)Activator.GetObject(
typeof(SampleObject), "tcp://localhost:8080/ValidateRegistration"); // Use the object if (obj.Equals(null)) { System.Console.WriteLine("Error: unable to locate server"); } else { Console.WriteLine(obj.ValidateRegistration("xyz-123")); } Console.ReadLine(); } }
501
The Complete Reference To Professional SOA with Visual Studio 2005
}
Listing 13-12. The client application using Visual Basic 2005 Imports System Imports System.Collections.Generic Imports System.Text Imports System.Runtime.Remoting.Channels Imports System.Runtime.Remoting.Channels.Tcp Imports VBSampleObject Namespace InsuranceClient Class Program Shared Sub Main() Dim chan As TcpChannel = New TcpChannel ChannelServices.RegisterChannel(chan, True)
Dim obj As SampleObject = CType(Activator.GetObject( _ GetType(SampleObject), _ "tcp://localhost:8080/ValidateRegistration"), SampleObject) If obj.Equals(Nothing) Then System.Console.WriteLine("Error: unable to locate server") Else Console.WriteLine(obj.ValidateRegistration("xyz-123")) End If Console.ReadLine() End Sub End Class End Namespace
The above code shows the client application required to consume our remoting objects. Notice how we have also registered a channel object. However we do not need to specify a opening port as we will only be requesting rathering than waiting for incoming connections. In the above code we have used Activator.GetObject.Activator.GetObject allows us to call the proxy to send messages to the remote object. However no messages are sent over the network until a method is called on the proxy. Activator.GetObject as well as using new() are used to call a remoting object as a Server Activated Object. See table 13-3 in the later section of (Differences between Server Activated Objects and Client Activated Objects) for more detailed comparisons between SAOs and CAOs.
Figure 13-2. Remoting server
502
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 13-3. Remoting client
Using Configuration File We can programmatically specify the configuration or we can define the configuration file. The advantage of using configuration files for Remoting clients and servers is that we do not have to change the code or need to recompile. Another advantage is that it simplifies the remoting code that we’re required to write. The xml configuration below shows how to configure for a remoting server (listing 13-13). Listing 13-13. Shows the xml configuration RemoteServerConfig.xml file for the above remoting server implementation.
In the above configuration file, RemoteServerConfig.xml, all of the remoting configurations must be added as child elements to . The element defines the name of the application. The service that is offered from the application must be listed as a child of . This is where we define the remote object itself. The remote object is defined within the element. Here we need to define the name of the assembly where the type of this object can be loaded from this is defined in the element. The last property in the object is the objectUri. objectUri is a name that is assigned to the object which will be used by the client. The mode attribute is set to SingleCall. If Singleton is required we simply alter the mode to Singleton:
Once the configuration file has been defined all that the application needs to do is read the configuration file to activate the channel by using the static method RemotingConfiguration.Configure().
503
The Complete Reference To Professional SOA with Visual Studio 2005
Listing 13-14. The listing below shows the C# implementation of the remoting server using System; using System.Collections.Generic; using System.Text; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; namespace InsuranceServer { public class VehicleDetailsServer : MarshalByRefObject { public static void Main(string[] args) {
RemotingConfiguration.Configure ("RemoteServerConfig.xml", false); System.Console.WriteLine ("Press the enter key to exit..."); System.Console.ReadLine(); } } }
Listing 13-15. The listing below shows the Visual Basic 2005 implementation of the remoting server Imports System Imports System.Collections.Generic Imports System.Text Imports System.Runtime.Remoting Imports System.Runtime.Remoting.Channels Imports System.Runtime.Remoting.Channels.Tcp Namespace InsuranceServer Public Class VehicleDetailsServer Inherits MarshalByRefObject Public Shared Sub Main(ByVal args As String())
RemotingConfiguration.Configure _ ("RemoteServerConfig.xml", False) System.Console.WriteLine("Press the enter key to exit...") System.Console.ReadLine() End Sub End Class End Namespace
Here the server is implemented in a console application. RemotingConfiguration.Configure() reads the configuration file RemoteServerConfig.xml to configure and activate the channel. The creation of the remote object and communication with the client is done by the remoting infrastructure. To make sure that the server is there for the client after it is initialized we use Console.ReadLine() to make sure that the server process will not end immediately.
504
The Complete Reference To Professional SOA with Visual Studio 2005
Creating a client using configuration file is as simple as creating the server with configuration. Here we will create a client using a configuration file. Listing 13-16. Shows RemoteClientConfig.xml which contains the client configuration for remoting.
The XML client configuration file RemoteClientConfig.xml uses the element to specify the interested remote server object. Under we can specify the URL of the server using protocol://hostname:port/application. In the example we had illustrated we have used tcp as the protocol, and the server runs on localhost with the port number 3080. The application name of the server is defined with the name attribute of the element in the server configuration file. The element specifies the remote object we want to access. As in the server configuration file, the type attribute defines the type of the remote object and the assembly. The url attribute defines the path to the remote object. Appended to the URL of the application is the endpoint name ValidateRegistration. The channel that is configured with the client can again be found in the configuration file machine.config, but this time it is the client channel and thus specified as “tcp client”. Let us have a look at the code required to load the configuration settings for the client. Listing 13-17. Shows the C# code for a remoting client using configurations using System; using System.Collections.Generic; using System.Text; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; using System.Runtime.Remoting; namespace InsuranceClient { class Client { public static void Main(string[] args) {
RemotingConfiguration.Configure ("RemoteClientConfig.xml", true); InsuranceOperation obj = new InsuranceOperation();
505
The Complete Reference To Professional SOA with Visual Studio 2005
// Use the object if (obj.Equals(null)) { System.Console.WriteLine ("Error: unable to locate server"); } else { Console.WriteLine(obj.ValidateRegistration("xyz-123")); } Console.ReadLine(); } } }
Listing 13-18. Shows the Visual Basic 2005 code for a remoting client using configurations Imports System Imports System.Collections.Generic Imports System.Text Imports System.Runtime.Remoting Imports System.Runtime.Remoting.Channels Imports System.Runtime.Remoting.Channels.Tcp Namespace InsuranceClient Class Client Public Shared Sub Main(ByVal args As String())
RemotingConfiguration.Configure _ ("RemoteClientConfig.xml", True) Dim obj As VBSampleObject.InsuranceOperation = _ New VBSampleObject.InsuranceOperation If obj.Equals(Nothing) Then System.Console.WriteLine _ ("Error: unable to locate server") Else Console.WriteLine(obj.ValidateRegistration("xyz-123")) End If Console.ReadLine() End Sub End Class End Namespace
As in the server, we can activate the client channel by calling the RemotingConfiguration.Configure(). Using configuration files we can simply use new to create the remote object. By using new the remoting framework will automatically reference the remote object for us. Any call made to the reference will be automatically marshaled to the server.
506
The Complete Reference To Professional SOA with Visual Studio 2005
Client Activated Objects (CAOs) Client-activated objects are unlike well-known objects, these objects can have states. A client-activated object is not created with every call it is only instantiated on the server when the client creates it. Client-activated objects (CAOs) are server-side objects that are activated upon request from the client. When the client submits a request for a server object using "new" operator or Activator.CreateInstance(), an activation request message is sent to the remote application. The server then creates an instance of the requested class and returns an ObjRef back to the client application that invoked it. A proxy is then created on the client side using the ObjRef. The client's method calls will be executed on the proxy. Client-activated objects can store state information between method calls for its specific client and not across different client objects. Each invocation of "new" returns a proxy to an independent instance of the server type. See listing 13-19 and listing 13-20 for an example of client activated object of the same insurance application in the previous example. Listing 13-19. Client Activated Object server implementation using C# using System; using System.Collections.Generic; using System.Text; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; using System.Runtime.Remoting.Activation; namespace InsuranceServer { public class VehicleDetailsServer : MarshalByRefObject { public static void Main(string[] args) { TcpServerChannel channel = new TcpServerChannel(9080); ChannelServices.RegisterChannel(channel, true); RemotingConfiguration.ApplicationName = "ValidateRegistration";
RemotingConfiguration.RegisterActivatedServiceType (typeof(InsuranceOperation)); System.Console.WriteLine ("Press the enter key to exit..."); System.Console.ReadLine(); } } }
Listing 13-20. Client Activated Object server implementation using Visual Basic 2005 Imports System Imports System.Collections.Generic Imports System.Text Imports System.Runtime.Remoting Imports System.Runtime.Remoting.Channels Imports System.Runtime.Remoting.Channels.Tcp
507
The Complete Reference To Professional SOA with Visual Studio 2005
Imports System.Runtime.Remoting.Activation Namespace InsuranceServer Public Class VehicleDetailsServer Inherits MarshalByRefObject Public Shared Sub Main(ByVal args As String()) Dim channel As TcpServerChannel = _ New TcpServerChannel(9080) ChannelServices.RegisterChannel(channel, True) RemotingConfiguration.ApplicationName = _ "ValidateRegistration"
RemotingConfiguration.RegisterActivatedServiceType _ (GetType(VBSampleObject.InsuranceOperation)) System.Console.WriteLine _ ("Press the enter key to exit...") System.Console.ReadLine() End Sub End Class End Namespace
The RemotingConfiguration class provides the RegisterActivatedServiceType method which to allow us to programmatically configure a type for client activation. We use this method to configure the server application for the client-activated implementation: Listing 13-21. Implement client activation using RegisterActivatedServiceType using C# RemotingConfiguration.RegisterActivatedServiceType (typeof(InsuranceOperation));
Listing 13-22. Implement client activation using RegisterActivatedServiceType using Visual Basic 2005 RemotingConfiguration.RegisterActivatedServiceType _ (GetType(VBSampleObject.InsuranceOperation))
When the server application executes this line of code, it registers the InsuranceOperation type as a client activated object. This means that the host will accept client activation requests for the InsuranceOperation type. Upon receiving an activation request, the Remoting infrastructure instantiates an instance of the InsuranceOperation class. Listing 13-23. Client Activated Object InsuranceOperation using C# using System; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; /// /// Sample object to demonstrate the use of .NET Remoting. /// public class InsuranceOperation : MarshalByRefObject { ///
508
The Complete Reference To Professional SOA with Visual Studio 2005
/// Constructor /// /// public InsuranceOperation() {
Console.WriteLine("Constructor has been called"); } public string ValidateRegistration(string regno) { if (regno == "xyz-123") return "claim has been approved"; else return "No claim has been lodged"; } }
Listing 13-24. Client Activated Object InsuranceOperation using Visual Basic 2005 Imports System Imports System.Runtime.Remoting Imports System.Runtime.Remoting.Channels Public Class InsuranceOperation Inherits MarshalByRefObject Public Sub New()
Console.WriteLine("Constructor has been called") End Sub Public Function ValidateRegistration(ByVal regno As String) As String If regno = "xyz-123" Then Return "claim has been approved" Else Return "No claim has been lodged" End If End Function End Class
The above InsuranceOperation class is similar to the previous server activated InsuranceOperation implementation except we have added a constructor so that we can see and monitor when the constructor is called. Unlike server-activated implement client-activated implementation will invoke the constructor. Listing 13-25. Client Activated Object client implementation using C# using System; using System.Collections.Generic; using System.Text; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; using System.Runtime.Remoting;
509
The Complete Reference To Professional SOA with Visual Studio 2005
using System.Runtime.Remoting.Activation; namespace InsuranceClient { class Client { static void Main(string[] args) {
TcpClientChannel channel = new TcpClientChannel(); ChannelServices.RegisterChannel(channel, true); object[] attrs = { new UrlAttribute( "tcp://localhost:9080/ValidateRegistration") }; InsuranceOperation obj = (InsuranceOperation)Activator.CreateInstance( typeof(InsuranceOperation), null, attrs); // Use the object if (obj.Equals(null)) { System.Console.WriteLine ("Error: unable to locate server"); } else { Console.WriteLine( obj.ValidateRegistration("xyz-123")); } Console.ReadLine(); Console.WriteLine(); } } }
Listing 13-26. Client Activated Object client implementation using Visual Basic 2005 Imports System Imports System.Collections.Generic Imports System.Text Imports System.Runtime.Remoting.Channels Imports System.Runtime.Remoting.Channels.Tcp Imports System.Runtime.Remoting.Activation Imports VBSampleObject Namespace InsuranceClient Class Program Shared Sub Main()
Dim channel As TcpClientChannel = New TcpClientChannel ChannelServices.RegisterChannel(channel, True) Dim attrs As Object() = { _ New UrlAttribute( _
510
The Complete Reference To Professional SOA with Visual Studio 2005
"tcp://localhost:9080/ValidateRegistration")} Dim obj As InsuranceOperation = _ CType(Activator.CreateInstance( _ GetType(InsuranceOperation), Nothing, attrs), _ InsuranceOperation) If obj.Equals(Nothing) Then System.Console.WriteLine("Error: unable to locate server") Else Console.WriteLine(obj.ValidateRegistration("xyz-123")) End If Console.ReadLine() End Sub End Class
End Namespace The above code listing 13-25, listing 13-26 shows the client implementation using client-activate implementation. Instead of using the new operator, we can create client-activated objects with the Activator class. Well-known objects are created with the GetObject() method. Client-activated objects require the method CreateInstance() this is because the remote object is instantiated on the request of the client. By using the CreateInstance() method we can also invoke non-default constructors. By using the Activator.CreateInstance() we can instantiated a client-activated remote object. We must define the URL to the remote server. The UrlAttribute can be used to provide the URL of the remote object that is passed to the CreateInstance() method. The second argument of CreateInstance allows passing arguments to the constructor we can pass any number of parameters or datatype because the parameter value is of object[] type. In the example in listing 13-25 and listing 13-26 we have defined null as the constructor do not require any parameters. The last parameter of the Activator.CreateInstance() is the attrs array. This is an object array that has only one element. This is an UrlAttribute where we specific the URL to the remote object to the constructor of this class.
Figure 13-4. Server window
The above figure shows an image of the response from the server. We can see that our server is started and when a request is received the InsuranceOperation’s constructor is executed. Whilst the constructor has also been executed on the server window shows that the reference call from the client had been marshaled to the server where it is executed.
511
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 13-5. Client window.
In the above diagram, the client window shows the response from invoking the validation function on the server.
Using Configuration File For client-activated objects the code required for client and server are the same namely: Listing 13-27. Loading client configuration using C# RemotingConfiguration.Configure ("RemoteClientConfig.xml", true); InsuranceOperation obj = new InsuranceOperation();
Listing 13-28. Loading client configuration using Visual Basic 2005 RemotingConfiguration.Configure _ ("RemoteClientConfig.xml", True) Dim obj As InsuranceOperation = New InsuranceOperation
The code required to load configuration for that of server-activate and client-activated are the same. Listing 13-29. Loading server configuration using C# RemotingConfiguration.Configure ("RemoteServerConfig.xml", false);
Listing 13-30. Loading server configuration using Visual Basic 2005 RemotingConfiguration.Configure _ ("RemoteServerConfig.xml", True)
Though the XML configuration which defines client activated code is slightly different. Listing 13-31. RemoteClientConfig.xml client configuration
Listing 13-32. RemoteServerConfig.xml client configuration
The server configuration file must set the tag instead of . With the tag, only the type attribute with the namespace and assembly name must be defined.
Using Lifetime Leases Client-activated objects use lifetime leases to determine the duration of their existence. When a client creates an object, it specifies a default duration for which the object should exist. If the remote object reaches the end of its default lifetime duration, the object contacts the client and asks whether it should continue to exist and for how long. If the client is not currently available, a default time limit is specified for which the server object waits while trying to contact the client before marking itself available for garbage collection. The client might even request an indefinite default lifetime, preventing the remote object from being recycled until the server application domain is torn down. The lifetime of a marshal-by-reference object is the duration for which the object resides in memory. All marshal-by-reference server-activated and client-activated objects have a lifetime of their own. These objects are released from memory after the lifetime expires and the object is marked for garbage collection. The garbage collector then removes the objects from memory. The .NET Remoting system deletes an object only when it is marked as ready for garbage collection. The lifetime lease manager of the server application domain is responsible for determining the objects that are ready for garbage collection. However, a sponsor object can request a new lease for a particular object by registering itself with the lease manager.
513
The Complete Reference To Professional SOA with Visual Studio 2005
A lifetime lease is created for the marshal-by-reference object when the object is remoted outside an application domain. Each application domain contains a lease manager that manages the leases in its domain. The role of the lease manager is to periodically review the leases for expiration. If a lease expires, the lease manager goes through its list of sponsors for that object and checks to see if any of the sponsors want to renew the object’s lease. If no sponsor wishes to renew the lease then the lease manager removes the lease. The object is then deleted, and garbage collection reclaims the object memory. As such the lifetime of an object can be extended to longer than specified by its lifetime lease. There are a few ways in which we can influence leasing times of objects. One way is to use configuration files, and another way is to do it programmatically for the server, the remote object, or in the client. Let us look at what can be configured first. Table 13-2. Default configuration
Attribute
Description
leaseTime
Define the period of the lease for the application. The default leaseTime is 5 minutes.
sponsorshipTimeout
Define the period of time the lease manager waits for the sponsor to respond when notified that a lease has expired. If the sponsor does not respond in the specified time. The garbage collector disposes of the remote object. The default period is 2 minutes.
renewOnCallTime
Define the amount of time that the lease time is extended when a function call is made on the object. The default period is 2 minutes.
leaseManagerPollTime
Define how often the lease manager should check the expiration of the lease. The default period is 10 seconds.
Configuration The below configuration contains information about the lifetime of all client-activated objects serviced by this application Listing 13-33. The below configuration can be set inside the configuration of the remoting application
The configuration listed in listing 13-33 will set the lease time to five minutes, sponsorshiptime out to 2 minutes, renew on call time to two minutes and lease manager poll time to ten seconds. Valid values for each are a decimal number and a time unit. Time units are defined as D for days, H for hours, M for minutes, S for seconds, and MS for milliseconds. Listing 13-34. The xml configuration below shows a remoting client application’s configuration file with lifetime leases.
514
The Complete Reference To Professional SOA with Visual Studio 2005
Code Setting the lifetime option in the configuration file is quite useful especially if we wanted to have the same lifetime management for all objects for the server. If we need to define remote objects with different lifetime requirements then we would need to set the lifetime for the object programmatically. We can configure the lifetime lease within our code. To do this we need to override the InitializeLifetimeService function of the MarshalByRefObject class. The following is the syntax used to override the InitializeLifetimeService function see listing 13-35 and 13-36. Listing 13-35. C# implementation of configuring lease by code using System; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Lifetime; public class InsuranceOperation : MarshalByRefObject { /// /// Constructor /// /// public InsuranceOperation() { Console.WriteLine("Constructor has been called"); } public string ValidateRegistration(string regno) { if (regno == "xyz-123")
515
The Complete Reference To Professional SOA with Visual Studio 2005
return "claim has been approved"; else return "No claim has been lodged"; }
public override object InitializeLifetimeService() { ILease lease = (ILease)base.InitializeLifetimeService(); if (lease.CurrentState == LeaseState.Initial) { lease.InitialLeaseTime = TimeSpan.FromMinutes(2); lease.SponsorshipTimeout = TimeSpan.FromMinutes(3); lease.RenewOnCallTime = TimeSpan.FromSeconds(3); } return lease; } }
Listing 13-36. Visual Basic 2005 implementation of configuring lease by code Imports System Imports System.Runtime.Remoting Imports System.Runtime.Remoting.Channels
Imports System.Runtime.Remoting.Lifetime Public Class InsuranceOperation Inherits MarshalByRefObject Public Sub New() Console.WriteLine("Constructor has been called") End Sub Public Function ValidateRegistration(ByVal regno As String) _ As String If regno = "xyz-123" Then Return "claim has been approved" Else Return "No claim has been lodged" End If End Function
Public Overloads Overrides Function _ InitializeLifetimeService() As Object Dim lease As ILease = _ CType(MyBase.InitializeLifetimeService, ILease) If lease.CurrentState = LeaseState.Initial Then lease.InitialLeaseTime = TimeSpan.FromMinutes(2) lease.SponsorshipTimeout = TimeSpan.FromMinutes(3) lease.RenewOnCallTime = TimeSpan.FromSeconds(3) End If Return lease End Function
516
The Complete Reference To Professional SOA with Visual Studio 2005
End Class
The LeaseTime option defines the remote object’s maximum time to lease. The object will be deactivated if the client does not need the remote object for this time period. Every time a method is invoked the leasing time is incremented by the value defined with within RenewOnCallTime. In listing 13-35 and listing 13-36, we have set the InitialLeaseTime to two minutes, SponsorshipTimeout to three minutes and RenewOnCallTime to three. In the remote object class we can override the InitializeLifetimeService() method. The method InitializeLifetimeService() from the base class MarshalByRefObject returns a reference to the ILease interface that can be used to change the default values. Changing the values is only possible as long as the lease has not been activated, so that is why we need to check for the current state to compare it with the enumeration value LeaseState.Initial.
Renewing Lifetime Leases After we have created a lifetime lease for an object, we can only extend LeaseTime property of the lease object. The CurrentLeaseTime property returns the amount of time remaining on the lease. One way to renew the lease is by having the client application call the ILease.Renew method. The other way is to have a sponsor renew the lease. The listing 13-37 and 13-38 shows how we can use ILease.Renew to extend our lease time. Listing 13-37. Shows implementation of ILease.Renew in C# using System; using System.Collections.Generic; using System.Text; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; using System.Runtime.Remoting; using System.Runtime.Remoting.Activation; using System.Runtime.Remoting.Lifetime; using System.Threading; namespace InsuranceClient { class Client { static void Main(string[] args) { TcpClientChannel channel = new TcpClientChannel(); ChannelServices.RegisterChannel(channel, true); object[] attrs = { new UrlAttribute( "tcp://localhost:9080/ValidateRegistration") }; InsuranceOperation obj = (InsuranceOperation)Activator.CreateInstance( typeof(InsuranceOperation), null, attrs); // Use the object
Thread.Sleep(5000); ILease lease = (ILease)RemotingServices.GetLifetimeService(obj);
517
The Complete Reference To Professional SOA with Visual Studio 2005
Console.WriteLine("Current Lease Time: " + lease.CurrentLeaseTime); TimeSpan expireTime = lease.Renew(TimeSpan.FromMinutes(5)); Console.WriteLine("After Lease Renew: " + expireTime); if (obj.Equals(null)) { System.Console.WriteLine ("Error: unable to locate server"); } else { Console.WriteLine( obj.ValidateRegistration("xyz-123")); } Console.ReadLine(); Console.WriteLine(); } } }
Listing 13-38. Shows implementation of ILease.Renew in Visual Basic 2005 Imports System Imports System.Collections.Generic Imports System.Text Imports System.Runtime.Remoting Imports System.Runtime.Remoting.Channels Imports System.Runtime.Remoting.Channels.Tcp Imports System.Runtime.Remoting.Activation Imports VBSampleObject Imports System.Runtime.Remoting.Lifetime Imports System.Threading Namespace InsuranceClient Class Program Shared Sub Main() Dim channel As TcpClientChannel = New TcpClientChannel ChannelServices.RegisterChannel(channel, True) Dim attrs As Object() = { _ New UrlAttribute("tcp://localhost:9080/ValidateRegistration")} Dim obj As InsuranceOperation = _ CType(Activator.CreateInstance(GetType(InsuranceOperation), _ Nothing, attrs), InsuranceOperation)
Thread.Sleep(5000) Dim lease As ILease = _ CType(RemotingServices.GetLifetimeService(obj), ILease) Console.WriteLine("Current Lease Time: " + _ lease.CurrentLeaseTime.ToString())
518
The Complete Reference To Professional SOA with Visual Studio 2005
Dim expireTime As TimeSpan = _ lease.Renew(TimeSpan.FromMinutes(5)) Console.WriteLine("After Lease Renew: " + _ expireTime.ToString()) If obj.Equals(Nothing) Then System.Console.WriteLine("Error: unable to locate server") Else Console.WriteLine(obj.ValidateRegistration("xyz-123")) End If Console.ReadLine() End Sub End Class End Namespace
In the above code we’re using the ILease interface of the remote object by calling the method GetLifetimeService(). Calling the property CurrentLeaseTime we can access the actual value of the lease to display it in the console. We then renew the lease time by another 5 minutes. The result is shown in figure 13-6.
Figure 13-6. Shows the result from the renewal in leaes time.
In figure 13-6 we can see that even though five seconds has elapsed and the lease time is set at four minutes and fifty-five seconds. By renewing our lease time to five minutes it has reset the lease time.
Differences between Server Activated Objects and Client Activated Objects The difference between server activated and client activated objects are shown in the table below. Table 13-3. The table above highlights the difference between server-activated and client-activated objects.
Client sideactivation code (Code required on the client side)
Single Call/Singleton Objects
Client-Activated Objects
a) Activator.GetObject()
a) Activator.CreateInstance()
b) new() with config file
b) new() with CFG file
Client's config file references the URL:
Client's CFG file references the URL. For example http://localhost:80/ValidateRegistration
ValidateRegistration = http://localhost:80/ ValidateRegistration/ ValidateRegistration.soap
519
The Complete Reference To Professional SOA with Visual Studio 2005
Activation of the Message is only sent when the first method call is server object made. No activation messages is sent upon requesting the reference. Constructor is not executed.
Activation messages is sent to the server when a proxy is created after the client creates the object. Constructors with parameters are supported.
Lifetime of the server object
The lifetime for single call and singleton is determined by the configuration on the server. Singleton objects are also subjected to lifetime management.
Lifetime is the earlier of these two events:
a) Use configuration file to specify the type (SingleCall or Singleton).
configuration file can be used to export the client-activated object.
Server side registration
a) Lease expires b) When the client loses its reference on the server object
b) Use RegisterWellKnownServiceType() api to register the type. Advantages of the models
a) Clients can be compiled against server component’s base class or interface definition.
a) Classic COM "coclass" like invocation of the server object.
b) Useful to perform finite operations on the server side.
b) Gives clients more flexibility to govern the server object's lifetime.
c) Client can pass constructor parameters to c) Applications that uses Single call objects are easily deployed in a Load Balanced environment, the created object. as they don't hold state. d) Server Objects can hold state for its specific client between method calls. d) Singleton Objects can maintain state information across client objects.
Transport Channels Channels are stateless objects that transport messages between applications across remoting boundaries, whether between application domains, processes, or computers. A channel can listen on an endpoint for inbound messages, send outbound messages to another endpoint, or both. This allows us to plug in a wide range of protocols, even if the common language runtime is not at the other end of the channel. The .NET Remoting infrastructure defines three kinds of channels: TCP, HTTP and IPC. IPC is the named pipe protocol which can be used to transmit messages. In remoting it also is possible to create our own custom channels and plug them into the .NET Remoting infrastructure. The .NET Framework provides the System.Runtime.Remoting.Channels name-space, which includes the interfaces and classes that we use to work with channels. All channels implement the IChannel interface. The IChannel interface provides properties such as ChannelName and ChannelPriority, which uniquely identify a channel and define the channel priority, respectively.
TCP Channel The TCP protocol is support by the .NET remoting infrastructure. TCP protocol is utilized for transporting serialized stream across .NET Remoting boundaries. The TcpChannel type is defined in the System.Runtime.Remoting.Channels.Tcp namespace. Which implements the IChannel, IChannelReceiver, and IChannelSender interfaces. This means that the TcpChannel supports both sending and receiving data across the
520
The Complete Reference To Professional SOA with Visual Studio 2005
.NET Remoting boundaries. The TcpChannel type uses binary wire format to serialize object by default. We had demonstrated implementing Remoting by using TCP in the previous example.
HTTP Channel The .NET Remoting infrastructure also provides a transport that utilizes the HTTP protocol for transporting the serialized message stream across the Internet. By utilizing HTTP it is particularly useful across network boundaries where there are firewalls. As HTTP is a typical web protocol most networks support HTTP. The HttpChannel type defined in the System .Runtime.Remoting.Channels.Http namespace implements the HTTP transport functionality. Like the TcpChannel type, HttpChannel can send and receive data across .NET Remoting boundaries. The HttpChannel type serializes message objects by using a SOAP wire format by default. The below shows an application implementing HTTP channel configuration. Listing 13-39. Implementation of Server using C# using System; using System.Collections.Generic; using System.Text; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http; namespace InsuranceServer { public class VehicleDetailsServer : MarshalByRefObject { public static void Main(string[] args) { // Create an instance of a channel
HttpChannel channel = new HttpChannel(8081); ChannelServices.RegisterChannel(channel, false); // Register as an available service with the name // ValidateRegistration RemotingConfiguration.RegisterWellKnownServiceType( typeof(InsuranceOperation), "ValidateRegistration", WellKnownObjectMode.Singleton); System.Console.WriteLine ("Press the enter key to exit..."); System.Console.ReadLine(); } } }
Listing 13-40. Implementation of Server using Visual Basic 2005 Imports System Imports System.Collections.Generic Imports System.Text Imports System.Runtime.Remoting
521
The Complete Reference To Professional SOA with Visual Studio 2005
Imports System.Runtime.Remoting.Channels
Imports System.Runtime.Remoting.Channels.Http Imports System.Runtime.Remoting.Activation Imports VBSampleObject Namespace InsuranceServer Public Class VehicleDetailsServer Inherits MarshalByRefObject Public Shared Sub Main(ByVal args As String())
Dim channel As HttpChannel = New HttpChannel(8081) ChannelServices.RegisterChannel(channel, False) RemotingConfiguration.RegisterWellKnownServiceType _ (GetType(InsuranceOperation), "ValidateRegistration", _ WellKnownObjectMode.Singleton) System.Console.WriteLine("Press the enter key to exit...") System.Console.ReadLine() End Sub End Class End Namespace
In the listing above we have demonstrated creating a remoting server using HTTP protocol by creating an instance of the HttpChannel type that listens for incoming connections on port 8081. We can change the port to any available number on the systems.
Note: Keep in mind that Internet Information Services (IIS) runs on port 80. If port 80 is already occupied then we will need to specify another port. This may involve opening the port in the firewall.
Listing 13-41. Implementation of the client remoting application using C# using System; using System.Collections.Generic; using System.Text; using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http; namespace InsuranceClient { class Client { public static void Main(string[] args) { // Create a channel for communicating with the remote object
HttpChannel chan = new HttpChannel(); ChannelServices.RegisterChannel(chan, false); // Create an instance of the remote object
InsuranceOperation obj = (InsuranceOperation)Activator.GetObject( typeof(InsuranceOperation),
522
The Complete Reference To Professional SOA with Visual Studio 2005
"http://localhost:8081/ValidateRegistration"); // Use the object if (obj.Equals(null)) { System.Console.WriteLine ("Error: unable to locate server"); } else { Console.WriteLine(obj.ValidateRegistration("xyz-123")); } Console.ReadLine(); } } }
Listing 13-42. Implementation of the client remoting application using Visual Basic 2005 Imports System Imports System.Collections.Generic Imports System.Text Imports System.Runtime.Remoting.Channels
Imports System.Runtime.Remoting.Channels.Http Imports System.Runtime.Remoting Imports System.Runtime.Remoting.Activation Imports VBSampleObject Namespace InsuranceClient Class Client Shared Sub Main(ByVal args As String())
Dim chan As HttpChannel = New HttpChannel ChannelServices.RegisterChannel(chan, False) Dim obj As InsuranceOperation = _ CType(Activator.GetObject(GetType(InsuranceOperation), _ "http://localhost:8081/ValidateRegistration"), _ InsuranceOperation) If obj.Equals(Nothing) Then System.Console.WriteLine("Error: unable to locate server") Else Console.WriteLine(obj.ValidateRegistration("xyz-123")) End If Console.ReadLine() Console.WriteLine() End Sub End Class End Namespace
523
The Complete Reference To Professional SOA with Visual Studio 2005
The above code shows the implementation of the remoting client implementing HTTP channel. Switching between TCP, HTTP and IPC is fairly simple in most cases its just a simple matter of substituting the TCP for HTTP or for IPC. Using HTTP Channel we can also view the wsdl document generated by using a browser. We can do this by simply browsing to http://localhost/ValidateRegisration?wsdl to view the WSDL document.
Figure 13-7. The figure above shows the WSDL document for the remoting object.
IPC Channel With the release of .NET Framework 2.0 the .NET Remoting infrastructure now provide Inter-Process Communication (IPC). IPC is a form of communication channel for .NET Remoting and can be used with the IPC system of the Windows operating system. Since IPC does not use network communication. The IPC channel is thus much faster than the HTTP and TCP channel. But it can only be used for communication between application domains on the same physical computer. Like the HTTP and TCP channels the IpcChannel Type is defined in the System.Runtime.Remoting.Channels.Ipc namespace which implements the IPC transport functionality. The IpcChannel can send and receive data across the .NET remoting boundaries but only on the same physical machine. In the example below the usage of an application implementing IPC channel configuration is demonstrated (see listing 13-43 and listing 13-44). Listing 13-43. The below code shows the IPC Server implementation using C# using System; using System.Collections.Generic; using System.Text; using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Ipc; namespace InsuranceServer { public class VehicleDetailsServer : MarshalByRefObject
524
The Complete Reference To Professional SOA with Visual Studio 2005
{ public static void Main(string[] args) { // Create an instance of a channel
IpcChannel channel = new IpcChannel("ValidateRegistration"); // register the channel with security disabled
ChannelServices.RegisterChannel(channel, false); // Register as an available service with the name // ValidateRegistration RemotingConfiguration.RegisterWellKnownServiceType( typeof(InsuranceOperation), "ValidateRegistration", WellKnownObjectMode.Singleton); System.Console.WriteLine ("Press the enter key to exit..."); System.Console.ReadLine(); } } }
Listing 13-44. The below code shows the IPC Server implementation using Visual Basic 2005 Imports System Imports System.Collections.Generic Imports System.Text Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Channels Imports System.Runtime.Remoting.Channels.Ipc Imports System.Runtime.Remoting.Activation Imports VBSampleObject Namespace InsuranceServer Public Class VehicleDetailsServer Inherits MarshalByRefObject Public Shared Sub Main(ByVal args As String())
Dim channel As IpcChannel = _ New IpcChannel("ValidateRegistration") ‘register the channel with security disabled
ChannelServices.RegisterChannel(channel, False) RemotingConfiguration.RegisterWellKnownServiceType _ (GetType(InsuranceOperation), "ValidateRegistration", _ WellKnownObjectMode.Singleton) System.Console.WriteLine("Press the enter key to exit...") System.Console.ReadLine() End Sub End Class End Namespace
525
The Complete Reference To Professional SOA with Visual Studio 2005
In the listing above in listing 13-43 and listing 13-44 we have demonstrated creating a remoting server using the IPC protocol by creating an instance of the IpcChannel type that listens for incoming connections on the named pipe that we have created called “ValidateRegistration”. The IpcChannel is then registered using the ChannelServices.RegisterChannel() function. The first parameter for the RegisterChannel is the IpcChannel object that we had created. The second parameter for the RegisterChannel method is a Boolean value which defines whether we want to enable security for the channel in this case we have specified false to disable. Listing 13-45. The below code shows the IPC Client implementation using C# using System; using System.Collections.Generic; using System.Text; using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc; namespace InsuranceClient { class Client { public static void Main(string[] args) { // Create a channel for communicating with the remote object
IpcChannel chan = new IpcChannel(); ChannelServices.RegisterChannel(chan, false); // Create an instance of the remote object
InsuranceOperation obj = (InsuranceOperation) Activator.GetObject(typeof(InsuranceOperation), "ipc://ValidateRegistration/ValidateRegistration"); // Use the object if (obj.Equals(null)) { System.Console.WriteLine ("Error: unable to locate server"); } else { Console.WriteLine(obj.ValidateRegistration("xyz-123")); } Console.ReadLine(); } } }
Listing 13-46. The below code shows the IPC Client implementation using Visual Basic 2005 Imports System Imports System.Collections.Generic Imports System.Text
Imports System.Runtime.Remoting.Channels Imports System.Runtime.Remoting.Channels.Ipc
526
The Complete Reference To Professional SOA with Visual Studio 2005
Imports System.Runtime.Remoting Imports System.Runtime.Remoting.Activation Imports VBSampleObject Namespace InsuranceClient Class Client Shared Sub Main(ByVal args As String())
Dim chan As IpcChannel = New IpcChannel ChannelServices.RegisterChannel(chan, False) Dim obj As InsuranceOperation = _ CType(Activator.GetObject(GetType(InsuranceOperation), _ "ipc://ValidateRegistration/ValidateRegistration"), _ InsuranceOperation) If obj.Equals(Nothing) Then System.Console.WriteLine _ ("Error: unable to locate server") Else Console.WriteLine(obj.ValidateRegistration("xyz-123")) End If Console.ReadLine() Console.WriteLine() End Sub End Class End Namespace
The above code shows the implementation of the remoting client implementing IPC channel. Notice that we don’t need to specify a port number for IPC we only need to specify the named pipe as well as the remotable instance of the remoting server. This is because IPC can only used on the same computer. It is ideal for application to application communication.
Channel Sinks The .NET Remoting architecture is very flexible because it possesses a clear separation of object responsibilities. The channel architecture employs a series of channel sink objects linked together into a sink chain. Each channel sink within the chain has a clearly defined role in the processing of the message. The channel sink performs certain functions on the message before the message is forwarded onto the next channel sink in the chain. Within the channel sink chain we can access the message that is routed to or coming from a Remoting object. This allows us to perform tasks such as logging, security, custom encryption, applying filters, and imposing other security restrictions.
527
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 13-8. shows channel sink chains on the client and on the server.
In the above figure the client object makes calls on a transparent proxy, which in turn converts the method call into a message object. The message object is routed through the context sink chains until it reaches the formatter sink which is the first sink in the chain. The formatter sink is responsible for serializing the message object to a byte stream by using a particular wire format. The formatter sink then passes the stream to the next sink in the chain for further processing. The last sink in the channel sink chain is responsible for transporting the stream over the wire by using a specific transport protocol. To implement channel sink providers to create channel sink chains. We need to implement properties and methods that implement the IClientChannelSinkProvider, IClientFormatterSinkProvider, or IServerChannelSinkProvider interfaces. So that when we activate a remote object, the remoting system retrieves the channel sink provider from the current channel and calls the CreateSink method on the channel sink provider to create the first channel in the chain. When the CreateSink method is invoked, it creates its own channel sink. The CreateSink call is forwarded to the next sink provider in the chain (if one exists), it ensures that the next sink and the current one are linked together. The first channel sink on a client must be a formatter sink that serializes the message into a stream. The last sink on the channel sink chain should be a transport sink that sends the stream over the network wire.
Remotable Bank Debit Log Message sinks adds flexibility to the .NET Remoting architecture. These sinks can be chained together to form message sink chains, which processes .NET Remoting messages and move them through contexts and application domains. In this section we will be implementing a simple remotable Bank debit application using message sinks to monitor the various stages of the incoming request as well as response on both the client and the server.
528
The Complete Reference To Professional SOA with Visual Studio 2005
The Server We will start with the Server implementation of our remotable Bank debit application which only needs to perform a simple BankDebit() operation. Listing 13-47. Shows the server implementation in C# using System; using System.Threading; using System.Security; using System.Security.Principal; using System.Runtime.Remoting; class Calc : MarshalByRefObject, IBank { private static double bankbalance = 500.145; public double BankDebit( double amt ) { Console.WriteLine("Calling BankDebit method"); Console.WriteLine("Current balance: $" + bankbalance); Console.WriteLine("Debit amount: $" + amt); bankbalance -= amt; Console.WriteLine("Balance after debit: $" + bankbalance); return (bankbalance); } } class Server { static void Main(string[] args) { RemotingConfiguration.Configure( AppDomain.CurrentDomain.BaseDirectory + "server.config", false); Console.WriteLine("Press enter to exit the server"); Console.ReadLine(); }
}
Listing 13-48. Shows the server implementation in Visual Basic 2005 Imports System Imports System.Threading Imports System.Security Imports System.Security.Principal Imports System.Runtime.Remoting Imports icalc Imports System.Collections Imports System.IO Imports System.Runtime.Remoting.Messaging Imports System.Runtime.Remoting.Channels Imports System.Runtime.Serialization.Formatters
529
The Complete Reference To Professional SOA with Visual Studio 2005
Class Calc Inherits MarshalByRefObject Implements icalc.IBank Private Shared bankbalance As Double = 500.145 Public Function BankDebit(ByVal amt As Double) As Double Implements IBank.BankDebit Console.WriteLine("Calling BankDebit method") Console.WriteLine("Current balance: $" + bankbalance.ToString()) Console.WriteLine("Debit amount: $" + amt.ToString()) bankbalance -= amt Console.WriteLine("Balance after debit: $" + bankbalance.ToString()) Return (bankbalance) End Function End Class Class Server Shared Sub Main(ByVal args As String()) RemotingConfiguration.Configure _ (AppDomain.CurrentDomain.BaseDirectory + _ "server.config", False) Console.WriteLine("Press enter to exit the server") Console.ReadLine() End Sub
End Class In the server implementation we have a Clac class which will be exposed with the BankDebit() function. This function will perform the debit by the specified amount though we will be closely monitoring the request as well as the response of the call to the function using remoting sinks. The functionality of BankDebit() is exposed through our configuration file Server.config. Listing 13-49. Server.config file
530
The Complete Reference To Professional SOA with Visual Studio 2005
In the configuration file we have registered the server as a Singleton. Notice that under the channel element, we added the element serverProviders. The serverProviders element contains three elements. The first element under serverProviders is formatter. The second element is where we tell the remoting server to add support for the wsdl document. The third element is the provider element. This is where our sink is added by using the type attribute. The type attributes defines the class required and the assembly where the class can be found. We will now look at the implementation of the sink on the server.
Listing 13-50. Shows the implementation of the ServerSinkProvider in C# public class ServerSinkProvider : IServerChannelSinkProvider { private IServerChannelSinkProvider next = null; public ServerSinkProvider() { Console.WriteLine("Entering constructor ServerSinkProvider"); } public ServerSinkProvider(IDictionary properties, ICollection providerData) { Console.WriteLine("Entering constructor" + "ServerSinkProvider with parameters"); } public void GetChannelData(IChannelDataStore channelData) { Console.WriteLine("Entering GetChannelData"); } public IServerChannelSink CreateSink(IChannelReceiver channel) { Console.WriteLine("Entering CreateSink"); IServerChannelSink nextSink = null; if (next != null) { nextSink = next.CreateSink(channel); } return new ServerSink(nextSink); } public IServerChannelSinkProvider Next { get
531
The Complete Reference To Professional SOA with Visual Studio 2005
{ Console.WriteLine("Getting Next Server Channel Sink"); return next; } set { Console.WriteLine("Setting Next Server Channel Sink"); next = value; } } }
Listing 13-51. Shows the implementation of the ServerSinkProvider in Visual Basic 2005 Public Class ServerSinkProvider Implements IServerChannelSinkProvider Private [next] As IServerChannelSinkProvider = Nothing Public Sub New() Console.WriteLine("Entering constructor ServerSinkProvider") End Sub Public Sub New(ByVal properties As IDictionary, _ ByVal providerData As ICollection) Console.WriteLine("Entering constructor" + _ " ServerSinkProvider with parameters") End Sub Public Sub GetChannelData(ByVal channelData As IChannelDataStore) _ Implements IServerChannelSinkProvider.GetChannelData Console.WriteLine("Entering GetChannelData") End Sub Public Function CreateSink(ByVal channel As IChannelReceiver) _ As IServerChannelSink Implements IServerChannelSinkProvider.CreateSink Console.WriteLine("Entering CreateSink") Dim nextSink As IServerChannelSink = Nothing If Not ([next] Is Nothing) Then nextSink = [next].CreateSink(channel) End If Return New ServerSink(nextSink) End Function Public Property Nextx() As IServerChannelSinkProvider _ Implements IServerChannelSinkProvider.Next Get Console.WriteLine("Getting Next Server Channel Sink") Return [next] End Get Set(ByVal value As IServerChannelSinkProvider) Console.WriteLine("Setting Next Server Channel Sink")
532
The Complete Reference To Professional SOA with Visual Studio 2005
[next] = value End Set End Property End Class
The channel sinks are connected to a server channel through implementations of the IServerChannelSinkProvider interface. Channel sink providers are stored in a chain, this allows us to manipulate and customize chaining all channel sink providers together IServerChannelSinkProvider provides a property called Next for this.
When multiple channel sink providers are specified in a configuration file, the remoting infrastructure will chain them together in the order they were found in the configuration file. During a RemotingConfiguration.Configure call the channel sink providers are created at the same time as the channel. In order to create the server provider we need to implement the methods defined by the IServerChannelSinkProvider interface.
Figure 13-9. The IServerChannelSinkProvider interface
Table 13-4. In order to implement IServerChannelSinkProvider we need to implement the following methods and property.
Name
Description
CreateSink
Create a sink chain.
GetChannelData
Retrieve the channel data for current sink.
Next
Get or set the next sink provider in the channel sink provider chain.
There are three members of IServerChannelSinkProvider. The first is a method called CreateSink(). This is where we can create our own custom channel sinks. CreateSink() creates the new channel sink (ServerSink). But notice it also forwards the CreateSink call to the next sink provider in the chain (if there is one). Listing 13-52. Forwarding CreateSink call using C# if (next != null) { nextSink = next.CreateSink(channel); }
Listing 13-53. Forwarding CreateSink call using Visual Basic 2005 If Not ([next] Is Nothing) Then nextSink = [next].CreateSink(channel) End If
In listing 13-52 and listing 13-53 the CreateSink function is responsible for ensuring that the next sink that is created are linked together.
533
The Complete Reference To Professional SOA with Visual Studio 2005
The second member of IServerChannelSinkProvider is the GetChannelData method. GetChannelData extracts information from the provider's IChannelDataStore member. Because GetChannelData is a member of the IServerChannelSinkProvider interfaces, this member is present in all channel sink providers. The last member of the IServerChannelSinkProvider is the Next property. This property simply gets or sets the next sink in the channel sink provider chain. Usually, this would be called before the CreateSink method to set the next provider in the chain so that the CreateSink method knows which provider to forward the CreateSink method call to. Once the provider has been implemented we will need to implement the ServerSink. A server ChannelSink must implement IServerChannelSink or IClientChannelSink depending on which side of the remoting infrastructure it is designed to run on. Listing 13-54. Shows the ServerSink implementation in C# public class ServerSink : BaseChannelObjectWithProperties, IServerChannelSink, IChannelSinkBase { private IServerChannelSink _next; public ServerSink(IServerChannelSink next) { Console.WriteLine("Entering ServerSink"); _next = next; } public void AsyncProcessResponse (IServerResponseChannelSinkStack sinkStack, object state, IMessage msg, ITransportHeaders headers, Stream stream) { Console.WriteLine("Entering AsyncProcessResponse"); } public Stream GetResponseStream (IServerResponseChannelSinkStack sinkStack, object state, IMessage msg, ITransportHeaders headers) { Console.WriteLine("Entering GetResponseStream"); return null; } public ServerProcessing ProcessMessage( IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, out System.Runtime.Remoting.Messaging.IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream) { Console.WriteLine("Entering ProcessMessage"); ServerProcessing spres = _next.ProcessMessage (sinkStack, requestMsg, requestHeaders, requestStream, out responseMsg, out responseHeaders, out responseStream);
534
The Complete Reference To Professional SOA with Visual Studio 2005
return spres; } public IServerChannelSink NextChannelSink { get { Console.WriteLine("Getting NextChannelSink"); return _next; } } }
Listing 13-55. Shows the ServerSink implementation in Visual Basic 2005 Public Class ServerSink Inherits BaseChannelObjectWithProperties Implements IServerChannelSink Implements IChannelSinkBase Private _next As IServerChannelSink Public Sub New(ByVal [next] As IServerChannelSink) Console.WriteLine("Entering ServerSink Constructor") _next = [next] End Sub Public Overrides ReadOnly Property Properties() _ As System.Collections.IDictionary _ Implements IChannelSinkBase.Properties Get Dim hashProperties As Hashtable = New Hashtable() Return hashProperties End Get End Property Public Sub AsyncProcessResponse(ByVal sinkStack _ As IServerResponseChannelSinkStack, ByVal state As Object, _ ByVal msg As IMessage, ByVal headers As ITransportHeaders, _ ByVal stream As Stream) _ Implements IServerChannelSink.AsyncProcessResponse Console.WriteLine("Entering AsyncProcessResponse") End Sub Public Function GetResponseStream _ (ByVal sinkStack As IServerResponseChannelSinkStack, _ ByVal state As Object, ByVal msg As IMessage, _ ByVal headers As ITransportHeaders) As Stream _ Implements IServerChannelSink.GetResponseStream Console.WriteLine("Entering GetResponseStream") Return Nothing End Function
535
The Complete Reference To Professional SOA with Visual Studio 2005
Public Function ProcessMessage _ (ByVal sinkStack As IServerChannelSinkStack, _ ByVal requestMsg As IMessage, _ ByVal requestHeaders As ITransportHeaders, _ ByVal requestStream As Stream, _ ByRef responseMsg As System.Runtime.Remoting.Messaging.IMessage, _ ByRef responseHeaders As ITransportHeaders, _ ByRef responseStream As Stream) _ As ServerProcessing Implements IServerChannelSink.ProcessMessage Console.WriteLine("Entering ProcessMessage") Dim spres As ServerProcessing = _next.ProcessMessage _ (sinkStack, requestMsg, requestHeaders, requestStream, _ responseMsg, responseHeaders, responseStream) Return spres End Function Public ReadOnly Property NextChannelSink() As IServerChannelSink _ Implements IServerChannelSink.NextChannelSink Get Console.WriteLine("Getting NextChannelSink") Return _next End Get End Property End Class
In the above listing we have implemented the ServerSink which implements the IServerChannelSink and IChannelSinkBase interface and inherits from the BaseChannelObjectWithProperties. Table 13-5. IServerChannelSink methods and properties
Name
Description
AsyncProcessResponse
Requests Asynchronous processing of the response from a method call.
GetResponseStream
Retrieve the stream from which the response message is serialized.
ProcessMessage
Requests message processing from the current sink.
NextChannelSink
Retrieve the next server channel sink in the server sink channel.
To understand the key method ProcessMessage() in the IServerChannelSink. We need to look back into the process of how a message is transmitted using the proxy. The job of a proxy is to convert a method call invoked on it into a message object. This message object, which implements the IMessage interface, is passed from the client end to the server end by invoking ProcessMessage on message sink objects. Message sinks are chained together in the sense that every message sink is responsible for calling ProcessMessage on the next message sink after it has performed its work. Below shows the parameters that ProcessMessage() requires:
536
The Complete Reference To Professional SOA with Visual Studio 2005
sinkStack - A stack of channel sinks that called the current sink. requestMsg - The message that contains the request. requestHeaders - Headers retrieved from the incoming message from the client. requestStream – The request stream that needs to be processed and passed onto the deserialization sink. responseMsg - This parameter is passed uninitialized. When this method returns, it contains an IMessage which holds the response message. responseHeaders - This parameter is passed uninitialized. When this method returns, it contains an ITransportHeaders that holds the headers that are to be added to return message heading to the client. responseStream - This parameter is passed uninitialized. When this method returns, it contains a Stream that is heading back to the transport sink.
The Client The client channel sink implementation is not too dissimilar to the server implementations Listing 13-56. Shows the client implementation in C# using System; using System.Threading; using System.Security; using System.Security.Principal; using System.Runtime.Remoting; class Client { static void Main(string[] args) { RemotingConfiguration.Configure (AppDomain.CurrentDomain.BaseDirectory + "client.config", false); ICalc c = (ICalc) RemotingServices.Connect(typeof(ICalc), "http://localhost:8081/calcsrv/calc"); Console.WriteLine("2 + 3 = {0}", c.Add(2, 3)); Console.WriteLine("4 + 5 = {0}", c.Add(4, 5)); Console.WriteLine("9 + 2 = {0}", c.Add(9, 2)); Console.ReadLine(); } }
Listing 13-57. Shows the client implementation in Visual Basic 2005 Imports System Imports System.Threading Imports System.Security Imports System.Security.Principal Imports System.Runtime.Remoting
537
The Complete Reference To Professional SOA with Visual Studio 2005
Class Client Shared Sub Main(ByVal args As String()) RemotingConfiguration.Configure("client.config", False) Dim c As icalc.ICalc = _ CType(RemotingServices.Connect(GetType(icalc.ICalc), _ "http://localhost:8081/calcsrv/calc"), icalc.ICalc) Console.WriteLine("2 + 3 = {0}", c.Add(2, 3)) Console.WriteLine("4 + 5 = {0}", c.Add(4, 5)) Console.WriteLine("9 + 2 = {0}", c.Add(9, 2)) Console.ReadLine() End Sub
End Class
The above client loads the following configurations from the client.config file.
Notice that under the channel element, similar to the server implementation except we added the element clientProviders. The clientProviders element contains two elements. The first element is the provider element.
This is where our sink is added by using the type attribute. The type attributes defines the class required and the assembly where the class can be found. The second element under clientProviders is the SOAP formatter where we ask the request to be encoded and transported using SOAP. The client provider doesn't look much different than its server side counterpart. Listing 13-58. Client sink provider using C# public class ClientSinkProvider: IClientChannelSinkProvider { private IClientChannelSinkProvider next = null; public ClientSinkProvider () { Console.WriteLine("Entering client ClientSinkProvider");
538
The Complete Reference To Professional SOA with Visual Studio 2005
} public ClientSinkProvider(IDictionary properties, ICollection providerData) { Console.WriteLine ("Entering client ClientSinkProvider with parameter"); } public IClientChannelSink CreateSink(IChannelSender channel, string url, object remoteChannelData) { Console.WriteLine("Entering CreateSink"); return new ClientSink(next.CreateSink(channel,url, remoteChannelData)); } public IClientChannelSinkProvider Next { get { Console.WriteLine("Getting Next Sink"); return next; } set { Console.WriteLine("Setting Next Sink"); next = value; } } }
Listing 13-59. Client sink provider using Visual Basic 2005 Public Class ClientSinkProvider Implements IClientChannelSinkProvider Private [_next] As IClientChannelSinkProvider = Nothing
Public Sub New() Console.WriteLine("Entering client ClientSinkProvider") End Sub
Public Sub New(ByVal properties As IDictionary, _ ByVal providerData As ICollection) Console.WriteLine _ ("Entering client ClientSinkProvider with parameter") End Sub
Public Function CreateSink(ByVal channel As IChannelSender, _ ByVal url As String, ByVal remoteChannelData As Object) _ As IClientChannelSink Implements IClientChannelSinkProvider.CreateSink Console.WriteLine("Entering CreateSink")
539
The Complete Reference To Professional SOA with Visual Studio 2005
Return New ClientSink([_next].CreateSink(channel, url, _ remoteChannelData)) End Function
Public Property [Next]() As IClientChannelSinkProvider _ Implements IClientChannelSinkProvider.Next Get Console.WriteLine("Getting Next Sink") Return [_next] End Get Set(ByVal value As IClientChannelSinkProvider) Console.WriteLine("Setting Next Sink") [_next] = value End Set End Property End Class
Figure 13-10. The IClientChannelSinkProvider interface
Table 13-6. In order to implement IClientChannelSinkProvider we need to implement the following methods and property.
Name
Description
CreateSink
Creates a sink chain.
Next
Gets or sets the next sink provider in the channel sink provider chain.
There are two members of IClientChannelSinkProvider. The first is a method called CreateSink(). This is where we can create our own custom channel sinks. CreateSink() creates the new channel sink (ClientSink). CreateSink() is also responsible for making sure that the next sink and the one that it creates are linked together this is how the chain on the client side gets built. The second member of IServerChannelSinkProvider is the Next property. This property simply gets or sets the next sink in the channel sink provider chain. Usually, this would be called before CreateSink() to set the next provider in the chain so our CreateSink() method knows which provider to forward the CreateSink() call to. Once the provider has been implemented we will need to implement the ClientSink. A client ChannelSink must implement IMessageSink and IClientChannelSink. It also needs to inherit from BaseChannelObjectWithProperties. The listing below shows the ClientSink Implementations: Listing 13-60. Shows the ClientSink implementation in C# public class ClientSink : BaseChannelObjectWithProperties, IMessageSink, IClientChannelSink { private IClientChannelSink _nextChnlSink;
540
The Complete Reference To Professional SOA with Visual Studio 2005
private IMessageSink _nextMsgSink; public IMessageCtrl AsyncProcessMessage (IMessage msg, IMessageSink replySink) { Console.WriteLine("Entering AsyncProcessMessage"); return _nextMsgSink.AsyncProcessMessage(msg, replySink); } public IMessage SyncProcessMessage(IMessage msg) { Console.WriteLine("Entering SyncProcessMessage"); return _nextMsgSink.SyncProcessMessage(msg); } public ClientSink(object next) { Console.WriteLine("Entering ClientSink"); _nextMsgSink = next as IMessageSink; _nextChnlSink = next as IClientChannelSink; }
public IMessageSink NextSink { get { Console.WriteLine("Getting NextSink MessageSink"); return _nextMsgSink; } } public IClientChannelSink NextChannelSink { get { Console.WriteLine("Getting NextSink ChannelSink"); return _nextChnlSink; } } public void AsyncProcessRequest (IClientChannelSinkStack sinkStack, IMessage msg, ITransportHeaders headers, Stream stream) { throw new Exception("Wrong sequence in config file"); } public void AsyncProcessResponse (IClientResponseChannelSinkStack sinkStack, object state, ITransportHeaders headers, Stream stream) { throw new Exception("Wrong sequence in config file");
541
The Complete Reference To Professional SOA with Visual Studio 2005
} public Stream GetRequestStream(IMessage msg, ITransportHeaders headers) { throw new Exception("Wrong sequence in config file"); } public void ProcessMessage(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream, out ITransportHeaders responseHeaders, out Stream responseStream) { throw new Exception("Wrong sequence in config file"); } }
Listing 13-61. Shows the ClientSink implementation in Visual Basic 2005 Public Class ClientSink Inherits BaseChannelObjectWithProperties Implements IMessageSink, IClientChannelSink Private _nextChnlSink As IClientChannelSink Private _nextMsgSink As IMessageSink Public Overrides ReadOnly Property Properties() _ As System.Collections.IDictionary _ Implements IChannelSinkBase.Properties Get Dim hashProperties As Hashtable = New Hashtable() Return hashProperties End Get End Property Public Function AsyncProcessMessage(ByVal msg As IMessage, _ ByVal replySink As IMessageSink) As IMessageCtrl _ Implements IMessageSink.AsyncProcessMessage Console.WriteLine("Entering AsyncProcessMessage") Return _nextMsgSink.AsyncProcessMessage(msg, replySink) End Function
Public Function SyncProcessMessage(ByVal msg As IMessage) _ As IMessage Implements IMessageSink.SyncProcessMessage Console.WriteLine("Entering SyncProcessMessage") Return _nextMsgSink.SyncProcessMessage(msg) End Function
Public Sub New(ByVal [next] As Object) Console.WriteLine("Entering ClientSink Constructor") _nextMsgSink = CType([next], IMessageSink) _nextChnlSink = CType([next], IClientChannelSink)
542
The Complete Reference To Professional SOA with Visual Studio 2005
End Sub
Public ReadOnly Property NextSink() As IMessageSink _ Implements IMessageSink.NextSink Get Console.WriteLine("Getting NextSink MessageSink") Return _nextMsgSink End Get End Property
Public ReadOnly Property NextChannelSink() As IClientChannelSink _ Implements IClientChannelSink.NextChannelSink Get Console.WriteLine("Getting NextSink ChannelSink") Return _nextChnlSink End Get End Property Public Sub AsyncProcessRequest _ (ByVal sinkStack As IClientChannelSinkStack, ByVal msg As IMessage, _ ByVal headers As ITransportHeaders, ByVal stream As Stream) _ Implements IClientChannelSink.AsyncProcessRequest Throw New Exception("Wrong sequence in config file") End Sub
Public Sub AsyncProcessResponse _ (ByVal sinkStack As IClientResponseChannelSinkStack, _ ByVal state As Object, ByVal headers As ITransportHeaders, _ ByVal stream As Stream) _ Implements IClientChannelSink.AsyncProcessResponse Throw New Exception("Wrong sequence in config file") End Sub
Public Function GetRequestStream(ByVal msg As IMessage, _ ByVal headers As ITransportHeaders) As Stream _ Implements IClientChannelSink.GetRequestStream Throw New Exception("Wrong sequence in config file") End Function
Public Sub ProcessMessage(ByVal msg As IMessage, _ ByVal requestHeaders As ITransportHeaders, _ ByVal requestStream As Stream, _ ByRef responseHeaders As ITransportHeaders, _ ByRef responseStream As Stream) _ Implements IClientChannelSink.ProcessMessage Throw New Exception("Wrong sequence in config file") End Sub
543
The Complete Reference To Professional SOA with Visual Studio 2005
End Class
In the above listing we have implemented the ClientSink which implements the IClientChannelSink and IMessageSink interface and inherits from the BaseChannelObjectWithProperties. Table 13-7. IClientChannelSink methods and properties
Name
Description
AsyncProcessRequest Requests for asynchronous processing of a method call on the current sink. AsyncProcessResponseRequests for asynchronous processing of a response to a method call on the current
sink. GetRequestStream
Returns the request serialized stream.
ProcessMessage NextChannelSink
Request message processing for the current sink. Retrieve the next channel sink in the client sink chain.
The client implementation of IClientChannelSink is quite similar to that of IServerChannelSink. In the client implementation each channel sink implements a IClientChannelSink. The first channel sink on the client side must implement IMessageSink. It typically implements IClientFormatterSink (which inherits from both IMessageSink, IChannelSinkBase, and IClientChannelSink) and is called a formatter sink because it transforms the incoming message into a stream (an IMessage object). The channel sink chain processes any message that is sent to or from an application domain. At this point, all we have is the message, but we are able to do anything we want with that message, and subsequent processing will use the message that we return to the system after processing. The figures below shows the execution result from execution the remotable Calculator application. We can see the order of sink operation through the output of the result.
Figure 13-11. Shows the execution result on the Server side.
544
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 13-12. Shows the execution result from the Client sides
Summary In this chapter we have explored .NET remoting. A possible alternative to XML Web services. .NET remoting is a generic system for different applications to use to communication with one another through a number of protocols such as HTTP, TCP and IPC. In .NET remoting much like Web services the proxy within the remoting architecture abstracts a lot of the complexities involved in cross boundry communication. When we create an instance of the remote object type in the client application, .NET Remoting creates a proxy object and sends it to the client application. This proxy object contains references to all the methods and properties of the server object. When we call a method that is on that proxy object, the remoting system receives the call, routes it to the server process, invokes the server object, and returns the return value to the client proxy, which returns the result to the client application. There are two categories of objects in remoting: remotable and nonremotable. Nonremotable objects do not provide the remoting system with a method to either copy them or use them in another application domain. Therefore, we can access these objects only in their own application domain. Remotable objects can either be accessed outside their application domain or context using a proxy or copied and passed outside their application domain or context. There’re two types of activation Server Activated Objects (SAOs) and Client-Activated Objects (CAOs). Server-activated objects are similar to classic stateless Web Services. While client-activated objects can have states. A client-activated object is instantiated on the server when the client creates it, and not with every method call. Lastly in this chapter we have also explored implementing channel sinks with remoting. The remoting architecture supports a channel architecture which provides flexibility by employing a series of channel sink objects linked together into a sink chain. Each channel sink in the chain has a clearly defined role in the processing of the message. The channel sink performs certain functions on the message before forwarding the message to the next channel sink in the chain.
545
The Complete Reference To Professional SOA with Visual Studio 2005
Chapter 14 Web Service Security The first step in implementing security in any application is to authenticate users. Implementing a robust authentication mechanism is not easy. As a general consensus it is recommended that we use the authentication services that the platform provides. In this case, the platform we are looking at consists of the Windows operating system, IIS, and the .NET Framework and common language runtime. The key areas to focus are authentication and authorization. Authentication is the process of discovering and verifying the identity of a user by examining the user’s credentials and then validating those credentials against some authentication authority. Currently, applications use a variety of authentication mechanisms. With the .NET 2.0 we can now implement some of these mechanisms with the .NET Framework Membership for user and role-based security. Authorization is the process of determining whether a user is allowed to perform a requested action. Authorization occurs after authentication and uses information about a user’s identity and roles to determine the resources that a user can access. We can also use .NET 2.0’s Membership functionalities to develop role-based security for authorization.
Windows Authentication We can use Windows Integrated Security to authenticate our users. In a Web service this works in much the same way as it does with web pages. The difference is that a web service is always executed by another application, and not directly by the browser. For that reason, there’s no built-in way to prompt the user for a user name and password. Instead, the application that is consuming the web service needs to supply the authentication information. The application might read this information from a configuration file or database, or it might prompt the user for this information before contacting the web service. The main downside to Windows Integrated Security is that it does not work well across the Internet, but it is an exceptional intranet solution because it can use the user’s logon information directly, without necessarily prompting the user to enter a username and password. Also, the password is never sent across the wire in plaintext. To require authentication, we need to enable Integrated Windows authentication for our client application and disable anonymous access in the IIS management console. To allow or deny specific users access to our service, we can use the ASP.NET’s Web.Config configuration system or set Access Control List (ACL) on the configuration file itself, as shown in the following example: Listing 14-1. Configuration within Web.Config
546
The Complete Reference To Professional SOA with Visual Studio 2005
The web service can also examine role membership. The example below will examine to see if the user has been authenticated and also if the role of the user is Administrator. Listing 14-2. Authenticated in C# using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class Service : System.Web.Services.WebService { [WebMethod()] public string TestWinAuthentication() { string strUserDetails = "";
if (!User.Identity.IsAuthenticated) { strUserDetails = "Not an authenticated user."; } else {
strUserDetails = "Authenticated as: " + User.Identity.Name + "; "; if (!User.IsInRole("Administrator")) { strUserDetails += "User is NOT an Administrator"; } else { strUserDetails += "User IS an Administrator"; } } return strUserDetails; }
547
The Complete Reference To Professional SOA with Visual Studio 2005
}
Listing 14-3. Authenticated in Visual Basic 2005 Imports System.Web Imports System.Web.Services Imports System.Web.Services.Protocols _ _ _ Public Class Service Inherits System.Web.Services.WebService _ Public Function TestWinAuthentication() As String Dim strUserDetails As String = ""
If Not User.Identity.IsAuthenticated Then strUserDetails = "Not an authenticated user." Else
strUserDetails = "Authenticated as: " + _ User.Identity.Name() + "; " If Not User.IsInRole("Administrator") Then strUserDetails += "User is NOT an Administrator" Else strUserDetails += "User IS an Administrator" End If End If Return strUserDetails End Function End Class
The above Web service, which provides a single TestWinAuthentication() method. This method checks to see if the user has been authenticated. If the user is authenticated, and if the role of the user belongs to the Administrator group. If the user is authenticated, it returns the user name (which will be a string in the form DomainName\UserName or Computer-Name\UserName). Within the listing 14-2 and 14-3 the Web service class provides a User property of type System.Security.Principal.IPrincipal, which we can use to retrieve information about the client user. We can authorize access to our Web service using the Authorization section in the ASP.NET Web.Config file. The User.IsAuthenticated property allows our code to determine if the current user has been authenticated. While the User.IsInRole method allows our code to determine if the current user is a member of the specified role. This is where we checked if the user is currently authenticated under the Administrator group. This works well when we know that the client of the XML Web service will be running as a specific Windows user. However what if we need a client running as one user, to act on behalf of another. Consider an ASP.NET page that accesses a secure XML Web service that does not impersonate the client who accesses it. In such a case, we need to programmatically set the username and password before connecting to the Web service. To submit user credentials to this service, the client needs to modify the NetworkCredential property of the proxy class. We have two options:
548
The Complete Reference To Professional SOA with Visual Studio 2005
*
One way is to create a new NetworkCredential object and attach this to the NetworkCredential property of the proxy object. When we create the NetworkCredential object, we will need to specify the user name and password that we want to access the web service as. This approach works with all forms of Windows authentication.
*
The second way only works if the web service is using Integrated Windows authentication, we can automatically submit the credentials of the current user by using the static DefaultCredentials property of the CredentialCache class and applying that to the NetworkCredential property of the proxy object.
Both the CredentialCache and NetworkCredential classes are found in the System.Net namespace. The NetworkCredential class is a base class that supplies credentials in password-based authentication schemes such as basic, digest, NTLM, and Kerberos The CredentialCache class is used when applications need to access multiple resources. These credential information are stored in a CredentialCache instance. The GetCredentail method can be called to compare the Uniform Resource Identifier (URI) and authenticate type provided with those stored in cache and return the first set of credentials that match. The DefaultCredentials property contains system credentials of the current security context. These represent user name, password and the domain of the user currently logged in. For ASP.NET applications, the default credentials are the user credentials of the logged-in user or the user being impersonated. To enable custom windows authentication for the web service we need to first configure IIS to take our principle information that web submit under NetworkCredential. To do this use the below steps:
Figure 14-1. Enabling Basic Authentication
Tip: Depending on the version of IIS used the screen may differ slightly.
1.
We can open the IIS MMC console by going to the start menu -> then select run and type “inetmgr”.
2.
In the left pane, expand the tree to find our virtual directory.
549
The Complete Reference To Professional SOA with Visual Studio 2005
3.
In the right pane, right-click service.asmx, and choose Properties.
4.
Select the File Security tab. Under Anonymous Access and Authentication Control in Windows XP or Windows 2000, or Authentication and Access Control under Windows Server 2003, click Edit.
5.
Disable anonymous access.
6.
Disable integrated Windows authentication.
7.
Enable basic authentication. (see figure 14-1.) A dialog window advising you that Basic Authentication uses clear text when transported across the internet. Click Yes to continue.
8.
Click OK to save these settings and exit the MMC console.
The following example uses basic authentication and illustrates a simple WebService (we’re still using the web service in listing 14-2 and listing 14-3 to illustrate authentication): Listing 14-4. Implementing NetworkCredential in C# using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Net; namespace CSTestAuthenticationClient { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void buttonUnaunthenticate_Click(object sender, EventArgs e) { try { WSAuthenticate.Service wsAuthenticate = new CSTestAuthenticationClient.WSAuthenticate.Service(); this.labelUnauthenticateResult.Text = wsAuthenticate.TestWinAuthentication(); } catch (Exception ex) { this.labelUnauthenticateResult.Text = ex.Message; } } private void ButtonAuthenticate_Click(object sender, EventArgs e) { try
550
The Complete Reference To Professional SOA with Visual Studio 2005
{ WSAuthenticate.Service wsAuthenticate = new CSTestAuthenticationClient.WSAuthenticate.Service(); // Supply some user credentials for the web service.
NetworkCredential credentials = new NetworkCredential( this.TextBoxLogin.Text, this.TextBoxPassword.Text); wsAuthenticate.Credentials = credentials; this.LabelAuthenticResult.Text = wsAuthenticate.TestWinAuthentication(); } catch (Exception ex) { this.LabelAuthenticResult.Text = ex.Message; } } } }
Listing 14-5. Implementing NetworkCredential in Visual Basic 2005 Imports System.Net Public Class Form1 Private Sub buttonUnaunthenticate_Click _ (ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles buttonUnaunthenticate.Click Try Dim wsAuthenticate As WSAuthenticate.Service = _ New WSAuthenticate.Service Me.labelUnauthenticateResult.Text = _ wsAuthenticate.TestWinAuthentication Catch ex As Exception Me.labelUnauthenticateResult.Text = ex.Message End Try End Sub Private Sub ButtonAuthenticate_Click _ (ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles ButtonAuthenticate.Click Try Dim wsAuthenticate As WSAuthenticate.Service = _ New WSAuthenticate.Service
Dim credentials As NetworkCredential = _ New NetworkCredential(Me.TextBoxLogin.Text, Me.TextBoxPassword.Text) wsAuthenticate.Credentials = credentials Me.LabelAuthenticResult.Text = wsAuthenticate.TestWinAuthentication Catch ex As Exception Me.LabelAuthenticResult.Text = ex.Message End Try End Sub End Class
551
The Complete Reference To Professional SOA with Visual Studio 2005
The above code shows a windows application with two text boxes and two buttons, see figure 14-2. One button performs an unauthenticated call, while the other submits the user name and password that have been entered in the text boxes. In this example the unauthenticated call will fail since we have disabled anonymous users in the section before. This means we must authenticate the client application the authenticated call will always succeed as long as we submit the correct credentials that correspond to a valid user on our web server. See figure 14-2.
Figure 14-2. Using unauthenticated and authenticated calls to the Web service.
Since NetworkCredential is found in System.Net. We need to first import the namespace for System.Net. In order to specify the user that we would like to authenticate ourselves under we would first need to use NetworkCredential where we pass in the login and password details of the user. This information is then attached to the Credentials property generated by the Web service proxy. See listing 14-6 and listing 14-7. Listing 14-6. Implementing NetworkCredential in C# WSAuthenticate.Service wsAuthenticate = new CSTestAuthenticationClient.WSAuthenticate.Service(); // Supply some user credentials for the web service. NetworkCredential credentials = new NetworkCredential( this.TextBoxLogin.Text, this.TextBoxPassword.Text); wsAuthenticate.Credentials = credentials;
Listing 14-7. Implementing NetworkCredential in Visual Basic 2005 Dim wsAuthenticate As WSAuthenticate.Service = _ New WSAuthenticate.Service Dim credentials As NetworkCredential = _ New NetworkCredential(Me.TextBoxLogin.Text, Me.TextBoxPassword.Text) wsAuthenticate.Credentials = credentials
If we need to use the credentials of the currently logged-in account (if we’re using a windows application or the account that the web application is running under) to access our web service. We can do so by checking the Integrated Windows authentication checkbox for the web service in IIS. By using DefaultCredentials we can pass in the default windows Principle information that we’re using to execute the application with to the Web service. Listing 14-8. Using default credentials in Visaul C# WSAuthenticate.Service wsAuthenticate = new CSTestAuthenticationClient.WSAuthenticate.Service();
552
The Complete Reference To Professional SOA with Visual Studio 2005
wsAuthenticate.Credentials = CredentialCache.DefaultCredentials; LabelAuthenticResult.Text = wsAuthenticate.TestWinAuthentication();
Listing 14-9. Using default credentials in Visual Basic 2005 Dim wsAuthenticate As WSAuthenticate.Service = _ New CSTestAuthenticationClient.WSAuthenticate.Service wsAuthenticate.Credentials = CredentialCache.DefaultCredentials LabelAuthenticResult.Text = wsAuthenticate.TestWinAuthentication
Managing Users by Using Membership ASP.NET Membership gives us a built-in way to validate and store user credentials. ASP.NET Membership can help us manage user authentication within a Web site. It is primarily used for ASP.NET web form applications, but it is also very useful when we need to implement user and role management within Web service. The ASP.NET membership model supports the following models: *
The ASP.NET membership supports creating new users and passwords.
*
Membership can be used to support storing user information these include user names, passwords, and supporting data in Microsoft SQL Server, Active Directory or other alternative data stores.
*
Membership supports password management, this includes creating, changing, and resetting them. Depending on membership options we choose, the membership system can also provide an automated password-reset system that takes a user-supplied question and response.
*
Membership supports the ability to expose a unique identifier for authenticated users. We can then use this identifier within our own applications and integrate with the ASP.NET personalization and role-management (authorization) system.
*
Specifying a custom membership provider, which allows us to substitute our own code to manage membership and maintain membership data in a custom data store.
ASP.NET membership has a set of classes and interfaces that we can use to create and manage users. Through membership we can authenticate users based on the credentials that they supply. The table below lists the membership classes and interfaces and also the functions that they provide. Table 14-1. ASP.NET Membership Classes
Class/Interface
Functions
Membership
Creates a new user.
Provides general membership facilities.
Deletes a user. Updates a user with new information. Returns a list of users. Finds a user by name or e-mail. Validates (authenticates) a user. Gets the number of users online.
553
The Complete Reference To Professional SOA with Visual Studio 2005
Searches for users by username or e-mail address. MembershipUser
Gets the password and password question.
Provides information about a specific user.
Changes the password. Determines whether the user is online. Determines whether the user is validated. Returns the date for last activity, login, and password change. Unlocks a user.
MembershipProvider
Defines functionality for data providers that can be used by the membership system.
The Membership provider defines the methods and properties that a provider is required to implement.
MembershipProviderCollection
Returns a collection of all the available providers.
MembershipUserCollection
Stores references to MembershipUser objects.
MembershipCreateStatus
Provides a description for success or failure when creating a new membership user.
MembershipCreateUserException
Provides the exception thrown if a user cannot be created. The MembershipCreateStatus enumeration value provides the reason for the exception available through the StatusCode property.
MembershipPasswordFormat
Defines the possible storage format available for password used by the membership provider. These are Clear, Hashed, Encrypted.
We can perform use the ASP.NET Web Site Administration Tool, which includes a security wizard. Configuring Membership is straight forward simply go to the Website menu -> ASP.NET Configuration. See figure 14-3 (below).
554
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 14-3. Start Web Site Administration Tool
If we are using Membership on a machine with SQL Server 2005, we don’t need to configure Membership provider to set up a database. We can launch the security setup wizard in Web Site Administration Tool to configure security (see figure 14-4).
Figure 14-4. Web Site Administration Tool security setup wizard
By using the Security wizard we can start adding users to our Membership database immediately. This will automatically create the database and store it under the App_Data folder when we create the first user, or if we programmatically access the Membership database. As both options are implemented through the SqlMembershipProvider. If required we can also configure Membership to use our own database for user management.
Creating a Membership Database on SQL Server Sometimes we want to store our database on a database server. Thus letting .NET create our database upon first use is not what we want. We can use the aspnet_regsql.exe tool that ships with the .NET Framework this tool will create the tables for us automatically. In the case of a custom provider, we have to prepare and configure the data store used by the custom provider according to the custom provider’s documentation. We can use the
555
The Complete Reference To Professional SOA with Visual Studio 2005
aspnet_regsql.exe tool in two ways either through a wizard interface or through the command line. If we just launch the tool without any parameters, it will launch with the wizard interface that will guide us through the process of creating a database. See figure 14-5.
Figure 14-5. aspnet_regsql.exe wizard
The wizard provides us with the option of either creating the necessary database or removing the tables from an existing database. See figure 14-6.
Figure 14-6. aspnet_regsql.exe wizard
556
The Complete Reference To Professional SOA with Visual Studio 2005
If we select to configure a new Sql Server or application services. See figure 14-6 (above). The setup wizard will prompt us for connection properties to our database server. We will also be prompted to select the database that we wanted to use to store our user membership information into. By selecting the option for the database, the setup wizard will create a database called aspnetdb and the relevant tables within it on the server we have specified.
Figure 14-7. aspnet_regsql.exe wizard
We can use the aspnet_regsql.exe tool from the command line as well. The aspnet_regsql.exe tool is located in C:\\Microsoft.NET\Framework\v2.0.50727. This tool is particularly useful when we need to automate our application during setup. We can call this tool from the command line and automatically set up the ASP.NET database tables required by our application. For example, to set up the Membership API database tables, we can execute the following command: aspnet_regsql.exe -E -S localhost -A mr
In this particular case we are registering an ASP.NET database table by using authentication with the current windows credentials on the server called localhost and adding support for features for Membership and RoleManagement. Table 14-2. The following table shows the most commonly used command switches with the Aspnet_regsql.exe tool.
Option
Description
-?
Display all tool help options in the command window
-W
This is the Wizard mode. This is the default if no command line arguments are specified.
-C connection string
Define the connection string to the computer running SQL Server database will be installed or already installed.
557
The Complete Reference To Professional SOA with Visual Studio 2005
-S server
Define the name of the computer running SQL Server where the database will be installed.
-U login id
The SQL Server user login id.
-P password
The SQL Server password used to log in with.
-E
Specifies the authentication using the current Windows credentials that the user is loggedin as.
-d database
Define the name of the database to create or modify. The default name is “aspnetdb”.
-sqlexportonly filename
Create a SQL script file. We can customize this file to modify specific features.
-A all|m|r|p|c|w
Adds support for one or more features. The following identifiers are used for ASP.NET features. All - All features m – Membership r - Role management p – Profile w - Web events Feature identifiers can be specified together or separately, as shown in the following examples. aspnet_regsql.exe -E -S localhost -A mp aspnet_regsql.exe –E -S localhost -A m -A p
-R all|m|r|p|c|w
Removes support for one or more features. The following identifiers are used for ASP.NET features. Feature identifiers can be specified together or separately, as shown in the following examples. aspnet_regsql.exe -E -S localhost -R mp aspnet_regsql.exe -E -S localhost -R m -R p
-Q
Runs the tool in quiet mode and does not confirm before removing a feature.
The aspnet_regsql.exe tool excutes sql scripts that can be found in C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 directory. As shown in the figure 14-8 below. The Install script installs whilst the Uninstall removes tables and databases.
558
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 14-8. SQL scripts for Membership
Going through any of the above steps will result in the automated creation of tables within the database. See figure 14-9.
Figure 14-9. Database tables created
Configuring an Application to Use Membership By default Membership will use SQL Server 2005 Express Edition however we can configure membership to use other providers such as other SQL Server 2005 Editions. With the default configuration using SQL Server 2005 Express Edition installed, we don’t have to prepare the data store and configure a Membership provider, because the ASP.NET runtime uses the file-based SQL Server 2005 provider and automatically creates the database file for us within App_Data. However, if we want to use our own SQL Server database, or to custom our Membership Provider, we will need to configure the provider as well as the connection string to the Membership database appropriately. To do
559
The Complete Reference To Professional SOA with Visual Studio 2005
this we will need to either modify the web.config file directly or edit the configuration properties through the ASP.NET Configuration Settings if the application is deployed on IIS.
Using Web.Config We can specify the default membership provider using the defaultProvider attribute of the membership element. The machine configuration specifies a SqlMembershipProvider instance named "AspNetSqlMembershipProvider" this is identified as the default provider if we do not specify a default provider explicitly. The "AspNetSqlMembershipProvider" connects to the aspnetdb database in the local SQL Server. To specify a custom default provider we can use the below entries either into Web.config or Machine.config files. We can also specify the default provider instance and options for that provider by configuring a provider in the membership section. We can use the element to identify a provider to add to the collection of providers available for the application. We can then identify this provider instance as the default provider. See listing 14-10. Listing 14-10. Configuration either within Web.config or Machine.config file
In listing 14-10 we have specified a element under the membership defaultprovider element. The element in the example defines the name for the provider, the type of the provider, the name of the connection string to use, the password retrieval mode, password reset mode, password format, whether to eanble question and answreing, whether to enable unique email support, whether to capture exceptions the eventlog. Membership has the following properties. Table 14-3. Membership Properties.
560
The Complete Reference To Professional SOA with Visual Studio 2005
Name
Description
ApplicationName
Gets or sets the name of the application.
EnablePasswordReset
Retrieve the value that signals whether the current membership provider is configured to allow users to reset passwords.
EnablePasswordRetrieval
Retrieve the value that signals whether the current membership provider allow users to retrieve passwords.
HashAlgorithmType
The identifier of the algorithm used to create hash passwords.
MaxInvalidPasswordAttempts
Retrieve the max number of invalid passwords or password answer attempts before the user is locked out.
MinRequiredNonAlphanumericCh Retrieve the minimum number of special charaters that must be used aracters in a valid password MinRequiredPasswordLength
Retrieve the minimum length for a password.
PasswordAttemptWindow
Retrieve the max number of invalid password or password answer attempts in specified minutes before the user is locked out.
PasswordStrengthRegularExpressi Retrieve the regular expression used to evaluate a password. on Provider
Retrieves a reference to the default membership provider for the application.
Providers
Retrieve a collection of membership providers that are available within the ASP.NET application.
RequiresQuestionAndAnswer
Retrieve the value indicating whether the membership provider requires the user to answer a password question for password reset and retrieval.
UserIsOnlineTimeWindow
Retrieve the time window in number of minutes after the last activity for a user to be online.
Using ASP.NET Configuration Settings To configure provider details using IIS is straight forward simply open the properties of an Web application that we’re interested to configure for. Then select ASP.NET tab -> Edit Configuration. See figure 14-10.
561
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 14-10. Edit conifuration properties for ASP.NET
This will display the ASP.NET Configuration Settings diaglog window. The ASP.NET Configuration Settings diaglog window is quite useful. As it simplifies web.config configurations within a Web application dramatically. We can configure providers by selecting the Authentication tab -> then select Manage Providers under the Membership section.
Figure 14-11. ASP.NET Configuration Settings
562
The Complete Reference To Professional SOA with Visual Studio 2005
A provider settings diaglog is shown in figure 14-12. From here we can Add/Remove or modify existing provider details.
Figure 14-12. ASP.NET Provder Settings diaglog
Implementing Membership In the previous sections we have looked at setting up a database where user membership details can be stored. As well as looking at configuring a provider to access the database within the application. Now we will look at how we can use membership details to perform validations. Membership comes with a series of public methods that allow us to perform validation and user management. See table 14-4. Table 14-4. Membership public methods
Name
Description
CreateUser
Adds a new user to a data store.
DeleteUser
Removes a user from the database.
FindUsersByEmail
Retrieves a collection of membership users where the e-mail address contains the specified e-mail address to match.
FindUsersByName
Retrieves a collection of membership matching user name.
563
The Complete Reference To Professional SOA with Visual Studio 2005
GeneratePassword
Generates a random password of the specified length.
GetAllUsers
Retrieve all users in the database
GetNumberOfUsersOnl Retrieve the number of users currently accessing the application. ine GetUser
Retrieve the information for a membership user from the database.
GetUserNameByEmail
Retrieve the user name by the user name’s email address.
UpdateUser
Update the database with user information.
ValidateUser
Validate that the user name and password are valid
By using the following configuration in Web.config or Machine.config see listing 14-11. We can access Membership details within our application. See listing 14-12. Listing 14-11. Configuration settings for membership
Listing 14-12. Implementing Membership using C# public void VerifyUsername() { MembershipUser user = Membership.GetUser(UsernameTextBox.Text, false); if (user == null) {
564
The Complete Reference To Professional SOA with Visual Studio 2005
Msg.Text = "The user name " + Server.HtmlEncode(UsernameTextBox.Text) + " was not found. Please check the value and reenter your user name."; QuestionLabel.Text = ""; QuestionLabel.Enabled = false; AnswerTextBox.Enabled = false; ResetPasswordButton.Enabled = false; } else { QuestionLabel.Text = user.PasswordQuestion; QuestionLabel.Enabled = true; AnswerTextBox.Enabled = true; ResetPasswordButton.Enabled = true; } } public void ResetPassword_OnClick(object sender, EventArgs args) { string newPassword = ""; try { newPassword = Membership.Provider.ResetPassword(UsernameTextBox.Text, AnswerTextBox.Text); } catch (NotSupportedException e) { Msg.Text = "An error has occurred resetting your password: " + e.Message + "." + "Please check your values and try again."; } catch (MembershipPasswordException e) { Msg.Text = "Invalid password answer. Please reenter the answer and try again."; return; } catch (System.Configuration.Provider.ProviderException e) { Msg.Text = "The specified user name does not exist. Please check your value and try again."; } if (newPassword != "") { Msg.Text = "Password reset. Your new password is: " + Server.HtmlEncode(newPassword); } else { Msg.Text = "Password reset failed. Please reenter your values and try again."; } }
Listing 14-13. Implementing Membership using Visual Basic 2005
565
The Complete Reference To Professional SOA with Visual Studio 2005
Public Sub VerifyUsername() Dim user As MembershipUser = Membership.GetUser(UsernameTextBox.Text, False) If user Is Nothing Then Msg.Text = "The user name " & Server.HtmlEncode(UsernameTextBox.Text) & " was not found. Please check the value and reenter your user name." QuestionLabel.Text = "" QuestionLabel.Enabled = False AnswerTextBox.Enabled = False ResetPasswordButton.Enabled = False Else QuestionLabel.Text = user.PasswordQuestion QuestionLabel.Enabled = True AnswerTextBox.Enabled = True ResetPasswordButton.Enabled = True End If End Sub
Public Sub ResetPassword_OnClick(sender As Object, args As EventArgs) Handles ResetPassword.Click Dim newPassword As String = "" Try newPassword = Membership.Provider.ResetPassword(UsernameTextBox.Text, AnswerTextBox.Text) Catch e As NotSupportedException Msg.Text = "An error has occurred resetting your password: " & e.Message & "." & _ "Please check your values and try again." Catch e As MembershipPasswordException Msg.Text = "Invalid password answer. Please reenter the answer and try again." Return Catch e As System.Configuration.Provider.ProviderException Msg.Text = "The specified user name does not exist. Please check your value and try again." End Try If newPassword "" Then Msg.Text = "Password reset. Your new password is: " & Server.HtmlEncode(newPassword) Else Msg.Text = "Password reset failed. Please reenter your values and try again." End If End Sub
The listings 14-12 and 14-13 above demonstrates using membership to validate a user by username. By calling the GetUser function under the VerifyUsername method. We can also reset a password by using the Membership.Provider.ResetPassword function this will generate a new password for the user. Figure 13-13 below demonstrates the UI for the application.
566
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 13-13. User interface
Custom Authentication and Authorization with SOAP Headers In Chapter 1 and Chapter 5 we had briefly explained SOAP header and its structure within SOAP messaging protocol. Communicating with a Web service method using SOAP follows a standard format. Part of this format is the data that is encoded in an XML document. The XML document consists of a root Envelope element, which in turn consists of a required Body element and an optional Header element. The Body element comprises the data specific to the message. The optional Header element can contain additional information not directly related to the particular message. Each child element of the Header element is called a SOAP header. The SOAP specification itself does not strictly define the content of a SOAP header. As such the SOAP headers can be used to store data related to the message. An example of how a SOAP header can be used is to store security detail information for the requesting application.
Defining SOAP Headers Windows authentication works well for intranet scenarios, in which we are authenticating against a user in our own domain. On the Internet, however, we would really want to perform custom authentication and authorization, perhaps against a SQL database. In that case, we should pass custom credentials (such as the username and password) to our service and let it handle the authentication and authorization itself. A convenient way to deliver additional information with a request to a XML Web service is to include the information into a SOAP header. To do this we need to define a class that derives from SOAPHeader in our service and then declare a public field of our service as that type. This is then exposed in the public contract for our service and made available to the client when the proxy is created from the wsdl.exe tool. We will start by looking at an example of a Web service implementation security using SOAP header. Listing 14-14. Web service that implements SOAPHeader using C#
567
The Complete Reference To Professional SOA with Visual Studio 2005
using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class Service : System.Web.Services.WebService { public AuthHeader sHeader; [WebMethod(Description = "This method requires a custom soap" + "header set by the caller")] [SoapHeader("sHeader")] public string SecureMethod() { if (sHeader == null) return "ERROR: Please supply credentials"; else return "USER: " + sHeader.Username; } } // AuthHeader class extends from SoapHeader
public class AuthHeader : SoapHeader { public string Username; public string Password; }
Listing 14-15. Web service that implements SOAPHeader using Visual Basic 2005 Imports System.Web Imports System.Web.Services Imports System.Web.Services.Protocols _ _ _ Public Class Service Inherits System.Web.Services.WebService Public sHeader As AuthHeader _ _ Public Function SecureMethod() As String If sHeader Is Nothing Then Return "ERROR: Please supply credentials" Else
568
The Complete Reference To Professional SOA with Visual Studio 2005
Return "USER: " + sHeader.Username End If End Function End Class
Public Class AuthHeader Inherits SoapHeader Public Username As String Public Password As String End Class
To define a class representing a SOAP header. We need to first create a class deriving from the SoapHeader class with a name matching the root element for the SOAP header. Listing 14-16. Implementing SoapHeader using C# public class AuthHeader : SoapHeader
Listing 14-17. Implementing SoapHeader using Visual Basic 2005 Public Class AuthHeader Inherits SoapHeader
Then we need to add public fields or properties, matching the names and their respective data types for each element that we would want to be in the SOAP header. Listing 14-18. SOAP Header
JohnDoe password
For instance, given the need to create a SOAP header which contains Username and Password details in listing 14-18. We can define the class to represent the SOAP header. See listing 14-19. Listing 14-19. SOAP Header Class using Visaul C# public class AuthHeader : SoapHeader { public string Username; public string Password; }
Listing 14-20. SOAP Header Class using Visual Basic 2005 Public Class AuthHeader Inherits SoapHeader Public Username As String Public Password As String End Class
569
The Complete Reference To Professional SOA with Visual Studio 2005
To process SOAP headers within a Web service. Add a public member to the class implementing the Web service of the type representing the SOAP header. Listing 14-21. Setting a public property matching the header type using C# [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class Service : System.Web.Services.WebService {
public AuthHeader sHeader; Listing 14-22. Setting a public property matching the header type using Visual Basic 2005 _ _ _ Public Class Service Inherits System.Web.Services.WebService
Public sHeader As AuthHeader
To apply a SoapHeader attribute to each Web service method that intends to process the SOAP header. Set the property of the SoapHeader attribute to the name of the member variable created in the previous step. See listing 14-23. Listing 14-23. Demonstrates setting SoapHeader Attribute using C# [WebMethod(Description = "This method requires a custom soap" + "header set by the caller")] [SoapLogger]
[SoapHeader("sHeader")] public string SecureMethod()
Listing 14-24. Demonstrates setting SoapHeader Attribute using Visual Basic 2005 _
_ Public Function SecureMethod() As String
Defining a SOAP Header Client A XML Web services client can send and receive SOAP headers when communicating with a Web service. The proxy class generated by using the wsdl.exe utility will contain information about the SOAP headers. The proxy class generated will contain member variables representing the SOAP header details. The proxy class also has definitions for the corresponding classes representing the SOAP header. For example, proxy classes generated for the previous Web service will have a member variable of type AuthHeader and a definition for the AuthHeader class. Listing 14-25. Client application utilizing SOAP header using C# using System; using System.Collections.Generic;
570
The Complete Reference To Professional SOA with Visual Studio 2005
using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace CSSoapHeaderClient { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void ButtonAccess_Click(object sender, EventArgs e) { WSSoapHeaderService.Service wsHeaderService = new WSSoapHeaderService.Service(); WSSoapHeaderService.AuthHeader authHeader = new WSSoapHeaderService.AuthHeader(); authHeader.Username = "JohnDoe"; authHeader.Password = "password"; wsHeaderService.AuthHeaderValue = authHeader; this.LabelResult.Text = wsHeaderService.SecureMethod(); } } }
Listing 14-26. Client application utilizing SOAP header using Visual Basic 2005 Public Class Form1 Private Sub ButtonAccess_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles ButtonAccess.Click Dim wsHeaderService As WSSoapHeaderService.Service = _ New WSSoapHeaderService.Service Dim authHeader As WSSoapHeaderService.AuthHeader = _ New WSSoapHeaderService.AuthHeader authHeader.Username = "JohnDoe" authHeader.Password = "password" wsHeaderService.AuthHeaderValue = authHeader Me.LabelResult.Text = wsHeaderService.SecureMethod End Sub End Class
To process SOAP headers within a Web service client we need to first create a reference to the Web service. Then we need to create a new instance of the class representing the SOAP header. Listing 14-27. Creating a new instance of the SOAP header using C#
571
The Complete Reference To Professional SOA with Visual Studio 2005
WSSoapHeaderService.AuthHeader authHeader = new WSSoapHeaderService.AuthHeader();
Listing 14-28. Creating a new instance of the SOAP header using Visual Basic 2005 Dim authHeader As WSSoapHeaderService.AuthHeader = _ New WSSoapHeaderService.AuthHeader
Then we need to populate the values for the SOAP header. Listing 14-29. Defining values for the header using C# authHeader.Username = "JohnDoe"; authHeader.Password = "password";
Listing 14-30. Defining values for the header using Visual Basic 2005 authHeader.Username = "JohnDoe" authHeader.Password = "password"
Then we create a new instance of the proxy class. Listing 14-31. Creating an instance of the Web service through our Proxy using C# WSSoapHeaderService.Service wsHeaderService = new WSSoapHeaderService.Service();
Listing 14-32. Creating an instance of the Web service through our Proxy using Visual Basic 2005 Dim wsHeaderService As WSSoapHeaderService.Service = _ New WSSoapHeaderService.Service
Then we need to assign the SOAP header object to the member variable of the proxy class representing the SOAP header. So that when we do make a request the SOAP header along with its values will be sent to the Web service. Listing 14-33. Assign SOAP header to the Web service object using C# wsHeaderService.AuthHeaderValue = authHeader;
Listing 14-34. Assign SOAP header to the Web service object using Visual Basic 2005 wsHeaderService.AuthHeaderValue = authHeader
Lastly we can call the method on the proxy class that communicates with the Web service method. Listing 14-35. Calling the WebMethod on the service using C# this.LabelResult.Text = wsHeaderService.SecureMethod();
Listing 14-36. Calling the WebMethod on the service using Visual Basic 2005 Me.LabelResult.Text = wsHeaderService.SecureMethod
Finally when we can call the WebMethod on the Web service. The SOAP header portion of the SOAP request sent to the Web service will include the contents of the data stored in the SOAP header object. See the SOAP Request and Response Below. Listing 14-37. Demonstrates a Request from our SoapHeaderClient Application to the SoapHeaderService.
572
The Complete Reference To Professional SOA with Visual Studio 2005
JohnDoe password
Listing 14-38. Demonstrates a Response from our SoapHeaderClient Application to the SoapHeaderService.
USER: JohnDoe
Implementing Token Authentication with SOAP Headers Security using Windows authentication is great for web services when we only have a small group of users such as for an internal intranet setup who all have an existing account on the server. However, this method doesn’t scale well for public web services. A common solution is to write our own authentication system. In the security model that we will cover in this section, users will call a specific web method in the web service to login, at which point they will supply credentials (such as a user name and password combination). The login method will register the user session and create a new, unique token. By utilizing SOAP headers we can allow the users to reconnect to the web service by supplying the ticket to every other method. A token system has a number of benefits. As with forms authentication, it is flexible. It also optimizes performance and ensures scalability, because we can cache the ticket in memory. On subsequent requests, we can verify the validity of the token rather easily than authenticating the user against the database. Finally, it allows us to take advantage of SOAP headers, which make the ticket management and authorization process transparent to the client.
573
The Complete Reference To Professional SOA with Visual Studio 2005
Implementing Security Token Service With ASP.NET 2.0, it becomes possible to simplify custom authentication in a web service. Although it’s still up to us to transfer the user credentials and keep track of who has logged in by issuing and verifying tickets, we can use the .NET internal implementation of membership and role manager features to handle the authentication and authorization. In the following sections, we will see how to create a custom ticket-based authentication system that leverages membership and role management in this way.
Note: This implementation should not be used for high security Web service implementations. The reason is that the TokenID used in this instance is a GUID and in this instance it poses as a vulnerability. The message is sent as a cleartext through the Web a user can easily intercept the message and impersonate the GUID user. Please refer to Chapter 15 for Web Service Enhancement (WSE) where we examine how to implement security using certificate. and Chapter 16 for security with Windows Communication Foundation (WCF).
Below is an implementation of our Web service implementing the Token security system. Listing 14-39. SoapSecurityService, implementing token security in Web Service using C# using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; using System.Web.Security; using System.Security; using SecurityLibrary; [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class Service : WebService { public SecurityLibrary.TokenHeader Token; public Service () { //Uncomment the following line if using designed components //InitializeComponent(); } [WebMethod] [SoapHeader("Token", Direction = SoapHeaderDirection.Out)] public string Login(string username, string password) { if (Membership.ValidateUser(username, password)) { SecurityLibrary.Token token = new SecurityLibrary.Token(username); Application[token.TokenID] = token; Token = new SecurityLibrary.TokenHeader(token.TokenID); return "logged in"; } else { throw new SecurityException("Invalid credentials.");
574
The Complete Reference To Professional SOA with Visual Studio 2005
} return "cannot login"; } [WebMethod] [SoapHeader("Token", Direction = SoapHeaderDirection.In, Required=true)] public string PerformSecuredOperation1() { AuthorizeUser(Token.TokenID, "Administrator"); //if user does not belong to a valid role then an security //exception will be thrown before return is executed return "Secure operation has been performed 1"; } [WebMethod] [SoapHeader("Token", Direction = SoapHeaderDirection.In, Required = true)] public string PerformSecuredOperation2() { AuthorizeUser(Token.TokenID, "Administrator"); return "Secure operation has been performed 2"; } [WebMethod] [SoapHeader("Token", Direction = SoapHeaderDirection.In, Required = true)] public string PerformSecuredOperation3() { AuthorizeUser(Token.TokenID, "Administrator"); return "Secure operation has been performed 3"; } private SecurityLibrary.Token AuthorizeUser(string tokenID) { SecurityLibrary.Token token = (SecurityLibrary.Token)Application[tokenID]; if (token != null) { return token; } else { throw new SecurityException("Invalid token."); } } private SecurityLibrary.Token AuthorizeUser(string usertoken, string role) { Token token = AuthorizeUser(usertoken); if (Roles.IsUserInRole(token.UserName, role)) {
575
The Complete Reference To Professional SOA with Visual Studio 2005
return token; } else { throw new SecurityException("Insufficient permissions."); } } [WebMethod] public void CreateTestUser(string username, string password) { if (Membership.GetUser(username) != null) { //we can delete the user if it exists throw new SecurityException("User already exists in system!"); } Membership.CreateUser(username, password); string role = "Administrator"; if (!Roles.RoleExists(role)) { Roles.CreateRole(role); } Roles.AddUsersToRole(new string[] { username }, role); } }
Listing 14-40. SoapSecurityService, implementing token security in Web Service using Visual Basic 2005 Imports System Imports System.Web Imports System.Web.Services Imports System.Web.Services.Protocols Imports System.Web.Security Imports System.Security Imports VBSecurityLibrary _ _ Public Class Service Inherits System.Web.Services.WebService Public SHToken As SecurityLibrary.TokenHeader Public Sub New() End Sub _ _ Public Function Login(ByVal username As String, _ ByVal password As String) As String If Membership.ValidateUser(username, password) Then
576
The Complete Reference To Professional SOA with Visual Studio 2005
Dim token As SecurityLibrary.Token = _ New SecurityLibrary.Token(username) Application(token.TokenID) = token SHToken = _ New SecurityLibrary.TokenHeader(token.TokenID) Return "logged in" Else Throw New SecurityException("Invalid credentials.") End If Return "cannot login" End Function _ _ Public Function PerformSecuredOperation1() As String AuthorizeUser(SHToken.TokenID, "Administrator") Return "Secure operation has been performed 1" End Function _ _ Public Function PerformSecuredOperation2() As String AuthorizeUser(SHToken.TokenID, "Administrator") Return "Secure operation has been performed 2" End Function _ _ Public Function PerformSecuredOperation3() As String AuthorizeUser(SHToken.TokenID, "Administrator") Return "Secure operation has been performed 3" End Function Private Function AuthorizeUser(ByVal tokenID As String) _ As SecurityLibrary.Token Dim token As SecurityLibrary.Token = _ CType(Application(tokenID), SecurityLibrary.Token) If Not (token Is Nothing) Then Return token Else Throw New SecurityException("Invalid token.") End If End Function Private Function AuthorizeUser(ByVal usertoken As String, _ ByVal role As String) As SecurityLibrary.Token Dim token As SecurityLibrary.Token = AuthorizeUser(usertoken) If Roles.IsUserInRole(token.UserName, role) Then Return token Else Throw New SecurityException("Insufficient permissions.") End If End Function
577
The Complete Reference To Professional SOA with Visual Studio 2005
_ Public Sub CreateTestUser(ByVal username As String, _ ByVal password As String) If Not (Membership.GetUser(username) Is Nothing) Then Throw New SecurityException("User already exists in system!") End If Membership.CreateUser(username, password) Dim role As String = "Administrator" If Not Roles.RoleExists(role) Then Roles.CreateRole(role) End If Roles.AddUsersToRole(New String() {username}, role) End Sub End Class
The listing 14-39 and listing 14-40 above shows the Web service implementation of our token security system. We also need a security token library which is used to derive from SoapHeader and also store relevent information relating to the token. See listing 14-41 (below) Listing 14-41. Demonstrates SecurityLibrary using C# using System; using System.Collections.Generic; using System.Text; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; namespace SecurityLibrary { public class TokenHeader : SoapHeader { public string TokenID; public TokenHeader(string tokenID) { TokenID = tokenID; } public TokenHeader() {} } public class Token { private string userName; public string UserName { get { return userName; } } private string tokenID; public string TokenID {
578
The Complete Reference To Professional SOA with Visual Studio 2005
get { return tokenID; } } public Token(string userName) { this.userName = userName; // Create the token GUID. tokenID = Guid.NewGuid().ToString(); } } }
Listing 14-42. Demonstrates SecurityLibrary using Visual Basic 2005 Imports System Imports System.Collections.Generic Imports System.Text Imports System.Web Imports System.Web.Services Imports System.Web.Services.Protocols Namespace SecurityLibrary Public Class TokenHeader Inherits SoapHeader Public TokenID As String Public Sub New(ByVal ltokenID As String) TokenID = ltokenID End Sub Public Sub New() End Sub End Class Public Class Token Private luserName As String Public ReadOnly Property UserName() As String Get Return luserName End Get End Property Private ltokenID As String Public ReadOnly Property TokenID() As String Get Return ltokenID End Get End Property Public Sub New(ByVal userName As String) Me.luserName = userName ltokenID = Guid.NewGuid.ToString
579
The Complete Reference To Professional SOA with Visual Studio 2005
End Sub End Class End Namespace
To use our custom token security, the first step is to decide what user-specific information we want to keep in our memory. We need to create a custom class that represents this information. This class can include information about the user (name, e-mail address, and so on) and the user’s permissions. We’re also storing the token id information along with the token so that the information can be retrieved at a later date. In our implementation the Token ID is a randomly generated GUID to ensure that the tokens do not overlap. See listing 14-43. Listing 14-43. Demonstrates token class used to store information relating to the token using C# public class Token { private string userName; public string UserName { get { return userName; } } private string tokenID; public string TokenID { get { return tokenID; } } public Token(string userName) { this.userName = userName; // Create the token GUID. tokenID = Guid.NewGuid().ToString(); } }
Listing 14-44. Demonstrates token class used to store information relating to the token using Visual Basic 2005 Public Class Token Private luserName As String Public ReadOnly Property UserName() As String Get Return luserName End Get End Property Private ltokenID As String Public ReadOnly Property TokenID() As String Get Return ltokenID End Get End Property Public Sub New(ByVal userName As String)
580
The Complete Reference To Professional SOA with Visual Studio 2005
Me.luserName = userName ltokenID = Guid.NewGuid.ToString End Sub End Class
Once we have the token class, we can store relevant information into it, we need to create a SOAP header. The header will track the token for us. See listing 14-45. The TokenHeader in our implementation is derived from SoapHeader. We will be serializing an instance of the TokenHeader object into the SOAPHeader. Thus all the information it needs to contain is the TokenID information from which we can then later retrieve all the relevant information back again.
Listing 14-45. Demonstrates TokenHeader class implementing SoapHeader using C# public class TokenHeader : SoapHeader { public string TokenID; public TokenHeader(string tokenID) { TokenID = tokenID; } public TokenHeader() {} }
Listing 14-46. Demonstrates TokenHeader class implementing SoapHeader using Visual Basic 2005 Public Class TokenHeader Inherits SoapHeader Public TokenID As String Public Sub New(ByVal ltokenID As String) TokenID = ltokenID End Sub Public Sub New() End Sub End Class
We must then add a member variable for the TicketHeader to our web service. See listing 14-47. Listing 14-47. Demonstrates an instance of TokenHeader in our main Web service using C# [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class Service : System.Web.Services.WebService { public SecurityLibrary.TokenHeader Token;
Listing 14-48. Demonstrates an instance of TokenHeader in our main Web service using Visual Basic 2005 _ _ Public Class Service Inherits System.Web.Services.WebService Public SHToken As SecurityLibrary.TokenHeader
581
The Complete Reference To Professional SOA with Visual Studio 2005
The next step is to create a dedicated web method that logs the user in. User will need to submit user login and password to this method. The method will then retrieve the user information, create the Token object, and issue the token. In our example, a Login() web method checks the user credentials using the static Membership.ValidateUser() method. A new token is constructed with the user information and stored in a userspecific slot in the Application collection. At the same time, a new SOAP header is issued with the token so that the user can access other methods with the token information. See listing 14-49. Here’s the example for the Login() method: Listing 14-49. Login() method using C# [WebMethod] [SoapHeader("Token", Direction = SoapHeaderDirection.Out)] public string Login(string username, string password) { if (Membership.ValidateUser(username, password)) { SecurityLibrary.Token token = new SecurityLibrary.Token(username); Application[token.TokenID] = token; Token = new SecurityLibrary.TokenHeader(token.TokenID); return "logged in"; } else { throw new SecurityException("Invalid credentials."); } return "cannot login"; }
Listing 14-50. Login() method using Visual Basic 2005 _ _ Public Function Login(ByVal username As String, _ ByVal password As String) As String If Membership.ValidateUser(username, password) Then Dim token As SecurityLibrary.Token = _ New SecurityLibrary.Token(username) Application(token.TokenID) = token SHToken = _ New SecurityLibrary.TokenHeader(token.TokenID) Return "logged in" Else Throw New SecurityException("Invalid credentials.") End If Return "cannot login" End Function
In the listing 14-50 above, the Token object is stored in the Application collection, which is global to all users. The tokens are stored using GUID that was generated to prevent them from overwriting each other. We can then use the token id information that’s embedded in the Soap header to retrieve the user information. In this way, our code can check the Application collection first, and if a matching Token is found, no database call is required. But if the Token isn’t present, the information can still be retrieved from the database.
582
The Complete Reference To Professional SOA with Visual Studio 2005
The next step is to verify the credential information, the following AuthorizeUser() method checks for a matching token and returns the Token if it’s found. Otherwise an exception is thrown, this exception will be raised as a SOAP exception which will be returned to the client. See listing 14-51. Listing 14-51. Login() function using C# private SecurityLibrary.Token AuthorizeUser(string tokenID) { SecurityLibrary.Token token = (SecurityLibrary.Token)Application[tokenID]; if (token != null) { return token; } else { throw new SecurityException("Invalid token."); } }
Listing 14-52. Login() function using Visual Basic 2005 Private Function AuthorizeUser(ByVal tokenID As String) _ As SecurityLibrary.Token Dim token As SecurityLibrary.Token = _ CType(Application(tokenID), SecurityLibrary.Token) If Not (token Is Nothing) Then Return token Else Throw New SecurityException("Invalid token.") End If End Function
We also have an additional AuthorizeUser() which verifies that the user belongs to a specific role. The ASP.NET role management provider handles the role-checking work. Listing 14-53. Verifying that the user belongs to a role using C# private SecurityLibrary.Token AuthorizeUser(string usertoken, string role) { Token token = AuthorizeUser(usertoken); if (Roles.IsUserInRole(token.UserName, role)) { return token; } else { throw new SecurityException("Insufficient permissions."); } }
Listing 14-54. Verifying that the user belongs to a role using Visual Basic 2005 Private Function AuthorizeUser(ByVal usertoken As String, _ ByVal role As String) As SecurityLibrary.Token Dim token As SecurityLibrary.Token = AuthorizeUser(usertoken) If Roles.IsUserInRole(token.UserName, role) Then Return token Else
583
The Complete Reference To Professional SOA with Visual Studio 2005
Throw New SecurityException("Insufficient permissions.") End If End Function
Now we create a Web method to use the AuthorizeUser() method to check that the user has the required permissions. Here’s an example that checks that the client is an administrator before allowing the client to perform some functionality. Listing 14-55. Demonstrates PerformSecuredOperation() using C# [WebMethod] [SoapHeader("Token", Direction = SoapHeaderDirection.In)] public string PerformSecuredOperation1() { AuthorizeUser(Token.TokenID, "Administrator"); //if user does not belong to a valid role then an security //exception will be thrown before return is executed return "Secure operation has been performed 1"; }
Listing 14-56. Demonstrates PerformSecuredOperation() using Visual Basic 2005 _ _ Public Function PerformSecuredOperation1() As String AuthorizeUser(SHToken.TokenID, "Administrator") Return "Secure operation has been performed 1" End Function
Inorder to create a user account to test the token authentication we have implemented CreateTestUser() which uses Membership to create a new user for us. We can then use this user to login and then perform some operation on our PerformSecuredOperation() function. Listing 14-57. Demonstrates CreateTestUser() used to create an user of the role Administrator in C# [WebMethod] public void CreateTestUser(string username, string password) { if (Membership.GetUser(username) != null) { //we can delete the user if it exists throw new SecurityException("User already exists in system!"); } Membership.CreateUser(username, password); string role = "Administrator"; if (!Roles.RoleExists(role)) { Roles.CreateRole(role); } Roles.AddUsersToRole(new string[] { username }, role); }
Listing 14-58. Demonstrates CreateTestUser() used to create an user of the role Administrator in Visual Basic 2005
584
The Complete Reference To Professional SOA with Visual Studio 2005
_ Public Sub CreateTestUser(ByVal username As String, _ ByVal password As String) If Not (Membership.GetUser(username) Is Nothing) Then Throw New SecurityException("User already exists in system!") End If Membership.CreateUser(username, password) Dim role As String = "Administrator" If Not Roles.RoleExists(role) Then Roles.CreateRole(role) End If Roles.AddUsersToRole(New String() {username}, role) End Sub
In order to enable the Membership functionalities we also need to make a few entries into our web.config file. Listing 14-59. ConnectionString
We need to tell the Membership management where our database is located. In our case it is a default database created Web Site Administration which is used to manage users. Listing 14-60. Membership configuration.
585
The Complete Reference To Professional SOA with Visual Studio 2005
In the configuration above we define the properties of the Membership management. We also define password policies and where the information will be stored. The last thing we need to define is:
This will allow ASP.NET Membership to manage roles for us. As in the example we need to assign users to the Administrator role that we had defined. Thus roleManager must be enabled.
Implement Client for Token Security Now we can create a client application that will utilize the SOAP token Web service system we had implemented in the earlier section.
Figure 14-14. Client application using token security to authenticate
In this case, a Windows application provides two text boxes for the user to supply a user name and password (see figure 14-14). This information is passed to the Login() method, and then the PerformSecuredOperation() method is called to retrieve the data. This method succeeds for a user with the Administrator role but fails for everyone else. Listing 14-61. Demonstrates the token application using C# using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace CSTokenAuthentication { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private WSTokenService.Service wsts = new CSTokenAuthentication.WSTokenService.Service();
586
The Complete Reference To Professional SOA with Visual Studio 2005
private void ButtonAccess_Click(object sender, EventArgs e) { try { wsts.Login(this.textBoxLogin.Text, this.textBoxPass.Text); this.labelResult.Text = wsts.PerformSecuredOperation1() + Environment.NewLine + wsts.PerformSecuredOperation2() + Environment.NewLine + wsts.PerformSecuredOperation3(); } catch (Exception ex) { this.labelResult.Text = ex.Message; } } private void buttonCreateUser_Click(object sender, EventArgs e) { wsts.CreateTestUser(this.textBoxLogin.Text, this.textBoxPass.Text); } } }
Listing 14-62. Demonstrates the token application using Visual Basic 2005 Public Class Form1 Private wsts As WSTokenService.Service = _ New WSTokenService.Service Private Sub ButtonAccess_Click _ (ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles button1.Click Try wsts.Login(Me.textBoxLogin.Text, Me.textBoxPass.Text) Me.labelResult.Text = _ wsts.PerformSecuredOperation1(+Environment.NewLine + _ wsts.PerformSecuredOperation2 + Environment.NewLine + _ wsts.PerformSecuredOperation3) Catch ex As Exception Me.labelResult.Text = ex.Message End Try End Sub Private Sub buttonCreateUser_Click _ (ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles buttonCreateUser.Click wsts.CreateTestUser(Me.textBoxLogin.Text, Me.textBoxPass.Text) End Sub End Class
In Visual Studio 2005 when we add a Web reference Visual Studio 2005 will automatically generate the proxy class for us. The proxy class will help us manage the token so as a client we don’t need to be aware of the header that’s actually being transported to and from the requests. As we can see in the SOAP exchange below.
587
The Complete Reference To Professional SOA with Visual Studio 2005
Listing 14-63. Demonstrates the Login() SOAP request
JohnDoe password
In the above listing we are making a SOAP request to the Login() method within the security Token Web service. Listing 14-64. Demonstrates Login() response with TokenHeader information
5e3f718f-8e92-4305-8e83-7a56c5eced25
logged in
In the listing above we can see the response from the login function contains the SOAP header for TokenHeader. This TokenHeader contains TokenID. The client application that requested the Login() method
does not have to implement anything to handle this. This is handled by our proxy to the Web service. Listing 14-65. Shows PerformSecuredOperation1() SOAP request with TokenHeader
5e3f718f-8e92-4305-8e83-7a56c5eced25
588
The Complete Reference To Professional SOA with Visual Studio 2005
In the listing above we are making a request to the PerformSecuredOperation1() operation. However notice that the request now contains SOAP header information. Which contains the TokenHeader as well as the TokenID that was issued by our Web service. Listing 14-66. PerformSecuredOperation1() SOAP response
Secure operation has been performed 1
The SOAP response above shows the response from PerformSecuredOperation1(). Listing 14-67. PerformSecuredOperation2() SOAP request
5e3f718f-8e92-4305-8e83-7a56c5eced25
In the listing above we are making a request to the PerformSecuredOperation2() operation. Notice that the request also contains SOAP header information. Which contains the TokenHeader as well as the TokenID that was issued by our Web service even though we did not have to perform anything special again all of it is handled by the proxy. Listing 14-68. PerformSecuredOperation2() SOAP response
Secure operation has been
589
The Complete Reference To Professional SOA with Visual Studio 2005
performed 2
The SOAP response above shows the response from PerformSecuredOperation2(). Listing 14-69. PerformSecuredOperation2() SOAP request
5e3f718f-8e92-4305-8e83-7a56c5eced25
In the listing above we are making a request to the PerformSecuredOperation3() operation. Notice that the request also contains SOAP header information. Listing 14-70. PerformSecuredOperation1() SOAP response
Secure operation has been performed 3
The SOAP response above shows the response from PerformSecuredOperation3(). By using SOAP headers to implement tokens the client application does not need to be aware of the token management. That’s because the Login() method issues the token, and in turn it is managed by the proxy class. As long as the client uses the same instance of the proxy class, the same ticket value will be submitted automatically, and the user will be authenticated.
Summary In this chapter, we have covered:
590
The Complete Reference To Professional SOA with Visual Studio 2005
Windows Authentication - We can use windows authentication to authenticate our users. This is particularly
useful in an intranet environment. In Web service this works in much the same way as it does with web pages. The difference is that a web service is always executed by another application, and not directly by the browser. Managing Users by Using Membership - ASP.NET Membership provides us with a built-in way to validate and store user credentials. ASP.NET Membership is particularly useful when implementing user and role management within Web services.
Custom Authentication and Authorization with SOAP Headers – The optional Header element can contain additional information not directly related to the particular message. Each child element of the Header element is called a SOAP header. We thus use SOAP header to store security credential details. This is particularly useful as it saves the client from having to authenticate themselves upon each WebMethod call.
591
The Complete Reference To Professional SOA with Visual Studio 2005
Chapter 15 Web Services Enhancements 3.0 Web services are evolving rapidly. This is due to a consensus in companies such as Microsoft, IBM, BEA Systems, and VeriSign, working together with organizations such as the Organization for the Advancement of Structured Information Standards (OASIS) to formulate new specifications to address rising issues. These specifications called the Web Service Specifications also refered to as WS-* specifications. These are based on XML, SOAP, and WSDL extensibility models. Together, these specifications define a set of composable features to make Web services secure, reliable and interoperable. All of these specifications are composable which means we can mix and choose the only ones that we need. We do not have to implement any particular standards but as the industry as a whole slowly adopts these standards we will also need to adopt them in order to interoperate with other Web services that are governed by the specifications. The WS-Specifications provide an important framework for Web services to interoperate securely. Microsoft provides a set of tools for .NET called the Web Services Enhancements (WSE). WSE includes managed APIs for implementing selected WS-specifications in a composable manner. The latest WSE release is v3.0. WSE 3 greatly simplifies the development and deployment of secure Web services using .NET. It allows developers and administrators to apply security policies to the Web services running on .NET Framework 2.0. Using WSE 3.0 we can sign, encrypt SOAP messages using Kerberos tickets, X.509 certificates and other custom binary and XML based security tokens. Along with username/password credentials which can be used for authentication purposes. WSE also provides an enhanced security model which provides a foundation for policy based security for Web services. It also supports the ability to establish trust issue services for retrieval and validation of security tokens. It also simplifies the ability to establish more efficient long running secure communication via secure conversations. In this chapter, we will be focusing to explore how to develop .NET Web services and client applications by leveraging WSE functionalities to implement secure Web services. We will explore using WSE 3.0 to provide supports for secure communication by learning about WSE authentication as well as implementing custom token management. We will also be looking at implementing SOAP message signing and encryption using X.509 certificates through WS-Security specification. Lastly we will learn to implement binary file transfer through the use of Message Transmission Optimization Mechanism (MTOM).
Web Services Enhancements Overview The engine that drives Web Services Enhancements is a separate WSE runtime that’s integrated with the .NET Framework and can be hosted by ASP.NET (see figure 15-1 below).
592
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 15-1. Demonstrates the WSE layer
This runtime essentially intercepts SOAP request and response messages and invokes a set of filters that either serialize specification compliant SOAP response message headers (in the case of outbound response messages) or interpret specification compliant request message headers (in the case of inbound request messages). These filters can handle SOAP messages transported over both HTTP or TCP. The filters and the WSE runtime are implemented by the Microsoft.Web.Services assembly (Microsoft.Web.Services.dll), and WSE provides a set of APIs that allows us to programmatically determine the behavior of these inputs and output filters in order to implement the desired functionalities described by the various specifications. The WSE runtime can also be installed at a Web service client computer and used by client applications that consume Web services that require the additional support for advanced Web services headers. As on the Web service provider, the WSE runtime on the client passes SOAP messages through a set of filters that either serialize supported headers for outgoing messages or abstract the supported headers from incoming messages into proxy objects that the client application consumes.
WS-Security The Web service security (WS-Security) specification defines SOAP extensions for message integrity, and message confidentiality. The WS-Security specification provides message level security end-to-end security support rather than point-to-point security such as those provided by SSL/HTTPS. WS-Security defines a method of implementing Web service security using SOAP. It defines rules for authentication, signatures, and encryption mechanisms. WS-Security also defines a general mechanism for associating security tokens with messages. The token support itself is extensible and is not restricted to a specific type of security token. Typically a client will be required to provide proof of identity and or a business certificate. Additionally, WS-Security describes how to encode binary security tokens such as X.509 certificates and Kerberos ticket as well as how to include opaque encrypted keys. We can also extend security mechanisms that can be used to further describe the characteristics of the credentials.
Security Tokens WS-Security uses the concept of soft security tokens, which are logical entities generated by the system to ensure authentication. These refers to Username/Password, Kerberos tickets, or X.509 certificates. A developer can also build custom binary security tokens if necessary and use them without breaking the specification. For this purpose, WSE provides the BinarySecurityToken class. Classes that we build that derive from this will be compatible with the WS-Security soft token specification.
593
The Complete Reference To Professional SOA with Visual Studio 2005
To add a security token to an outbound message using WSE, all that we need to do is to programmatically define the token using an instance of an appropriate class that overrides the SecurityToken base class then add this object to the SoapContext of the outbound message. When received by a WSE-enabled application, the WSE runtime generates security token objects based on contents of the Security header in the incoming message. These tokens, which belong to the SoapContext object for the incoming message, are then presented to the appropriate security token manager for authentication and authorization. These security token objects are accessible to our application for as long as the SoapContext object exists.
Installing Web Services Enhancements Web Services Enhancements 3.0 is an addon onto Visual Studio 2005. You can either download WSE from Microsoft or you can find it on the accompanied source CD. Installing WSE is fairly straight forward. Simply run the install wizard for WSE 3.0.
Figure 15-2. WSE 3.0 install wizard
During setup, we will be prompted to select from several setup type options, including options to install only the runtime files, runtime plus tools, documentation, Visual Studio tools, and a custom install option. These setup options help to differentiate between the different types of WSE components that should be installed. We can also specify Custom option, which allow us to select the various components manually. Most developers should choose the Visual Studio® Developer option, which installs the WSE 3.0 runtime files, documentation and samples, standalone tools, and the Visual Studio 2005 tools (see figure 15-13 below).
594
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 15-3. WSE setup types
WSE 3.0 contains several QuickStart sample applications and documentation that demonstrates how to use various classes in the WSE assembly. But the engine of WSE 3.0 is a single assembly called Microsoft.Web.Services3.dll, which is installed by default under C:\Program Files\Microsoft WSE\v3.0. In addition, this assembly gets automatically registered in the Global Assembly Cache (GAC).
Using Web Services Enhancements In order to use the WSE assembly in our Web services projects, we will need to register it as a SOAP extension within either the machine.config or web.config configuration files. If we update the machine.config file, then the assembly will automatically be registered for all future Web services projects. Otherwise, we will need to update the web.config files for each new project individually. Fortunately, Microsoft also provides the WSE Settings tool that integrates with Visual Studio 2005 and can be used to automatically make the needed modifications to the Web.config file. With the WSE Settings tool installed, it is simple to enable any Web service or client that consumes such a Web service to use the WSE runtime. To configure WSE settings for a Visual Studio 2005 application, simply right-click on the project that requires WSE in the Solution Explorer window in Visual Studio 2005 and click WSE Settings. This displays the WSE Settings tool (see figure 15-4 below).
595
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 15-4. The WSE settings tool
Enabling WSE for an ASP.NET Web service is quite simple with this tool. All that we need to do is select WSE Settings 3.0 from the context menu in solution explorer for our project. Then select both check boxes on the General tab. To enable WSE for an application consuming a WSE-enabled Web service, we need only select the “Enable this project for Web Services Enhancements” check box see figure 15-5 (below). By enabling this option the necessary assembly reference will be added to the project, and the SOAP extensions configurations will be automatically entered into our Web.config file.
596
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 15-5. Enabling WSE for a project Listing 15-1. Demonstrates the Web.config file after WSE has been enabled.
The rest of the tabs in this tool allow us to configure various components of WSE that correspond to the specifications that the Web service needs to use.
WSE Communication Process There are several stages involved in securing communication between the client and the Web service. Messages are authenticated to prevent tampering or messages spoofing. The communication channel is secured to prevent eavesdropping and to ensure confidentiality. The steps below outline the WSE stages to secure client and Web service communication.
Figure 15-6. Shows the WSE stages in communication
Requesting Process The communication process starts with the client generating a Web service request. This process involves three steps: initializing the UsernameToken, establishing message integrity, encrypting sensitive data in the message, (see figure 15-6 above).
598
The Complete Reference To Professional SOA with Visual Studio 2005
During initialization the UsernameToken implements a token object with a SendPlainText password option to send the password over the network as plaintext. This is often required because directory services such as Active Directory require plaintext passwords for credential validation. SendPlainText is the default option of the UsernameTokenManager which is similar to basic authentication over HTTP. When sending clear text password we should always secure the communication channel between the client and the server this can be achieved using Secure Socket Layer (SSL). To add security we can also add message level encryption by using WSE 3.0. The next stage is establishing message integrity, at this stage data origin authentication is established between the client and the service, either implicitly or explicitly, depending upon one of the two following methods that we can choose to secure messages between the client and the service: The usernameOverTransportSecurity turnkey assertion with HTTPS. The usernameForCertificateSecurity turnkey assertion.
To ensure security when we use server certificates with HTTPS using the turnkey assertion help to provide data integrity and data confidentiality at the transport level. If we require message origin authentication from the client, we would need to install and use a certificate for the client. Using usernameForCertificateSecurity turnkey assertion WSE 3.0 can provide support for data confidentiality and message origin authentication. This is achieved when a derived key token is included in the request message this message is then encrypted with a wrapped symmetric encryption key. Then using the service’s X.509 certificate public key the wrapped symmetric key is encrypted. This derived key token is referred to as an encrypted key. This key is accompanied with a valid UsernameToken, message origin authentication is provided when the client uses the derived key token to sign the message. Encrypting sensitive data in the message, at this stage we should encrypt the message from the client to the service to ensure that only the service, as the intended recipient of the message, can process it. The method that we choose to secure the communication channel between the client and the service should also provide data confidentiality.
Response Process The response process is a little more complicated in WSE as the service needs to authenticate the client and return a response. This part of the process has five steps: decrypting the request message, verifying message integrity, validating the password, establishing the response integrity, encrypting the response. *
The first of these steps is the decryption of the request message. It is at this stage that we choose whether to secure the communication channel between the client and the service and to determine how to decrypt the request message. There are two forms of decryption at this stage if transport level encryption had been enabled using the usernameOverTransportSecurity assertion which relies on SSL to decrypt the message. WSE 3.0 also provides support for certificate based decryption using the usernameForCertificateSecurity assertion which decrypts the derived key token that had been encrypted using the wrapped symmetric key. Then using the derived key token to decrypt the message signature, the UsernameToken, and the rest of the message that the client had encrypted.
*
The second step is to verify the message integrity to ensure that the message had not been altered. The option that we had selected in step one on how to secure communication between the client and the service determines how the message integrity will be verified. WSE uses usernameOverTransportSecurity assertion relying on SSL to verify message integrity. Otherwise if a client certificate is provided then the certificate can be used to verify the message origin authentication. This is achieved with WSE 3.0 using the usernameForCertificateSecurity assertion verifies the message integrity using the derived key token that was sent by the client and was decrypted in step one.
599
The Complete Reference To Professional SOA with Visual Studio 2005
*
The third step is to validate the password. After the service receives the message using WSE 3.0 the UsernameTokenManager class validates the information in the UsernameToken using the AuthenticateToken method. The UsernameTokenManager can be used to validate credentials against an Active Directory domain controller. If a directory service or a database is used then we can extend the implementation of the UsernameTokenManager class.
*
The fourth step is to establish response integrity. At this stage the method used to establish the response message’s integrity depends upon whether communication is secured at the message layer using WSE 3.0 or at the transport layer using SSL. If the communication is secured at the transport level then message integrity is provided by using SSL. If communication is secured at the message level then the response message will be signed with a key derived from the encrypted key which was sent in the request message.
*
The last step is the encrypting the response. Encryption is dependent on whether communication is secured at the message level using WSE 3.0 or at the transport level using SSL. If communication is secured at the transport level the encryption for the message is left to SSL. If communication is secured at the message layer then response signature and the message is encrypted with a key derived from the encrypted key sent in the request message.
Implementing WSE Service Using WS-Security requires coding on both the client and the server. The server is expecting authentication information to be packed into the SOAP header. The client has to take steps to create this header with the user’s credentials. The server needs to validate these credentials against a user data store before executing the service request. We will now implement WSE authentication. In order to implement the following example WE 3.0 must be installed on the computers that we’re going to use to develop WSE-enabled applications. In later sections we will explore how to use the WSE API to manually attach security tokens to outgoing SOAP messages. This process can also be automated so that the WSE runtime adds the required tokens for us. In order to do this, us must configure a policy for outbound messages and define a security token cache that WSE can use to get a valid token. In Visual Studio Create a new Web service project by select File -> New -> Web Site. Select ASP.NET Web Service under templates. Choose the location that we want the project to be in and also the preferred language to be used.
600
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 15-7. Creating a new Web Service project
To enable a Visual Studio 2005 project to support WSE 3.0. Right mouse click on the project in solution explorer and select WSE Settings 3.0 (see figure 15-8 below).
Figure 15-8. WSE Settings 3.0
601
The Complete Reference To Professional SOA with Visual Studio 2005
On the General tab, select the “Enable this project for Web Services Enhancements” check box, and also select the “Enable Microsoft Web Services Enhancements Soap Protocol Factory” then click OK (see figure 15-9 below). this will add reference to the WSE 3 assembly as well configure the necessary settings within the Web.config configuration file.
Figure 15-9. Enabling WSE
After we enable the service application to support WSE 3.0 SOAP extensions, we must enable policy support. If our application does not currently have a policy cache file, we can add one and enable policy support by performing the following steps. 1.
In Visual Studio 2005, right-click the application project and select WSE Settings 3.0.
2.
On the Policy tab, select the “Enable Policy” check box. Selecting this check box will automatically add the wse3policyCache.config file as the default name for the policy cache file.
3.
Within the Edit Application Policy group, select Add and then type "usernameTokenSecurity" for the new application policy.
4.
Click OK to start the WSE Security Settings Wizard, and then click Next (see figure 15-10. below).
602
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 15-10. WSE Security wizard
5.
On the Authentication Settings page, the wizard provides us with options to secure a service or a client. Select the secure a service application option button to configure the service.
6.
The wizard also provides us with authentication method choices on the same page. Select Username and click Next.
Figure 15-11. WSE Authentication Settings
7.
On the Users and Roles section, we can configure authorization based on the user name or roles associated with the user represented in the UsernameToken. By default, the perform authorization check box is cleared. If we wanted to perform authorization through the policy assertion, select the perform authorization check box, add users and roles as appropriate, and then click Next. In this example we will not be using this.
603
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 15-12. WSE Users and Roles
8.
On the Message Protection page, we can configure options for message protection. For transport layer security, select None (to rely on transport protection for example point-to-point security using SSL/HTTPS only) for the Protection Order this will use the usernameOverTransportSecurity assertion. For this example select None (rely on transport protection). Click Next. If we select any other protection option, the policy assertion will use usernameForCertificateSecurity. This is because the other options under Protection Order other than None rely on transport protection and will require a certificate for signing and encrypting, In this example select the option for Sign, Encrypt, Encrypt Signature. By default, the Enable WS-Security 1.1 Extensions check box is selected. This option must be enabled if we are going to use certificate security.
Figure 15-13. WSE Message Protection
9.
On the Create Security Settings page, review the settings, and then click Finish (see figure 15-14 below).
604
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 15-14. WSE Summary
10. This will add the usernameTokenSecurity under the Application Policy section. Click ok to complete the process and save the settings to the configuration file wse3policyCache.config (see figure 15-15 below).
Figure 15-15. WSE Settings
After we have completed the above steps, our server security policy should look similar to the following code below. Listing 15-2. Demonstrates the generated wse3policyCache.config
605
The Complete Reference To Professional SOA with Visual Studio 2005
We can see that the configuration is set to use usernameOverTransportSecurity as we had specified during the configuration wizard. Listing 15-3. Web.config
The listing above demonstrates the Web.Config file that has been modified by the WSE configuration wizard. We can see that the wse3policyCache.config policy file has been set in the Web.Config file and also that
606
The Complete Reference To Professional SOA with Visual Studio 2005
SOAP extensions had been set to the WSE 3.0 assembly. This is necessary for WSE to intercept messages in order to apply the ws-security. Listing 15-4. Demonstrates the Web service code in Visual C# using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; using Microsoft.Web.Services3.Design; using Microsoft.Web.Services3; [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [Policy("usernameTokenSecurity")] public class Service : System.Web.Services.WebService { public Service () { //Uncomment the following line if using designed components //InitializeComponent(); } [WebMethod] public string EmployeeSalaryDetail(string id) { if (id == "123") { return "Salary for John Doe is $xyz"; } return "no salary details found"; } }
Listing 15-5. Demonstrates the Web service code in Visual Basic .NET Imports System.Web Imports System.Web.Services Imports System.Web.Services.Protocols Imports Microsoft.Web.Services3.Design Imports Microsoft.Web.Services3 _ _ _ _ Public Class Service Inherits System.Web.Services.WebService _ Public Function EmployeeSalaryDetail(ByVal id As String) As String If id = "123" Then Return "Salary for John Doe is $xyz"
607
The Complete Reference To Professional SOA with Visual Studio 2005
End If Return "no salary details found" End Function End Class
In the listings 15-4 and listings 15-5 above we have created a standard Web service the only difference is that we have specified to use Policy("usernameTokenSecurity") this is a way of telling WSE to apply the policy of usernameTokenSecurity within our class. As in WSE we can specify many different policies. With the policy that we have selected using username and password token authentication the WSE engine will validate against the windows user accounts on the server by default. In the following section we will examine how to create a client application to consume the WSE web service.
Implementing WSE Client Creating a client that implements WSE is quite simple. Thanks to the WSE settings configuration tool. We will start by creating a console application in Visual Studio. In Visual Studio Create a new console application by selecting File -> New -> Project. Select the preferred language to be used then select Console Application from under templates. Choose the location that the project and the name of the project.
Figure 15-16. Create a new console project
Enabling WSE for the console application is the same process as enabling for the web service. To enable a Visual Studio 2005 project to support WSE 3.0. Right mouse click on the console project in solution explorer and select WSE Settings 3.0.
608
The Complete Reference To Professional SOA with Visual Studio 2005
On the General tab, select the Enable this project for Web Services Enhancements check box, and then click OK. This will add reference to the WSE 3 assembly as well configure the necessary settings within the app.config configuration file for the console application. After we enable the service application to support WSE 3.0 SOAP extensions, we must enable policy support. If our application does not currently have a policy cache file, we can add one and enable policy support by performing the following steps. 1.
In Visual Studio 2005, right-click the application project and select WSE Settings 3.0.
2.
On the Policy tab, select the “Enable Policy” checkbox. Selecting this setting automatically adds wse3policyCache.config a policy cache file. (This is the same process as configuring WSE policy for the Web service).
3.
In “Edit Application Policy”, select Add, and then type "usernameTokenSecurity" for the new application policy.
4.
Click OK to start the WSE Security Settings Wizard, and then click Next.
5.
In “Authentication Settings” page, we are provided with a choice on how to secure a service or a client. Select “Secure a client application” to configure the client.
6.
The wizard also provides a choice of authentication methods in the same step. Select Username, and then click Next (see figure 15-17 below).
Figure 15-17. Authentication settings for WSE client
7.
In “Optionally Provide Username and Password” page, we are provided with options to define a user name and password. Select “Specify Username Token in code” checkbox is selected and select Next.
609
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 15-18. Authenticate through Username and Password
8.
On the “Message Protection” page, we can define options for message security. To configure for transport layer security, select None which means that WSE will rely on transport protection using SSL. The Protection Order will use the usernameOverTransportSecurity assertion. If we select any other protection option, the policy assertion usernameForCertificateSecurity will be used. By default, the Enable WS-Security 1.1 Extensions check box is enabled. This setting must be enabled if we are using message layer security.
9.
Click Next to bring up the summary window then Finish to confirm.
10. Then OK on the WSE Settings dialog to save settings to the configuration file.
Listing 15-6. Demonstrates the wse3policyCache.config for the console client application.
Listing 15-7. Demonstrates the app.config file
610
The Complete Reference To Professional SOA with Visual Studio 2005
The listing 15-6 above, demonstrates the wse3policyCache.config file that was created by the WSE configuration wizard. The policy had been converted to use usernameOverTransportSecurity which means that it will not be signed or encrypted but totally rely on the security of SSL/HTTPS. In the app.config file listing 15-7 above, we can see that the wse3policyCache.config policy file has been set in the configuration file. To access the WSE Web service from our client application simply create a web reference to our WSE Web service. Then click Add Reference to complete.
Figure 15-19. Adding web reference to WSE Web service
When we add a Web reference to the service from the client application, two proxies are generated for the Web service, one is a non-WSE 3.0 proxy and the other is WSE 3.0 enabled. In the WSE enabled proxy Microsoft uses the naming convention of service name + "Wse". For example, if our Web service is named "MyService", our WSE 3.0–enabled Web service proxy class name would be "MyServiceWse".
611
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 15-20. Demonstrates two server proxies one WSE enabled the other non-WSE
We can also use the WseWsdl3.exe tool under C:\Program Files\Microsoft WSE\v3.0\Tools to generate the WSE proxy. The following command creates a client proxy class in C# for a Web service located at the specified URL. The WSDL to SoapClient tool saves the client proxy class in the file MyProxyClass.cs. WseWsdl3 http://hostServer/WebServiceRoot/WebServiceName.asmx?WSDL MyProxyClass.cs
The following command creates a client proxy class in Visual Basic for a Web service located at the specified URL. The WSDL to SoapClient tool saves the client proxy class in the file MyProxyClass.vb. WseWsdl3 http://hostServer/WebServiceRoot/WebServiceName.asmx?WSDL MyProxyClass.vb VB
Listing 15-8. Demonstrates Client application implementing Visual C# using System; using System.Collections.Generic; using System.Text; using Microsoft.Web.Services3.Security.Tokens; namespace CSConsoleClient { class Program { static void Main(string[] args) { WSEProxy.ServiceWse proxy = new WSEProxy.ServiceWse(); try { UsernameToken token = new UsernameToken("BookUser", "BookUser", PasswordOption.SendPlainText); proxy.SetClientCredential(token); proxy.SetPolicy("usernameTokenSecurity"); string strDetails = proxy.EmployeeSalaryDetail("123"); Console.WriteLine(strDetails); Console.ReadLine(); } catch (Exception ex) { String strError = ex.Message; Console.WriteLine(strError); Console.ReadLine(); } } } }
612
The Complete Reference To Professional SOA with Visual Studio 2005
Listing 15-9. Demonstrates Client application implementing Visual Basic .NET Imports Microsoft.Web.Services3.Security.Tokens Module Module1 Sub Main() Dim proxy As WSEProxy.ServiceWse = New WSEProxy.ServiceWse Try Dim token As UsernameToken = _ New UsernameToken("BookUser", "BookUser", _ PasswordOption.SendPlainText) proxy.SetClientCredential(token) proxy.SetPolicy("usernameTokenSecurity") Dim strDetails As String = proxy.EmployeeSalaryDetail("123") Console.WriteLine(strDetails) Console.ReadLine() Catch ex As Exception Dim strError As String = ex.Message Console.WriteLine(strError) Console.ReadLine() End Try End Sub End Module
In listing 15-8 and listing 15-9 above, we have created a client application that will consume the WSE web service. In the above listings we have used the ServiceWSE proxy to create an object to the Web service. Attaching a username token to a request message is as simple as defining a new UsernameToken object and attaching it to the proxy context using the SetClientCredential function for the outbound message shown below: Listing 15-10. Using Visual C# UsernameToken token = new UsernameToken("BookUser", "BookUser", PasswordOption.SendPlainText); proxy.SetClientCredential(token);
Listing 15-11. Using Visual Basic .NET Dim token As UsernameToken = New UsernameToken("BookUser", "BookUser", _ PasswordOption.SendPlainText) proxy.SetClientCredential(token)
Note: The Username in this case is BookUser, this is using Windows Integrated Security so we need to ensure that the user BookUser is added onto the system.
613
The Complete Reference To Professional SOA with Visual Studio 2005
We then need to attach the policy we had configured through the WSE configuration wizard. This policy contains information about how WSE should handle the security headers. This policy needs to be attached to the proxy object by using the WSE proxy’s SetPolicy function. Listing 15-12. Using Visual C# proxy.SetPolicy("usernameTokenSecurity");
Listing 15-13. Using Visual Basic .NET proxy.SetPolicy("usernameTokenSecurity")
Once all the necessary information is set in the proxy object. We can make the necessary request to our webservice through proxy.EmployeeSalaryDetail("123") just as how we would normally make a call to the Web service. The result is shown below.
Figure 15-21. Shows a successfully authenticated and authorized Web service call
However if an incorrect credential is provided a SOAP fault will be generated. The requesting application will be denied access to the WebMethod.
Figure 15-22. Shows the exception thrown if an incorrect credential is used
The listing below demonstrates a request message sent to the WSE service we can see that because we had selected plaintext and to transmit the password is actually not encrypted. Listing 15-14. Demonstrates the request sent to the WSE Web service
123
http://tempuri.org/EmployeeSalaryDetail urn:uuid:cb166956-1202-4f34-bbcb-94c0d4d71572
http://schemas.xmlsoap.org/ws/2004/08/ addressing/role/anonymous
http://localhost:1704/CSService/Service.asmx
2006-06-13T07:49:40Z 2006-06-13T07:54:40Z
BookUser BookUser 1MUXtG6OAAEjBjKQPHchmA== 2006-06-13T07:49:40Z
615
The Complete Reference To Professional SOA with Visual Studio 2005
123
The listing below demonstrates the response sent by the Web service to the client. Listing 15-15. Demonstrates the response received from the WSE Web service
http://tempuri.org/ EmployeeSalaryDetailResponse urn:uuid:66faec6b-e9d4-485d-90af-62d3e1def4ee
urn:uuid:cb166956-1202-4f34-bbcb-94c0d4d71572
http://schemas.xmlsoap.org/ws/2004/08/addressing/ role/anonymous
2006-06-13T07:49:40Z 2006-06-13T07:54:40Z
Salary for John Doe is $xyz
Salary for John Doe is $xyz
Implementing Custom Username Service On the server, a SOAP extension runs to process the SOAP header when the message arrives with the authentication information packed into the Security element. This is done by an instance of a class deriving from SecurityTokenManager. In the following example we will explore how to use our own user data store to validate and authenticate. We will need to create an instance of a type that inherits from UsernameTokenManager and look the credentials up against our own user security datastore whether it’s a flat file, a database or a xml file. The UserNameTokenManager class derives from SecurityTokenManager. We can do the work of authentication by overriding the virtual AuthenticateToken method on the base class of UserNameTokenManager. This method gets passed the user name that the client sent, and our job in implementing this method is to look up the user’s password and send it back as a return value of the method call. The WSE code then compares the passwords and decides if the caller should be authenticated or not. In this example the security policy of the client will be the same as the security policy we had used in the previous example. The client implementation of the WSE code will still be the same as it really is the server’s responsibility to authenticate and validate the requesting client. As such switching to a custom Username token validation will not affect client implementation. The listing below demonstrates the server implementations of custom username token validation. Listing 15-16. Demonstrates implementing the Web service in Visual C# using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; using Microsoft.Web.Services3; using Microsoft.Web.Services3.Security.Tokens;
617
The Complete Reference To Professional SOA with Visual Studio 2005
using Microsoft.Web.Services3.Security; [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [Policy("usernameTokenSecurity")] public class Service : System.Web.Services.WebService { public Service() { //Uncomment the following line if using designed components //InitializeComponent(); } [WebMethod] public string EmployeeSalaryDetail(string id) { if (id == "123") { return "Salary for John Doe is $xyz"; } return "no salary details found"; } }
Listing 15-17. Demonstrates implementing the Web service in Visual Basic .NET Imports System Imports System.Collections.Generic Imports System.Text Imports Microsoft.Web.Services3.Security.Tokens Imports Microsoft.Web.Services3 Imports Microsoft.Web.Services3.Security Imports System.Xml Imports System.Security.Permissions Imports System.Web.Security Imports System.Security.Principal Namespace AuthenticationManager Public Class CustomUsernameTokenManager Inherits UsernameTokenManager Public Sub New() End Sub Public Sub New(ByVal nodes As XmlNodeList) MyBase.New(nodes) End Sub Protected Overloads Overrides Function AuthenticateToken _ (ByVal token As UsernameToken) As String Dim username As String = token.Username
618
The Complete Reference To Professional SOA with Visual Studio 2005
If username = "john" Then Return "doe" Else Throw New ApplicationException End If End Function End Class End Namespace
The Web service implementation for custom usertoken authentication is the same as the previous example. As the configuration is really up to the UsernameTokenManager that we will now implement in the section below. The WSE engine will look into the Web.config file for any custom token manager details that had been specified. It will then load the relevant token managers for authentication and authorization.
Listing 15-18. Demonstrates implementing UsernameTokenManager using Visual C# //AuthenticationManager.cs using System; using System.Collections.Generic; using System.Text; using Microsoft.Web.Services3.Security.Tokens; using Microsoft.Web.Services3; using Microsoft.Web.Services3.Security; using System.Xml; using System.Security.Permissions; using System.Web.Security; using System.Security.Principal; namespace AuthenticationManager { [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public class CustomUsernameTokenManager : UsernameTokenManager { /// /// Constructs an instance of this security token manager. /// public CustomUsernameTokenManager() { } /// /// Constructs an instance of this security token manager. /// /// /// An XmlNodeList containing XML elements from a /// configuration file. public CustomUsernameTokenManager(XmlNodeList nodes) : base(nodes) { }
619
The Complete Reference To Professional SOA with Visual Studio 2005
/// /// Returns the password or password equivalent /// for the username provided. /// Adds a principal to the token whith user's roles. /// /// The username token /// The password (or password equivalent) /// for the username
protected override string AuthenticateToken(UsernameToken token) { string username = token.Username; if (username == "john") return "doe"; else throw new ApplicationException(); } } }
Listing 15-19. Demonstrates implementing UsernameTokenManager using Visual Basic .NET ‘AuthenticationManager.cs Imports System Imports System.Collections.Generic Imports System.Text Imports Microsoft.Web.Services3.Security.Tokens Imports Microsoft.Web.Services3 Imports Microsoft.Web.Services3.Security Imports System.Xml Imports System.Security.Permissions Imports System.Web.Security Imports System.Security.Principal Namespace AuthenticationManager
Public Class CustomUsernameTokenManager Inherits UsernameTokenManager Public Sub New() End Sub Public Sub New(ByVal nodes As XmlNodeList) MyBase.New(nodes) End Sub
Protected Overloads Overrides Function AuthenticateToken _ (ByVal token As UsernameToken) As String Dim username As String = token.Username If username = "john" Then Return "doe" Else
620
The Complete Reference To Professional SOA with Visual Studio 2005
Throw New ApplicationException End If End Function End Class End Namespace
The key in implementing custom username token validation is in inheriting from the UsernameTokenManager class and then overriding the AuthenticateToken function (see listing 15-18, and listing 15-19). The AuthenticateToken function is the method that is executed when used during validation. The requesting user token is passed into the function. Here we can perform our custom functions whether it is from a flat file, database or a XML file. The password once retrieved needs to be returned in which case WSE will compare with the password that is contained in the token. The advantage of this is sometimes the password that is passed in might be hashed. We are abstracted from the complexity involved in different client security policy implementations by WSE. It is important to note that we will need to throw an exception if password can not be found. As sometimes a developer simply returns an empty string due to pure habit. This is a risk as the requesting application may also send a blank string as a password field. Once the CustomUsernameTokenManager class is created and compiled, it must be registered as a security token manager using the WSE configuration utility. We would deploy this assembly into the bin directory of our web service application and fill out the Security tab in the WSE configuration dialog to point to our custom CustomUsernameTokenManager assembly. In Visual Studio 2005, right-click the application project and select WSE Settings 3.0.
Figure 5-23. WSE Security Tab
1.
On the Security Tab, under Security Tokens Managers select Add
621
The Complete Reference To Professional SOA with Visual Studio 2005
2. Set the Type name as: AuthenticationManager.CustomUsernameTokenManager 3.
Set the Namespace to: http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd
4.
Set the LocalName as: UsernameToken
The type attribute field requires fully qualified type name, followed by the assembly name. The namespace declaration and the LocalName attribute must be listed exactly as shown.
Figure 15-24. Add a SecurityToken Manager
5.
Click OK to close the SecurityToken Manager and then OK again to close the WSE Settings dialog.
The settings in WSE settings will add the securityTokenManager into the Web.config file see listing 15-20 below. Listing 15-20. Web.config
622
The Complete Reference To Professional SOA with Visual Studio 2005
Our custom usernameTokeManager is added as a type in the Web.config configuration file, the type of the SecurityTokenManager is comprised of the namespace and class implementing the handler and the name of the assembly containing the class, without extension. In the listing below we will be adding a Web Reference to the WSE enabled Web Service the reference will be named as WSEProxy. Listing 15-21. Demonstrates the client code required to access the Web service in Visual C# using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using Microsoft.Web.Services3.Security.Tokens; using Microsoft.Web.Services3;
623
The Complete Reference To Professional SOA with Visual Studio 2005
public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { WSEProxy.ServiceWse proxy = new WSEProxy.ServiceWse(); try { UsernameToken token = new UsernameToken("john", "doe", PasswordOption.SendPlainText); proxy.SetClientCredential(token); proxy.SetPolicy("usernameTokenSecurity"); string strReturn = proxy.HelloWorld(); Response.Write(strReturn); } catch (Exception ex) { String strError = ex.Message; Response.Write(strError); } } }
Listing 15-22. Demonstrates the client code required to access the Web service in Visual Basic .NET Imports System Imports System.Collections.Generic Imports System.Text Imports Microsoft.Web.Services3.Security.Tokens Namespace CSConsoleClient Public Class Program Shared Sub Main() Dim proxy As WSEProxy.ServiceWse = New WSEProxy.ServiceWse Try Dim token As UsernameToken = _ New UsernameToken("john", "doe", _ PasswordOption.SendPlainText) proxy.SetClientCredential(token) proxy.SetPolicy("usernameTokenSecurity") Dim strReturn As String = proxy.EmployeeSalaryDetail("123") Console.WriteLine(strReturn) Console.ReadLine() Catch ex As Exception Dim strError As String = ex.Message Console.WriteLine(strError) Console.ReadLine() End Try End Sub
624
The Complete Reference To Professional SOA with Visual Studio 2005
End Class End Namespace
The client code used to access the Web service is the same as that from the previous example.
Figure 15-25. Shows the result from the execution.
X. 509 Certificate X.509 is used in cryptography. It is an International Telecommunication Union (ITU-T) standard which is used for Public Key Infrastructure (PKI). X.509 most known for specifying standard formats for public key certificates and a certification path for validation algorithm. X.509 replaces user IDs and passwords with digital certificates. A trusted third party Certificate Authority (CA) is an entity which issues digital certificates for use by other parties. X.509 refers to an authentication scheme built around public key encryption. With X.509, a trusted, third-party CA assigns each user a signed digital certificate and a pair of encryption keys, a public key and a private key. X.509 digital certificates are widely used as a basis for securing communications between separate endpoints. For example, they are used to support the HTTP Secure Sockets Layer (SSL) protocol, otherwise known as HTTPS. We will be working directly with the X.509 certificates. We can obtain a test certificate in several ways, making a certificate using the makecert.exe command-line tool to generate a test certificate or obtaining a test certificate from VeriSign, WSE 3.0 also comes with test certificates that we can use.
The X.509 Certificate Management Tool In order to manage our certificates we need to be able to install them and remove them when necessary. The Microsoft Management Console (MMC) Certificates snap-in tool can be used to manage certificates. The X.509 Certificate tool allows us to display details about X.509 certificates stored on the local computer and to set permissions on the files containing the keys for an X.509 certificate. The Certificates snap-in also allows us to, among other tasks, import and export X.509 certificates on a local computer. In the following examples we will be using the WSE test certificates, these certificates are installed with WSE 3.0 quickstart (the WSE 3.0 quickstart is included on the source for download from the book Web site). 1.
Open a new MMC console by clicking Start -> Run
2.
In the Run box, type mmc, and then click OK.
3.
The MMC console window should now appear on the File menu, click Add/Remove Snap-in, and then click Add.
4.
The Add Standalone Snap-in Under Snap-in, double-click Certificates.
625
The Complete Reference To Professional SOA with Visual Studio 2005
5.
Click My user account, and then click Finish. This allows us to manage certificates for the current user. Certificates – Current User appears on the list of selected snap-ins for the new console.
6.
While the Add Standalone snap-in is still open under Snap-in, add another Certificates snap-in by doubleclicking on the Certificates.
7.
Add the computer Computer Management snap in, by selecting Add and then selecting Computer Management from the list of possible snap ins. Click Add, click Local computer, and then click Finish.
8.
Click Close to close the Add Standalone Snap-in and OK to close the Add/Remove Snap-in dialog windows. This will allows us to manage local computer certificates.
9.
To save this console, on the File menu, click Save.
Figure 15-26. Shows using the certificates tool in MMC
TIP: The certificates that are displayed are installed by default when you install WSE 3.0
WSECertificate3.exe WSE also comes with a X.509 certificate tool (WSECertificate3.exe). The X.509 Certificate tool displays details about X.509 certificates stored on the local computer. This information helps us diagnose configuration issues related to X.509 certificates. The WSECertificate3.exe tool allows us to View details about an X.509 certificate and view the attributes of the file containing the private key for an X.509 certificate. To run the X.509 Certificate tool 1.
Click Start, point to All Programs, point to Microsoft WSE 2.0, and then click X.509 Certificate Tool.
626
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 15-27. Shows the WSE X.509 Certificate Tool.
To view details about an X.509 certificate 2.
Enter the Certificate Location and Store Name for the X.509 certificate.
3.
Click Open Certificate.
4.
Choose the X.509 certificate, and then click OK.
To view the attributes of the file containing the private key for an X.509 certificate 5.
Enter the Certificate Location and Store Name for the X.509 certificate.
6.
Click Open Certificate.
7.
Choose the X.509 certificate, and then click OK.
8.
Click View Private Key File Properties.
A dialog box appears with file properties for the file containing the private key associated with the X.509 certificate. We can use this dialog box to give permission to the user account that the WSE is running under by doing the following: 1.
Click the Security tab.
2.
If the user account that the WSE is running under is not listed in the Group or user names list, click Add.
3.
The Select Users, Computers, or Groups dialog box appears.
627
The Complete Reference To Professional SOA with Visual Studio 2005
4.
In the Enter the object names to select box, type the name for the user account that the WSE is running under, and then click OK.
5.
Select the Allow check box for the Read permission.
6.
Click OK.
Sign and Encrypt a SOAP Message (End-To-End Security) WSE allows us to add encryption and signatures to outgoing messages. Signatures are generated using a specified security token object. All security token types supported by WSE can be used to sign a SOAP message. Though, not all instances of a token object support signing. Securing the communication channel between the client and the service is very important. We can enable security through the use of certificates by using the usernameForCertificateSecurity WSE 3.0 turnkey assertions. This will enable message level security or End-To-End security by providing data confidentiality to prevent eavesdropping. Message origin authentication can also be validated to prevent tampering or message spoofing. Message level security is implemented by using the service’s X.509 certificate. The usernameForCertificateSecurity turnkey assertion can be used to secure the communication channel. However this is not compatible with client computers that have implemented WS-Security 1.0. This is because the usernameForCertificateSecurity turnkey assertion depends on the ability to reference elements as security tokens, and enables the option for signature confirmation to correlate a response message with the request that prompted it. Both of these features are only available in WS-Security 1.1. If we need to implement security at message level between client and service with a solution that is compatible with WS-Security 1.0 we will need to implement this by creating a custom policy assertion. We can configure both the Web service implementing WSE as well as the WSE client application to implement Sign and Encrypt simply by modifying the policy we had created earlier by using the WSE configuration tool. Because we have selected to Sign and Encrypt our messages WSE will prompt us to enter our X.509 certificate. To configure policy support to use Sign and Encrypt in WSE 3.0-enabled Visual Studio 2005 project we will be using the example we had created earlier with token authentication.
Configuring WSE Web service to Sign and Encrypt 1.
In Visual Studio 2005, right-click the application project and select WSE Settings 3.0.
2.
On the Policy tab, select the Enable Policy checkbox. Selecting this setting adds a policy cache file with the default name wse3policyCache.config.
3.
Under Edit Application Policy, click Add, and then type a policy friendly name for the new application policy, such as "usernameTokenSecurity."
4.
Click OK to start the WSE Security Settings Wizard, and then click Next.
5.
On the Authentication Settings page, the wizard provides a choice to secure a service application.
6.
The wizard also provides a choice of authentication methods in the same step. Select Username, and then click Next.
628
The Complete Reference To Professional SOA with Visual Studio 2005
7.
On the Optionally Provide Users and Roles page, click Next to continue.
8.
On the Message Protection page, we can configure options for message protection. We will select “Sign and Encrypt”. This will automatically use the usernameForCertificateSecurity policy assertion.
Figure 15-28. WSE Message Protection
9.
Click Next.
10. We will now come to a Server Certificate configuration page. On the Store Location choose LocalMachine. And Click on Select Certificate.
Figure 15-29. Selecting a X.509 Certificate
11. Select the WSE2QuickStartServer certificate then click OK. Then Next.
629
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 15-30. WSE Server Certificate configuration
12. On the Create Security Settings page, review the settings, and then click Finish. 13. Click OK to close the WSE Settings dialog window.
Configuring WSE Client Application to Sign and Encrypt In order to implement secure communication we must implement security on both sides. Using the WSE settings tool the steps are the same as that of configuring for WSE service. The only difference is we need to select Client during the Authentication Settings step in the policy configuration. Here are the steps to implementing security on the client side. 1.
In Visual Studio 2005, right-click the application project and select WSE Settings 3.0.
2.
On the Policy tab, select the Enable Policy checkbox. Selecting this setting adds a policy cache file with the default name wse3policyCache.config.
3.
Under Edit Application Policy, click Add, and then type a policy friendly name for the new application policy, such as "usernameTokenSecurity."
4.
Click OK to start the WSE Security Settings Wizard, and then click Next.
5.
On the Authentication Settings page, the wizard provides a choice to secure a Client.
6.
The wizard also provides a choice of authentication methods in the same step. Select Username, and then click Next.
7.
On the Optionally Provide Username and Password page, click Next to continue.
8.
On the Message Protection page, we can configure options for message protection. We will select “Sign and Encrypt”. This will automatically use the usernameForCertificateSecurity policy assertion.
9.
Click Next.
630
The Complete Reference To Professional SOA with Visual Studio 2005
10. We will now come to a Server Certificate configuration page. On the Store Location choose LocalMachine. And Click on Select Certificate. 11. Select the WSE2QuickStartServer certificate then click OK. Then Next. 12. On the Create Security Settings page, review the settings, and then click Finish. 13. Click OK to close the WSE Settings dialog window. Listing 15-23. Demonstrates the signed and encrypted request SOAP Message
. . .
2006-06-14T06:47:07Z 2006-06-14T06:52:07Z
. . .
fHa41bEoBYaCAV/QUp7bNFJtOJM=
. . .
Listing 15-24. Demonstrates the signed and encrypted response SOAP Message
/7vTIR7+xHJb+TvPrmohsg3pPos=
. . . .
l1EsdLhBi2jilH9iy0uzfZsT0+w=
cVOlLPE71rdX7y8+x4affGu+YXQ=
Best Security Practice The securest method of transmitting message is setting message protection level to Sign, Encrypt, Encrypt Signature. This means that we will sign the message to ensure integrity, as well as encrypt the SOAP message but WSE will also encrypt the signature themselves to provide additional level of security.
Figure 15-31. Message Protection, Signing, Encrypting, Encrypt Signature
While when sending user token details across the wire. Instead of specifying to send the Password as a plain text we can also specify to send the password as a Hashed value. UsernameToken token = new UsernameToken("BookUser", "BookUser", PasswordOption.SendHashed); To add wired security we can specify IIS to implement SSL/HTTPS. All of these options when combined provide the optimum security solution when sending data across the wire in a service-oriented environment.
Note: Using Signing and Encryption will have an impact on the performance as it takes resource to encrypted and signed SOAP message. As the amount of data that we send to the Web service increase so too does the time it takes to encrypt and decrypt.
Binary Exchange with Message Transmission Optimization Mechanism (MTOM) In spite of the flexibility and acceptance of XML in application architecture, there are certain limitations associated with XML. These limitations are for example media data and data that includes digital signatures are
633
The Complete Reference To Professional SOA with Visual Studio 2005
two of the most common examples. The reason is with media data there are highly standardized formats where compression plays a major part. While for digital signatures, the binary integrity required would not be preserved if it were serialized into a structured XML format. At the same time serializing binary data proved to be extremely resource intensive. As a result there are various methods for sending binary data through the use of Web services. These are: *
XML Representation: Replace any non-Xml data with a structured XML representation and include it in our message. The problem here is that it bloats the data tremendously. However, if we are sending something like Microsoft Word documents, we might want to consider saving them in XML format.
*
SOAP with Attachments (SwA): Use SOAP with Attachments to send binary data with SOAP in a MIME Multipart message. SOAP with Attachments was the first attempt by Microsoft (along with Hewlett Packard) at solving the opaque data/attachments problem. Unfortunately SwA had poor composability and it did not work well with the WS-* specifications.
*
WS-Attachments with DIME: Compared to SOAP with attachments this is a faster and more efficient solution to sending binary data. However it also has the same composability issues as SwA. As in the case with SwA, it does not use a SOAP envelope approach to messaging. This limits DIME’s ability of the higher-level Web service specifications to properly work upon a message.
*
Base 64 Encoding: This method of encoding has been used for quite sometime and is well known for its binary data problem. Although base-64-encoded data is usually more efficient from a message-size perspective than using XML Representation, it still increases the data size by about 33% even when only single byte characters are used.
*
Message Transmission and Optimization Mechanism (MTOM): MTOM is widely accepted today in binary transport. The MTOM approach take advantage of the SOAP infrastructure, but gain the transport efficiencies provided by a SOAP with Attachments solution. MTOM is supported in WSE 3.0 and it will also be supported by the future Windows Communication Foundation (WCF) see chapter 16.
MTOM implementation combines the benefits of composability of Base 64 encoding with the transport efficiency of SwA. The binary data is dealt with just like it is with SwA it is simply streamed as binary data as one of the Multipurpose Internet Mail Extensions (MIME) message parts. MTOM utilizes what is called an XML Information Set (Infoset). Infoset allows for easy serialization/deserialization of the entire message into XML form. At the Infoset level, immediately before the message is serialized, the binary data is accessed, it is temporarily treated as base-64-encoded text. By using the Infoset, we can implement WS-Security for binary attachments. In MTOM the WS-Security layer create a digital signature for message level security. The binary data is streamed through a layer in which it is temporarily encoded to base-64. During the streaming the signature of the message is calculated. The encoded base-64 data is not transferred or held in memory. On deserialization, the same concepts apply. The raw binary is transferred directly to the higher layer, but any processing layers that access it would do so through a temporary base-64-encoding layer (see figure 15-32 below).
634
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 15-32. MTOM process
Implementing MTOM Service Implementing MTOM with WSE is quite simple. We can configure it from the WSE Settings tool. 1.
Open the Web service project in Visual Studio 2005.
2.
In Solution Explorer, right-click the project name, and then click WSE Settings 3.0….
3.
Select the General tab.
635
The Complete Reference To Professional SOA with Visual Studio 2005
4.
Select Enable this project for Web Services Enhancements and Enable Microsoft Web Services Enhancements SOAP Protocol Factory.
5.
To enable our Web service to use MTOM select the Messaging tab.
6.
Choose always for the Server Mode (see figure 15-32).
Figure 15-32. Enabling MTOM
There are several options under the Server Mode drop down list. Optional, Alaways and Never. The optional MTOM Mode specifies that WSE processes all incoming SOAP messages whether or not they are MTOM encoded and that all SOAP responses and SOAP faults are MTOM encoded. The Sever Mode for the option always specifies MTOM encoding will be applied to all incoming and outgoing SOAP messages. And if a SOAP request is received that is not encoded using MTOM, a SOAP fault is returned to the sender. Select Off for Client Mode and leave MaxMimeParts at 64 and check Require Soap Evelope First Click OK to close the WSE settings Dialog This adds an Element to the Web service's Web.config file. Having done the above steps we can start utilizing MTOM immediately. All that we need to do is add a Web service method that has a parameter or return value with a type that is either a byte array or a type that contains a byte array. MTOM will be used automatically as the byte data is sent across the wire. The following code example shows a Web service method that returns a byte array using the contents from a file on disk and then returns it in the SOAP message. Listing 15-25. Demonstrates the service using Visual C#
636
The Complete Reference To Professional SOA with Visual Studio 2005
using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; using System.IO; [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class Service : System.Web.Services.WebService { public Service () { //Uncomment the following line if using designed components //InitializeComponent(); } [WebMethod] public byte[] GetFile(string fileName) { byte[] response; String filePath = AppDomain.CurrentDomain.BaseDirectory + @"App_Data\" + fileName; response = File.ReadAllBytes(filePath); return response; } }
Listing 15-26. Demonstrates the service using Visual Basic .NET using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; using System.IO; [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class Service : System.Web.Services.WebService { public Service () { //Uncomment the following line if using designed components //InitializeComponent(); } [WebMethod] public byte[] GetFile(string fileName) { byte[] response; String filePath = AppDomain.CurrentDomain.BaseDirectory + @"App_Data\" + fileName; response = File.ReadAllBytes(filePath);
637
The Complete Reference To Professional SOA with Visual Studio 2005
return response; } }
By default the amount of data sent or received by the Web service is set at a limit of 4 MB to exceed 4 MB, configure the Web server to handle the larger amount of data by modifying the Web.config file. We can increase the ASP.NET limits on the maximum size of SOAP messages and the maximum number of seconds that a request is allowed to execute by adding the configuration element to the application's web.config file. The following code example will set the ASP.NET limit for the maximum size of an incoming request to 400MB, and the maximum amount of time a request is allowed to execute to 5 minutes (300 seconds).
To cater for large files we will also need to increase the WSE limit on the maximum size of SOAP messages using the Element. To send and receive the largest possible SOAP messages, set the value of the element to -1. The following code example disables the limit on the maximum size of SOAP messages by WSE.
Listing 15-27. Demonstrates a complete Web.config
638
The Complete Reference To Professional SOA with Visual Studio 2005
Implementing MTOM Client Implementing MTOM for a client is quite straight forward. As all of the real hard work is taken care of by WSE. We do not need to do anything special aside from using the WSE proxy to facilitate communication between the Client and the Server. 1.
Open the Web service project in Visual Studio 2005.
2.
In Solution Explorer, right-click the project name, and then click WSE Settings 3.0….
3.
Select the General tab.
4.
Select Enable this project for Web Services Enhancements.
5.
To enable our Web service to use MTOM select the Messaging tab.
6.
Choose always for the Server Mode.
7.
Select On for Client Mode and leave MaxMimeParts at 64 and check Require Soap Evelope First
8. Click OK to close the WSE settings Dialog This adds an Element to the client application’s app.config file. The following settings are added to the App.config file. Listing 15-28. The client appliaction’s App.config after configuration
http://localhost:4529/MTOMService/Service.asmx
Having done the above steps we can start utilizing MTOM immediately. The following code example shows a client application requesting for the GetFile WebMethod. Because we are using MTOM WSE will manage the retrival of the byte array automatically. The byte array will be retrieved from the Web service and written to hard disk on the client side. Here’s the client implementing below. Listing 15-29. Demonstrates MTOM client using Visual C# using System; using System.Collections.Generic; using System.Text; using System.IO; namespace MTOMClient { class Program { static void Main(string[] args) { WSEProxy.ServiceWse wseproxy = new MTOMClient.WSEProxy.ServiceWse(); byte [] content = wseproxy.GetFile("test.txt"); File.WriteAllBytes("test.txt", content); } } }
640
The Complete Reference To Professional SOA with Visual Studio 2005
Listing 15-30. Demonstrates MTOM client using Visual Basic .NET Imports System Imports System.Collections.Generic Imports System.Text Imports System.IO Module Module1 Sub Main() Dim wseproxy As WSEProxy.ServiceWse = _ New VBMTOMClient.WSEProxy.ServiceWse() Dim content As Byte() = wseproxy.GetFile("test.txt") File.WriteAllBytes("test.txt", content) End Sub End Module
Summary In this chapter we have explored using WSE to implement WS-Security. The WS-Security specification defines SOAP extensions for message integrity, message confidentiality, and single message authentication. These mechanisms can be used to accommodate a wide variety of security models and encryption technologies. WSSecurity is implemented at the message level rather than transport. Using WSE we have implemented message authentication using security tokens based on username and password. We have also implemented digital signature and encryption using X.509 certificates. The best method of security is through a combination of security over transport using SSL/HTTPS (poingto-point security) as well as SOAP message signing and encryption (end-to-end security). In this chapter we have also examined Message Transmission Optimization Mechanism (MTOM). MTOM combines the composability of Base 64 encoding with the transport efficiency of SOAP with Attachment (SwA). MTOM is the new binary standard that will be supported by Windows Communication Foundation (WCF). Using WSE 3.0 will give us a lot more communication security options. WSE 3.0 supports the latest WS-* specifications. The same ones will be supported by Windows Communication Foundation. This makes WSE 3.0 and WCF wire-compatible and thus allow WCF clients to interoperate with WSE 3.0 services and vice versa.
641
The Complete Reference To Professional SOA with Visual Studio 2005
Chapter 16. Windows Communication Foundation (WCF) Windows Communication Foundation (formerly code-named "Indigo") is a new set of .NET technologies that revolutionizes building and running connected systems. WCF provides a new breed of communications infrastructure that views all distributed components as a service. The heart of WCF is built around the Web services architecture. Advanced Web services support in Windows Communication Foundation provides secure, reliable, and transacted messaging along with interoperability. Microsoft endeavored to improve the serviceoriented landscape and with the aim to improve programming model and development efficiency of distributed service development through the use of WCF. WCF is built on the .NET Framework and unifies a broad array of distributed systems capabilities in a composable and extensible architecture, spanning transports, security systems, messaging patterns, encodings, network topologies, and hosting models. Windows Communication Foundation is an exciting technology because it removes the need to explicitly choose the technology that we need to use up-front. In the past developers are required to contend with a variety of different technology choices for building distributed applications. These include XML Web services (ASMX), Web Services Enhancements (WSE), .NET Remoting, Microsoft Message Queue (MSMQ) and Enterprises Services (COM+). All of these different technologies complement each other in different ways. As a result developers and architects are faced with the daunting task of balancing the pros and cons of each technology before development. Making the wrong choice in technology at the beginning could have a significant impact later on. Developing with WCF however is different. WCF is very robust because it has a programming model which combines different technologies into a single Service-oriented programming model for distributed computing. WCF also unifies a wide range of transports (HTTP, TCP, UDP, IPC), security mechanisms (public and symmetric keys, certificates), topologies (point-to-point, end-to-end, peer-to-peer, publish-and-subscribe), and assurances (transacted, reliable, durable) all of this provide WCF with rich connectivity to many existing systems. In this chapter we will cover the fundamentals of WCF. We will also learn to develop secure, reliable WCF service as well as WCF Client. Some of the things that we will cover includes: *
Implementing WCF Service
*
Implementing A WCF Service Client
*
Developing a hosting environment from which WCF service can be launched.
*
Implementing Custom Binding, Reliable Mesasging and Security
*
Implementing WCF with Microsoft Message Queue
*
WCF Sessions
*
WCF Transactions
*
Duplex Communication
642
The Complete Reference To Professional SOA with Visual Studio 2005
Note: In order to compile the examples in this chapter you will need to download “WinFx Runtime” which can be found when you search at http://www.microsoft.com/download/. Once the runtime has been installed “Orcas” which contains the Development Tools for WinFX should also be installed. Orcas can also be found at http://www.microsoft.com/download/.
WCF Foundamentals A WCF Service is a program that exposes a collection of Endpoints. Each Endpoint is a portal for communicating with the world. A WCF endpoint is composed of three parts, address, binding and contracts. These are also referred to as the ABCs of WCF see figure 16-1.
Figure 16-1. ABCs of Windows Communication Foundation
*
"A" stands for Address - Refers to where is the the service located? The Address is a network address where the Endpoint resides. It can be a URI, an Identity or a collection of headers. The headers are used to provide additional addressing information beyond the Endpoint's URI. For example, address headers are useful for differentiating between multiple Endpoints that share the same address URI.
643
The Complete Reference To Professional SOA with Visual Studio 2005
*
"B" stands for Binding – Refers to how do we communicate with the service? The Binding specifies how the Endpoint communicates with the world including things like transport protocol (TCP, HTTP), encoding (text, binary), and security requirements (SSL, SOAP message security). A Binding has a name, a namespace, and a collection of composable binding elements. The Binding's name and namespace uniquely identify it in the service's metadata. Each binding element describes an aspect of how the Endpoint communicates with the world. Each BindingElement defines how to communicate with the Endpoint. The TcpTransportBindingElement indicates that the Endpoint will communicate with the world using TCP as the transport protocol. ReliableSessionBindingElement indicates that the Endpoint uses reliable messaging to provide message delivery assurances. SecurityBindingElement indicates that the Endpoint uses SOAP message security. Each binding element usually has properties that further describe the specifics of the how to communicating with the Endpoint.
*
"C" stands for Contract – Refers to what can the service do for us? The Contract specifies what the Endpoint communicates to the outside world. Each operation is a simple message exchange, for example one-way or request/response message exchange. The ContractDescription class is used to describe WCF Contracts and their operations. Inside a ContractDescription, exist a Contract operation has a corresponding OperationDescription. This describes aspects of the operation such as whether the operation is one-way or request/ response. Each OperationDescription also describes the messages that make up the operation using a collection of MessageDescriptions.
Contracts In WCF we can define several different types of contracts. *
ServiceContract - A service contract resides on the service side to specify which of the service’s endpoint should be exposed to callers. It is also used on the client side to specify the contract of the endpoint with which the client communicates and, in the case of duplex contracts, to specify the callback contract that the client must implement in order to participate in a duplex conversation.
*
OperationContract - The OperationContract declares that a method is an operation in a service contract. In the WCF model we must explicitly mark all operations that we want to expose. Only methods decorated with the OperationContract attribute are exposed as service operations. A service contract without any methods marked with the OperationContract attribute exposes no operations.
*
DataContract – The data contract provide information about the items that flow across service boundaries.
*
FaultContract - The FaultContract attribute is used to declare one or more specific exception conditions that are added to the Web Service Description Language (WSDL) description of the method as explicit SOAP fault messages returned by the method.
*
MessageContract- MessageContract attribute defines the structure of the message types our service uses.
Defining Service Contracts A ServiceContract defines what application interface will be exposed as a WCF service. WCF follows the service-orientation of "explicit boundaries". Which means unless we explicitly tell the runtime to do so nothing is exposed through WCF. WCF implements the model which strictly distinguishes between elements that are made visible and accessible to the outside world (all publicly accessible elements must be explicitly specified) and those without decorated explicit attributes to expose functionalities are private to the application. The "public", "private" and "protected" keywords of C# and Visual Basic and the underlying access protection mechanisms are meaningful to the code inside an application, but whether an interface or method that's public
644
The Complete Reference To Professional SOA with Visual Studio 2005
within the scope of an application shall indeed be publicly visible to the outside world is an entirely different matter altogether. However, there might cases where it is desirable to enforce that a method that's designed exclusively for accessing the application from the outside is not accidentally invoked from within the application. Under such circumstances, a method might be best declared as "private" towards the inside of the application, but is indeed made accessible to outside callers.
Listing 16-1. Demonstrates an example of implementing Service Contract using Visual C# using System.ServiceModel; [ServiceContract] public interface ICalculate { [OperationContract] double Add( double a, double b); [OperationContract] double Subtract( double a, double b); }
Listing 16-2. Demonstrates an example of implementing Service Contract using Visual Basic .NET Imports System.ServiceModel _ Public Interface ICalculate _ Function Add(ByVal a As Double, ByVal b As Double) As Double _ Function Subtract(ByVal a As Double, ByVal b As Double) As Double End Interface
Here the interface has been labeled with the [ServiceContract] attribute. That attribute explicitly marks a CLR interface as to carry contract metadata for WCF. Each method is explicitly labeled with the [OperationContract] attribute, which is the WCF equivalent to a "public" method. Based on the existence and the additional, optional parameters that can be supplied to these metadata attributes, the WCF runtime can, whenever required, turn the [ServiceContract] into an equivalent WSDL portType declaration. Each [OperationContract] declaration is then mapped to an equivalent WSDL operation definition whereby the parameter lists and return values are turned into XML schema declarations reference by the WSDL types section and the respective WSDL message mappings.
Defining Data Contracts The data contract defines the shape and rules for the data that is exchanged through operation's input and output messages. The split between the data contract and the service contract is important. Service contracts define the logic and semantic related set of operations grouped on an interface and these are about how a service behaves. The data contract defined information items that flow across service boundaries and that are handled with additional logic on the provider and consumer side.
645
The Complete Reference To Professional SOA with Visual Studio 2005
Listing 16-3. Demonstrates implementing DataContract using C# [DataContract] public class Person { [DataMember] public int Id; [DataMember] public string FirstName; [DataMember] public string LastName; }
Listing 16-4. Demonstrates implementing DataContract using VB _ Public Class Person _ Public Id As Integer _ Public FirstName As String _ Public LastName As String End Class
Above is a data contract for a person. The attributes stem from the System.Runtime.Serialization namespace that is the home of the new XmlFormatter infrastructure. The XmlFormatter is similar to the XmlSerializer (as well as the BinaryFormatter and SoapFormatter) in purpose, but there are quite few differences. The most significant difference between the XmlFormatter and the XmlSerializer is that the new infrastructure intentionally provide less control for developers over the XML schema and the way how data is serialized to and deserialized from XML. That may seem strange at first consideration we typically get increased control and flexibility. But this was the result of a trade off decision. We are now trading detail control for automatic versioning support of messages in the new versioning in WCF model. WCF’s versioning model provide an easier way of implementing loosely coupled, evolvable data structures. To take advantage of this new functionality, we will have to surrender some control over the schema details to the formatter infrastructure. The new XmlFormatter does not allow a data contract to be defined as XML attributes and elements. All data is always serialized into XML elements. Changes to a data contract can be breaking or nonbreaking. When a data contract is changed in a nonbreaking way, an application using the older version of the contract is able to communicate with an application using the newer version, and an application using the newer version of the contract is able to communicate with an application using the older version. On the other hand, a breaking change prevents communication in one or both directions. Any changes to a type that do not affect how it is transmitted and received are nonbreaking. Such changes do not change the data contract, only the underlying type. For example, we can change the name of a field in a nonbreaking way if we then set the Name property of the DataMember to the older version name. The following code shows version 1 of a data contract.
Listing 16-5. Demonstrates implementing Versioning in Visual C# // Version 1
646
The Complete Reference To Professional SOA with Visual Studio 2005
[DataContract] public class Person { [DataMember] private string Phone; }
Listing 16-6. Demonstrates implementing Versioning in Visual Basic ' Version 1 _ Public Class Person _ Private Phone As String End Class
The following code shows a nonbreaking change: Listing 16-7. Demonstrates implementing Versioning in Visual C# // Version 2. This is a non-breaking change because the data contract // has not changed, even though the type has. [DataContract] public class Person { [DataMember(Name = "Phone")] private string Telephone; }
Listing 16-8. Demonstrates implementing Versioning in Visual Basic .NET ' Version 2. This is a non-breaking change because the data contract ' has not changed, even though the type has. _ Public Class Person _ Private Telephone As String End Class
In versioning we can also force a check for a particular DataMember by using the IsRequired attribute. Listing 16-9. Demonstrates implementing Versioning in Visual C# [DataContract] public class Person { [DataMember] public int Id; [DataMember] public string FirstName; [DataMember] public string LastName;
647
The Complete Reference To Professional SOA with Visual Studio 2005
[DataMember(IsRequired = true)] public string MiddleName; }
Listing 16-10. Demonstrates implementing Versioning in Visual Basic .NET _ Public Class Person _ Public Id As Integer _ Public FirstName As String _ Public LastName As String _ Public MiddleName As String End Class
We can tell the XmlFormatter infrastructure to treat the newly introduced member as an optional member by labeling the new member with the IsRequired property on the [DataMember] attribute set to false. That means that if we receive data serialized by an older version of the contract (which might be embedded in a client proxy), the member will remain with its value upon deserialization and the newer version will gracefully accept an older version's input where this element is missing. If IsRequired is set to true and the respective element is missing in the deserialization input, an exception is raised.
RPC/Messaging WCF was created to improve on the existing model of service-orientation. As such WCF focuses on the serviceorientation idea that services exchange messages rather than procedure calls. Unlike the ASMX “stateless” service model WCF also support sessions which allows detailed control over the lifetime of a service instance. As such we can build services where instances are created and released for each call or a defined sequence of calls, where instances exist for the duration of a session, or we can even build singletons where one service instance is shared by all callers. What we cannot do, is to pass objects by reference or pass callback delegates this contrasts Remoting. The reason for this restriction is that a service-oriented technology cannot make as many assumptions about the network as the local area network technologies such as Remoting. In an environment where services can be easily separated across platforms, trust boundaries and wide area networks we can not assume that bi-directional connectivity is possible. Clients can also reside behind firewalls, or networks that utilize network address translation (NAT) or simply do not actively listen for messages or security restrictions may restrict the sending of calls. Therefore, implicit backchannels such as those established by callbacks and object references simply don't work in a services world. Instead, such backchannels must be explicitly established using so-called "duplex" conversations. In WCF we can implement a "typed message". A typed message is essentially like a typed DataSet. It is an explicitly composed message structure that is labeled with a [MessageContract] attribute as shown in listing 16-9 and listing 16-10 has zero or more [MessageHeader] members and zero or more [MessageBody] members. The [MessageHeader] members are mapped to headers in the SOAP envelope while [MessageBody] members are represented as elements within the SOAP envelope's body section see listing 16-9 and listing 16-10 below. Listing 16-9. Demonstrates implementing MessageContract and MessageBody in Visual C# public enum UpdateConcurrency
648
The Complete Reference To Professional SOA with Visual Studio 2005
{ UpdateIfModified, FailIfModified } [DataContract] public class UpdateBehavior { [DataMember] public UpdateConcurrency UpdateConcurrencyMode; } [MessageContract] public class StorePersonMessage { [MessageHeader] public UpdateBehavior UpdateBehavior; [MessageBody] public Person Person; } [ServiceContract] public interface IPeople { [OperationContract] void StorePerson(StorePersonMessage storePersonMessage); }
Listing 16-10. Demonstrates implementing MessageContract and MessageBody in Visual Basic .NET Public Enum UpdateConcurrency UpdateIfModified FailIfModified End Enum _ Public Class UpdateBehavior _ Public UpdateConcurrencyMode As UpdateConcurrency End Class _ Public Class StorePersonMessage _ Public UpdateBehavior As UpdateBehavior _ Public Person As Person End Class _ Public Interface IPeople _
649
The Complete Reference To Professional SOA with Visual Studio 2005
Sub StorePerson(ByVal storePersonMessage As StorePersonMessage) End Interface
We can also define message contract in an “inline” manner by specifying the operation’s parameter list. This is useful if we want to add some additional information in the SOAP header but we don’t want to define an explicit message class. Any parameter that has been labeled with MessageHeader attribute will be mapped to the envelope’s header section. We can similarly specify other parameters to be added to the SOAP body by decorating parameters with the MessageBody attribute. See listing 16-11 and listing 16-12. Listing 16-11. Demonstrates implementing inline message contract using Visual C# [OperationContract] void StorePerson( [MessageHeader] UpdateBehavior UpdateBehavior1, [MessageBody] Person Person1);
Listing 16-12. Demonstrates implementing inline message contract using Visual Basic .NET _ Sub StorePerson( ByVal UpdateBehavior1 As UpdateBehavior, _ ByVal Person1 As Person)
If we need additional control over the Message’s content. We can use the System.ServiceModel.Message argument with our operation. This provides us with immediate access to the WCF Message see listing 16-13 and listing 16-14 below. The Message class exposes all headers in a collection where we can examine the content of a range of special headers such as those relevant for security and addressing. The body of the content is represented as an XmlReader. Listing 16-13. Demonstrates implementing Message argument using Visual C# [ServiceContract] public interface IPeople { [OperationContract] public void StorePerson(Message msg); }
Listing 16-14. Demonstrates implementing Message argument using Visual Basic .NET _ Public Interface IPeople _ Sub StorePerson(msg As Message) End Interface
WCF is responsible for dispatching the messages to the correct operation. Messages that are received that do not have a matching Action header to the contract’s OperationContract Attribute are rejected. If we would like to accept all messages regardless of their Action header we can set a wildcard indicator which is represented by a single asterisk (“*”). If this operation is present, all messages that cannot be matched are sent to this operation. Which results in more flexibility to the SOAP messaging endpoint.
650
The Complete Reference To Professional SOA with Visual Studio 2005
Listing 16-15. Demonstrates using Action wildcard attribute using Visual C# [ServiceContract] public interface IMyMessageHandler { [OperationContract(Action="*")] public void HandleAnyMessage(Message message); }
Listing 16-16. Demonstrates using Action wildcard attribute using Visual Basic .NET _ Public Interface IMyMessageHandler Public _ Sub HandleAnyMessage(message As Message) End Interface
Binding and Address (Endpoint) The endpoint binding defines what protocols, transport, and encoding the endpoint will use for all its communication and defines how securities work. WCF provides several predefined binding models. These are a combination of transports, encodings and behaviors. These predefined models allow us in most cases to simply select one of these predefined bindings. If required we can also implement custom binding. See table 16-1 below which shows several predefined binding models that we can use. Table 16-1. Binding Models
Class
Description
BasicHttpBinding
The BasicHttpBinding transports messages using HTTP
CustomBinding
Custom binding allows us to tailor our need to define a new binding from a set of binding elements.
MsmqIntegrationBinding The MsmqIntegrationBinding binding can be used to map Microsoft Message Queuing Service (MSMQ) messages to Windows Communication Foundation (WCF) messages.
NetMsmqBinding
The NetMsmqBinding binding provides support for loosely coupled applications for queuing with Microsoft Message Queue (MSMQ). This allows services to scale with failure isolation, load leveling and disconnected operations.
NetNamedPipeBinding
This binding provides a secure and reliable binding for same machine communication.
NetPeerTcpBinding
The NetPeerTcpBinding binding provides support for TCP transport. This is used to support peer-topeer or multiparty applications.
NetTcpBinding
The NetTcpBinding creates a run-time communication stack by default. NetTcpBinding utilizes WSReliableMessaging for reliability. It also ensures message security and authentication by using Windows
651
The Complete Reference To Professional SOA with Visual Studio 2005
Security. NetTcpBinding uses TCP for message delivery, and a binary message encoding.
WSDualHttpBinding
This binding uses HTTP for message delivery. The WSDualHttpBinding create a runtime stack implementing WS-ReliableMessaging for reliability, WS-Security for message security and authentication. This binding requires that the client has a public URI that provides a callback endpoint for the service.
WSHttpBinding
This binding uses HTTP for message delivery. The WSHttpBinding is used for non-duplex service contracts and provides support for securing with WS-Federation protocol.
Each of the predefined bindings supports some degree of customization of their respective features. If we examine the configuration file required when specifying a particular binding there exists a section under this section where the binding used by WCF is defined. We can add a number of named customizations to these subsections. The concrete binding that is used for an endpoint is selected by specifying the bindingSectionName and the respective bindingConfigurationName within the definition for the endpoint. Below shows an example of binding configuration in WCF.
Figure 16-35. Example architecture
Figure 16-35 demonstrates a disconnected architecture. Messages arrive at the message queue regardless of whether the Server side services are up or down. As each Order Processing Service becomes available. The order processing service application will receive orders as they come in to the queue. The orders will be processed immediately but if the order processing service is down then the queue will hold the order until the service is up again. In listing 16-36 and listing 16-37 we first check to see if the Microsoft Message Queue exists using the MessageQueue class within the System.Messaging namespace. If it does not exist then we will create a mesasge queue on the server. Listing 16-39. Creating queue in Visual C# if (!MessageQueue.Exists
702
The Complete Reference To Professional SOA with Visual Studio 2005
(ConfigurationManager.AppSettings["queueName"])) MessageQueue.Create (ConfigurationManager.AppSettings["queueName"], true);
Listing 16-40. Creating queue in Visual Basic .NET If Not MessageQueue.Exists _ (ConfigurationManager.AppSettings("queueName")) Then MessageQueue.Create _ (ConfigurationManager.AppSettings("queueName"), True)
Once we have established that the queue on the server exists then we can connect to it. We need to add an event to the ReceiveCompleted event. This is so that when MSMQ has completed receiving a message into the queue we want to be notified and we want the method ProcessOrder to be executed. Listing 16-41. Implementing ReceiveCompleted event in Visual C# MessageQueue Queue = new MessageQueue (ConfigurationManager.AppSettings["queueName"]); Queue.ReceiveCompleted += new ReceiveCompletedEventHandler(ProcessOrder); Queue.BeginReceive();
Listing 16-42. Implementing ReceiveCompleted event in Visual Basic .NET Dim Queue As MessageQueue = New MessageQueue _ (ConfigurationManager.AppSettings("queueName")) AddHandler Queue.ReceiveCompleted, AddressOf ProcessOrder Queue.BeginReceive()
The ProcessOrder function is called whenever the message queue receives a new message. To retrieve the message we can use the EndReceive function to receive the message asynchronously. Not surprisingly, the message itself is represented by an object on the queue. As such we need to cast the message back to PurchaseOrder. Listing 16-43. ProcessOrder using Visual C# MessageQueue Queue = (MessageQueue)source; // End the asynchronous receive operation. System.Messaging.Message msg = Queue.EndReceive(asyncResult.AsyncResult); msg.Formatter = new System.Messaging.XmlMessageFormatter (new Type[] { typeof(PurchaseOrder) }); PurchaseOrder po = (PurchaseOrder)msg.Body; Random statusIndexer = new Random(); po.Status = (OrderStates)statusIndexer.Next(3); Console.WriteLine("Processing {0} ", po); Queue.BeginReceive();
Listing 16-43. ProcessOrder using Visual Basic .NET Dim Queue As MessageQueue = CType(source, MessageQueue) Dim msg As System.Messaging.Message = _ Queue.EndReceive(asyncResult.AsyncResult) msg.Formatter = New System.Messaging.XmlMessageFormatter _ (New Type() {GetType(PurchaseOrder)})
703
The Complete Reference To Professional SOA with Visual Studio 2005
Dim po As PurchaseOrder = CType(msg.Body, PurchaseOrder) Dim statusIndexer As Random = New Random po.Status = CType(statusIndexer.Next(3), _ Order.MSMQ.OrderStates) Console.WriteLine("Processing {0} ", po) Queue.BeginReceive()
The service also uses an Order class library. This library is used to display information regarding the order. The client uses the same library to send data to the message queue. The class is marked as serializable and such the values contained in the class can be serialized and sent to the queue.
Listing 16-44. Shows implementing the order class using Visual C# using System; using System.Text; namespace MSMQ { // Define the Purchase Order Line Item [Serializable] public class PurchaseOrderLineItem { public string productId; public float unitCost; public int quantity; public override string ToString() { String displayString = "Order LineItem: " + quantity + " of " + productId + " @unit price: $" + unitCost + "\n"; return displayString; } public float TotalCost { get { return unitCost * quantity; } } } public enum OrderStates { Pending, Processed, Shipped } // Define Purchase Order [Serializable] public class PurchaseOrder { public string poNumber;
704
The Complete Reference To Professional SOA with Visual Studio 2005
public string customerId; public PurchaseOrderLineItem[] orderLineItems; public OrderStates orderStatus; public float TotalCost { get { float totalCost = 0; foreach (PurchaseOrderLineItem lineItem in orderLineItems) totalCost += lineItem.TotalCost; return totalCost; } } public OrderStates Status { get { return orderStatus; } set { orderStatus = value; } } public override string ToString() { StringBuilder strbuf = new StringBuilder("Purchase Order: " + poNumber + "\n"); strbuf.Append("\tCustomer: " + customerId + "\n"); strbuf.Append("\tOrderDetails\n"); foreach (PurchaseOrderLineItem lineItem in orderLineItems) { strbuf.Append("\t\t" + lineItem.ToString()); } strbuf.Append("\tTotal cost of this order: $" + TotalCost + "\n"); strbuf.Append("\tOrder status: " + Status + "\n"); return strbuf.ToString(); } } }
Listing 16-45. Shows implementing the order class using Visual Basic .NET Imports System Imports System.Text Namespace MSMQ
705
The Complete Reference To Professional SOA with Visual Studio 2005
_ Public Class PurchaseOrderLineItem Public productId As String Public unitCost As Single Public quantity As Integer Public Overloads Overrides Function ToString() As String Dim displayString As String = "Order LineItem: " & _ quantity.ToString() & " of " & productId & _ " @unit price: $" & unitCost.ToString() Return displayString End Function Public ReadOnly Property TotalCost() As Single Get Return unitCost * quantity End Get End Property End Class Public Enum OrderStates Pending Processed Shipped End Enum _ Public Class PurchaseOrder Public poNumber As String Public customerId As String Public orderLineItems As PurchaseOrderLineItem() Public orderStatus As OrderStates Public ReadOnly Property TotalCost() As Single Get Dim _totalCost As Single = 0 For Each lineItem As PurchaseOrderLineItem In orderLineItems _totalCost += lineItem.TotalCost Next Return _totalCost End Get End Property Public Property Status() As OrderStates Get Return orderStatus End Get Set(ByVal value As OrderStates) orderStatus = value End Set End Property
706
The Complete Reference To Professional SOA with Visual Studio 2005
Public Overloads Overrides Function ToString() As String Dim strbuf As StringBuilder = New StringBuilder _ ("Purchase Order: " & poNumber & Environment.NewLine) strbuf.Append(ControlChars.Tab & "Customer: " & customerId _ & Environment.NewLine) strbuf.Append(ControlChars.Tab & "OrderDetails" & _ Environment.NewLine) For Each lineItem As PurchaseOrderLineItem In orderLineItems strbuf.Append(ControlChars.Tab & ControlChars.Tab & _ lineItem.ToString()) Next strbuf.Append(ControlChars.Tab & _ "Total cost of this order: $" & TotalCost & Environment.NewLine) strbuf.Append(ControlChars.Tab & "Order status: " & _ Status & Environment.NewLine) Return strbuf.ToString() End Function End Class End Namespace
The client implementation is shown below.
Listing 16-46. Demonstrates client side implementation using Visual C# using System; using System.Collections.Generic; using System.Text; using System.Transactions; using System.ServiceModel.MsmqIntegration; using System.ServiceModel; using System.Messaging; namespace MSMQ { class Program { static void Main(string[] args) { // Create the purchase order PurchaseOrder po = new PurchaseOrder(); po.customerId = "xyz customer id"; po.poNumber = Guid.NewGuid().ToString(); PurchaseOrderLineItem lineItem1 = new PurchaseOrderLineItem(); lineItem1.productId = "Blue Widget"; lineItem1.quantity = 10; lineItem1.unitCost = 15.58F; PurchaseOrderLineItem lineItem2 = new PurchaseOrderLineItem(); lineItem2.productId = "Red Widget";
707
The Complete Reference To Professional SOA with Visual Studio 2005
lineItem2.quantity = 890; lineItem2.unitCost = 45.89F; po.orderLineItems = new PurchaseOrderLineItem[2]; po.orderLineItems[0] = lineItem1; po.orderLineItems[1] = lineItem2; using (OrderProcessorProxy orderProcessor = new OrderProcessorProxy("OrderResponseEndpoint")) { //Set the correlation ID such that the client can //correlate the response to the order MsmqMessage ordermsg = new MsmqMessage(po); using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required)) { orderProcessor.SubmitPurchaseOrder(ordermsg); scope.Complete(); } Console.WriteLine("Order has been submitted:{0}", po); } Console.WriteLine(); Console.WriteLine("Press to terminate client."); Console.ReadLine(); } } }
Listing 16-47. Demonstrates client side implementation using Visual Basic .NET Imports System Imports System.Text Namespace MSMQ _ Public Class PurchaseOrderLineItem Public productId As String Public unitCost As Single Public quantity As Integer Public Overloads Overrides Function ToString() As String Dim displayString As String = "Order LineItem: " & _ quantity.ToString() & " of " & productId & _ " @unit price: $" & unitCost.ToString() Return displayString End Function Public ReadOnly Property TotalCost() As Single Get Return unitCost * quantity End Get End Property End Class
708
The Complete Reference To Professional SOA with Visual Studio 2005
Public Enum OrderStates Pending Processed Shipped End Enum _ Public Class PurchaseOrder Public poNumber As String Public customerId As String Public orderLineItems As PurchaseOrderLineItem() Public orderStatus As OrderStates Public ReadOnly Property TotalCost() As Single Get Dim _totalCost As Single = 0 For Each lineItem As PurchaseOrderLineItem In orderLineItems _totalCost += lineItem.TotalCost Next Return _totalCost End Get End Property Public Property Status() As OrderStates Get Return orderStatus End Get Set(ByVal value As OrderStates) orderStatus = value End Set End Property Public Overloads Overrides Function ToString() As String Dim strbuf As StringBuilder = New StringBuilder _ ("Purchase Order: " & poNumber & Environment.NewLine) strbuf.Append(ControlChars.Tab & "Customer: " & customerId _ & Environment.NewLine) strbuf.Append(ControlChars.Tab & "OrderDetails" & _ Environment.NewLine) For Each lineItem As PurchaseOrderLineItem In orderLineItems strbuf.Append(ControlChars.Tab & ControlChars.Tab & _ lineItem.ToString()) Next strbuf.Append(ControlChars.Tab & _ "Total cost of this order: $" & TotalCost & Environment.NewLine) strbuf.Append(ControlChars.Tab & "Order status: " & _ Status & Environment.NewLine) Return strbuf.ToString() End Function End Class End Namespace
709
The Complete Reference To Professional SOA with Visual Studio 2005
In the Client implementation the order is set before it is sent to the message queue. We will be relying on WCF to send the message to the queue. By using the System.ServiceModel.MsmqIntegration.MsmqMessage. The MsmqMessage class encapsulates an MSMQ message that is sent and received, over a MSMQ integration channel, to and from an existing MSMQ application. Listing 16-48. Implementing MsmqMessage using Visual C# MsmqMessage ordermsg = new MsmqMessage(po); using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required)) { orderProcessor.SubmitPurchaseOrder(ordermsg); scope.Complete(); }
Listing 16-49. Implementing MsmqMessage using Visual Basic .NET Using orderProcessor As OrderProcessorProxy = New OrderProcessorProxy("OrderResponseEndpoint") Dim ordermsg As MsmqMessage(Of PurchaseOrder) = New MsmqMessage(Of PurchaseOrder)(po) Using scope As TransactionScope = New TransactionScope(TransactionScopeOption.Required) orderProcessor.SubmitPurchaseOrder(ordermsg) scope.Complete() End Using
The last thing we need to do is to specify the binding and the endpoints for the message queue. This is so that the client application can readily connect to the queue in code using the endpoint name specified in the configuration. 1.
To specify the configuration file in Visual Studio go to the Tools menu -> WCF SvcConfigEditor. This will bring up the Microsoft Service Configuraiton Editor. Select File-> New Config.
2.
We need to create a new Bindings first. Expand Advanced node.
3.
Then right mouse click on Bindings and select Create a New Binding.
4.
Select msmqIntegrationBinding. Then click OK.
710
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 16-36. Specifying msmqIntegrationBinding
5.
Change the Name of the binding from NewBinding to OrderProcessorBinding.
6.
Select the Security tab on OrderProcessorBinding and change the security Mode to None.
Now we need to create an endpoint to point to the MSMQ. 7.
To create a new endpoint right mouse click on endpoints then select “New Client Endpont”.
8.
Give the endpoint the name of OrderResponseEndpoint
9.
On the endpoint Binding attribute specify msmqIntegrationBinding from the dropdownlist.
10. On the BindingConfiguration attribute specify OrderProcessorBinding from the dropdownlist 11. Enter Client.MSMQ.IOrderProcessor as the Contract name 12. Enter msmq.formatname:DIRECT=OS:.\private$\Orders as the value of the address. If the message queue is not on the same computer as the client application add the name of the computer in the address. So its in the format msmq.formatname:DIRECT=OS:[computer name]\private$\Orders. 13. Once the above steps had been completed select Save As from the File menu and save the App.config configuration file to the client application’s location. 14. Once the above steps had been completed the configuration file should look like below.
711
The Complete Reference To Professional SOA with Visual Studio 2005
Now we can execute the application. Since we’re using MSMQ as middleware we don’t have to start both applications at the same time. The results are shown below in figure 16-37 and figure 16-38.
Figure 16-37. Client order application
712
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 16-38. Order Processing Service
WCF Sessions WCF sessions are used to allow messages to maintain state over a period of time. Implementing sessions is quite easy and all we have to do is set the Session parameter to True within ServiceContract [ServiceContract(Session=true)] and WCF will make sure that a session is established for the communication between endpoints using that particular contract. The existence of such a communication session does, however, not immediately control how instances of the service are handled. The correlation between a service instance and a session is explicitly controlled through the [ServiceBehavior] property InstanceMode. If we need the instance to stay alive for as long as the session lasts, we can use InstanceMode.PrivateSession and if we need to have a new instance for every call irrespective of the session scope, you use InstanceMode.PerCall. In the latter case, we can, if we wanted to, store and recover whatever state we want to associate with the session using the session identifier that's readily available as a value on OperationContext.Current.SessionIdentifier. Listing 16-50. Implementing Session in Visual C# [ServiceContract(Session=true)] public interface IMyService { [OperationContract] int Add(int num); }
Listing 16-51. Implementing Session in Visual Basic .NET _ Public Interface IMyService _ Function Add(ByVal num As Integer) As Integer End Interface
713
The Complete Reference To Professional SOA with Visual Studio 2005
WCF Transactions WCF supports a variety of transacted communications. The following code demonstrates a transacted service operation. To enable a transaction in WCF, use the transaction parameters within the OperationBehavior attribute, the listing 16-52 and listing 16-53 shows an example of implementing automatic transaction by setting TransactionAutoComplete = true. Listing 16-52. Implementing Transaction in Visual C# [ServiceContract(Session=true)] public interface IMyService { [OperationContract] [OperationBehavior( TransactionScopeRequired = true, TransactionAutoComplete= true)] int Add(int num); }
Listing 16-53. Implementing Transaction in Visual Basic .NET _ Public Interface IMyService _ _ Function Add(ByVal num As Integer) As Integer End Interface
Duplex Communication Traditional remote procedure calls (RPCs) use in-and-out operations. WCF supports multichannel inout operations, otherwise known as duplex communication. These are implemented using duplex contracts. A duplex Contract defines two logical sets of operations, A set that the Service exposes for the Client to call and a set that the Client exposes for the Service to call. The programming model for defining a duplex Contract is to split each set in a separate type (each type must be a class or an interface). We should use ServiceContract to define our inputs and CallContract to define the outputs. In the following example we will be developing a duplex WCF service that performs a large operation before sending a response back to the client on a separate channel see listing 16-54 and listing 16-55. Listing 16-54. Demonstrates service implementation using Duplex communication using Visual C# using System; using System.ServiceModel; using System.Threading; [ServiceContract(Namespace = "http://WCF.Duplex", Session = true, CallbackContract=typeof(ICalculatorDuplexCallback))] public interface ICalculatorDuplex {
714
The Complete Reference To Professional SOA with Visual Studio 2005
[OperationContract(IsOneWay=true)] void Clear(); [OperationContract(IsOneWay = true)] void VeryLongAddOperation(double n); }
public interface ICalculatorDuplexCallback { [OperationContract(IsOneWay = true)] void Equals(double result); [OperationContract(IsOneWay = true)] void Duration(string duration); }
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)] public class CalculatorService : ICalculatorDuplex { double result; TimeSpan totalDuration; ICalculatorDuplexCallback callback = null; public CalculatorService() { result = 0.0D; callback = OperationContext.Current.GetCallbackChannel (); } public void Clear() { callback.Duration("Operation duration in milliseconds: " + totalDuration.TotalMilliseconds); result = 0.0D; } public void VeryLongAddOperation(double n) { DateTime start = DateTime.Now; Thread.Sleep(2000); result += n; callback.Equals(result); totalDuration = (TimeSpan)DateTime.Now.Subtract(start); } }
Listing 16-55. Demonstrates using Duplex communication using Visual Basic .NET Imports System Imports System.ServiceModel
715
The Complete Reference To Professional SOA with Visual Studio 2005
Imports System.Runtime.Serialization Imports System.Threading
_ Public Interface ICalculatorDuplex _ Sub Clear() _ Sub VeryLongAddOperation(ByVal n As Double) End Interface
Public Interface ICalculatorDuplexCallback _ Sub Equals(ByVal result As Double) _ Sub Duration(ByVal duration As String) End Interface
_ Public Class CalculatorService Implements ICalculatorDuplex Private result As Double Private totalDuration As TimeSpan Private callback As ICalculatorDuplexCallback = Nothing Public Sub CalculatorService() result = 0 callback = OperationContext.Current.GetCallbackChannel _ (Of ICalculatorDuplexCallback)() End Sub Public Sub Clear() Implements ICalculatorDuplex.Clear callback.Duration("Operation duration in milliseconds: " + _ totalDuration.TotalMilliseconds) result = 0 End Sub Public Sub VeryLongAddOperation(ByVal n As Double) _ Implements ICalculatorDuplex.VeryLongAddOperation Dim start As DateTime = DateTime.Now Thread.Sleep(2000) result += n callback.Equals(result)
716
The Complete Reference To Professional SOA with Visual Studio 2005
totalDuration = CType(DateTime.Now.Subtract(start), TimeSpan) End Sub End Class
The duplex communication is achieved by implementing duplex contracts. We use ServiceContract to define our inputs and CallContract to define the outputs. See the listing below example: Listing 16-56. Using Visual C#
[ServiceContract(Namespace = "http://WCF.Duplex", Session = true, CallbackContract=typeof(ICalculatorDuplexCallback))] Listing 16-57. Using Visual Basic .NET _
The OperationContract is also decorated with the IsOneWay = true attribute. This property indicates that the method should not deliver a reply. Thus all response to the client should only be treated as a one-way message. To set up a duplex receiver, we must first implement a ServiceContract and use the callback channel (from the OperationContext). Here is an example: Listing 16-58. Using Visual C#
public CalculatorService() { result = 0.0D; callback = OperationContext.Current.GetCallbackChannel ();
} Listing 16-59. Using Visual Basic .NET Public Sub CalculatorService() result = 0
callback = OperationContext.Current.GetCallbackChannel _ (Of ICalculatorDuplexCallback)() End Sub
Now we need to set the configuration for the WCF service. 1.
Select Tools->WCF SvcConfigEditor to bring up Microsoft Service Configuration Editor
2.
Select File->New Config
3.
We need to create a new binding to support the duplex communication so browse to the Advanced node right mouse click on Bindings and select “Create a New Binding”.
4.
Select wsDualHttpBinding, then click OK
717
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 16-40. wsDualHttpBinding
5.
Change the name of the binding to “duplexBinding”
6.
Select the Security tab of the new duplexBinding node, change the security Mode to None.
7.
Because this is a duplex communication we also need to add a behavior to the configuration. Right mouse click on Behaviors node under Advanced. Select “New Behavior”
8.
Change the name of the behavior to “CalculatorServiceBehavior”
9.
Now we can create a service element. Select the Services node right mouse click and select “New Service”
10. Select CalculatorServiceBehavior from the BehaviorConfiguration drop downlist and change the name of the service from NewServiceType to CalculatorService 11. Now we’re finally ready to create an end point right mouse click on the CalculatorService node we’ve just created. Select New Endpoint. 12. Select wsDualHttpBinding from for the Binding property. And add ICalculatorDuplex as the name for the Contract. 13. Select duplexBinding as the BindingConfiguration 14. Now Select File->Save to save the configuration as Web.config Listing 16-60. Demonstrates the Web.config file created.
718
The Complete Reference To Professional SOA with Visual Studio 2005
Implementing the client application for duplex communication is not very different to how we normally develop. All the duplex specification is handled by WCF at the binding level. The only thing to keep in mind is that we do need to wait for the WCF service to return the result from the execution. As the client does not wait for the service to return and this causes an exception to be thrown when the server tries to return the result and realize the proxy is out of scope. To implement the client first create a new console application and call it Client. Then use the svcutil to generate the proxy by: svcutil http://localhost:10433/Service/Service.svc Or for Visual Basic .NET: svcutil http://localhost:10433/Service/Service.svc /language:vb
Include the output.config and the generated CalculatorService class to the project rename the output.config file to App.config.
Listing 16-61. Demonstrates duplex client implementation using Visual C# using System; using System.ServiceModel; // The service contract is defined in generatedProxy.cs, // generated from the service by the svcutil tool. // Define class which implements callback interface of //duplex contract public class CallbackHandler : ICalculatorDuplexCallback { public void Equals(double result) {
719
The Complete Reference To Professional SOA with Visual Studio 2005
Console.WriteLine("Equals({0})", result); } public void Duration(string duration) { Console.WriteLine(duration); } } class Client { static void Main() { // Construct InstanceContext to handle messages on callback // interface InstanceContext instanceContext = new InstanceContext(new CallbackHandler()); // Create a proxy with given client endpoint configuration using (CalculatorDuplexProxy proxy = new CalculatorDuplexProxy(instanceContext)) { Console.WriteLine("request very long operation"); // Call very long service operation. double value = 100.00D; proxy.VeryLongAddOperation(value); // Complete equation proxy.Clear(); System.Threading.Thread.Sleep(5000); } Console.WriteLine(); Console.WriteLine("Press to terminate client."); Console.ReadLine(); } }
Listing 16-62. Demonstrates duplex client implementation using Visual Basic .NET Imports System Imports System.ServiceModel Imports System.Runtime.Serialization Imports System.Threading
_ Public Interface ICalculatorDuplex _
720
The Complete Reference To Professional SOA with Visual Studio 2005
Sub Clear() _ Sub VeryLongAddOperation(ByVal n As Double) End Interface
Public Interface ICalculatorDuplexCallback _ Sub _Equals(ByVal result As Double) _ Sub Duration(ByVal duration As String) End Interface
_ Public Class CalculatorService Implements ICalculatorDuplex Private result As Double Private totalDuration As TimeSpan Private callback As ICalculatorDuplexCallback = Nothing Public Sub CalculatorService() result = 0 callback = OperationContext.Current.GetCallbackChannel _ (Of ICalculatorDuplexCallback)() End Sub Public Sub Clear() Implements ICalculatorDuplex.Clear callback.Duration("Operation duration in milliseconds: " + _ totalDuration.TotalMilliseconds) result = 0 End Sub Public Sub VeryLongAddOperation(ByVal n As Double) _ Implements ICalculatorDuplex.VeryLongAddOperation Dim start As DateTime = DateTime.Now Thread.Sleep(2000) result += n callback._Equals(result) totalDuration = CType(DateTime.Now.Subtract(start), TimeSpan) End Sub End Class
To set up a duplex sender, we need to implement a Callbackcontract handle the the callback from the proxy. This method is executed by the client’s proxy when the request is returned by the WCF service. Listing 16-63. CallbackHandler using Visual C#
721
The Complete Reference To Professional SOA with Visual Studio 2005
public class CallbackHandler : ICalculatorDuplexCallback { public void Equals(double result) { Console.WriteLine("Equals({0})", result); } public void Duration(string duration) { Console.WriteLine(duration); } }
Listing 16-64. CallbackHandler using Visual Basic .NET Public Class CallbackHandler Implements ICalculatorDuplexCallback Public Sub _Equals(ByVal result As Double) _ Implements ICalculatorDuplexCallback._Equals Console.WriteLine("Equals({0})", result) End Sub Public Sub Duration(ByVal duration As String) _ Implements ICalculatorDuplexCallback.Duration Console.WriteLine(duration) End Sub End Class
Then create an instance of the InstanceContext class which is used to handle the incoming messages. By passing in an object of the CallbackHandler the proxy will invoke the CallbackHandler and relevant methods within the object upon receiving the message from the WCF service. Listing 16-65. Implementing InstanceContext in Visual C# InstanceContext instanceContext = new InstanceContext(new CallbackHandler()); // Create a proxy with given client endpoint configuration using (CalculatorDuplexProxy proxy = new CalculatorDuplexProxy(instanceContext)) { Console.WriteLine("request very long operation"); // Call very long service operation. double value = 100.00D; proxy.VeryLongAddOperation(value);
Listing 16-66. Implementing InstanceContext in Visual Basic .NET Dim instanceContext As InstanceContext = New InstanceContext(New CallbackHandler) Dim proxy As CalculatorDuplexProxy = New CalculatorDuplexProxy(instanceContext) Try Console.WriteLine("request very long operation") Dim value As Double = 100 proxy.VeryLongAddOperation(value)
722
The Complete Reference To Professional SOA with Visual Studio 2005
Now we need to examine the configuration for the WCF client application. Using the svcutil.exe we have already generated the output.config file which we have renamed to App.config. Simply right mouse click the App.config file in solution explorer select “Edit WCF Configuration”. Expand the Advanced node, under Bindings selet the wsDualHttpBinding node add an address of http://localhost:8000/myClient/ to the ClientBaseAddress property. We need to add this address because when the WCF service returns the result this is the address from which the WCF service will call. Select File->Save to commit the changes to the App.config file.
Figure 16-40. Client application result.
Summary In this chapter, we have covered the fundamentals of WCF ABCs. We have also learnt to implement WCF service as well as creating WCF client with the help of SvcUtil.exe to automatically create client side proxy and configuration. We have walked through developing hosting environment for a WCF service from which a WCF service can be launched. We have also covered developing for secure and reliable messaging. While configuring the WCF service and client with Microsoft Service Configuration Editor (SvcConfigEditor) which helps to fast track WCF configuration files. We have explored the concept of bindings and endpoints and looked at developing and implementing both. We have also covered how to implement custom bindings to mix and match our requirement in protocols with WCF. In this chapter we have also looked at using WCF to communicate with a Microsoft Message Queue (MSMQ). This allows the client to submit orders to the middleware queue regardless of the status of the processing service. Lastly we have implemented duplex communication with the new WCF duplex model.
723
The Complete Reference To Professional SOA with Visual Studio 2005
Chapter 17. Architecture Conceptualization with Distributed System Designers With Microsoft Visual Studio Team System comes with a suite of designers. These designer tools are used to help reduce the complexity of developing and deploying service-oriented applications. With these designers, application architects can visualize their architecture. The designers themselves can generate codes to help work with the developers while the code changes are synchronized with the visual design. Infrastructure architects can create logical diagrams of their infrastructures such as datacenters. With these designers we can validate the requirements of the application design against that of the logical design. There are four Distributed System Designers: *
Application Designer (AD): Represents applications that expose services and communicate through endpoints.
*
Logical Datacenter Designer (LDD): Represents the logical structure of a datacenter.
*
System Designer (SD): Represents the arrangement of applications defined in the application designer.
*
Deployment Designer (DD): Used to create a deployment configuration for a system.
Application Designer The application designer is suitable for application architects. It is essentially a whiteboard allowing an application architect to drag and drop shapes to create diagrams of their application system. Services and applications can be dragged and dropped onto the design surface, from there necessary configuration settings can be made, and then applications and services can be connected. The application designer has several benefits compared to Visio type designs: *
The diagrams can produce code that the developers can use to implement services
*
The diagrams can be validated against one or more logical datacenters
*
The diagrams can generate reports for IT operations
*
The diagrams are also very visually pleasing
Implementing Application Designer In the example below we will be using the Application Designer to create a contact management application designed for AdventureWorks. The contact management application consists of a Web service, a web based application used to consume the Web service and the AdventureWorks SQL server database. To start the Application Designer select File->New->Project. Under project types select Distributed System Solutions, under Templates there will be Distributed System and Logical Datacenter template, select Distributed System from under the Templates section see figure 17-1.
724
The Complete Reference To Professional SOA with Visual Studio 2005
Enter the name of ApplicationDesigner, click OK
Figure 17-1. Opening Distributed System Solutions
We now have a blank work space for our application designer. A file called ApplicationDesigner.ad is created (this is named after the solution name). The toolbox now contains General Designer Tools, Endpoint Tools, Applications Tools see figure 17-2.
Figure 17-2. Application Designer Toolbox Table 17-1. Application Designer Tools
725
The Complete Reference To Professional SOA with Visual Studio 2005
Item Pointer Connection Comment WebServiceEndpoint WebContentEndpoint GenericEndpoint WindowsApplication ASP.NETWebService ASP.NETWebApplication OfficeApplication ExternalWebService ExternalDatabase BizTalkWebService GenericApplication
Description The pointer tool is used for selecting and moving objects The connection tool is used to link two application prototype endpoints The comment tools creates a comment text box Represents a connection endpoint for a web service provider/consumer Represents a connection endpoint for a web content provider/consumer Represents a connection point to services of a generic type provider/consumer Represents a windows application An ASP.NET web service application that includes a web service endpoint An ASP.NET web application that includes a web content endpoint Represents a Microsoft Office application (Excel, Word and Outlook templates) A reference to a single web service defined by a single Web Service Description Language .wsdl file Represents a database system Reprents a BizTalkWebService A generic user-defined application that supports user-defined settings and constraints.
Click the ASP.NETWebService Tool from under the Applications section of the toolbar and drag and drop it on to the design surface. This will create an ASP.NETWebApplication shape onto our designer see figure 17-3. By default the the ASP.NETWebApplication shape has one Web service endpoint called WebService1.
Figure 17-3. ASP.NETWebApplication for Web service
Right click on the ASP.NETWebApplication shape for our Web service select properties change the name to WebserviceContactManagement. This will rename our shape to WebserviceContactManagement. Then click the ExternalDatabase component in the Applications section of the toolbar and drag and drop the tool onto the designer. This will create the ExternalDatabase shape on the designer. By default the ExternalDatabase shape also has one endpoint called Database1 figure 17-4.
Figure 17-4. ExternalDatabase
726
The Complete Reference To Professional SOA with Visual Studio 2005
Right Click on the database shape and select properties, by default the name is Database1 change the name to AdventureWorks. This will change the name of the endpoint, this implies that other applications will be connecting to the AdventureWorks database.
Connecting the Applications To connect the applications it usually is a simple matter of selecting the connection tool from the general designer section of the toolbox and drag and drop the endpoint of the required connections. For example now we will need to create a connection from the AdventureWorks database to our WebserviceContactManagement service. Select the Connection tool from the General Designer Simply select the ExternalDatabase (AdventureWorks) shape’s endpoint and then select our ASP.NETWebApplication(WebserviceContactManagement) see figure 17-5.
Figure 17-5. Establishing a connection.
Creating connections is fairly straight forward. The application designer contains constraints about connections for example we can not connect a connection between a Web service endpoint and that of a Database endpoint see figure 17-6. Logically it doesn’t make sense as a Web service endpoint provides service functionalities and the endpoint itself is to be consumed. While a database endpoint is used by an application to connect to the database. So if we tried to drag and drop a connection from a Web service endpoint to a database endpoint the designer will not allow us to establish the connection.
727
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-6. Connecting ASP.NETWebApplication endpoint to ExternalDatabase endpoint
Once the connection has been established a Connection Properties window will appear prompting for the Database details. In the Choose Data Source dialog box, enter the data source and data provider. For this example, select Microsoft SQL Server and the .NET Data Provider for SQL Server, respectively. Click Continue. In the Connection Properties dialog box figure 17-7, enter the database server name, the security context, and the database name. (We can enter a period for the server name to indicate as local SQL Server installation, or enter .\sqlexpress for default installations of SQL Express edition.) Click Test Connection to verify that the configuration information for the data source is correct. Click OK to establish the connection.
Figure 17-7. Database Connection Property
TIP: If we’re only whiteboarding our idea to designer we don’t have to specify the connection details simply click cancel to configure the connection at a later time.
To verify the connection properties, right-click the database consumer endpoint of our web service and select Properties. In the properties section the connection information is stored under Connection String, as shown in figure 17-8 (below). This Connection String property will be generated into the Web.config file of the AdventureWorks application when it is implemented.
728
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-8. Demonstrates the connection properties of the Webservice endpoint.
Now we should have a diagram which look like the figure below.
Figure 17-9. ASP.NETWebApplication connected to a ExternalDatabase
As we configure the database information it is generated into a XML file. To file this file simply right-click the Database1.sdm file in the solution explorer and choose to open it with the XML editor. We cannot have the XML editor and the Application Designer open at the same time. We will be prompted to close and save the diagram prior to opening the .sdm file. The listing below shows the .sdm file generated so far: Listing 17-1. XML file describing the database application
In the above listing we can see that the diagram object has a state of Implemented. This is also categorized by the object’s shadow over its shape see figure 17-9. There are several different endpoints that are used for different providers. We can only connect a consumer endpoint to only a single provider endpoint. The Table 17-2 illustrates the different shapes for different endpoints and their associated meanings. Table 17-2. Object endpoint representations
Endpoint
Description Generic endpoint
Database endpoint
Web content endpoint
Web service endpoint
Rules for Connecting Applications The following rules apply when connecting applications: *
We can create connections between existing endpoints, or if an application does not have endpoints, we can add them, if supported by the application type.
*
Endpoints define their role in communication as consumers or providers of services. Therefore, the direction in which we draw a connection does not affect the direction of that connection.
*
When an application or endpoint is selected, choosing the Connect command from the Diagram or context menu opens a connection dialog box. In the connection dialog box, we can choose a compatible application and a provider endpoint on that application to complete the connection.
*
We can begin a connection from a provider endpoint by using the Connection tool or the Connect command.
731
The Complete Reference To Professional SOA with Visual Studio 2005
*
We cannot draw connections directly between applications using the Connection tool. However, we can draw a connection between an application and a suitable provider endpoint, starting from either the application or the provider endpoint.
*
If compatible provider and consumer endpoints exist, we can connect them by beginning the connection from either endpoint using the Connection tool or Connect command.
*
If a connection has been deleted, we can reconnect the disconnected applications directly between their endpoints.
Defining Web Service Prototypes One of the key features of the Application Designer is the ability to define the operations and parameters for web services that are exposed on the diagram. This is part of the contract-first design, where we first design the service contracts for communicating between different application types. If we have an existing .wsdl file, we can also consume the operations from the existing exposed service. To start defining the Endpoint of the ASP.NETWebApplication simply select the WebService1 endpoint. Right click on the endpoint and select Define Operations to open the Web Service Details window. Using the Web Service Details window, we can add the operations, parameters, types, and details. For this sample application, we will be creating the following operations: AddContact, UpdateContactByID, RemoveContactByID, SelectContactByID see figure 17-10 below. To add these operations Click and type the name AddContact.
Figure 17-10. Add operation
1.
Click the plus sign next to the AddContact function to reveal the section.
2.
Then click and add the following parameters: FirstName, MiddleName, LastName change their Type to String.
3.
Following the above steps add the operations for UpdateContactByID, RemoveContactByID and SelectContactByID see figure 17-11 below.
732
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-11. Web Service Details.
Adding an Endpoint through WSDL We can also add a Web service endpoint from a WSDL document. In this example we will be creating a reference from another Web service. The second web service is defined in the listing below. Listing 17-2. Sample Web service using Visual C# using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class Service : System.Web.Services.WebService { public Service () { //Uncomment the following line if using designed components //InitializeComponent(); } [WebMethod] public string HelloWorld1() { return "Hello World"; } [WebMethod] public string HelloWorld2() { return "Hello World";
733
The Complete Reference To Professional SOA with Visual Studio 2005
} [WebMethod] public string HelloWorld3() { return "Hello World"; } }
Listing 17-3. Sample Web service using Visual Basic .NET Imports System.Web Imports System.Web.Services Imports System.Web.Services.Protocols _ _ _ Public Class Service Inherits System.Web.Services.WebService _ Public Function HelloWorld1() As String Return "Hello World" End Function _ Public Function HelloWorld2() As String Return "Hello World" End Function _ Public Function HelloWorld3() As String Return "Hello World" End Function End Class
To add the above implementation or any WSDL document to the designer as an endpoint simply right mouse-click the ASP.NETWebApplication object and select “Create Web Service Endpoint From WSDL” see figure 17-12.
734
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-12. Creating a Web service from a WSDL document
This will bring up the Add Web Reference dialog window see figure 17-13 below. Enter the url containing the WSDL document. Please keep in mind that the port number may differ if you’re launching the Web service application with ASP.NET Development Web Server. Once complete select the Add Reference button.
Figure 17-13. Add reference.
This will result in another Web service endpoint called Service see figure 17-14 below.
735
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-14. A new endpoint
Selecting the Service endpoint and looking into the Web Service Details window. We can see that the WebMethods had been entered into the details section see figure 17-15 below.
Figure 17-15. Web Service Details.
Implement the Application In this section we will generate the actual code for a developer to implement from the diagram we had constructed. When an application is implemented, the Application Designer automatically generates the corresponding project, code files, and configuration files. Because the application diagram is synchronized with the code and configuration files, the diagram is immediately updated if the files are modified. Similarly, changes to the diagram are reflected in the code and configuration files. Upon implementation, the application prototypes will be identified by the shadow effect around the object shape.
Creating a Toolbox Item The first thing that we need to do is to select the implementation language used to generate. For this example we will select Visual C# for Visual Basic users select Visual Basic. 1.
Click ASP.NETWebApplication in the application diagram and right mouse click and select Properties. In the Implementation section, select the language to generate as Visual C# figure 17-16.
736
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-16. Select the language to implement
We can also add our diagrams to the Toolbox. 2.
Simply right mouse click the ASP.NETWebApplication shape and select “Add to Toolbox”.
3.
In the Name field type in WebserviceContactManager then click OK see figure 17-17 below.
Figure 17-17. Add to Toolbox
4.
The Save File dialog box appears we’re prompted to save the Application Designer Prototype. Click Save, and WebserviceContactManager is added to our Toolbox see figure 17-18.
737
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-18. WebserviceContactManager
This is particularly useful by adding our shape to the toolbar we can easily drag and drop the duplicates of WebserviceContactManager to the designer. The WebserviceContactManager will contain the exact same properties.
Generating Code Now that we have selected the necessary language for our shape we can implement the application to let Visual Studio create our code for us. 1.
To implement the shape ASP.NETWebApplication simply right click the shape and choose Implement Application. Alternatively, we can select Diagrams -> Implement Application from the main menu. This will in turn launch the Confirm Application implementation dialog box see figure 17-19.
Figure 17-19. Confirm Application Implementation.
738
The Complete Reference To Professional SOA with Visual Studio 2005
2.
Select OK and wait for the application code to be generated inside the solution. We may receive a warning that the connection string is being written into the configuration files unencrypted see figure 17-20. Select close to let the process continue.
Figure 17-20. Security warning dialog box.
The result of the implementation is that a new web service project has been added to the solution. This new project includes language-specific source and configuration files see figure 17-21.
Figure 17-21. A new web service project
Notice now that our WebserviceContactManager is implemented. All implemented components are represented in the Application Designer by a shadow border outlining the component on the diagram surface see figure 17-22.
Figure 17-22. Implemented ASP.NETWebApplication
739
The Complete Reference To Professional SOA with Visual Studio 2005
Updating the Design One of the advantages of using the application designer is that we can make changes within our code and Visual Studio will automatically reflect the changes within the Application Designer. In the following example we will create an additional method in our newly generated Web service code. Double-click MyService1.cs in the Solution Explorer to display the generated code. Notice that the operations and parameters we defined earlier in the designer have been implemented in code. We can see all four methods have been implemented into code: AddContact, UpdateContactByID, RemoveCotnactByID and SelectContactByID see listing 17-4 and listing 17-5 below.
Listing 17-4. Demonstrates the newly generated code in Visual C# using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; namespace WebserviceContactManagement { [System.Web.Services.WebServiceBinding( Name = "WebService1", ConformsTo = System.Web.Services.WsiProfiles.BasicProfile1_1, EmitConformanceClaims = true), System.Web.Services.Protocols.SoapDocumentService()] public class WebService1 : System.Web.Services.WebService { /// /// Add a contact /// [System.Web.Services.WebMethod(), System.Web.Services.Protocols.SoapDocumentMethod (Binding = "WebService1")] public void AddContact(string FirstName, string MiddleName, string LastName) { throw new System.NotImplementedException(); } /// /// Update a contact detail by ID /// [System.Web.Services.WebMethod(), System.Web.Services.Protocols.SoapDocumentMethod(Binding = "WebService1")] public void UpdateContactByID(int ContactID, string FistName, string MiddleName, string LastName) { throw new System.NotImplementedException(); } ///
740
The Complete Reference To Professional SOA with Visual Studio 2005
/// Remove a contact detail by ID /// [System.Web.Services.WebMethod(), System.Web.Services.Protocols.SoapDocumentMethod (Binding = "WebService1")] public void RemoveContactByID(int ContactID) { throw new System.NotImplementedException(); } /// /// Select a contact by ID /// [System.Web.Services.WebMethod(), System.Web.Services.Protocols.SoapDocumentMethod (Binding = "WebService1")] public DataSet SelectContactByID(int ContactID) { throw new System.NotImplementedException(); } } }
Listing 17-5. Demonstrates the newly generated code in Visual Basic .NET Imports System.Web Imports System.Web.Services Imports System.Web.Services.Protocols
Namespace WebserviceContactManagement _ _ Public Class WebService1 ''' ''' Add a contact ''' _ _ Public Sub AddContact(ByVal FirstName As String, _ ByVal MiddleName As String, ByVal LastName As String) End Sub ''' ''' Update a contact detail by ID '''
741
The Complete Reference To Professional SOA with Visual Studio 2005
_ _ Public Sub UpdateContactByID(ByVal ContactID As Integer, _ ByVal FirstName As String, ByVal MiddleName As String, _ ByVal LastName As String) End Sub ''' ''' Remove a contact detail by ID ''' _ _ Public Sub RemoveContactByID(ByVal ContactID As Integer) End Sub ''' ''' Select a contact by ID ''' _ _ Public Function SelectContactByID(ByVal ContactID As Integer) _ As System.Data.DataSet End Function End Class End Namespace
Now we will be implementing a new WebMethod called FindContactByFirstName see listing 17-6 and listing 17-7. Listing 17-6. New FindContactByFirstName WebMethod using Visual C# /// /// Find a contact by first name /// [System.Web.Services.WebMethod(), System.Web.Services.Protocols.SoapDocumentMethod(Binding = "WebService1")] public DataSet FindContactByFirstName(string FirstName) { throw new System.NotImplementedException(); }
Listing 17-7. New FindContactByFirstName WebMethod using Visual Basic .NET _
742
The Complete Reference To Professional SOA with Visual Studio 2005
Public Function FindContactByFirstName(ByVal FirstName As String) _ As DataSet Throw New System.NotImplementedException End Function
Upon saving the WebService1.cs file will result in an immediate update to the Application Designer see figure 17-23. The newly added function will have been added to the Web Service Details window.
Figure 17-23. Newly implemented FindContactByFirstName
Now to test the service code that was generate open the source code again. Because we are returning a DataSet from some of the functions we need to add the System.Data namespace into the code. So for C# users add using System.Data; for Visual Basic .NET users add Imports System.Data. Press F5 to Run the Web service application see figure 17-24. When prompted to Run a dialog window may appear asking you whether you want to enable debugging.
Figure 17-24. The implementations of the Webservice using Visual C#
743
The Complete Reference To Professional SOA with Visual Studio 2005
We will complete the rest of the implementation of the Web service by using the code in the listing 17-8 and listing 17-9. Listing 17-8. The full implementation of the Web service code using Visual C#. using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; using System.Data; using System.Data.SqlClient; using System.Configuration; namespace WebserviceContactManagement { [System.Web.Services.WebServiceBinding(Name = "WebService1", ConformsTo = System.Web.Services.WsiProfiles.BasicProfile1_1, EmitConformanceClaims = true), System.Web.Services.Protocols.SoapDocumentService()] public class WebService1 : System.Web.Services.WebService { SqlConnection sqlcon = new SqlConnection (ConfigurationManager.AppSettings["ConnectionString"] .ToString()); /// /// Add a contact /// [System.Web.Services.WebMethod(), System.Web.Services.Protocols.SoapDocumentMethod (Binding = "WebService1")] public void AddContact(string FirstName, string MiddleName, string LastName) { sqlcon.Open(); SqlTransaction transaction = this.sqlcon.BeginTransaction("ContactTran"); SqlCommand sqlcmdEmployee = new SqlCommand( @"insert into Person.Contact (FirstName, MiddleName, LastName) Values (@FirstName, @MiddleName, @LastName)", sqlcon); sqlcmdEmployee.Transaction = transaction; sqlcmdEmployee.Parameters.Add ("@FirstName", SqlDbType.VarChar, 50).Value = FirstName; sqlcmdEmployee.Parameters.Add ("@MiddleName", SqlDbType.VarChar, 50).Value = MiddleName; sqlcmdEmployee.Parameters.Add ("@LastName", SqlDbType.VarChar, 50).Value = LastName; sqlcmdEmployee.ExecuteNonQuery(); transaction.Commit(); sqlcon.Close();
744
The Complete Reference To Professional SOA with Visual Studio 2005
} /// /// Update a contact detail by ID /// [System.Web.Services.WebMethod(), System.Web.Services.Protocols.SoapDocumentMethod (Binding = "WebService1")] public void UpdateContactByID(int ContactID, string FirstName, string MiddleName, string LastName) { sqlcon.Open(); SqlTransaction transaction = this.sqlcon.BeginTransaction("ContactTran"); SqlCommand sqlcmdEmployee = new SqlCommand( @"update Person.Contact set FirstName = @FirstName, MiddleName = @MiddleName, LastName = @LastName where Person.Contact.ContactID = @ContactID;", sqlcon); sqlcmdEmployee.Transaction = transaction; sqlcmdEmployee.Parameters.Add ("@ContactID", SqlDbType.Int, sizeof(int)).Value = ContactID; sqlcmdEmployee.Parameters.Add ("@FirstName", SqlDbType.VarChar, 50).Value = FirstName; sqlcmdEmployee.Parameters.Add ("@MiddleName", SqlDbType.VarChar, 50) .Value = MiddleName; sqlcmdEmployee.Parameters.Add ("@LastName", SqlDbType.VarChar, 50).Value = LastName;
sqlcmdEmployee.ExecuteNonQuery(); transaction.Commit(); sqlcon.Close(); } /// /// Remove a contact detail by ID /// [System.Web.Services.WebMethod(), System.Web.Services.Protocols.SoapDocumentMethod (Binding = "WebService1")] public void RemoveContactByID(int ContactID) { sqlcon.Open(); SqlTransaction transaction = this.sqlcon.BeginTransaction("ContactTran"); SqlCommand sqlcmdEmployee = new SqlCommand( @"delete from Person.Contact where
745
The Complete Reference To Professional SOA with Visual Studio 2005
Person.Contact.ContactID = @ContactID;", sqlcon); sqlcmdEmployee.Transaction = transaction; sqlcmdEmployee.Parameters.Add ("@ContactID", SqlDbType.Int, sizeof(int)).Value = ContactID; sqlcmdEmployee.ExecuteNonQuery(); transaction.Commit(); sqlcon.Close(); } /// /// Select a contact by ID /// [System.Web.Services.WebMethod(), System.Web.Services.Protocols.SoapDocumentMethod (Binding = "WebService1")] public DataSet SelectContactByID(int ContactID) { // retrieve employee contact details string sql = String.Format ("select ContactID, Title, FirstName, MiddleName, LastName" + " from Person.Contact where ContactID = {0}", ContactID); SqlCommand sqlcmd = new SqlCommand(sql, sqlcon); SqlDataAdapter da = new SqlDataAdapter(sql, sqlcon); DataSet ds = new DataSet(); da.Fill(ds); sqlcon.Close(); return ds; } /// /// Find a contact by first name /// [System.Web.Services.WebMethod(), System.Web.Services.Protocols.SoapDocumentMethod (Binding = "WebService1")] public DataSet FindContactByFirstName(string FirstName) { // retrieve employee contact details string sql = String.Format ("select ContactID, Title, FirstName, MiddleName, LastName" + " from Person.Contact where FirstName like '%{0}%'", FirstName); SqlCommand sqlcmd = new SqlCommand(sql, sqlcon); SqlDataAdapter da = new SqlDataAdapter(sql, sqlcon); DataSet ds = new DataSet(); da.Fill(ds); sqlcon.Close(); return ds; }
746
The Complete Reference To Professional SOA with Visual Studio 2005
} }
Listing 17-9. The full implementation of the Web service code using Visual Basic .NET Imports System.Web Imports System.Web.Services Imports System.Web.Services.Protocols Imports System.Data Imports System.Data.SqlClient
Namespace WebserviceContactManagement _ _ Public Class WebService1 Private sqlcon As SqlConnection = New SqlConnection _ (ConfigurationManager.AppSettings("ConnectionString").ToString()) ''' ''' Add a contact ''' _ _ Public Sub AddContact(ByVal FirstName As String, _ ByVal MiddleName As String, ByVal LastName As String) sqlcon.Open() Dim transaction As SqlTransaction = _ Me.sqlcon.BeginTransaction("ContactTran") Dim sqlcmdEmployee As SqlCommand = _ New SqlCommand("insert into Person.Contact (FirstName," & _ " MiddleName, LastName) Values (@FirstName, @MiddleName, " & _ " @LastName)", sqlcon) sqlcmdEmployee.Transaction = transaction sqlcmdEmployee.Parameters.Add("@FirstName", SqlDbType.VarChar, _ 50).Value = FirstName sqlcmdEmployee.Parameters.Add("@MiddleName", SqlDbType.VarChar, _ 50).Value = MiddleName sqlcmdEmployee.Parameters.Add("@LastName", SqlDbType.VarChar, _ 50).Value = LastName sqlcmdEmployee.ExecuteNonQuery() transaction.Commit() sqlcon.Close() End Sub ''' ''' Update a contact detail by ID
747
The Complete Reference To Professional SOA with Visual Studio 2005
''' _ _ Public Sub UpdateContactByID(ByVal ContactID As Integer, _ ByVal FirstName As String, ByVal MiddleName As String, _ ByVal LastName As String) sqlcon.Open() Dim transaction As SqlTransaction = _ Me.sqlcon.BeginTransaction("ContactTran") Dim sqlcmdEmployee As SqlCommand = New SqlCommand _ ("update Person.Contact set FirstName = @FirstName, " & _ " MiddleName = @MiddleName, LastName = @LastName " & _ " where Person.Contact.ContactID = @ContactID;", sqlcon) sqlcmdEmployee.Transaction = transaction sqlcmdEmployee.Parameters.Add("@ContactID", SqlDbType.Int) _ .Value = ContactID sqlcmdEmployee.Parameters.Add("@FirstName", _ SqlDbType.VarChar, 50).Value = FirstName sqlcmdEmployee.Parameters.Add("@MiddleName", _ SqlDbType.VarChar, 50).Value = MiddleName sqlcmdEmployee.Parameters.Add("@LastName", _ SqlDbType.VarChar, 50).Value = LastName sqlcmdEmployee.ExecuteNonQuery() transaction.Commit() sqlcon.Close() End Sub ''' ''' Remove a contact detail by ID ''' _ _ Public Sub RemoveContactByID(ByVal ContactID As Integer) sqlcon.Open() Dim transaction As SqlTransaction = _ Me.sqlcon.BeginTransaction("ContactTran") Dim sqlcmdEmployee As SqlCommand = _ New SqlCommand("delete from Person.Contact where " & _ " Person.Contact.ContactID = @ContactID;", sqlcon) sqlcmdEmployee.Transaction = transaction sqlcmdEmployee.Parameters.Add("@ContactID", SqlDbType.Int) _ .Value = ContactID sqlcmdEmployee.ExecuteNonQuery() transaction.Commit() sqlcon.Close() End Sub ''' ''' Select a contact by ID ''' _
748
The Complete Reference To Professional SOA with Visual Studio 2005
_ Public Function SelectContactByID(ByVal ContactID As Integer) _ As System.Data.DataSet Dim sql As String = String.Format("select ContactID, Title, " & _ " FirstName, MiddleName, LastName from Person.Contact where" & _ " ContactID = {0}", ContactID) Dim sqlcmd As SqlCommand = New SqlCommand(sql, sqlcon) Dim da As SqlDataAdapter = New SqlDataAdapter(sql, sqlcon) Dim ds As DataSet = New DataSet da.Fill(ds) sqlcon.Close() Return ds End Function ''' ''' Find a contact by first name ''' _ _ Public Function FindContactByFirstName(ByVal FirstName As String) _ As System.Data.DataSet Dim sql As String = String.Format("select ContactID, " & _ " Title, FirstName, MiddleName, LastName from Person.Contact " & _ " where FirstName like '%{0}%'", FirstName) Dim sqlcmd As SqlCommand = New SqlCommand(sql, sqlcon) Dim da As SqlDataAdapter = New SqlDataAdapter(sql, sqlcon) Dim ds As DataSet = New DataSet da.Fill(ds) sqlcon.Close() Return ds End Function End Class End Namespace
To test the service press F5 to start the WebService1.asmx. Select the SelectContactByID link and enter a ContactID to test the service see figure 17-25.
749
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-25. SelectContactByID
The result of the execution is shown in figure 17-26.
Figure 17-26. SelectContactByID result
750
The Complete Reference To Professional SOA with Visual Studio 2005
Adding a Web Application Once we have established that our Web service is working. Its time to implement a Web application that will consume the service. 1.
Return to the Application Designer diagram.
2.
Select the ASP.NETWebApplication Tool and drag and drop it onto the designer
3.
Right mouse click and select properties. Rename the object from WebApplication1 to WebApplicationWSConsumer.
4.
Select your preferred language for implementation.
5.
To connect the web application to the web service, right click the WebApplicationWSConsumer and select Connect.
6.
In the Connect To section, select WebserviceContactManagement for the application and WebService1 for the endpoint and click OK figure 17-27.
Figure 17-27. Create Connection
7.
The completed diagram is shown in figure 17-28. It is also a good idea to illustrate the diagram by drag and drop the comment tool from the Toolbox.
751
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-28. Complete design
Now we can implement the application right mouse click on WebApplicationWSConsumer and selecting Implement Application. The result of implementing our design is that a new web application project has been added to the solution, figure 17-29 below.
Figure 17-29. ASP.NETWebApplication Properties.
In the new Web Application project that Visual Studio has automatically created, a web reference to the Web service project is automatically added to the project. To create a simple user interface (UI) for our contact management system edit Default.aspx see figure 17-30.
752
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-30. The web application layout
To implement the above design we will need to drag and drop a series of UI elements within the table to create an operational web page. We will need to drag and drop a series of Labels and Textboxes from the Toolbox onto the designer to achieve this. Please refer to the source code for this chapter for the implementation of Web Application as coverage is beyond scope of this book. listing 17-10 below shows the html for the Web application. Listing 17-10. ASP.NET HTML SourceCode
Untitled Page
753
The Complete Reference To Professional SOA with Visual Studio 2005
Update Contact | Contact ID | |
First Name | |
Middle Name | |
Last Name | |
754 The Complete Reference To Professional SOA with Visual Studio 2005 |
Remove contact by ID | Contact ID | |
|
Create Contact | First Name | |
Middle Name | |
Last Name | |
|
755
The Complete Reference To Professional SOA with Visual Studio 2005
Find User by First Name | First Name | |
| |
|
The listing below demonstrates the code used to implement our calls to the web service from the Web Application. Listing 17-11. Demonstrates the implementation of the ASP.NET code in the code behind using Visual C# using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using WebApplicationWSConsumer.WebServiceProxies; public partial class _Default : System.Web.UI.Page
756
The Complete Reference To Professional SOA with Visual Studio 2005
{ protected void Page_Load(object sender, EventArgs e) { } protected void BtnContactByID_Click(object sender, EventArgs e) { WebService1 proxies = new WebService1(); DataSet ds = proxies.SelectContactByID( int.Parse(this.TextbxGetContactContactID.Text)); this.GridView1.DataSource = ds; this.GridView1.DataBind(); } protected void ButtonUpdatecontact_Click(object sender, EventArgs e) { WebService1 proxies = new WebService1(); proxies.UpdateContactByID(int.Parse(this.txtbxContactID.Text), this.txtbxFirstName.Text, this.txtbxMiddleName.Text, this.txtbxLastName.Text); } protected void ButtonRemoveContact_Click(object sender, EventArgs e) { WebService1 proxies = new WebService1(); proxies.RemoveContactByID( int.Parse(this.TextbxRemoveContactContactID.Text)); } protected void ButtonCreateContact_Click(object sender, EventArgs e) { WebService1 proxies = new WebService1(); proxies.AddContact(this.TextbxCreateContactFirstName.Text, this.TextbxCreateContactMiddleName.Text, this.TextbxCreateContactLastName.Text); } protected void ButtonFindUser_Click(object sender, EventArgs e) { WebService1 proxies = new WebService1(); DataSet ds = proxies.FindContactByFirstName( this.TextbxFindUserFirstName.Text); GridView2.DataSource = ds; GridView2.DataBind(); } }
Listing 17-12. Demonstrates the implementation of the ASP.NET code in the code behind using Visual Basic .NET Imports System.Data Imports WebApplicationWSConsumer.WebServiceProxies
757
The Complete Reference To Professional SOA with Visual Studio 2005
Partial Class _Default Inherits System.Web.UI.Page Protected Sub BtnContactByID_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles BtnContactByID.Click Dim proxies As WebService1 = New WebService1 Dim ds As DataSet = proxies.SelectContactByID _ (Integer.Parse(Me.TextbxGetContactContactID.Text)) Me.GridView1.DataSource = ds Me.GridView1.DataBind() End Sub Protected Sub ButtonUpdatecontact_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles ButtonUpdatecontact.Click Dim proxies As WebService1 = New WebService1 proxies.UpdateContactByID(Integer.Parse(Me.txtbxContactID.Text), _ Me.txtbxFirstName.Text, Me.txtbxMiddleName.Text, _ Me.txtbxLastName.Text) End Sub Protected Sub ButtonRemoveContact_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles ButtonRemoveContact.Click Dim proxies As WebService1 = New WebService1 proxies.RemoveContactByID(Integer.Parse _ (Me.TextbxRemoveContactContactID.Text)) End Sub Protected Sub ButtonCreateContact_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles ButtonCreateContact.Click Dim proxies As WebService1 = New WebService1 proxies.AddContact(Me.TextbxCreateContactFirstName.Text, _ Me.TextbxCreateContactMiddleName.Text, _ Me.TextbxCreateContactLastName.Text) End Sub Protected Sub ButtonFindUser_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles ButtonFindUser.Click Dim proxies As WebService1 = New WebService1 Dim ds As DataSet = proxies.FindContactByFirstName _ (Me.TextbxFindUserFirstName.Text) GridView2.DataSource = ds GridView2.DataBind() End Sub End Class
The result of the Web application querying the Web service is shown in the figure 17-31.
758
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-31. Result from execution
Settings and Constraints In the application designer we can also define a number of constraints. These constraints can be specified against endpoints as well as objects. For example if we need to enable support on a Windows Server 2003 machine for a Web Application object. 1.
Select a Web service object then open the Settings and Constraints window.
2.
Select the Operation System checkbox to enable it, see figure 17-32.
759
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-32. Enable Logical Server Constraint
There are different constraint settings for different objects. If we selected a Web based (either Web service or Web content) endpoint there are a number of hosting constraints that we can specify see figure 17-33.
Figure 17-33. Hosting Constraints
System Designer The System Designer is another designer from the Distributed System Designer suite. This allows us to configure the actual deployment of a particular configured use of the applications but does not refer to the deployment of the application themselves. In other words it describes the deployment of the application systems to reflect the deployable system. For example we are to deploy the system we had built from the previous section from the Application Designer to two separate systems where each requires a different configuration of the same basic functions. This might be a necessary case if our Database and Web service is to be hosted internally while the Web application can be hosted externally on a separate machine all together. Before we begin we should clarify the meaning of a System. A System described by the System designer defines the architectural representation of a system and how it looks within the deployed environment. In the following examples we will be creating a System Designer using the Application Designer diagram we had designed earlier. In this example we will be creating two environments one for the intranet where our Database and our Web service will sit for secured internal use. Whilst our Web based application will be hosted externally for public access.
760
The Complete Reference To Professional SOA with Visual Studio 2005
1.
Start the System Designer by right clicking on the Application Designer project within the solution explorer.
2.
Select “New Distributed System Diagram…” see figure 17-34.
Figure 17-34. Add a System Designer
3.
This will bring up a “Add New Item” dialog window. Select Distributed System diagrams from the Categories section and select System Diagram from the Templates section. Rename the Diagram as Internal.sd see figure 17-35.
761
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-35. Adding a System Diagram
Selecting Add will create a new designer workspace in Visual Studio, figure 17-36. A new window called System View will also appear. This window contains all the objects that we had created in our Application Designer.
Figure 17-36. Internal System Designer
4.
Select the objects from the System View on the left hand side see figure 17-36. Drag and drop the objects onto the work space. The system box on screen represents an implementation of the deployed internal architecture.
5.
Complete the implementation by dragging the WebserviceContactManagement (Web service) and the AdventureWorks (Database) objects onto the workspace.
6.
Use the connection tool from the Toolbox to connect the objects figure 17-37.
762
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-37. Internal architecture representation.
7.
Since our internal system will be protected by a firewall the only way to access the system is through a proxy server. We can represent this using a system designer. Simply select the Web service endpoint, right click and select Add Proxy Endpoint see figure 17-38.
Figure 17-38. Internal architecture
Now we have a complete internal representation of what we had implemented through Application designer. To implement the external system where our Web application will be hosted follow the following steps: 8.
In the solution explorer right-click Solution Items and select Add-> New Distributed System Diagram. In the Add New Item dialog box, select System Diagram, Name it External.sd and click Add.
9.
Now with a new empty work space drag and drop WebApplicationWSConsumer onto the designer.
763
The Complete Reference To Professional SOA with Visual Studio 2005
10. Right click on the Web service endpoint and select Add Proxy Endpoint. 11. Then use the connection tool from the Toolbox and select the Web content endpoint the select the edge of the system boundry. We should have something that look like figure 17-39.
Figure 17-39. External System Diagram
Now we have two System Diagrams. To represent them on one diagram we can use a nesting technique. Here are the steps below: 12. Create a new system diagram by right click on Solution Items and select Add-> New Distributed System Diagram. 13. Select Distributed System Diagrams from Categories and System Diagram from Templates. 14. Enter Overall.sd as the name of the diagram. 15. Click Add 16. This will create a blank work space for a new system diagram select Internal and External from the Systems folder under System View and drag and drop them onto the designer. 17. Then use the connection tool to link the endpoints together see figure 17-40.
764
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-40. Over all representation of internal and external System Diagram
With a nested multilevel system diagram we can easily traverse the different system diagram levels by right clicking on a sub system diagram and selecting “Open in System Designer” see figure 17-41.
Figure 17-41. Viewing sub system diagrams
Specifying Logical Datacenter Diagram The logical datacenter diagram allows us to create the hardware setup to run the application on. Too often developers have developed software without considering the setup of existing infrastructure. In the following example we will be following on from the previous examples to create a logical datacenter to host the Web application we had created previously. 1.
Right click on the Solution Items and select Add -> New Distributed System Diagram.
2.
Select Distributed System Diagrams from the Categories and Logical Datacenter Diagram from the Templates. Rename the diagram as Infrastructure.ldd figure 17-42.
765
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-42. New Logical Datacenter Diagram
3.
Select Add to create a new designer.
At this point another an infrastructure logical diagram would have been created. There’re also new tools in the Toolbox that we can use to create our infrastructure see figure 17-43.
Figure 17-43. Toolbox for Logical Datacenter Designer Table 17-3. Tools for the Logical Datacenter
766
The Complete Reference To Professional SOA with Visual Studio 2005
Tools
Description
Pointer Connection Comment WebSiteEndpoint HTTPClientEndpoint DatabaseClientEndpoint GenericServerEndpoint GenericClientEndpoint ZoneEndpoint WindowsClient IISWebServer DatabaseServer GenericServer Zone
Used to drag and drop objects on the diagram Used to connect two similar endpoints Used to add a comment to the diagram Manages Serverside communication with a logical IIS web server Manages clientside communication with a logical IIS web server Manages client-side communication with a logical database server Manages server-side communication with a logical generic server Manages client-side communication with a logical generic server Manages communication on the boundry of a zone Corresponds to a Windows client or server that hosts a Windows Application Corresponds to a IIS Web server Corresponds to a database server Corresponds to a user-defined server or component Zones can be nested. A zone corresponds to a logical boudry that is separate from other portions of a datacenter.
Generally an infrastructure is protected through firewalls. A zone as such defines the communication boundaries within the Logical Datacenter Designer. They are used to define communication boundaries, physical boundaries or security boundaries. Let’s add the internal and external zones to the designer: 1.
Select the zone tool from the Toolbox and drag and drop it onto the designer surface.
2.
Rename the zone by clicking on the Zone1 text and renaming it to Internal
3.
Repeat the process to create an External zone see figure 17-44.
767
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-44. Zones
Now we can place the relevant servers into the zones. We can start by adding the database and the IIS web server to the internal zone followed by an IIS web server to the external zone. 1.
Select DatabaseServer tool from the Toolbox and drag and drop the tool onto the Internal zone.
2.
Do the same with the IISWebServer by drag and dropping the tool onto the Internal zone.
3.
Drag and drop a new IISWebServer tool to the External zone. We should have something similar to figure 1745.
Figure 17-45. Server setup within the zones.
Communication between zones are managed through the zone endpoints. The communications can be inbound, outbound, or bidirectional. The arrows used between the zones are used to represent the communication flow. To implement connection between the zones, we will start with implementing the connection for the internal zone. Follow the following steps: 4.
Select connection tool from the Toolbox. Select the inbound arrow (>) in dark grey in the diagram and then select one of the WebSiteEndpoint for the IISWebServer object. This will create an incoming communication flow.
5.
To create an outgoing communication flow select the outbound arrow (>) in lighter colour and select the other not yet assigned WebSiteEndpoint in the IISWebServer.
We also need to establish a database connection from the IIS web server to the DatabaseServer.
768
The Complete Reference To Professional SOA with Visual Studio 2005
6.
Select the DatabaseClientEndpoint and drag and drop the tool onto the IISWebServer.
7.
Then select the connection tool from the Toolbox and select the DatabaseClientEndpoint on the IISWebServer and then select the DatabaseServer’s DatabaseServerEndpoint.
Having completed the above steps the diagram should look similar to the figure 17-46.
Figure 17-46. Internal infrastructure with connections
8.
Now to configure the connection for the External Zone. Select the connection tool then select incoming zone endpoint connection from the Internal zone (the (>) with grey) to the outgoing zone endpoint of the External Zone (the (>) without grey).
Tip: We can drag the Zone endpoint around the boudry of the zone object to visually improve the layout of the communication flow.
9.
To connect the External IISWebServer to the communication flow. Select the connection tool then select the WebSiteEndpoint followed by selecting the incoming zone communication endpoint.
10. To specify an outgoing communication flow from the External zone to the Internal zone select the connection tool then select the WebSiteEndpoint of the IISWebServer followed by selecting the outgoing zone endpoint.
We also want to distinguish between the two IISWebServers. It is always a good idea to give them names that they can be identified by individually. 11. Select the IISWebServer in the Internal Zone right click the object select properties. Rename the object to IISWebServerInternal. 12. Select the IISWebServer in the External Zone right click the object select properties. Rename the object to IISWebServerExternal. 13. Now we should have something similar to the figure 17-47.
769
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-47. Infrastructure
Tip: The zone endpoint can be configured as Bidirectional, Outbound and Inbound. To configure the communication flow, select an endpoint then right click and select properties. In properties under Behavior under Communication Flow we can select from the drop down list figure 17-48.
Figure 17-48. Communication Flow
770
The Complete Reference To Professional SOA with Visual Studio 2005
Settings and Constraints In the Logical Datacenter Diagram we can also specify constraints for all logical servers and endpoints. For example we can specify the security constraints for an IISWebServer. To do this simply select the object and right click then select Settings and Constraints. Using constraints we can specify the security requirements for an Internal IISWebServer see figure 17-49.
Figure 17-49. Constraints for IISWebServer.
Importing IIS Server Settings Using the Logical Designer we can also import IIS settings into the settings and constraints. The logical IISWebServer should represent the actual IISWebServer in the real infrastructure. So its important to ensure that the constraints are correct. To import settings: 1.
Right click on the Logical Server Settings. The context menu contains an option to Import Settings see figure 17-50.
771
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-50. Import Settings
Select the option this will bring up a wizard see figure 17-51.
Figure 17-51. Import Settings
2.
Select Next to continue the process. This will bring us to an IIS setting window. Incase the IIS web server is not on the same machine as Visual Studio we can specify the necessary information in this window to connect to the IIS Web server see figure 17-52.
772
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-52. Import Wizard
3.
Once the wizard connects to the IIS Web server it may detect that we might have several Web sites specified on our IIS Web Server. In this case it will prompt us to select which Web Site setting we want to use as a binding setting for a WebSiteEndpoint. Once the selection is complete select Next to complete the process figure 17-53.
Figure 17-53. Selecting Endpoint
4.
We will be prompted to confirm the process before the imported setting overwrites the current settings associated for the Endpoint figure 17-54.
773
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-54. Confirm import settings
We can see that the Logical Sever Settings is named after the server. Selecting the WebSiteEndpoint1 as the binding endpoint we can see that the settings had been imported successfully. Below shows a screenshot of the before import image figure 17-55 and an after image figure 17-56 for comparison.
Figure 17-55. Before import
774
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-56. New settings after import
Deployment Diagram Deployment Diagram is the final diagram that we need to construct to consolidate all the information we had entered into the Application Diagram, System Diagram and Logical Datacenter Diagram. It provides a means to validate the different settings specified by that of the application architect, to the system architect to the infrastructure architect. This process usually is extremely tedious and complicated in the real world with endless meetings between architects. However with Visual Studio this consolidation of information and verification can be achieved with a click of a button. In the following example we will be implementing a deployment diagram to consolidate all of the diagrams we had created in the previous section.
Creating the Deployment Diagram 1.
Open the System Diagram Overall.sd we had created earlier.
2.
Right click on the work space and select Define Deployment figure 17-57.
775
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-57. Overall System Diagram
3.
This raises a Define Deployment dialog window figure 17-58. The Logical Datacenter diagram selects Infrastructure as our default datacenter diagram. This is the same infrastructure Logical Datacenter Diagram we had created earlier.
Figure 17-58. Define Deployment Diagram
4.
Select OK to continue the process.
776
The Complete Reference To Professional SOA with Visual Studio 2005
This will result in the generation of an Overall1.dd deployment diagram see figure 17-59 below.
Figure 17-59. Generated Deployment Diagram
Once the deployment diagram has been created we need to associated the infrastructure that we had specified with actual applications that will reside on them. There are two ways to associate applications to infrastructures the easiest way is simply selecting the application we’re interested in and drag and dropping them into the relevant application figure 17-60.
Figure 17-60. Drag and drop application to server binding.
If this results in an incorrect binding between application and server then a cross will be shown figure 17-61.
777
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-61. Incompatiable
Alternatively we can use the Bind Application option to associate application to server: 5.
We can do this by right click on the WebApplicationWSConsumer application then selecting Bind Application figure 17-62.
Figure 17-62. Bind Application
A bind application to logical server dialog window will appear.
Figure 17-63. Selecting a logical server
6.
Because the web service consumer is situated outside on the external infrastructure we will select IISWebServerExternal (this is the name of the IIS Web server we had specified in Logical Datacenter Designer). The application is now associated with the logical server see figure 17-64.
778
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-64. Associated application and logical server
7.
Do the same for WebserviceContactManagement application by right click on the application and selecting Bind Application. The designer is smart enough to work out that there is only one web server that can host the WebserviceContactManagement application and that’s using the IIS Web server in the Internal Zone see figure 17-65.
Figure 17-65. Selecting logical server
8.
Do the same process to AdventureWorks Database application by right click on the database application and selecting Bind Application. Select the Database server that’s shown see figure 17-66.
Figure 17-66. Selecting a Database Server
Once the process is complete all the application under the System View window should be shown as see figure 17-67 below.
779
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-67. System View
Each of the logical servers in the deployment diagram also shows to have an application to have bound to them figure 17-68.
Figure 17-68. Deployment Diagram
Validating the Deployment Scenario After we have created the deployment diagram. We can validate our deployment secenario against the settings and constraints that what we had specified through the different designers. To start the validation process simply right click on the deployment designer work space and select Validate Diagram figure 17-69.
780
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-69. Validate Diagram
The Error List window will display any errors or warnings that Visual Studio will come across as being inconsistent between the diagrams see figure 17-70.
Figure 17-70. Error List
To check what actually resulted in the warning. Simply double click on the warning to view the inconsistency. In this case the two IIS Web application settings are inconsistent. We’re brought to the System Diagram which resulted in the inconsistency. The object in question now has a red cross on the diagram, figure 17-71.
781
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-71. Inconsistency in diagram is marked with a red cross
After double clicking on the warning message in the Error List window. A dialog window appears it shows where the inconsistency is located. In this case it is the authentication mode. As with the connecting web service we have specified an authentication mode of none. Whilst the current IIS web server requires Windows authentication mode. To rectify the warning simply set the Mode from Windows to None. Then save the changes on the solution designer.
Figure 17-72. Modifying settings and constraints.
Going back to the deployment designer right click on the screen and select Validate Diagram again to make sure that there is no more errors left, figure 17-73.
782
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-73. Error List
Generating Deployment Report After we have created a valid deployment diagram. We can generate a deployment report. The report generation feature is particularly handy, as it provides the means to document everything within the architecture for reference at a later date. Generating the report is very simple. Follow the following steps: 1.
Right click on the deployment diagram and select Generate Deployment Report figure 17-74.
Figure 17-74. Generate Deployment Report
The Overall1 HTML report is generated. It’s a large document which contains all system diagrams and logical datacenter diagrams as well as all details on endpoints, resources and settings see figure 17-75.
783
The Complete Reference To Professional SOA with Visual Studio 2005
Figure 17-75. Infrastructure deployment report.
We can also view this document in the web browser simply right click on the document and select View in Browser.
Summary In this chapter we have learnt how to conceptually represent diagrams using the four designers from the Distributed Systems Designer suite: Application Designer, System Designer, Logical Datacenter Designer and Deployment Designer. The application designer can be used to construct diagrams that represent the actual software system. We can represent different types of application using the application designer then using the connection tool to establish the links between the systems. The system designer can be used to configure the deployment view of a particular use of the actual application system. Using the diagrams that we have configured in the system designer we can also specify the logical datacenter diagram. This diagram represents the infrastructure of a datacenter. Once the diagrams had been completed we can consolidate all the information acquired into a deployment diagram. This is where application systems are consolidated to specific logical servers. Through the deployment diagram we can validate settings and constraints that we had specified at different levels of the diagram. From the deployment diagram we can also generate a deployment report. The report contains all information about the deployable components and infrastructures. It is a very detailed report that can be used as reference in future.
784
The Complete Reference To Professional SOA with Visual Studio 2005
Indexes & & .........................................................................137 ' .........................................................................137 > .............................................................................137 < ..............................................................................137 " .........................................................................137
. .NET Data Provider.....................................................189 .NET DataSets.............................................................185 .NET Deployment .......................................................389 .NET Framework.........................................................100 .NET Framework 2.0...................................................103 .NET Framework class libraries ..................................101 .NET Serialization.......................................................271 .NET Web Service Message Flow...............................124 .NET XML Serialization .............................................271
A ADO.NET ...................................................................182 ADO.NET DataSet Events ..........................................218 ADO.NET DataSets ....................................................213 Advanced Web Service Programming ........................419 Application Proxy .........................................................68 Architectural Tradeoff Matrix .......................................26 Architectural Tradeoff Triangle ....................................26 Assembly Information.................................................390 Asymmetric (Public) Key Encryption ...........................65 Async Data Access......................................................183 Asynchronous Web service .........................................432 Attributes and Namespaces .........................................136 Authentication...............................................................60 Authorization ................................................................60 Autos Window ............................................................362
B Basic services ................................................................48 BEA ..............................................................................45 BeginExecuteReader ...................................................183 BeginExecuteXmlReader ............................................183 binding ........................................................................177 Boolean .......................................................................143 Breakpoint Window ....................................................363 Budget Consideration....................................................81 Buffering .....................................................................419 BufferResponse ...........................................................419 Business and IT.............................................................80 Business Benefits of SOA .............................................27 Business Process Execution Language for Web Services (BPEL4WS).............................................................54 Byte .............................................................................143
C CacheDuration .................................................... 419, 424 Call Stack Window ..................................................... 362 CDATA ...................................................................... 138 CDATA sections......................................................... 138 Choreography ............................................................... 53 Cities............................................................................. 24 Class View.................................................................. 114 ClickOnce ........................................................... 399, 403 Code Coverage............................................................ 378 ColumnChanged ......................................................... 218 ColumnChanging........................................................ 218 Command.................................................................... 186 Common Language Runtime (CLR)........................... 102 Common Type System (CTS)..................................... 102 Confidentiality .............................................................. 61 Connected System Strategy .......................................... 71 Connection.................................................................. 186 ConnectionString ........................................................ 190 Continuous Track.......................................................... 86 Controlled code sharing .............................................. 389 Controlling Serialization............................................. 282 Coordination Services................................................... 55 Copying DataSet Contents.......................................... 216 Creating Data Views ................................................... 217 Creating XML Web Services...................................... 316 Cross Entities Query ..................................................... 52
D Data Adapters ............................................................. 195 Data Encoding ............................................................ 161 Data Providers ............................................................ 186 DataAdapter................................................................ 187 Data-Centric Services ................................................... 48 DataReader ......................................................... 186, 197 DataRow ..................................................................... 208 DataSet........................................................................ 207 DataTable.................................................................... 207 Datatype picker ........................................................... 155 Date............................................................................. 143 dateTime ..................................................................... 144 decimal........................................................................ 144 definitions ................................................................... 175 DeleteCommand ......................................................... 196 Deploying Track ........................................................... 85 Deployment ................................................................ 389 Description.................................................................. 419 Description for a Web Method.................................... 425 Developing Track ......................................................... 84 Distributed Event Driven Architecture and SOA........ See EDA Document.................................................................... 114 Document Object Model............................................. 240
785
The Complete Reference To Professional SOA with Visual Studio 2005
DocumentType............................................................242 double..........................................................................144 duration .......................................................................144
E EDA ..............................................................................55 Elements......................................................................134 EnableSession .....................................................419, 427 EndExecuteNonQuery.................................................183 EndExecuteReader ......................................................183 EndExecuteXmlReader ...............................................183 Enterprise Application Integration (EAI) ......................52 Enterprise Architecture .................................................25 Enterprise Service Bus & Services................................56 Entity Aggregation ........................................................50 enumeration.................................................................149 Envisioning Track .........................................................84 Error list ......................................................................141 Error List.....................................................................113 ESB ......................See Enterprise Service Bus & Services ExecuteReader ............................................................183 ExecuteScalar..............................................................193 ExpectedExceptionAttribute .......................................377
F Facets ..........................................................................149 Factories........................................................................24 fractionDigits ..............................................................150
G Gathering Internal Support............................................81 gDay............................................................................144 GET and POST ...........................................................128 GetFileBuffered()........................................................424 GetFileUnbuffered()....................................................424 GetResponse................................................................170 global.asax ..................................................................115 gMonth........................................................................144 gMonthDay .................................................................145 Governance ...................................................................85 gYear...........................................................................145 gYearMonth ................................................................145
H hexBinary....................................................................145 Horizontal Partitions .....................................................51 HTTP ..........................................................................126 HTTP With .NET........................................................130 HttpWebRequest .........................................................130 HttpWebResponse...............................................130, 170 Hyper Text Transfer Protocol (HTTP) ........................124
I Implementing Sampling ..............................................382 Initializing and Cleaning Up Tests ..............................379 InsertCommand ...........................................................195 Instrumentation ...........................................................382 int 145
integer ......................................................................... 145 Integrity ........................................................................ 61 Internal Politics............................................................. 80 Inter-Platform Connection ............................................ 76 Invoking Web Method using .NET HTTP POST, GET and SOAP .............................................................. 164 IsClosed ...................................................................... 199 IT Cost Savings............................................................. 74 IT Infrastructure Evolution ........................................... 25 Iterative Quality Assurance........................................... 47
J Just-In-Time (JIT)....................................................... 102
L language...................................................................... 146 Language constructs ................................................... 153 Legacy Enterprise Architecture .................................... 33 length .......................................................................... 150 list 154 Locals Window........................................................... 362 Logical Layers to Physical Tiers................................... 49 Logic-Centric Services ................................................. 48 long............................................................................. 146 Loose Coupling............................................................. 29
M managed applications.................................................. 102 Managed Development ............................................... 102 Manipulating XML with .NET ................................... 240 Manually Creating a Typed Dataset............................ 220 Manufactured................................................................ 24 maxExclusive.............................................................. 150 maxInclusive............................................................... 150 maxLength .................................................................. 151 Measuring a SOA ......................................................... 78 message....................................................................... 176 Message Reliability....................................................... 68 MessageName..................................................... 419, 429 Metropolis..................................................................... 23 minExclusive .............................................................. 151 minInclusive ............................................................... 151 minLength................................................................... 152 minOccurs................................................................... 157 MSF .............................................................................. 81 MSF Agile .................................................................... 83 MSF Risk Management ................................................ 90 MSF Tracks .................................................................. 82
N Name........................................................................... 146 namespaces ................................................................. 135 NCName ............................................................. 135, 146 negativeInteger ........................................................... 146 NMTOKEN ................................................................ 157 No-impact deployment.............................................. 389 noNamespaceSchemaLocation ................................... 156 nonNegativeInteger..................................................... 147 nonPositiveInteger ...................................................... 147
786
The Complete Reference To Professional SOA with Visual Studio 2005
Non-repudiation ............................................................61 normalizedString .........................................................147 Numeric types .............................................................142
O OdbcDataAdapter........................................................187 OdbcDataReader .........................................................187 OLE DB Data Provider in .NET .................................189 OleDBAuthors ............................................................190 OleDbCommand .........................................................192 OleDbConnection................................................189, 190 OleDbDataAdapter......................................................187 OleDbDataReader ...............................................187, 199 Open Schema ..............................................................310 Opening and Closing Connections ..............................190 Operational Management ..............................................86 OracleDataAdapterfor .................................................187 OracleDataReader .......................................................187 Orchestration................................................................53 Organization Vision ......................................................80 Organizational Roadmap...............................................79 Overloaded ..................................................................429
P pattern .........................................................................152 Planning Track ..............................................................84 Point-to-Point vs End-to-End Security..........................61 portType ......................................................................177 positiveInteger.............................................................147 Primary Keys...............................................................215 Profiling ......................................................................381 Program Management ...................................................87 Project Conversion Report ..........................................111 Project Conversion Wizard .........................................111 Project Teams................................................................86 Properties ....................................................................113 Public Services ..............................................................49 Publishing ...................................................................399
Q QName ........................................................................147
R RecordsAffected..........................................................199 Relationships with Typed Dataset ...............................227 restriction ....................................................................153 RowChanged...............................................................218 RowChanging..............................................................219 RowDeleted.................................................................219 RowDeleting ...............................................................219
S SAML ...................................................................67, 181 Sampling .....................................................................381 schemaLocation...........................................................156 Security Basics ..............................................................60 Security in Service Oriented Architecture.....................60 Security with Federation ...............................................66
SelectCommand .......................................................... 195 SerializableClass......................................................... 279 Serialization Formatter ............................................... 273 Serializing Arrays ....................................................... 293 Server Explorer........................................................... 113 service......................................................................... 178 Service Oriented Architecture....................................... 23 Service Oriented Enterprise Architecture ..................... 33 Service Types................................................................ 48 Services......................................................................... 30 Session State ............................................................... 427 short ............................................................................ 148 Simple Object Access Protocol (SOAP) ..................... 159 simpleType ................................................................. 153 Single View of Entity ................................................... 50 SOA Architectural Roadmap ........................................ 44 SOA Driven Project Development......................See MSF SOA future vision ......................................................... 46 SOA Governance .......................................................... 47 SOA maturity assessment ............................................. 46 SOA planning ............................................................... 46 SOA roadmap definition............................................... 47 SOAP .................................................................... 31, 159 SOAP Body ................................................................ 160 SOAP Fault................................................................. 161 SOAP Header.............................................................. 160 SOAP Interceptor.......................................................... 66 SOAP Message Monitoring .......................................... 65 SOAP Request ............................................................ 161 SOAP Response.......................................................... 162 SOAP via HTTP ......................................................... 162 Solution Explorer........................................................ 113 SqlCommand.ExecuteXmlReader .............................. 184 SqlCommandBuilder .................................................. 210 SqlConnection Class ................................................... 190 SqlDataAdapter........................................................... 210 SqlDataReader ............................................................ 198 SqlTruncateException................................................. 228 SqlUdt......................................................................... 184 Stabilizing Track........................................................... 85 Standardization ............................................................. 24 Static Analysis ............................................................ 380 StreamReader.............................................................. 130 StreamWriter............................................................... 130 string ........................................................................... 148 Strongly Typed XML Serialization............................. 299 Support for digital signature ....................................... 180 Symmetric Key Encryption........................................ 65 System.Data.SqlTypes ................................................ 184 System.Runtime.Serialization.Formatters.Soap.......... 276 System.Xml.Serialization ........................................... 279
T TableCleared............................................................... 219 TableClearing ............................................................. 219 TableNewRow ............................................................ 219 Task List ............................................................. 114, 118 Technology Soup .......................................................... 33 Test Plan ..................................................................... 354 TestCleanupAttribute.................................................. 379 TestInitializeAttribute................................................. 379 Tests............................................................................ 376
787
The Complete Reference To Professional SOA with Visual Studio 2005
time .............................................................................148 token............................................................................148 Toolbox.......................................................................113 totalDigits....................................................................152 TransactionOption.......................................................419 Transitional Services .....................................................49 Transportation ...............................................................24 Typed ADO.NET DataSet...........................................219 types ............................................................................175
U UDDI.............................................................................32 UDDI SDK..................................................................180 UDDI v3......................................................................179 Union ..........................................................................154 unmanaged applications ..............................................102 unsignedByte...............................................................148 unsignedInt..................................................................148 unsignedLong..............................................................149 unsignedShort..............................................................149 UpdateCommand.........................................................196 Urban Infrastructure ......................................................25 Using Web Deployment Projects ................................404
V ValidationType............................................................266 Virtual Enterprises ........................................................25 Visual Studio 2005 Editions........................................105 Visual Studio 2005 Express Editions ..........................105 Visual Studio 2005 Professional Edition.....................106 Visual Studio 2005 Projectless Development..............110 Visual Studio 2005 Standard Edition ..........................105 Visual Studio 2005 Team Edition for Software Architects ...............................................................................104 Visual Studio 2005 Team Edition for Software Developers .............................................................105 Visual Studio 2005 Team Edition for Software Testers ...............................................................................105 Visual Studio 2005 Team Foundation Server..............105 Visual Studio 2005 Team Roles ..................................104 Visual Studio 2005 Team Suite...................................105 Visual Studio 2005 Team System ...............................388 Visual Studio IDE .......................................................112 Visual Studio Windows...............................................113
W Watch Window ...........................................................361 Web Server Description Language (WSDL)...............103 Web Service ..........................................................28, 315 Web Service Authentication..........................................63 Web Service Choreography Interface (WSCI) ..............53 Web Service Management Orchestration ......................59 Web service technology stack .....................................124 Web Service Template ................................................106 Web Services Description Language (WSDL)............175 Web Setup Project.......................................................414 web.config...................................................................114 Well-formed XML ......................................................138 whiteSpace ..................................................................153
WriteXmlSchema ....................................................... 266 WS-* Standards .......................................................... 180 WSDL................................................................... 31, 178 WS-Federation............................................................ 180 WS-Policy................................................................... 180 WS-PolicyAttachment ................................................ 181 WS-SecureConversation ............................................. 180 WS-Security.......................................................... 64, 180 WS-SecurityPolicy...................................................... 180 WS-Trust .................................................................... 180
X XACML...................................................................... 181 XCOPY....................................................................... 389 XKMS......................................................................... 181 XML ........................................................................... 134 XML and DataSet ....................................................... 266 XML and XML Schema ............................................... 30 XML Comments ......................................................... 136 XML Datatypes .......................................................... 142 XML Date and time types........................................... 142 XML declaration......................................................... 138 XML Encryption........................................................... 64 XML Name and string types....................................... 143 XML Parser ................................................................ 247 XML Prohibited character literals............................... 137 XML Schema.............................................................. 155 XML Schema Definition (XSD) ................................. 141 XML Schema Structures............................................. 155 XML Serialization ...................................................... 279 XML Signature ............................................................. 65 XML Validation.......................................................... 262 XML Web service....................................................... 124 XML Web Services ...................................................... 30 XML Whitespace........................................................ 137 XmlAnyAttribute................................................ 296, 310 XmlAnyElement ................................................. 296, 310 XmlAttribute............................................................... 242 XML-Data Reduced (XDR)........................................ 262 XmlDocument............................................................. 242 XmlDocumentFragment ............................................. 242 XmlDocumentType .................................................... 242 XmlElement........................................................ 242, 283 XmlEntity ................................................................... 242 XmlEntityReference ................................................... 242 XmlInclude ................................................................. 297 XmlNodeType ............................................................ 252 XmlNotation ............................................................... 242 XmlProcessingInstruction........................................... 242 XmlReader.................................................................. 249 XmlRoot ..................................................................... 283 XMLSchemainstance.................................................. 155 XmlSchemaSet’s......................................................... 266 XmlTextReader........................................................... 250 XMLTextReader......................................................... 252 XmlWriter................................................................... 249 XPath .................................................................... 30, 256 XPathNavigator .......................................................... 255 XPathNodeType ......................................................... 257 xs:sequence ................................................................. 140 XSD .................................................................... 158, 259
788