12.07.2015 Views

Using SOAP and Web Services with Ensemble - InterSystems ...

Using SOAP and Web Services with Ensemble - InterSystems ...

Using SOAP and Web Services with Ensemble - InterSystems ...

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong><strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>Version 2008.207 October 2008<strong>InterSystems</strong> Corporation 1 Memorial Drive Cambridge MA 02142 www.intersystems.com


<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong><strong>InterSystems</strong> Version 2008.2 07 October 2008Copyright © 2008 <strong>InterSystems</strong> CorporationAll rights reserved.This book was assembled <strong>and</strong> formatted in Adobe Page Description Format (PDF) using tools <strong>and</strong> information fromthe following sources: Sun Microsystems, RenderX, Inc., Adobe Systems, <strong>and</strong> the World Wide <strong>Web</strong> Consortium atwww.w3c.org. The primary document development tools were special-purpose XML-processing applications builtby <strong>InterSystems</strong> using Caché <strong>and</strong> Java.<strong>and</strong>Caché WEBLINK, Distributed Cache Protocol, M/SQL, N/NET, <strong>and</strong> M/PACT are registered trademarks of <strong>InterSystems</strong>Corporation.<strong>and</strong><strong>InterSystems</strong> TrakCare, <strong>InterSystems</strong> Jalapeño Technology, Enterprise Cache Protocol, ECP, <strong>and</strong> <strong>InterSystems</strong>Zen are trademarks of <strong>InterSystems</strong> Corporation.All other br<strong>and</strong> or product names used herein are trademarks or registered trademarks of their respective companiesor organizations.This document contains trade secret <strong>and</strong> confidential information which is the property of <strong>InterSystems</strong> Corporation,One Memorial Drive, Cambridge, MA 02142, or its affiliates, <strong>and</strong> is furnished for the sole purpose of the operation<strong>and</strong> maintenance of the products of <strong>InterSystems</strong> Corporation. No part of this publication is to be used for any otherpurpose, <strong>and</strong> this publication is not to be reproduced, copied, disclosed, transmitted, stored in a retrieval system ortranslated into any human or computer language, in any form, by any means, in whole or in part, <strong>with</strong>out the expressprior written consent of <strong>InterSystems</strong> Corporation.The copying, use <strong>and</strong> disposition of this document <strong>and</strong> the software programs described herein is prohibited exceptto the limited extent set forth in the st<strong>and</strong>ard software license agreement(s) of <strong>InterSystems</strong> Corporation coveringsuch programs <strong>and</strong> related documentation. <strong>InterSystems</strong> Corporation makes no representations <strong>and</strong> warrantiesconcerning such software programs other than those set forth in such st<strong>and</strong>ard software license agreement(s). Inaddition, the liability of <strong>InterSystems</strong> Corporation for any losses or damages relating to or arising out of the use ofsuch software programs is limited in the manner set forth in such st<strong>and</strong>ard software license agreement(s).THE FOREGOING IS A GENERAL SUMMARY OF THE RESTRICTIONS AND LIMITATIONS IMPOSED BYINTERSYSTEMS CORPORATION ON THE USE OF, AND LIABILITY ARISING FROM, ITS COMPUTERSOFTWARE. FOR COMPLETE INFORMATION REFERENCE SHOULD BE MADE TO THE STANDARD SOFTWARELICENSE AGREEMENT(S) OF INTERSYSTEMS CORPORATION, COPIES OF WHICH WILL BE MADE AVAILABLEUPON REQUEST.<strong>InterSystems</strong> Corporation disclaims responsibility for errors which may appear in this document, <strong>and</strong> it reserves theright, in its sole discretion <strong>and</strong> <strong>with</strong>out notice, to make substitutions <strong>and</strong> modifications in the products <strong>and</strong> practicesdescribed in this document.For Support questions about any <strong>InterSystems</strong> products, contact:<strong>InterSystems</strong> Worldwide Customer SupportTel: +1 617 621-0700Fax: +1 617 374-9391Email: support@<strong>InterSystems</strong>.com


Table of ContentsAbout This Book ................................................................................................................................ 11 About <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> ..................................................................................................... 31.1 <strong>Ensemble</strong> Support for <strong>Web</strong> <strong>Services</strong> ...................................................................................... 31.2 <strong>Ensemble</strong> Support for <strong>Web</strong> Clients ........................................................................................ 51.2.1 The <strong>SOAP</strong> Client Wizard ............................................................................................. 51.2.2 The Proxy Client .......................................................................................................... 61.2.3 The Business Operation of an <strong>Ensemble</strong> <strong>Web</strong> Client .................................................. 71.3 Specific St<strong>and</strong>ards Supported in <strong>Ensemble</strong> ........................................................................... 82 Creating an <strong>Ensemble</strong> <strong>Web</strong> Service .............................................................................................. 92.1 Overall Behavior .................................................................................................................... 92.2 Basic Requirements ............................................................................................................. 112.2.1 Development Tasks .................................................................................................... 112.2.2 Configuration Tasks ................................................................................................... 132.3 Defining <strong>Web</strong> Methods for Use in <strong>Ensemble</strong> ...................................................................... 142.3.1 Basic Steps of a <strong>Web</strong> Method .................................................................................... 142.3.2 Returning Faults to the Caller .................................................................................... 152.3.3 Example ..................................................................................................................... 162.3.4 Note About Class Queries .......................................................................................... 162.4 Implementing the OnProcessInput Method ......................................................................... 172.4.1 Creating Request <strong>and</strong> Response Classes .................................................................... 182.4.2 <strong>Using</strong> the SendRequestSync Method ......................................................................... 182.4.3 <strong>Using</strong> the SendRequestAsync Method ...................................................................... 192.4.4 Example ..................................................................................................................... 192.5 Viewing the WSDL .............................................................................................................. 202.6 Example ............................................................................................................................... 212.7 Creating a Switch in OnProcessInput .................................................................................. 232.8 Enabling <strong>SOAP</strong> Sessions ..................................................................................................... 242.9 Additional Options ............................................................................................................... 243 Creating an <strong>Ensemble</strong> <strong>Web</strong> Client .............................................................................................. 273.1 Overview .............................................................................................................................. 273.2 Basic Steps ........................................................................................................................... 293.2.1 Development Tasks .................................................................................................... 293.2.2 Configuration Tasks ................................................................................................... 293.3 <strong>Using</strong> the <strong>SOAP</strong> Client Wizard ............................................................................................ 303.3.1 Generated Classes <strong>and</strong> XMLKEEPCLASS ............................................................... 303.3.2 <strong>Using</strong> the Process Method ......................................................................................... 30<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>iii


3.4 Available Runtime Settings .................................................................................................. 323.4.1 Specifying Basics ....................................................................................................... 323.4.2 Specifying Credentials ............................................................................................... 323.4.3 Specifying an SSL Configuration .............................................................................. 333.4.4 Specifying a Proxy Server ......................................................................................... 343.5 Generated Classes for an <strong>Ensemble</strong> <strong>Web</strong> Client .................................................................. 343.6 Creating a Business Operation Class Manually ................................................................... 373.6.1 Basic Requirements of the Class ............................................................................... 373.6.2 Basic Requirements of the Methods .......................................................................... 383.6.3 Ways to Execute the Proxy Methods ......................................................................... 383.6.4 Reference Information ............................................................................................... 40Appendix A: Common Tasks in the <strong>Ensemble</strong> Management Portal ........................................... 43A.1 Adding a Business Host to a Production ............................................................................. 43A.2 Enabling a Business Host .................................................................................................... 44A.3 Editing Other Runtime Settings .......................................................................................... 44A.4 Creating <strong>Ensemble</strong> Credentials ........................................................................................... 45Appendix B: Customizing Startup <strong>and</strong> Teardown ....................................................................... 47B.1 Callback Methods ................................................................................................................ 47B.2 The Startup Sequence .......................................................................................................... 48B.3 The Teardown Sequence ...................................................................................................... 48Appendix C: <strong>Using</strong> the <strong>SOAP</strong> Inbound Adapter .......................................................................... 51C.1 Notes .................................................................................................................................... 51C.2 Development Tasks .............................................................................................................. 52C.3 Configuration Tasks ............................................................................................................. 52C.4 Settings of the Inbound Adapter .......................................................................................... 53Index ................................................................................................................................................. 55iv<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>


List of TablesBasic <strong>Web</strong> Service Parameters .......................................................................................................... 12Common Properties of %<strong>SOAP</strong>.WSDL.Reader ................................................................................ 31<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>v


About This BookThis book describes how an <strong>Ensemble</strong> programmer can create <strong>Ensemble</strong> <strong>Web</strong> services <strong>and</strong> <strong>Ensemble</strong><strong>Web</strong> clients. You should be reasonably familiar <strong>with</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> services.This book contains the following chapters:• About <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong>• Creating an <strong>Ensemble</strong> <strong>Web</strong> Service• Creating an <strong>Ensemble</strong> <strong>Web</strong> ClientThis book also contains the following appendixes:• Common Tasks in the <strong>Ensemble</strong> Management Portal• Customizing Startup <strong>and</strong> Teardown• <strong>Using</strong> the <strong>SOAP</strong> Inbound AdapterThere is also a detailed Table of Contents.For more information, try the following sources:• Developing <strong>Ensemble</strong> Productions describes how to create <strong>Ensemble</strong> productions in general.• Managing <strong>Ensemble</strong> Productions includes information on monitoring <strong>and</strong> correcting the statusof <strong>Ensemble</strong> adapters. It also includes information on common settings used in all business hosts.<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 1


1About <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong><strong>Ensemble</strong> provides support for <strong>SOAP</strong> 1.1 (Simple Object Access Protocol). This support is easy touse, efficient, <strong>and</strong> fully compatible <strong>with</strong> the <strong>SOAP</strong> specification. This support is built into <strong>Ensemble</strong><strong>and</strong> does not require any complex middleware or operating system extensions. It is available on everyplatform supported by <strong>Ensemble</strong>.<strong>Using</strong> <strong>Ensemble</strong> <strong>SOAP</strong> support, you can do the following:• Add a <strong>Web</strong> service to an <strong>Ensemble</strong> production in order to provide a <strong>SOAP</strong>-enabled front end tothe production. Client applications can invoke this <strong>Ensemble</strong> <strong>Web</strong> service by using the <strong>SOAP</strong>protocol. Such methods can be discovered <strong>and</strong> invoked by other <strong>SOAP</strong>-aware applications.<strong>Ensemble</strong> runs <strong>SOAP</strong> methods directly <strong>with</strong>in the database; the execution is highly efficient.• Add a <strong>Web</strong> client to an <strong>Ensemble</strong> production. You can use a tool to generate a business operation<strong>and</strong> the proxy client classes, given the existing WSDL document of the <strong>Web</strong> service you want touse. The <strong>Ensemble</strong> <strong>Web</strong> client invokes the external <strong>Web</strong> service via the <strong>Ensemble</strong> <strong>SOAP</strong> outboundadapter <strong>and</strong> a generated proxy client class.This chapter discusses the following topics:• An overview of <strong>Ensemble</strong> support for <strong>Web</strong> service• An overview of <strong>Ensemble</strong> support for <strong>Web</strong> clients• Where to find information on specific st<strong>and</strong>ards supported by <strong>Ensemble</strong>1.1 <strong>Ensemble</strong> Support for <strong>Web</strong> <strong>Services</strong>You can provide a <strong>SOAP</strong>-enabled front end for your <strong>Ensemble</strong> production. To do so, you create an<strong>Ensemble</strong> <strong>Web</strong> service, which is both a <strong>Web</strong> service <strong>and</strong> an <strong>Ensemble</strong> business service. Internally,<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 3


About <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong>your <strong>Web</strong> methods generally receive <strong>SOAP</strong> request messages, use them to construct <strong>and</strong> send<strong>Ensemble</strong> request messages as needed <strong>with</strong>in the production, receive the <strong>Ensemble</strong> response messages,<strong>and</strong> use them to construct <strong>SOAP</strong> response messages.To enable you to create an <strong>Ensemble</strong> <strong>Web</strong> service, <strong>Ensemble</strong> provides the base <strong>Ensemble</strong> <strong>Web</strong> serviceclass (EnsLib.<strong>SOAP</strong>.Service), as well as supporting classes in the %<strong>SOAP</strong> <strong>and</strong> %XML packages.<strong>Ensemble</strong> provides powerful, built-in support for <strong>Web</strong> services. The base <strong>Ensemble</strong> <strong>Web</strong> service classdoes the following for you:• Validates incoming <strong>SOAP</strong> messages.• Unpacks <strong>SOAP</strong> messages, converts data to <strong>Ensemble</strong> representation, <strong>and</strong> invokes the correspondingmethod, which sends an <strong>Ensemble</strong> request message to a destination inside the production.• Runs the method.• Receives an <strong>Ensemble</strong> response message <strong>and</strong> then constructs <strong>and</strong> returns a response message (a<strong>SOAP</strong> message) to the caller.The <strong>SOAP</strong> specification does not include session support. However, it is often useful to maintain asession between a <strong>Web</strong> client <strong>and</strong> the <strong>Web</strong> service that it uses. You can do this <strong>with</strong> an <strong>Ensemble</strong> <strong>Web</strong>service. If a <strong>Web</strong> service uses sessions, it establishes a session ID <strong>and</strong> allows repeated calls on theservice after one successfully authenticated call from a client.The <strong>Ensemble</strong> <strong>Web</strong> service class also provides the full functionality of any <strong>Ensemble</strong> business service.Note:To create an <strong>Ensemble</strong> <strong>Web</strong> service, you do not use an <strong>Ensemble</strong> adapter.4 <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>


1.2 <strong>Ensemble</strong> Support for <strong>Web</strong> Clients<strong>Ensemble</strong> Support for <strong>Web</strong> ClientsYou can invoke an external <strong>Web</strong> service from <strong>with</strong>in an <strong>Ensemble</strong> production. To do so, you createan <strong>Ensemble</strong> <strong>Web</strong> client.At a high level, your <strong>Ensemble</strong> <strong>Web</strong> client receives <strong>Ensemble</strong> requests, converts them to <strong>SOAP</strong> requests<strong>and</strong> sends them to the appropriate <strong>Web</strong> service. Similarly, it receives <strong>SOAP</strong> responses <strong>and</strong> convertsthem into <strong>Ensemble</strong> responses.The <strong>Ensemble</strong> <strong>Web</strong> client consists of the following parts, all of which you can generate in Studio byusing the <strong>SOAP</strong> client wizard:• A proxy client class that defines a proxy method for each method defined by the <strong>Web</strong> service. Thepurpose of the proxy client is to specify the location of the <strong>Web</strong> service <strong>and</strong> to contain the proxymethods. Each proxy method uses the same signature used by the corresponding <strong>Web</strong> servicemethod <strong>and</strong> invokes that method when requested.• A business operation that uses the <strong>Ensemble</strong> <strong>SOAP</strong> outbound adapter to invoke the proxy methods.• Supporting classes as needed to define XML types <strong>and</strong> <strong>Ensemble</strong> messages.1.2.1 The <strong>SOAP</strong> Client WizardIn order to underst<strong>and</strong> these parts, it is useful to consider how they are generated. First, when you usethe <strong>SOAP</strong> client wizard, you provide the URL for the WSDL of the <strong>Web</strong> service of interest. The wizardreads the WSDL <strong>and</strong> then generates a set of classes.<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 5


About <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong>1.2.2 The Proxy ClientThe generated classes include the proxy client class that defines a proxy method for each method ofthe <strong>Web</strong> service. Each proxy method sends a <strong>SOAP</strong> request to the <strong>Web</strong> service (as shown below) <strong>and</strong>receives the corresponding <strong>SOAP</strong> response.6 <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>


<strong>Ensemble</strong> Support for <strong>Web</strong> ClientsAs shown in the figure, the generated classes also include classes that define any XML types neededas input or output for the methods.1.2.3 The Business Operation of an <strong>Ensemble</strong> <strong>Web</strong> ClientThe wizard also gives you the option of generating a business operation class that invokes the proxyclient, as well as classes that define message types as needed. The following figure shows how theseclasses work:<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 7


About <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong>The classes <strong>and</strong> methods shown <strong>with</strong>in dashed lines are all generated by the <strong>SOAP</strong> client wizard.The business operation uses the <strong>SOAP</strong> outbound adapter, which provides useful runtime settings <strong>and</strong>the generic method InvokeMethod. To invoke a proxy method in the proxy client class, the businessoperation class calls InvokeMethod, passing to it the name of the method to run, as well as anyarguments. In turn, InvokeMethod calls the method of the proxy client class.1.3 Specific St<strong>and</strong>ards Supported in <strong>Ensemble</strong>For information on the specific st<strong>and</strong>ards followed by the Caché/<strong>Ensemble</strong> support for <strong>SOAP</strong> <strong>and</strong><strong>Web</strong> services, see the book <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> Caché in the Caché documentationset.Also see <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> Caché for WSDL limitations in the Caché/<strong>Ensemble</strong>support for <strong>Web</strong> services.8 <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>


2Creating an <strong>Ensemble</strong> <strong>Web</strong> ServiceThis chapter describes how to create an <strong>Ensemble</strong> <strong>Web</strong> service, which is a <strong>Web</strong> service in an <strong>Ensemble</strong>production. When you do this, you are providing a <strong>SOAP</strong>-enabled interface to the production. Thischapter discusses the following:• Overall behavior of an <strong>Ensemble</strong> <strong>Web</strong> service• Basic requirements for creating one• How to define <strong>Web</strong> methods <strong>with</strong>in an <strong>Ensemble</strong> <strong>Web</strong> service• How to implement the OnProcessInput method of an <strong>Ensemble</strong> <strong>Web</strong> service• How to view the WSDL for your <strong>Web</strong> service that <strong>Ensemble</strong> automatically generates <strong>and</strong> publishesfor• A simple example• How to create a switch inside OnProcessInput method if you want to address different destinations,depending on the <strong>Web</strong> method called• How to enable <strong>SOAP</strong> sessions• A summary of ways you can fine-tune the <strong>Web</strong> methods in your <strong>Ensemble</strong> <strong>Web</strong> service2.1 Overall BehaviorAn <strong>Ensemble</strong> <strong>Web</strong> service is based on EnsLib.<strong>SOAP</strong>.Service or a subclass. This class extends bothEns.BusinessService (so that it is an <strong>Ensemble</strong> business service) <strong>and</strong> %<strong>SOAP</strong>.<strong>Web</strong>Service (so that itcan act as a <strong>Web</strong> service as well). An <strong>Ensemble</strong> <strong>Web</strong> service behaves as follows:<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 9


Creating an <strong>Ensemble</strong> <strong>Web</strong> Service• Because it is a <strong>Web</strong> service, it has a WSDL document (generated automatically) that describesthe <strong>Web</strong> methods available in it. The service can receive any <strong>SOAP</strong> message that conforms to theWSDL <strong>and</strong> sends <strong>SOAP</strong> responses in return.• Because it is an <strong>Ensemble</strong> business service, it is an integral part of the <strong>Ensemble</strong> production towhich you add it. Monitoring, error logging, runtime parameters, <strong>and</strong> all the rest of the <strong>Ensemble</strong>machinery are available as usual.Note:An <strong>Ensemble</strong> <strong>Web</strong> service is not available unless the production is running (<strong>and</strong> thebusiness service is enabled).In contrast to most other <strong>Ensemble</strong> inbound interfaces, the ProcessInput method of the business serviceis not invoked automatically. This means that your <strong>Web</strong> methods must invoke this method as appropriate,passing to it the appropriate request <strong>Ensemble</strong> message <strong>and</strong> receiving an <strong>Ensemble</strong> responsemessage. You can define any message that you need.The ProcessInput method of the <strong>Web</strong> service performs required internal activities <strong>and</strong> then invokesthe OnProcessInput method of the business service, passing to in whatever <strong>Ensemble</strong> request messageit received. The OnProcessInput method is an empty callback method; you customize it to send therequest message to some destination <strong>with</strong>in <strong>Ensemble</strong>.The following figure shows the overall flow of request messages:10 <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>


Basic RequirementsCommunication <strong>with</strong> the outside world is done via <strong>SOAP</strong> request <strong>and</strong> response messages. <strong>Ensemble</strong>request <strong>and</strong> response messages are used <strong>with</strong>in the production. For the <strong>Ensemble</strong> messages, the precedingfigure shows only the requests; the responses are returned by the same path, in reverse.2.2 Basic RequirementsTo create a <strong>Web</strong> service in an <strong>Ensemble</strong> production, you create a new business service class, add it toyour production, <strong>and</strong> configure it.2.2.1 Development TasksImportant:<strong>InterSystems</strong> recommends that you do not place custom code or data in the systemprovidednamespaces ENSLIB or ENSDEMO where it will be deleted the next timeyou upgrade <strong>Ensemble</strong>. The ENSEMBLE namespace <strong>and</strong> any new namespace thatyou create to hold your work is preserved across <strong>Ensemble</strong> upgrades.<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 11


Creating an <strong>Ensemble</strong> <strong>Web</strong> ServiceIn the <strong>Ensemble</strong> Studio, write <strong>and</strong> compile a new business service class. The following list describesthe basic requirements:• Your class should extend EnsLib.<strong>SOAP</strong>.Service. This class extends both Ens.BusinessService (sothat it is an <strong>Ensemble</strong> business service) <strong>and</strong> %<strong>SOAP</strong>.<strong>Web</strong>Service (so that it can act as a <strong>Web</strong> serviceas well).• The class should define the ADAPTER parameter as null ("").• The class should specify values for other parameters:Basic <strong>Web</strong> Service ParametersItemSERVICENAME parameterLOCATION parameterNAMESPACE parameterTYPENAMESPACEparameterRESPONSENAMESPACEparameterDescriptionName of the <strong>Web</strong> service. This name must start <strong>with</strong>a letter <strong>and</strong> must contain only alphanumericcharacters.The default service name is"My<strong>Ensemble</strong>Request<strong>Web</strong>Service"URI for invoking the <strong>Web</strong> service. This can beabsolute or can be relative to the WSDL request URL.For example:"http://localhost/csp/My<strong>Ensemble</strong>/MyProduction/My<strong>Web</strong>Service.cls"The default is null.URI that defines the target XML namespace for your<strong>Web</strong> service, so that your service, <strong>and</strong> its contents,do not conflict <strong>with</strong> another service. This is initiallyset to http://tempuri.org which is a temporaryURI used by <strong>SOAP</strong> developers during development.XML namespace for the schema in the types definedby the <strong>Web</strong> service. If you do not specify thisparameter, the schema is in the namespace givenby NAMESPACE instead.URI that defines the XML namespace for theresponse messages. By default, this is equal to thenamespace given by the NAMESPACE parameter.• The class should define <strong>Web</strong> methods, as described in the next section.• The class should implement the OnProcessInput method, as described in “Implementing theOnProcessInput Method.”12 <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>


• The class can optionally implement any or all of the startup <strong>and</strong> teardown methods: OnInit,OnTearDown, OnProductionStart, <strong>and</strong> OnProductionStop.The following example shows in general what the class might look like:Class ESOP.Shell Extends EnsLib.<strong>SOAP</strong>.Service{Parameter ADAPTER="";Parameter NAMESPACE = "http://www.myapp.org";Parameter SERVICENAME = "MyServiceName";///This is the <strong>Web</strong> method exposed to the outside world;///It receives a <strong>SOAP</strong> request message <strong>and</strong> sends an <strong>Ensemble</strong>///request message to ProcessInputMethod My<strong>Web</strong>Method() As ResponseType [<strong>Web</strong>Method]{///implement your method here;///call ..ProcessInput}///This method is called by ProcessInput <strong>and</strong> forwards///an <strong>Ensemble</strong> request message to a business host in the production///(<strong>and</strong> receives <strong>and</strong> returns an <strong>Ensemble</strong> response reply)Method OnProcessInput(pInput As %RegisteredObject,ByRef pOutput As %RegisteredObject) As %Status{//call basic web service method to send message received from <strong>Web</strong> method//for exampleQuit ..SendRequestSync("ConfigName",pInput,.pOutput)}}Basic Requirements2.2.2 Configuration TasksTo add your <strong>Ensemble</strong> <strong>Web</strong> service (a business service) to an <strong>Ensemble</strong> production, use the <strong>Ensemble</strong>Management Portal to do the following:1. Add an instance of your custom class to the <strong>Ensemble</strong> production.Important:Ensure that the configuration name is the same as the full class name, includingpackage. This is a requirement for running an <strong>Ensemble</strong> <strong>Web</strong> service.2. Enable the business service.3. Set the PoolSize setting to 0.For other settings, see the book Managing <strong>Ensemble</strong> Productions.4. Run the production.If you are not familiar <strong>with</strong> the <strong>Ensemble</strong> Management Portal, see the appendix “Common Tasks inthe <strong>Ensemble</strong> Management Portal.”<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 13


Creating an <strong>Ensemble</strong> <strong>Web</strong> Service2.3 Defining <strong>Web</strong> Methods for Use in <strong>Ensemble</strong>You can use an instance method or a class method as a <strong>Web</strong> method for use in <strong>Ensemble</strong>. This sectiondescribes the basic requirements, as well as the steps generally included in an <strong>Ensemble</strong> <strong>Web</strong> method.• Define the method <strong>with</strong>in a subclass of EnsLib.<strong>SOAP</strong>.Service, as described in “Basic Requirements.”• Mark the method <strong>with</strong> the <strong>Web</strong>Method keyword.• Ensure that all arguments <strong>and</strong> return values are XML-enabled:- If the method uses an object as an argument or a return value, you must ensure that the objectis XML-enabled. That is, the class definitions for the types must extend %XML.Adaptor. Thedefault settings for this class are normally suitable; if not, see <strong>Using</strong> XML <strong>with</strong> Caché.- If the method uses a data set as an argument or return value, you must ensure the data set isof type %XML.DataSet, which is an XML-enabled subclass of the st<strong>and</strong>ard %ResultSet.- To use a collection (%ListOfObjects or %ArrayOfObjects) as an argument or a return value,you must ensure that the ELEMENTTYPE parameter of the collection is set <strong>and</strong> refers to anXML-enabled class.2.3.1 Basic Steps of a <strong>Web</strong> MethodWithin an <strong>Ensemble</strong> <strong>Web</strong> service, a <strong>Web</strong> method should generally do the following:1. Construct an <strong>Ensemble</strong> request message <strong>and</strong> set its properties <strong>with</strong> received in the inbound <strong>SOAP</strong>message.2. Invoke the ProcessInput method of the <strong>Web</strong> service, passing the request message to it.3. Check the status returned by the ProcessInput method <strong>and</strong> react appropriately.4. Then:• In the case of success, look at the <strong>Ensemble</strong> response message that is returned by reference<strong>and</strong> use it to construct the return value of the <strong>Web</strong> method. As noted previously, the returnvalue must be XML-enabled so that it can be packaged as a <strong>SOAP</strong> response.• In the case of failure, call the ReturnMethodStatusFault or ReturnStatusFault method ofthe <strong>Web</strong> service; see the next section for details.The ProcessInput method has the following signature:14 <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>


Method OnProcessInput(pInput As %RegisteredObject,ByRef pOutput As %RegisteredObject,ByRef pHint As %String) As %StatusHere:1. pInput is the <strong>Ensemble</strong> request message that you are sending.2. pOutput is the <strong>Ensemble</strong> response message that is sent in return.Defining <strong>Web</strong> Methods for Use in <strong>Ensemble</strong>3. pHint is an optional string that you can use to identify the <strong>Ensemble</strong> request; see the section“Creating a Switch in OnProcessInput,” later in this chapter.2.3.2 Returning Faults to the CallerBy default, if an error occurs when ProcessInput runs, the <strong>Web</strong> service returns a <strong>SOAP</strong> message tothe caller, but the <strong>SOAP</strong> message does not indicate where precisely the fault occurred. An examplefollows:<strong>SOAP</strong>-ENV:ServerServer Application ErrorERROR #5002: Cache error: zGetCustomerInfo+10^ESOP.<strong>Web</strong>Service.1Your <strong>Web</strong> methods should check for an error <strong>and</strong> use ReturnMethodStatusFault orReturnStatusFault. In case of error, the message will be more informative, as follows:<strong>SOAP</strong>-ENV:MethodServer Application ErrorESOP.<strong>Web</strong>ServiceERROR ErrException:zGetCustomerRequest+8^ESOP.MyOperation.1 -logged as '13 Jul 2007' number 4 @'set x=100/0'The ReturnMethodStatusFault <strong>and</strong> ReturnStatusFault methods return a <strong>SOAP</strong> fault to the caller<strong>and</strong> then trap the error. These methods have the following signatures:ClassMethod ReturnStatusFault(pCode As %String,pStatus As %Status)ClassMethod ReturnMethodStatusFault(pStatus As %Status)<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 15


Creating an <strong>Ensemble</strong> <strong>Web</strong> ServiceHere:• pCode is a string that represents the error code to use in the element of the <strong>SOAP</strong>fault. The ReturnMethodStatusFault method uses the generic error code <strong>SOAP</strong>-ENV:Method• pStatus is the status to use in the returned <strong>SOAP</strong> fault. This is used to construct the details of the<strong>SOAP</strong> fault.Also notice that these methods set the element of the <strong>SOAP</strong> fault.2.3.3 ExampleThe following shows a simple example:Method GetCustomerInfo(ID As %Numeric)As ESOP.<strong>SOAP</strong>Response [<strong>Web</strong>Method]{//create <strong>Ensemble</strong> request message <strong>with</strong> given IDset request=##class(ESOP.CustomerRequest).%New()set request.CustomerID=ID//send <strong>Ensemble</strong> request message//ProcessInput calls OnProcessInput, which actually//sends the messageset sc=..ProcessInput(request,.response,"GetCustomerInfo")if $$$ISERR(sc) do ..ReturnMethodStatusFault(sc)//use info from <strong>Ensemble</strong> response to create <strong>SOAP</strong> responseset soapresponse=##class(ESOP.<strong>SOAP</strong>Response).%New()set soapresponse.CustomerID=response.CustomerIDset soapresponse.Name=response.Nameset soapresponse.Street=response.Streetset soapresponse.City=response.Cityset soapresponse.State=response.Stateset soapresponse.Zip=response.Zip}quit soapresponse2.3.4 Note About Class QueriesYou can also use a class query as a <strong>Web</strong> method, if the class query is defined <strong>with</strong>in a subclass ofEnsLib.<strong>SOAP</strong>.Service. To do so, mark the query <strong>with</strong> the <strong>Web</strong>Method keyword. In practice, this maybe less useful <strong>with</strong>in an <strong>Ensemble</strong> production, because the class query has no way to call theProcessInput method of the <strong>Web</strong> service, <strong>and</strong> thus no has no way to communicate <strong>with</strong> the rest of theproduction. Therefore, this book does not discuss this option.16 <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>


Implementing the OnProcessInput Method2.4 Implementing the OnProcessInput MethodYour custom business service class should implement the OnProcessInput method, which forwardsthe <strong>Ensemble</strong> request as appropriate <strong>with</strong>in the production. The OnProcessInput method should havethe following signature:Method OnProcessInput(pInput As %RegisteredObject,ByRef pOutput As %RegisteredObject,ByRef pHint As %String) As %StatusHere:1. pInput is the <strong>Ensemble</strong> request message that you are sending.2. pOutput is the <strong>Ensemble</strong> response message that is sent in return.3. pHint is an optional string that you can use to decide how to h<strong>and</strong>le the <strong>Ensemble</strong> request; see thesection “Creating a Switch in OnProcessInput,” later in this chapter.The OnProcessInput method should do some or all of the following:1. Create a request message (an instance of Ens.Request or a subclass), which will be the messagethat your business service sends. Or simply forward the input that the business service receives.For information on creating messages, see the subsection “Creating Request <strong>and</strong> ResponseClasses.”2. Call a suitable method of the business service to send the request to some destination <strong>with</strong>in theproduction. Specifically, call one of the following inherited methods, as appropriate for yourneeds:• SendRequestSync sends a message synchronously (waits for a response). For details, seethe subsection “<strong>Using</strong> the SendRequestSync Method.”• SendRequestAsync sends a message asynchronously (does not wait for a response). Fordetails, see the subsection “<strong>Using</strong> the SendRequestAsync Method.”• SendDeferredResponse sends a response that was previously deferred. This method is lesscommonly used. For details, see the book Developing <strong>Ensemble</strong> Productions.Each of these methods returns a status (specifically, an instance of %Status).3. Make sure that you set the output argument (pOutput). Typically you set this equal to the responsemessage that you have received.4. Return an appropriate status. This step is required.The following shows an example:<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 17


Creating an <strong>Ensemble</strong> <strong>Web</strong> ServiceMethod OnProcessInput(pInput As %RegisteredObject,ByRef pOutput As %RegisteredObject) As %Status{set sc= ..SendRequestSync("Lookup",pInput,.pOutput)Quit sc}This <strong>Web</strong> method does not construct a request message; it just forwards the input that the businessservice receives (pInput). Although it is compact, the <strong>Web</strong> method does perform the other three tasksdescribed in the previous list.2.4.1 Creating Request <strong>and</strong> Response ClassesAs noted earlier, your custom OnProcessInput method typically constructs a request message <strong>and</strong>sends it.• A request message is an instance of a subclass of Ens.Request <strong>and</strong> has properties to contain thedata of your request.• A response message is an instance of a subclass of Ens.Response <strong>and</strong> has properties to containthe data of the response.You will need to define each of these subclasses, as appropriate for your needs.2.4.2 <strong>Using</strong> the SendRequestSync MethodTo send a synchronous request, use the SendRequestSync method as follows:Set tSC = ..SendRequestSync(pTargetDispatchName, tRequest, .tResponse)This method takes the following arguments:• pTargetDispatchName — The configuration name of the business process or business operationto which the request is sent.• pRequest — Any persistent object, but typically a subclass of Ens.Request. This object containsthe data to send <strong>with</strong> the request.• pResponse — (By reference) Any persistent object, but typically a subclass of Ens.Response.This object receives the data returned by the response.• pTimeout — (Optional) The number of seconds to wait for a response. The default is -1 (waitforever).This method returns a status (an instance of %Status).If no response is expected, you can use SendRequestAsync instead of SendRequestSync.18 <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>


2.4.3 <strong>Using</strong> the SendRequestAsync MethodTo send an asynchronous request, use the SendRequestAsync method as follows:Set tSC = ..SendRequestAsync(pTargetDispatchName, tRequest)This method takes the following arguments:• pTargetDispatchName — The configuration name of the business process or business operationto which the request is sent.• tRequest — Any persistent object, but typically a subclass of Ens.Request. This object containsthe data to send <strong>with</strong> the request.This method returns a status (an instance of %Status).2.4.4 ExampleSuppose that you created an <strong>Ensemble</strong> <strong>Web</strong> service that could be used to look up customer information,given a customer ID. To transport request messages, you might use a class like the following:Class ESOP.CustomerRequest Extends Ens.Request [ClassType=persistent]{Property CustomerID As %Numeric;}To transport the corresponding responses, you might use a class like the following:Class ESOP.CustomerResponse Extends Ens.Response [ClassType=persistent]{Property CustomerID As %Numeric;Property Name As %String;Property Street As %String;Property City As %String;Property State As %String;Property Zip As %Numeric;}Implementing the OnProcessInput MethodYour custom OnProcessInput method sends the request message to another destination <strong>with</strong>in theproduction — a business host that performs the lookup.<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 19


Creating an <strong>Ensemble</strong> <strong>Web</strong> ServiceMethod OnProcessInput(pInput As %RegisteredObject,ByRef pOutput As %RegisteredObject) As %Status{set sc= ..SendRequestSync("Lookup",pInput,.pOutput)Quit sc}2.5 Viewing the WSDL<strong>Ensemble</strong> automatically creates <strong>and</strong> publishes a WSDL document that describes your <strong>Ensemble</strong> <strong>Web</strong>service. Whenever you modify <strong>and</strong> recompile the <strong>Web</strong> service, <strong>Ensemble</strong> automatically updates theWSDL correspondingly.To view the WSDL for the <strong>Web</strong> service, use the following URL:base/app-name/web_serv.cls?WSDLHere base is the base URL for your <strong>Web</strong> server (including port if necessary), /csp/app is the name ofthe CSP application in which the <strong>Web</strong> service resides, <strong>and</strong> web_serv is the class name of the <strong>Web</strong>service. (Typically, /csp/app is /csp/namespace, where namespace is the <strong>Ensemble</strong> namespace thatcontains the CSP application. )For example:http://localhost:57772/csp/samples/MyApp.StockService.cls?WSDLThe browser displays the WSDL document as an XML document. The following shows an example:20 <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>


Example2.6 ExampleThe following simple example shows an <strong>Ensemble</strong> <strong>Web</strong> service that can be used to look up customerinformation, given a customer ID.Class ESOP.<strong>Web</strong>Service Extends EnsLib.<strong>SOAP</strong>.Service{Parameter ADAPTER;Parameter NAMESPACE = "http://www.myapp.org";Parameter SERVICENAME = "CustomerLookupService";Method GetCustomerInfo(ID As %Numeric) As ESOP.<strong>SOAP</strong>Response [<strong>Web</strong>Method]{//create <strong>Ensemble</strong> request message <strong>with</strong> given IDset request=##class(ESOP.CustomerRequest).%New()set request.CustomerID=ID//send <strong>Ensemble</strong> request message//ProcessInput calls OnProcessInput, which actually//sends the messageset sc=..ProcessInput(request,.response,"GetCustomerInfo")if $$$ISERR(sc) do ..ReturnMethodStatusFault(sc)//use info from <strong>Ensemble</strong> response to create <strong>SOAP</strong> responseset soapresponse=##class(ESOP.<strong>SOAP</strong>Response).%New()<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 21


Creating an <strong>Ensemble</strong> <strong>Web</strong> <strong>Services</strong>et soapresponse.CustomerID=response.CustomerIDset soapresponse.Name=response.Nameset soapresponse.Street=response.Streetset soapresponse.City=response.Cityset soapresponse.State=response.Stateset soapresponse.Zip=response.Zip}quit soapresponseMethod OnProcessInput(pInput As %RegisteredObject,ByRef pOutput As %RegisteredObject) As %Status{set sc= ..SendRequestSync("Lookup",pInput,.pOutput)Quit sc}}The <strong>SOAP</strong> response class is as follows:///Class ESOP.<strong>SOAP</strong>Response Extends (%RegisteredObject, %XML.Adaptor){Property CustomerID As %Numeric;Property Name As %String;Property Street As %String;Property City As %String;Property State As %String;Property Zip As %Numeric;}Note the following points:• The example <strong>Web</strong> method (GetCustomerInfo) receives an <strong>Ensemble</strong> response message <strong>and</strong>uses it to construct a <strong>SOAP</strong> response message.• The <strong>SOAP</strong> response class has the same properties as the corresponding <strong>Ensemble</strong> response class.Unlike the <strong>Ensemble</strong> response, however, the <strong>SOAP</strong> response class is XML-enabled <strong>and</strong> non-persistent.• The OnProcessInput method just sends the <strong>Ensemble</strong> request message <strong>and</strong> returns the response<strong>and</strong> status, <strong>with</strong>out adding any further logic.• OnProcessInput sends all requests to a business host named Lookup, which performs the actuallookup. Lookup is not important for this example <strong>and</strong> is not shown in this book.• This <strong>Web</strong> service can receive only one type of <strong>SOAP</strong> message (a lookup request that contains acustomer ID). A more complex <strong>Web</strong> service would receive multiple types of <strong>SOAP</strong> messages,<strong>and</strong> would probably route each type to a different business host <strong>with</strong>in the production. The followingsection describes how to do this.22 <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>


Creating a Switch in OnProcessInput2.7 Creating a Switch in OnProcessInputUntil now this chapter has considered only a <strong>Web</strong> service that defines a single <strong>Web</strong> method. If your<strong>Web</strong> service defines multiple methods, you may want to send them to different destinations <strong>with</strong>in theproduction. To do so, you can use the optional hint argument of the ProcessInput <strong>and</strong> OnProcessInputmethods. The procedure is as follows:1. In each <strong>Web</strong> method, when you invoke ProcessInput, provide a hint argument that indicateswhich <strong>Web</strong> method is making this call. For example, provide the name of the method itself.2. Include the hint argument in the signature of OnProcessInput <strong>and</strong> use this argument to determinethe flow.For example, suppose that the previous example <strong>Web</strong> service defined two methods:• GetCustomerInfo, which should be sent to the GetCustomerInfoBO business operation.• GetStoreInfo, which should be sent to the GetStoreInfoBO business operation.To set up this logic, the methods would provide a hint when they called OnProcessInput. For example:Method GetCustomerInfo(ID As %Numeric) As ESOP.<strong>SOAP</strong>Response [ <strong>Web</strong>Method ]{//create <strong>Ensemble</strong> request message <strong>with</strong> given IDset request=##class(ESOP.CustomerRequest).%New()set request.CustomerID=ID//send <strong>Ensemble</strong> request message//ProcessInput calls OnProcessInput, which actually//sends the messageset sc=..ProcessInput(request,.response,"GetCustomerInfo")if $$$ISERR(sc) do ..ReturnMethodStatusFault(sc)//use info from <strong>Ensemble</strong> response to create <strong>SOAP</strong> responseset soapresponse=##class(ESOP.<strong>SOAP</strong>Response).%New()set soapresponse.CustomerID=response.CustomerIDset soapresponse.Name=response.Nameset soapresponse.Street=response.Streetset soapresponse.City=response.Cityset soapresponse.State=response.Stateset soapresponse.Zip=response.Zip}quit soapresponseAnd the OnProcessInput method could use the hint as follows:<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 23


Creating an <strong>Ensemble</strong> <strong>Web</strong> ServiceMethod OnProcessInputAlt(pInput As %RegisteredObject,ByRef pOutput As %RegisteredObject, pHint As %String) As %Status{if pHint="GetCustomerInfo"{set sc= ..SendRequestSync("GetCustomerInfoBO",pInput,.pOutput)}elseif pHint="GetStoreInfo" {set sc= ..SendRequestSync("GetStoreInfoBO",pInput,.pOutput)}Quit sc}Or, because the business operation has the same name as the corresponding <strong>Web</strong> method, <strong>with</strong> BOappended to it, you could use this instead:Method OnProcessInput(pInput As %RegisteredObject,ByRef pOutput As %RegisteredObject, pHint As %String) As %Status{set sc= ..SendRequestSync($Get(pHint)_"BO",pInput,.pOutput)Quit sc}2.8 Enabling <strong>SOAP</strong> SessionsThe <strong>SOAP</strong> specification does not include session support. However, it is often useful to maintain asession between a <strong>Web</strong> client <strong>and</strong> the <strong>Web</strong> service that it uses. You can do this <strong>with</strong> an <strong>Ensemble</strong> <strong>Web</strong>service. If a <strong>Web</strong> service uses sessions, it establishes a session ID <strong>and</strong> allows repeated calls on theservice after one successfully authenticated call from a client.Support for <strong>SOAP</strong> sessions is controlled by the <strong>SOAP</strong>SESSION class parameter. The default is 0, whichmean that the <strong>Web</strong> service does not use sessions.To enable <strong>SOAP</strong> sessions, create a subclass of EnsLib.<strong>SOAP</strong>.Service <strong>and</strong> set <strong>SOAP</strong>SESSION to 1 inthe subclass. Base your <strong>Ensemble</strong> <strong>Web</strong> service on this subclass.For more information on <strong>SOAP</strong> sessions, see the book <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> Caché inthe Caché documentation.2.9 Additional OptionsBecause your <strong>Ensemble</strong> <strong>Web</strong> service extends %<strong>SOAP</strong>.<strong>Web</strong>Service, you can use all the <strong>SOAP</strong> supportprovided by that class. This support includes options for the following customizations, among others:• Customizing the <strong>SOAP</strong> headers• Passing attachments in the <strong>SOAP</strong> messages• Changing the binding style of the <strong>SOAP</strong> messages from document-style (the default) to rpc-style24 <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>


• Changing the encoding style of the messages from literal (the default) to <strong>SOAP</strong>-encoded• Customizing the XML types used in the <strong>SOAP</strong> messages• Customizing the <strong>SOAP</strong>Action header used to invoke a <strong>Web</strong> method• Controlling whether elements are qualified (controlling the elementFormDefault attribute of the<strong>Web</strong> service)• Controlling the form of null arguments (to be an empty element rather than omitted)• Writing the <strong>Web</strong> method to have output parameters instead of return valuesAdditional OptionsFor these options <strong>and</strong> others, see <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> Caché in the Caché documentationset.<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 25


3Creating an <strong>Ensemble</strong> <strong>Web</strong> ClientThis chapter describes how to create an <strong>Ensemble</strong> <strong>Web</strong> client. At a high level, your <strong>Ensemble</strong> <strong>Web</strong>client receives <strong>Ensemble</strong> requests from elsewhere <strong>with</strong>in the production, converts them to <strong>SOAP</strong>requests, <strong>and</strong> sends them to the appropriate <strong>Web</strong> service. Similarly, it receives <strong>SOAP</strong> responses, convertsthem into <strong>Ensemble</strong> responses, <strong>and</strong> sends them back <strong>with</strong>in the production. This chapter discusses thefollowing topics:• An overview of the parts of an <strong>Ensemble</strong> <strong>Web</strong> client• The basic steps to create an <strong>Ensemble</strong> <strong>Web</strong> client• Details on how to use the <strong>SOAP</strong> client wizard to generate the classes needed for an <strong>Ensemble</strong><strong>Web</strong> client• Available runtime settings for the <strong>Ensemble</strong> <strong>Web</strong> client• Information on the classes generated by the <strong>SOAP</strong> client wizard• Details on how to create your own business operation class manually, rather than using the classgenerated by the <strong>SOAP</strong> client wizard3.1 OverviewAn <strong>Ensemble</strong> <strong>Web</strong> client consists of the following parts:• A proxy client class that defines a proxy method for each method defined by the <strong>Web</strong> service.Each proxy method uses the same signature used by the corresponding <strong>Web</strong> service method <strong>and</strong>invokes that method when requested.• A business operation that uses the <strong>Ensemble</strong> <strong>SOAP</strong> outbound adapter to invoke the proxy client.<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 27


Creating an <strong>Ensemble</strong> <strong>Web</strong> Client• Supporting classes as needed to define XML types <strong>and</strong> <strong>Ensemble</strong> messages.The following figure shows how the business operation, adapter, <strong>and</strong> proxy client class work together.Supporting classes are not shown here.In the preceding figure, all items <strong>with</strong>in dashed lines can be generated by the <strong>SOAP</strong> client wizard inStudio. You can then edit this code as needed.For a more detailed look at these parts, see “<strong>Ensemble</strong> Support for <strong>Web</strong> Clients,” earlier in this book.28 <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>


Basic Steps3.2 Basic StepsThis section outlines the basic steps to create an <strong>Ensemble</strong> <strong>Web</strong> client. The steps include developmenttasks <strong>and</strong> then configuration tasks.3.2.1 Development TasksImportant:<strong>InterSystems</strong> recommends that you do not place custom code or data in the systemprovidednamespaces ENSLIB or ENSDEMO where it will be deleted the next timeyou upgrade <strong>Ensemble</strong>. The ENSEMBLE namespace <strong>and</strong> any new namespace thatyou create to hold your work is preserved across <strong>Ensemble</strong> upgrades.To create an <strong>Ensemble</strong> <strong>Web</strong> client, do the following <strong>with</strong>in Studio:1. Use the <strong>SOAP</strong> client wizard to generate the business operation class, proxy client class, <strong>and</strong> supportingclasses. This tool is described in the next section of this chapter.2. Check whether you need to adjust the types of the inputs <strong>and</strong> outputs of the methods. In particular,if any of the methods of the <strong>Web</strong> service have inputs or outputs that could exceed 32K in length,<strong>and</strong> if you have not enabled support for long strings in <strong>Ensemble</strong>, you should change the types ofthose inputs or outputs to an appropriate stream class.3.2.2 Configuration TasksTo add your <strong>Ensemble</strong> <strong>Web</strong> client to an <strong>Ensemble</strong> production, use the <strong>Ensemble</strong> Management Portalto do the following:1. Add an instance of your custom business operation class to the <strong>Ensemble</strong> production, specificallythe business operation class generated by the <strong>SOAP</strong> client wizard.2. Enable the business operation.3. Specify appropriate values for the runtime settings of the associated adapter(EnsLib.SQL.OutboundAdapter), as discussed later in this chapter.4. Run the production.If you are not familiar <strong>with</strong> the <strong>Ensemble</strong> Management Portal, see the appendix “Common Tasks inthe <strong>Ensemble</strong> Management Portal” for information on these tasks.<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 29


Creating an <strong>Ensemble</strong> <strong>Web</strong> Client3.3 <strong>Using</strong> the <strong>SOAP</strong> Client WizardTo use the <strong>SOAP</strong> client wizard to generate an <strong>Ensemble</strong> <strong>Web</strong> client, do the following:1. In Studio, make sure that you are in the appropriate <strong>Ensemble</strong> namespace.2. Click Tools —> Add-ins —> <strong>SOAP</strong> Client Wizard.3. On the first screen, enter the entire URL of the WSDL document for the <strong>Web</strong> service you wantto work <strong>with</strong>.4. Click Next.5. Click the check box to the left of Create Business Operation in Package. This option instructs thewizard to define a business operation class that invokes the proxy client, as well as message classesfor use <strong>with</strong> that business operation.6. For Create Business Operation in Package, optionally change the subpackage name from BusOpto another name.7. For Optional Package Name, type a package name for the proxy client <strong>and</strong> related classes. Thedefault package name is the service name. Also see the section “Generated Classes <strong>and</strong> XML-KEEPCLASS.”8. For Class Type, choose a general type for the proxy client class: persistent or serial (the default).9. Click Next. The wizard generates <strong>and</strong> compiles the classes <strong>and</strong> displays a list of these classes.10. Click Finish.3.3.1 Generated Classes <strong>and</strong> XMLKEEPCLASSThe <strong>SOAP</strong> client wizard generates a set of classes; the details of these classes are discussed later inthis chapter.You specify the package in which the tool should create the proxy client class <strong>and</strong> the supportingclasses. If this package is the same as an existing package, by default the tool will overwrite anyexisting classes that have the same name. To prevent the wizard from overwriting a class definition,add the XMLKEEPCLASS parameter to that class <strong>and</strong> set this parameter equal to 1.3.3.2 <strong>Using</strong> the Process MethodInstead of using the wizard, you can use the Process method of the %<strong>SOAP</strong>.WSDL.Reader class. Touse this method:1. Create an instance of %<strong>SOAP</strong>.WSDL.Reader.30 <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>


2. Optionally set properties to control the behavior of your instance.Common Properties of %<strong>SOAP</strong>.WSDL.Reader<strong>Using</strong> the <strong>SOAP</strong> Client WizardPropertyCompileFlagsMakePersistentMakeSerialOutputTypeAttributeMakeBusinessOperationPurposeSpecifies the flags to use when compiling thegenerated classes.The initial expression is "dk"; use$System.OBJ.ShowFlags() to get information on theavailable flags.If this property is 1, the proxy client is a persistentobject; otherwise, it is a registered object. The initialexpression is 0.If this property is 1 <strong>and</strong> if MakePersistent is 1, the proxyclient is a serial class. The initial expression is 0.Controls how the WSDL reader will set theOUTPUTTYPEATTRIBUTE parameter in the proxyclient that it generates; which controls the use of thexsi:type attribute in the <strong>SOAP</strong> messages. See <strong>Using</strong><strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> Caché in the Cachédocumentation set.Specifies whether to generate an <strong>Ensemble</strong> businessoperation <strong>and</strong> related request <strong>and</strong> response objects.The ADAPTER setting for this business operation isEnsLib.<strong>SOAP</strong>.OutboundAdapter. This option works onlyif you are working <strong>with</strong>in an <strong>Ensemble</strong>-enablednamespace.For other properties, see the class documentation for %<strong>SOAP</strong>.WSDL.Reader.3. Invoke the Process method, providing the following arguments:• The first argument must be the URL of the WSDL of the <strong>Web</strong> service or the name of theWSDL file (including its complete path). Depending on the configuration of the <strong>Web</strong> service,it may be necessary to append a string that provides a suitable username <strong>and</strong> password; seethe examples.• The optional second argument is the name of the package in which the reader should placethe generated classes. If you do not specify a package, Caché uses the service name as thepackage name.<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 31


Creating an <strong>Ensemble</strong> <strong>Web</strong> Client3.4 Available Runtime SettingsThis topic describes the runtime settings for your <strong>Ensemble</strong> <strong>Web</strong> client, which fall into several generalgroups:• Basic settings• Settings related to credentials• The setting that controls use of SSL• Settings that control the use of a proxy serverFor any settings not listed here, see the book Managing <strong>Ensemble</strong> Productions.3.4.1 Specifying BasicsThe following settings specify the basic information for the <strong>Ensemble</strong> <strong>Web</strong> client.<strong>Web</strong>ServiceURL%StringSpecifies the URL where the <strong>Web</strong> service is located. If this setting is not given, the adapteruses the default location (the LOCATION parameter) declared in the proxy client class; seethe <strong>Web</strong>ServiceClientClass setting. Note that SSL will only work if this URL uses https://<strong>Web</strong>ServiceClientClass%StringSpecifies the full name (including package) of the proxy client class, specifically the classthat actually sends <strong>and</strong> receives <strong>SOAP</strong> messages to the <strong>Web</strong> service.Response Timeout%NumericSpecifies the timeout for getting a response from the remote <strong>Web</strong> server (the timeout foropening the connection to the server is always 5 seconds). The default value is 30.3.4.2 Specifying CredentialsThe <strong>Web</strong> service that you are accessing might require a username <strong>and</strong> password. In general, the<strong>Ensemble</strong> <strong>SOAP</strong> client can log into a <strong>Web</strong> service in either of the following ways:32 <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>


Available Runtime Settings• You can use WS-Security user authentication. In this case, you include a WS-Security header inthe <strong>SOAP</strong> request; this header includes the username <strong>and</strong> password. The proxy client automaticallydoes this if you specify a value for the <strong>SOAP</strong>Credentials setting.CAUTION:Ensure that you are using SSL between the <strong>Web</strong> client <strong>and</strong> the <strong>Web</strong> service. TheWS-Security header is sent in clear text, so this technique is not secure unlessSSL is used.• You can use basic HTTP user authentication, which is less secure than WS-Security but is sometimesrequired. In this case, you include the username <strong>and</strong> password in the HTTP header of the<strong>SOAP</strong> request. The proxy client automatically does this if you specify a value for the Credentialssetting.Use the technique that is appropriate for the <strong>Web</strong> service you are using.<strong>SOAP</strong>Credentials%StringCredentialsSpecify the ID of the <strong>Ensemble</strong> credentials that contain the username <strong>and</strong> password to beused in the WS-Security header of the <strong>SOAP</strong> request. For more information on WS-Securitysupport, see the book <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> Caché in the Caché documentationset.%StringSpecify the ID of the <strong>Ensemble</strong> credentials that contain the username <strong>and</strong> password to beused in the HTTP header.For information on creating <strong>Ensemble</strong> credentials, see the appendix “Common Tasks in the <strong>Ensemble</strong>Management Portal.”3.4.3 Specifying an SSL ConfigurationIf the <strong>Web</strong> server supports it, you can connect <strong>with</strong> SSL. To do so, specify a value for the followingruntime setting:SSLConfig%StringSpecifies the name of an existing SSL/TLS system configuration set to use, configured viathe System Management Portal.<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 33


Creating an <strong>Ensemble</strong> <strong>Web</strong> ClientFor information on creating <strong>and</strong> managing SSL/TLS configurations, see the chapter “<strong>Using</strong>SSL/TLS <strong>with</strong> Caché” in the Caché Security Administration Guide. The SSL/TLS configurationincludes an option called Configuration Name; this is the string to use in this setting.At the end of the SSLConfig string, you can add a vertical bar (|) followed by the private keypassword.Note:You must also ensure the <strong>Web</strong> service is at a URL that uses https://. The <strong>Web</strong>service location is determined by the <strong>Web</strong>ServiceURL setting; if this is not specified,the <strong>Ensemble</strong> <strong>Web</strong> client assumes the <strong>Web</strong> service is at the URL specified by theLOCATION parameter in proxy client class.3.4.4 Specifying a Proxy ServerYou can communicate <strong>with</strong> the <strong>Web</strong> service via a proxy server. To set this up, use the following runtimesettings:ProxyServerProxyPort%StringSpecifies the proxy server through which to send HTTP requests, if any.%IntegerProxyHTTPSSpecifies the proxy server port on which to send HTTP requests, if using a proxy server. Thedefault value is 80.%BooleanSpecifies whether the proxy (if any) uses HTTPS to communicate <strong>with</strong> the real HTTP/HTTPSserver.3.5 Generated Classes for an <strong>Ensemble</strong> <strong>Web</strong>ClientThis section provides information about the classes that the <strong>SOAP</strong> client wizard generates.Consider a <strong>Web</strong> service named MyService that has the following details:34 <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>


• It is hosted at http://localhost:57772/csp/gsop/MyApp.AddService.CLS• The target XML namespace for the <strong>Web</strong> service is http://www.myapp.org• It defines a <strong>Web</strong> method named AddService, which accepts two complex numbers as arguments<strong>and</strong> returns the result.Suppose that you use the <strong>SOAP</strong> client wizard to generate a <strong>Ensemble</strong> <strong>Web</strong> client for this <strong>Web</strong> service.If you specify the package for the client classes as MyClient, the <strong>SOAP</strong> client wizard will generatethe following classes <strong>and</strong> add them all to your current project:• It generates the MyClient.BusOp.MyServiceSoap class, which defines the business operation.Class MyClient.BusOp.MyServiceSoap Extends Ens.BusinessOperation{Parameter ADAPTER = "EnsLib.<strong>SOAP</strong>.OutboundAdapter";Generated Classes for an <strong>Ensemble</strong> <strong>Web</strong> ClientMethod Add(pRequest As MyClient.BusOp.AddRequest,Output pResponse As MyClient.BusOp.AddResponse) As %Library.Status{Set ..Adapter.<strong>Web</strong>ServiceClientClass = "MyClient.MyServiceSoap"Set tSC = ..Adapter.InvokeMethod("Add",.AddResult,pRequest.a,pRequest.b) Quit:$$$ISERR(tSC) tSC}Set tSC = pRequest.NewResponse(.pResponse) Quit:$$$ISERR(tSC) tSCSet pResponse.AddResult=AddResultQuit $$$OKXData MessageMap{Add}}• It generates the MyClient.AddService<strong>SOAP</strong> class, the proxy client class:Class MyClient.AddServiceSoap Extends %<strong>SOAP</strong>.<strong>Web</strong>Client{/// This is the URL used to access the web service.Parameter LOCATION = "http://localhost:57772/csp/gsop/MyApp.AddService.cls";/// This is the namespace used by the ServiceParameter NAMESPACE = "http://www.myapp.org";/// Use xsi:type attribute for literal types.Parameter OUTPUTTYPEATTRIBUTE = 1;/// This is the name of the ServiceParameter SERVICENAME = "AddService";Method Add(a As MyClient.ComplexNumber, b As MyClient.ComplexNumber)As MyClient.ComplexNumber [ Final, ProcedureBlock = 1,SoapBindingStyle = document, SoapBodyUse = literal, <strong>Web</strong>Method ]{Quit ..<strong>Web</strong>Method("Add").Invoke(##this,"http://www.myapp.org/MyApp.AddService.Add",.a,.b)<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 35


Creating an <strong>Ensemble</strong> <strong>Web</strong> Client}}• It generates the request <strong>and</strong> response message classes needed by the business operation. Therequest class is as follows:Class MyClient.BusOp.AddRequest Extends Ens.Request [ ClassType = persistent ]{Parameter RESPONSECLASSNAME = "MyClient.BusOp.AddResponse";Property a As MyClient.ComplexNumber;Property b As MyClient.ComplexNumber;}The response class is as follows:Class MyClient.BusOp.AddResponse Extends Ens.Response [ ClassType = persistent ]{Property AddResult As MyClient.ComplexNumber;}• Finally, it generates the MyClient.ComplexNumber class, which defines a complex number<strong>and</strong> which is used by the other classes./// Created from: http://localhost:57772/csp/gsop/MyApp.AddService.CLS?WSDL=1Class MyClient.ComplexNumber Extends (%RegisteredObject, %XML.Adaptor){Parameter XMLNAME = "ComplexNumber";Parameter XMLSEQUENCE = 1;Property Real As %xsd.double(XMLNAME = "Real") [ SqlFieldName = _Real ];Property Imaginary As %xsd.double(XMLNAME = "Imaginary");}When you compile these classes, the compiler also generates a class for each method defined in the<strong>Web</strong> service. These classes are not automatically added to your project <strong>and</strong> their internal details aresubject to change. These classes extend %<strong>SOAP</strong>.ProxyDescriptor, which you should never subclassyourself.36 <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>


Creating a Business Operation Class Manually3.6 Creating a Business Operation ClassManuallyRather than using the business operation class that the <strong>SOAP</strong> client wizard generates, you can createyour own class. This section describes how to do so. It discusses the following:• Basic requirements of the business operation class• Basic requirements of the methods in the business operation class• Specific techniques, <strong>with</strong> examples, for calling the proxy methods• Reference information for the adapter property <strong>and</strong> methods used hereImportant:<strong>InterSystems</strong> recommends that you do not place custom code or data in the systemprovidednamespaces ENSLIB or ENSDEMO where it will be deleted the next timeyou upgrade <strong>Ensemble</strong>. The ENSEMBLE namespace <strong>and</strong> any new namespace thatyou create to hold your work is preserved across <strong>Ensemble</strong> upgrades.3.6.1 Basic Requirements of the ClassThe following list describes the basic requirements of the business operation class• Your business operation class should extend Ens.BusinessOperation.• In your class, the ADAPTER parameter should equal EnsLib.<strong>SOAP</strong>.OutboundAdapter.• In your class, the INVOCATION parameter should specify the invocation style you want to use,which must be one of the following.- Queue means the message is created <strong>with</strong>in one background job <strong>and</strong> placed on a queue, atwhich time the original job is released. Later, when the message is processed, a differentbackground job will be allocated for the task. This is the most common setting.- InProc means the message will be formulated, sent, <strong>and</strong> delivered in the same job in whichit was created. The job will not be released to the sender’s pool until the message is deliveredto the target. This is only suitable for special cases.• Your class should define one method for each method of the proxy client, as described in the followingsection.• Your class should define a message map that includes one entry for each method. A message mapis an XData block entry that has the following structure:<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 37


Creating an <strong>Ensemble</strong> <strong>Web</strong> ClientXData MessageMap{methodname...}You will also need to define the <strong>Ensemble</strong> message classes that the business operation uses.3.6.2 Basic Requirements of the MethodsWithin your business operation class, your methods should invoke the proxy methods. Here the generalrequirements are as follows:1. The method should have the same signature as the proxy method that it is invoking.2. The method should be marked <strong>with</strong> the <strong>Web</strong>Method keyword.3. The method should set the SoapBindingStyle <strong>and</strong> SoapBodyUse keywords as expected by theproxy client. (That is, use the same values as in the signature of the corresponding proxy method.)4. The method should set the <strong>Web</strong>ServiceClientClass property of the adapter. When this property isset, a proxy client instance is created <strong>and</strong> placed in the %Client property of the adapter.5. The method should call the corresponding proxy method, using one of the techniques in the nextsection.6. The method should check the status.7. Then:• In the case of success, create a new response message (via the NewResponse method of therequest) <strong>and</strong> set its properties as appropriate.• In the case of failure, quit <strong>with</strong> the error.3.6.3 Ways to Execute the Proxy MethodsWithin your business operation, your methods should execute the proxy methods of the proxy clientclass. You can do this in multiple ways, which are best shown via an example. This section uses anexample <strong>Web</strong> service that has a <strong>Web</strong> method named GetStock that accepts a stock symbol (a string)<strong>and</strong> returns a number. Suppose that you have used the <strong>SOAP</strong> client wizard to generate a proxy client(GetStock.StockServiceSoap), which contains a method called GetStock.Also suppose that you have created message classes as follows:38 <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>


Class GetStock.BusOp.GetQuoteRequest Extends Ens.Request [ClassType=persistent]{Parameter RESPONSECLASSNAME = "GetStock.BusOp.GetQuoteResponse";Property StockName As %String;}AndClass GetStock.BusOp.GetQuoteRequest Extends Ens.Request [ClassType=persistent]{Parameter RESPONSECLASSNAME = "GetStock.BusOp.GetQuoteResponse";Property StockName As %String;}Creating a Business Operation Class ManuallyTo execute the proxy method GetStock, your business operation class can do any of the following:• Call the InvokeMethod method of the adapter <strong>and</strong> specify the name of the proxy method to run,as well as up to twelve arguments. In this case, there is only one argument (which we specify aspRequest.StockName). For example:Method GetQuote1(pRequest As GetStock.BusOp.GetQuoteRequest,Output pResponse As GetStock.BusOp.GetQuoteResponse) As %Status{set ..Adapter.<strong>Web</strong>ServiceClientClass = "GetStock.StockServiceSoap"set status = ..Adapter.InvokeMethod("GetQuote",.answer,pRequest.StockName)if $$$ISERR(status) quit statusset pResponse=##class(GetStock.BusOp.GetQuoteResponse).%New()set pResponse.GetQuoteResult=answerquit $$$OK}When you use the <strong>SOAP</strong> client wizard to generate the business operation, it uses this method.• Access the %Client property of the adapter, which gives you an instance of the proxy client class,<strong>and</strong> execute the proxy method of that property. The %Client property is set when you set the<strong>Web</strong>ServiceClientClass property. In this case, %Client has a method named GetQuote, whichaccepts a string stock symbol. For example:Method GetQuote2(pRequest As GetStock.BusOp.GetQuoteRequest,Output pResponse As GetStock.BusOp.GetQuoteResponse) As %Status{set ..Adapter.<strong>Web</strong>ServiceClientClass = "GetStock.StockServiceSoap"set client=..Adapter.%Clientset answer=client.GetQuote("GRPQ")set pResponse=##class(GetStock.BusOp.GetQuoteResponse).%New()set pResponse.GetQuoteResult=answerquit $$$OK}Note that <strong>with</strong> this technique, you do not have access to the retry logic of <strong>Ensemble</strong>.<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 39


Creating an <strong>Ensemble</strong> <strong>Web</strong> Client• Create a proxy method object by calling the <strong>Web</strong>Method method of the adapter. Set propertiesof this object as appropriate (one property per named argument). In this case, <strong>Web</strong>Method returnsan object <strong>with</strong> one property: StockName. After setting properties as needed, call the Invokemethod of that object. For example:Method GetQuote3(pRequest As GetStock.BusOp.GetQuoteRequest,Output pResponse As GetStock.BusOp.GetQuoteResponse) As %Status{set ..Adapter.<strong>Web</strong>ServiceClientClass = "GetStock.StockServiceSoap"set proxymethod=..Adapter.<strong>Web</strong>Method("GetQuote")set proxymethod.StockName=pRequest.StockNameset status=..Adapter.Invoke(proxymethod)if $$$ISERR(status) quit statusset pResponse=##class(GetStock.BusOp.GetQuoteResponse).%New()set pResponse.GetQuoteResult=proxymethod.%Resultquit $$$OK}In this case, you can provide any number of arguments.3.6.4 Reference InformationThis section provides reference information for the adapter property <strong>and</strong> methods mentioned in theprevious section.%ClientInvokeMethod%<strong>SOAP</strong>.<strong>Web</strong>ClientThe associated instance of the proxy client (an instance of %<strong>SOAP</strong>.<strong>Web</strong>Client). This propertyis set when you set the <strong>Web</strong>ServiceClientClass property of the adapter.Method InvokeMethod(pMethodName As %String,Output pResult As %RegisteredObject,ByRef pArg1,ByRef pArg2,ByRef pArg3,ByRef pArg4,ByRef pArg5,ByRef pArg6,ByRef pArg7,ByRef pArg8,ByRef pArg9,ByRef pArg10,ByRef pArg11,ByRef pArg12) As %Status40 <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>


<strong>Web</strong>MethodInvokeCalls the specified method of the proxy client class, passing as many as twelve arguments<strong>and</strong> returns the status. The output is returned by reference as the second argument.Method <strong>Web</strong>Method(pMethodName As %String) As %<strong>SOAP</strong>.ProxyDescriptorReturns an object that corresponds to the specified method. This object has one propertycorresponding to each method argument; you should set this properties before using theInvoke method. For details on %<strong>SOAP</strong>.ProxyDescriptor, see the class reference.Method Invoke(p<strong>Web</strong>Method As %<strong>SOAP</strong>.ProxyDescriptor) As %StatusCalls the given method <strong>and</strong> returns the status.Creating a Business Operation Class Manually<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 41


ACommon Tasks in the <strong>Ensemble</strong>Management PortalThis appendix describes common tasks that you perform in the <strong>Ensemble</strong> Management Portal. Thesetasks are needed to configure adapters as described in this book:• Adding a business service or operation to a production• Enabling a business service or business operation• Editing other runtime settings• Creating <strong>Ensemble</strong> credentialsA.1 Adding a Business Host to a ProductionTo add a business service or business operation to a production, do the following:1. Go to the [<strong>Ensemble</strong>] > [Productions] page.2. Find your production. Click the Configure button to the right of its name.3. Add the business host using these steps:• Click Add Service or Add Operation, as appropriate. A wizard is displayed.• Choose Other.• In the first drop-down list, choose the class name of the business host.<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 43


Common Tasks in the <strong>Ensemble</strong> Management Portal• Enter appropriate data in the remaining fields as described in Developing <strong>Ensemble</strong> Productions,<strong>and</strong> click OK.4. Find the new business host in the production. Select it by clicking on it.5. Edit the settings as needed.6. Click Apply to save changes or click Cancel to discard them.When you click Apply, all changes immediately take effect, even if the production is currentlyrunning.Note:This procedure implicitly adds the associated adapter as well.A.2 Enabling a Business HostTo enable a business service or business operation, do the following:1. Go to the [<strong>Ensemble</strong>] > [Productions] page.2. Find your production. Click the Configure button to the right of its name.3. Click the business host to select it.4. Edit General Settings. Enable the business service or operation by checking the Enabled box.5. Click Apply to save changes or click Cancel to discard them.When you click Apply, all changes immediately take effect, even if the production is currentlyrunning.A.3 Editing Other Runtime SettingsTo edit the settings of a business service, business operation, or associated adapter, do the followingin the <strong>Ensemble</strong> Management Portal:1. Go to the [<strong>Ensemble</strong>] > [Productions] page.2. Find your production. Click the Configure button to the right of its name.3. Click the business host to select it.4. Edit General Settings for the business service. Hover the cursor over any setting name to displaythe help text for that setting.44 <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>


For detailed descriptions, see the book Managing <strong>Ensemble</strong> Productions.5. Edit Specific Settings for the business service. Hover the cursor over any setting name to displaythe help text for that setting. For detailed information on these settings, see other chapters in thisbook.6. Click Apply to save changes or click Cancel to discard them.Creating <strong>Ensemble</strong> CredentialsWhen you click Apply, all changes immediately take effect, even if the production is currentlyrunning.A.4 Creating <strong>Ensemble</strong> CredentialsSome remote systems require a username <strong>and</strong> password to log into that system. <strong>Ensemble</strong> permits youto store username-password pairs in a centralized, secure table that can be viewed <strong>and</strong> edited only byusers <strong>with</strong> access to the <strong>Ensemble</strong> Management Portal.You define <strong>Ensemble</strong> credentials, which consist of an ID <strong>and</strong> the username-password pair. Then youuse the ID as the value of the Credentials setting or the <strong>SOAP</strong>Credentials setting of your adapter.To create <strong>Ensemble</strong> credentials, log into the <strong>Ensemble</strong> Management Portal <strong>and</strong> do the following:1. Go to the [<strong>Ensemble</strong>] > [Maintenance] page.2. Click Credentials.3. Click Create New Credentials.4. For ID, enter a unique string that identifies this username-password pair. This is the identifier thatyou will use elsewhere <strong>with</strong>in your production.5. For Username, enter the username that you will use to log on to the remote system.6. For Password, enter the corresponding password.7. Click Save.In some cases, it is not practical or possible to store the login data <strong>with</strong>in <strong>Ensemble</strong>. You can writecode to get this data <strong>and</strong> pass it to <strong>Ensemble</strong> automatically. For details, see the book Developing<strong>Ensemble</strong> Productions.<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 45


BCustomizing Startup <strong>and</strong> TeardownAll <strong>Ensemble</strong> business hosts inherit a set of callback methods that you can use to customize startup<strong>and</strong> teardown. You can customize any of these methods.B.1 Callback MethodsAll <strong>Ensemble</strong> business hosts inherit a set of callback methods that you can use to customize startup<strong>and</strong> teardown. You can customize any of these methods.OnInitOnTearDownMethod OnInit() As %StatusExecuted during startup of the business host. By default, this method does nothing.Method OnTearDown() As %StatusExecuted during teardown of the business host. By default, this method does nothing.OnProductionStartClassMethod OnProductionStart(pConfigName As %String) As %StatusExecuted when the production is started. By default, this method does nothing. Note that youcan use the adapter property %ConfigName to access the configured name of current businessservice.<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 47


Customizing Startup <strong>and</strong> TeardownOnProductionStopClassMethod OnProductionStop(pConfigName As %String) As %StatusExecuted when the production is stopped. By default, this method does nothing.For reference, the following sections describes the exact startup <strong>and</strong> teardown sequences.B.2 The Startup SequenceThe startup sequence is the same for business services <strong>and</strong> business operations:1. At production startup, <strong>Ensemble</strong> calls the OnProductionStart method of each business service<strong>and</strong> business operation class listed in the production configuration.2. <strong>Ensemble</strong> creates a background process for each of the business services <strong>and</strong> business operationsin the production configuration. <strong>Ensemble</strong> can allocate more than one background process perbusiness host; the PoolSize of the business host specifies the number of background processes tocreate.3. Within each background process, <strong>Ensemble</strong> creates an instance of the business host class <strong>and</strong> aninstance of its associated adapter class (if any). <strong>Ensemble</strong> then sets the configurable propertyvalues of those instances.4. <strong>Ensemble</strong> calls the OnInit methods of the business host objects <strong>and</strong> the associated adapter objects,respectively.B.3 The Teardown SequenceThe startup sequence is slightly different for business services <strong>and</strong> business operations:1. During production shutdown:• <strong>Ensemble</strong> disables each business service; no more incoming requests are accepted for thisproduction.• <strong>Ensemble</strong> waits for each business operation to reach a quiescent state. That is, it waits untileach business operation has completed all of its synchronous requests.2. The OnTearDown method in each adapter is called.3. All adapter <strong>and</strong> business host objects are destroyed <strong>and</strong> their background processes are killed.48 <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>


The Teardown Sequence4. The OnProductionStop class method for each business host is called, once for each configureditem of that class in the production.Similarly, while a production is running, a given business service or business operation can be disabledor become inactive according to its configured schedule. When this occurs, the associated adapter (ifany) is shut down, <strong>and</strong> its OnTearDown method is executed.<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 49


C<strong>Using</strong> the <strong>SOAP</strong> Inbound AdapterThe EnsLib.<strong>SOAP</strong>.InboundAdapter class is not meant for production use but can be helpful for debugging<strong>and</strong> demos. This appendix discusses it briefly.C.1 NotesThe <strong>SOAP</strong> inbound adapter (EnsLib.<strong>SOAP</strong>.InboundAdapter) does not require <strong>Web</strong> server software.Instead it spawns a TCP listener job using the <strong>Ensemble</strong> super server. This lets you run your servicein a foreground window, which is useful for debugging. (To do this, you must be running the servicelocally. Also make sure the PoolSize setting is 1 <strong>and</strong> the JobPerConnection setting is false.) It alsosupports SSL.The EnsLib.<strong>SOAP</strong>.InboundAdapter listens for HTTP input on a given port. When the adapter receivesinput, the following occurs:1. It extracts the HTTP <strong>SOAP</strong>action header.2. It constructs a stream (%Library.GlobalBinaryStream) that contains the body of the input.3. It calls the <strong>Web</strong> method that corresponds to the given <strong>SOAP</strong>action.<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 51


<strong>Using</strong> the <strong>SOAP</strong> Inbound AdapterC.2 Development TasksImportant:<strong>InterSystems</strong> recommends that you do not place custom code or data in the systemprovidednamespaces ENSLIB or ENSDEMO where it will be deleted the next timeyou upgrade <strong>Ensemble</strong>. The ENSEMBLE namespace <strong>and</strong> any new namespace thatyou create to hold your work is preserved across <strong>Ensemble</strong> upgrades.To use the <strong>Ensemble</strong> <strong>SOAP</strong> inbound adapter, write <strong>and</strong> compile a new business service class in<strong>Ensemble</strong> Studio. The following list describes the basic requirements:• Your class should extend EnsLib.<strong>SOAP</strong>.Service. This class extends both Ens.BusinessService (sothat it is an <strong>Ensemble</strong> business service) <strong>and</strong> %<strong>SOAP</strong>.<strong>Web</strong>Service (so that it can act as a <strong>Web</strong> serviceas well).• Your class should provide values for SERVICENAME <strong>and</strong> other parameters, as described in“Basic Requirements” of the chapter “Creating an <strong>Ensemble</strong> <strong>Web</strong> Service.”• The class should define <strong>Web</strong> methods, as described in “Defining <strong>Web</strong> Methods for Use in<strong>Ensemble</strong>.”C.3 Configuration TasksUse the <strong>Ensemble</strong> Management Portal to do the following:1. Add an instance of your custom class to the <strong>Ensemble</strong> production.Important:Ensure that the configuration name is the same as the full class name, includingpackage. This is a requirement for running an <strong>Ensemble</strong> <strong>Web</strong> service.2. Enable the business service.3. Set the PoolSize setting to 1 so that the adapter can use its TCP listener.4. Set the StayConnected setting to 0. Otherwise, clients may hang for their timeout period whilewaiting for the server to drop the connection.5. Specify other settings as needed; see the following section.6. Run the production.If you are not familiar <strong>with</strong> the <strong>Ensemble</strong> Management Portal, see the appendix “Common Tasks inthe <strong>Ensemble</strong> Management Portal.”52 <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>


C.4 Settings of the Inbound AdapterSettings of the Inbound AdapterThe inbound adapter uses the following settings:AllowSessions%BooleanIf this setting is true, this <strong>Web</strong> service establishes a session ID <strong>and</strong> allows repeated calls onthe service after one successfully authenticated call from a client. The default for this settingis false.AllowedIPAddresses%StringCallIntervalSpecifies a comma-separated list of remote IP addresses from which to accept connections.The adapter accepts IP addresses in dotted decimal form. An optional :port designation issupported, so either of the following address formats is acceptable: 192.168.1.22 or192.168.1.22:3298.If a port number is specified, connections from other ports will be refused.If the string starts <strong>with</strong> a ! character, the adapter initiates a connection to the specified address.In this case, only one address may be given, <strong>and</strong> if a port is specified, it supersedes the valueof the Port setting; otherwise, the Port setting is used.%NumericSpecifies the number of seconds that the adapter will listen for incoming data from its configuredsource, before checking for a shutdown signal from the <strong>Ensemble</strong> framework.If the adapter finds input, it acquires the data <strong>and</strong> passes it to the business service. The businessservice processes the data, <strong>and</strong> then the adapter immediately begins waiting for new input.This cycle continues whenever the production is running <strong>and</strong> the business service is enabled<strong>and</strong> scheduled to be active.The default CallInterval is 5 seconds. The minimum is 0.1 seconds.EnableSt<strong>and</strong>ardRequests%BooleanIf this setting is true, the adapter can also receive <strong>SOAP</strong> requests in the usual way (bypassingthe TCP connection). The default is false.<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 53


<strong>Using</strong> the <strong>SOAP</strong> Inbound AdapterJobPerConnectionPort%BooleanIf this setting is true, the adapter spawns a new job to h<strong>and</strong>le each incoming TCP connection<strong>and</strong> allows simultaneous h<strong>and</strong>ling of multiple connections. When false, it does not spawn anew job for each connection. The default is true.%StringReadTimeoutSSLConfigSpecifies the TCP port to connect to. TCP port numbers have a maximum value of 65535.%NumericSpecifies the number of seconds to wait for each successive incoming TCP read operation,following receipt of initial data from the remote TCP port. The default is 5 seconds. The rangeis 0–600 seconds (a maximum of 10 minutes).%StringSpecifies the name of an existing SSL/TLS system configuration set to use, configured viathe System Management Portal.For information on creating <strong>and</strong> managing SSL/TLS configurations, see the chapter “<strong>Using</strong>SSL/TLS <strong>with</strong> Caché” in the Caché Security Administration Guide. The SSL/TLS configurationincludes an option called Configuration Name; this is the string to use in this setting.At the end of the SSLConfig string, you can add a vertical bar (|) followed by the private keypassword.StayConnected%NumericSpecifies whether to keep the connection open between requests.• If this setting is 0, the adapter will disconnect immediately after every event.• If this setting is -1, the adapter auto-connects on startup <strong>and</strong> then stays connected.• This setting can also be positive (which specifies the idle time, in seconds), but such avalue is not useful for this adapter, which works by polling. If the idle time is longer thanthe polling interval (that is, the CallInterval) the adapter stays connected all the time. Ifthe idle time is shorter than the polling interval, the adapter disconnects <strong>and</strong> reconnectsat every polling interval.54 <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>


EnsLib.<strong>SOAP</strong>.OutboundAdapterusing, 37EnsLib.<strong>SOAP</strong>.Servicebasic behavior, 9error trapping, 15examples<strong>Ensemble</strong> <strong>Web</strong> client, generated classes, 34<strong>Ensemble</strong> <strong>Web</strong> service, 21hint argument <strong>and</strong> OnProcessInput, 23invoking proxy methods, 38OnProcessInput, 17request <strong>and</strong> response messages, 19response messages <strong>with</strong> <strong>and</strong> <strong>with</strong>out faulttrapping, 15<strong>Web</strong> method, 16<strong>Web</strong> service shell, 11WSDL (fragment), 20Hhint argumentintroduction, 17using, 23HTTPincluding username <strong>and</strong> password inheader, 32, 45HTTPSfor proxy server, 34specifying configuration to use, 33<strong>Web</strong> service location, 32IInvoke method, 38, 40InvokeMethod method, 34, 38, 40JJobPerConnection setting, 53Lliteral encoding, 24LOCATION parameter, 11, 32MMakeBusinessOperation property, 30MakePersistent property, 30MakeSerial property, 30message h<strong>and</strong>lers, 37message map, 37NNAMESPACE parameter, 11namespacesfor <strong>Web</strong> service, 11null values, 24OOnInit method, 47OnProcessInput methodimplementing, 17using hint argument, 23OnProductionStart method, 47OnProductionStop method, 47OnTearDown method, 47output parameters instead of return values, 24OUTPUTTYPEATTRIBUTE parameter, 30OutputTypeAttribute property, 30PPoolSize setting, 13PoolSize setting for inbound adapter, 52Port setting, 53ProcessInput methodin <strong>Ensemble</strong> <strong>Web</strong> service, 9invoking from <strong>Web</strong> method, 14proxy clientassociating <strong>with</strong> adapter, 32executing methods, 38generated classes, 34generating, 30introduction, 6invoking from a business operation, 7ProxyHTTPS setting, 34proxy methodsas generated by <strong>SOAP</strong> client wizard, 34calling, 38introduction, 6ProxyPort setting, 34proxy server, using, 34ProxyServer setting, 34Qqualified elements, 2456 <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>


RReadTimeout setting, 53RESPONSENAMESPACE parameter, 11ResponseTimeout setting, 32ReturnMethodStatusFault method, 15ReturnStatusFault method, 15rpc-style binding, 24runtime settings, editing, 44runtime settings, inboundenabling <strong>SOAP</strong> sessions, 24runtime settings, outboundbasics, 32credentials, 32specifying a proxy server, 34specifying SSL, 33Sschema, namespace for, 11securitycreating credentials, 45specifying credentials, 32SendRequestAsync, 19SendRequestSync, 18SERVICENAME parameter, 11sessions<strong>and</strong> inbound adapter, 53enabling, 24<strong>SOAP</strong>Action header, customizing, 24SoapBindingStyle keyword, 38SoapBodyUse keyword, 38<strong>SOAP</strong> client wizardadjusting generated code, 29<strong>and</strong> XMLKEEPCLASS, 30generated classes, 34introduction, 5running programmatically, 30using, 30<strong>SOAP</strong>Credentials setting, 32, 45<strong>SOAP</strong> encoding, 24<strong>SOAP</strong> faults, 15<strong>SOAP</strong> headersoptions, 24<strong>SOAP</strong> messagesadditional options, 24example classes, 19namespaces for, 11received by <strong>Ensemble</strong>, 3sent by <strong>Ensemble</strong>, 5<strong>SOAP</strong>SESSION parameter, 24<strong>SOAP</strong> sessions<strong>and</strong> inbound adapter, 53enabling, 24SSL<strong>and</strong> inbound adapter, 53connecting to <strong>Web</strong> service via, 33SSLConfig setting, 33, 53startupcustomizing, 47details, 48StayConnected setting, 53StayConnected setting for inbound adapter, 52Tteardowncustomizing, 47details, 48TLS, connecting to <strong>Web</strong> service via, 33TYPENAMESPACE parameter, 11Uunqualified elements, 24URL for <strong>Web</strong> service, 20W<strong>Web</strong> clientsbasic settings, 32business operation class, 7configuring, 29connecting via a proxy server, 34connecting via SSL, 33creating, 29credentials, 32generated classes, 6, 34in <strong>Ensemble</strong>, 5parts of, 27<strong>Web</strong>Method keyword, 14, 38<strong>Web</strong>Method method, 34, 38, 40<strong>Web</strong> methodsbasic requirements, 14basic steps, 14example, 16other options, 24specifying destinations, 17, 23<strong>Web</strong>ServiceClientClass property/setting, 38<strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong> 57


<strong>Web</strong>ServiceClientClass setting, 32<strong>Web</strong> servicesadditional options, 24configuration tasks, 13connecting to, via SSL, 33creating, 11example, 21forwarding request <strong>with</strong>in production, 17, 23invoking from <strong>Ensemble</strong>, 5parts of, 9providing in <strong>Ensemble</strong>, 3returning <strong>SOAP</strong> faults, 15specifying location for client, 32supporting sessions, 24WSDL, 20<strong>Web</strong> <strong>Services</strong> Securityadding header to <strong>SOAP</strong> request, 32, 45<strong>Web</strong>ServiceURL setting, 32WSDLusing to generate client, 30viewing, 20WS-Securityadding header to <strong>SOAP</strong> request, 32, 45XXML, projecting objects <strong>and</strong> data sets, 14XMLKEEPCLASS parameter, 30XML typesadjusting generated classes, 29customizing, 24generated for <strong>Web</strong> client, 6namespace for, 11xsi:type attribute, 3058 <strong>Using</strong> <strong>SOAP</strong> <strong>and</strong> <strong>Web</strong> <strong>Services</strong> <strong>with</strong> <strong>Ensemble</strong>

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!